Skip to content

Commit

Permalink
Add support for enabling/disabling TLS v1.0 and 1.1 in Conscrypt. (#1273
Browse files Browse the repository at this point in the history
)

* Re-add stats-log class for conscrypt metrics

This class is created by codegen in the gmscore version of conscrypt and so we need the logging path to go through it in order for it to be replaced in gmscore
  • Loading branch information
miguelaranda0 authored Dec 16, 2024
1 parent de879b1 commit 29fc037
Show file tree
Hide file tree
Showing 10 changed files with 233 additions and 107 deletions.
18 changes: 14 additions & 4 deletions android/src/main/java/org/conscrypt/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,21 @@
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.StandardConstants;
import javax.net.ssl.X509TrustManager;
import org.conscrypt.NativeCrypto;

/**
* Platform-specific methods for unbundled Android.
*/
@Internal
final public class Platform {
private static final String TAG = "Conscrypt";
static boolean DEPRECATED_TLS_V1 = true;
static boolean ENABLED_TLS_V1 = false;
private static boolean FILTERED_TLS_V1 = true;

private static Method m_getCurveName;
static {
NativeCrypto.setTlsV1DeprecationStatus(DEPRECATED_TLS_V1, ENABLED_TLS_V1);
try {
m_getCurveName = ECParameterSpec.class.getDeclaredMethod("getCurveName");
m_getCurveName.setAccessible(true);
Expand All @@ -89,7 +94,12 @@ final public class Platform {

private Platform() {}

public static void setup() {}
public static void setup(boolean deprecatedTlsV1, boolean enabledTlsV1) {
DEPRECATED_TLS_V1 = deprecatedTlsV1;
ENABLED_TLS_V1 = enabledTlsV1;
FILTERED_TLS_V1 = !enabledTlsV1;
NativeCrypto.setTlsV1DeprecationStatus(DEPRECATED_TLS_V1, ENABLED_TLS_V1);
}

/**
* Default name used in the {@link java.security.Security JCE system} by {@code OpenSSLProvider}
Expand Down Expand Up @@ -955,14 +965,14 @@ public static boolean isJavaxCertificateSupported() {
}

public static boolean isTlsV1Deprecated() {
return true;
return DEPRECATED_TLS_V1;
}

public static boolean isTlsV1Filtered() {
return false;
return FILTERED_TLS_V1;
}

public static boolean isTlsV1Supported() {
return false;
return ENABLED_TLS_V1;
}
}
17 changes: 16 additions & 1 deletion common/src/main/java/org/conscrypt/Conscrypt.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ public static class ProviderBuilder {
private String name = Platform.getDefaultProviderName();
private boolean provideTrustManager = Platform.provideTrustManagerByDefault();
private String defaultTlsProtocol = NativeCrypto.SUPPORTED_PROTOCOL_TLSV1_3;
private boolean deprecatedTlsV1 = true;
private boolean enabledTlsV1 = false;

private ProviderBuilder() {}

Expand Down Expand Up @@ -200,8 +202,21 @@ public ProviderBuilder defaultTlsProtocol(String defaultTlsProtocol) {
return this;
}

/** Specifies whether TLS v1.0 and 1.1 should be deprecated */
public ProviderBuilder isTlsV1Deprecated(boolean deprecatedTlsV1) {
this.deprecatedTlsV1 = deprecatedTlsV1;
return this;
}

/** Specifies whether TLS v1.0 and 1.1 should be enabled */
public ProviderBuilder isTlsV1Enabled(boolean enabledTlsV1) {
this.enabledTlsV1 = enabledTlsV1;
return this;
}

public Provider build() {
return new OpenSSLProvider(name, provideTrustManager, defaultTlsProtocol);
return new OpenSSLProvider(name, provideTrustManager,
defaultTlsProtocol, deprecatedTlsV1, enabledTlsV1);
}
}

Expand Down
59 changes: 35 additions & 24 deletions common/src/main/java/org/conscrypt/NativeCrypto.java
Original file line number Diff line number Diff line change
Expand Up @@ -1025,29 +1025,48 @@ static native void SSL_set_client_CA_list(long ssl, NativeSsl ssl_holder, byte[]

static native void set_SSL_psk_server_callback_enabled(long ssl, NativeSsl ssl_holder, boolean enabled);

private static final String[] ENABLED_PROTOCOLS_TLSV1 = Platform.isTlsV1Deprecated()
? new String[0]
: new String[] {
public static void setTlsV1DeprecationStatus(boolean deprecated, boolean supported) {
if (deprecated) {
TLSV12_PROTOCOLS = new String[] {
SUPPORTED_PROTOCOL_TLSV1_2,
};
TLSV13_PROTOCOLS = new String[] {
SUPPORTED_PROTOCOL_TLSV1_2,
SUPPORTED_PROTOCOL_TLSV1_3,
};
} else {
TLSV12_PROTOCOLS = new String[] {
DEPRECATED_PROTOCOL_TLSV1,
DEPRECATED_PROTOCOL_TLSV1_1,
SUPPORTED_PROTOCOL_TLSV1_2,
};

private static final String[] SUPPORTED_PROTOCOLS_TLSV1 = Platform.isTlsV1Supported()
? new String[] {
TLSV13_PROTOCOLS = new String[] {
DEPRECATED_PROTOCOL_TLSV1,
DEPRECATED_PROTOCOL_TLSV1_1,
} : new String[0];
SUPPORTED_PROTOCOL_TLSV1_2,
SUPPORTED_PROTOCOL_TLSV1_3,
};
}
if (supported) {
SUPPORTED_PROTOCOLS = new String[] {
DEPRECATED_PROTOCOL_TLSV1,
DEPRECATED_PROTOCOL_TLSV1_1,
SUPPORTED_PROTOCOL_TLSV1_2,
SUPPORTED_PROTOCOL_TLSV1_3,
};
} else {
SUPPORTED_PROTOCOLS = new String[] {
SUPPORTED_PROTOCOL_TLSV1_2,
SUPPORTED_PROTOCOL_TLSV1_3,
};
}
}

/** Protocols to enable by default when "TLSv1.3" is requested. */
static final String[] TLSV13_PROTOCOLS = ArrayUtils.concatValues(
ENABLED_PROTOCOLS_TLSV1,
SUPPORTED_PROTOCOL_TLSV1_2,
SUPPORTED_PROTOCOL_TLSV1_3);
static String[] TLSV13_PROTOCOLS;

/** Protocols to enable by default when "TLSv1.2" is requested. */
static final String[] TLSV12_PROTOCOLS = ArrayUtils.concatValues(
ENABLED_PROTOCOLS_TLSV1,
SUPPORTED_PROTOCOL_TLSV1_2);
static String[] TLSV12_PROTOCOLS;

/** Protocols to enable by default when "TLSv1.1" is requested. */
static final String[] TLSV11_PROTOCOLS = new String[] {
Expand All @@ -1059,20 +1078,12 @@ static native void SSL_set_client_CA_list(long ssl, NativeSsl ssl_holder, byte[]
/** Protocols to enable by default when "TLSv1" is requested. */
static final String[] TLSV1_PROTOCOLS = TLSV11_PROTOCOLS;

static final String[] DEFAULT_PROTOCOLS = TLSV13_PROTOCOLS;

// If we ever get a new protocol go look for tests which are skipped using
// assumeTlsV11Enabled()
private static final String[] SUPPORTED_PROTOCOLS = ArrayUtils.concatValues(
SUPPORTED_PROTOCOLS_TLSV1,
SUPPORTED_PROTOCOL_TLSV1_2,
SUPPORTED_PROTOCOL_TLSV1_3);
private static String[] SUPPORTED_PROTOCOLS;

public static String[] getDefaultProtocols() {
if (Platform.isTlsV1Deprecated()) {
return DEFAULT_PROTOCOLS.clone();
}
return SUPPORTED_PROTOCOLS.clone();
return TLSV13_PROTOCOLS.clone();
}

static String[] getSupportedProtocols() {
Expand Down
18 changes: 15 additions & 3 deletions common/src/main/java/org/conscrypt/OpenSSLProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,29 @@ public OpenSSLProvider() {

@SuppressWarnings("deprecation")
public OpenSSLProvider(String providerName) {
this(providerName, Platform.provideTrustManagerByDefault(), "TLSv1.3");
this(providerName, Platform.provideTrustManagerByDefault(), "TLSv1.3",
Platform.DEPRECATED_TLS_V1, Platform.ENABLED_TLS_V1);
}

OpenSSLProvider(String providerName, boolean includeTrustManager, String defaultTlsProtocol) {
OpenSSLProvider(String providerName, boolean includeTrustManager,
String defaultTlsProtocol) {
this(providerName, includeTrustManager, defaultTlsProtocol,
Platform.DEPRECATED_TLS_V1, Platform.ENABLED_TLS_V1);
}

OpenSSLProvider(String providerName, boolean includeTrustManager,
String defaultTlsProtocol, boolean deprecatedTlsV1,
boolean enabledTlsV1) {
super(providerName, 1.0, "Android's OpenSSL-backed security provider");

// Ensure that the native library has been loaded.
NativeCrypto.checkAvailability();

if (!deprecatedTlsV1 && !enabledTlsV1) {
throw new IllegalArgumentException("TLSv1 is not deprecated and cannot be disabled.");
}
// Make sure the platform is initialized.
Platform.setup();
Platform.setup(deprecatedTlsV1, enabledTlsV1);

/* === SSL Contexts === */
String classOpenSSLContextImpl = PREFIX + "OpenSSLContextImpl";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1837,22 +1837,6 @@ public void test_SSLSocket_TLSv1Supported() throws Exception {
}
}

// @TargetSdkVersion(35)
@Test
public void test_SSLSocket_SSLv3Unsupported_35() throws Exception {
assumeFalse(isTlsV1Filtered());
TestSSLContext context = new TestSSLContext.Builder()
.clientProtocol(clientVersion)
.serverProtocol(serverVersion)
.build();
final SSLSocket client =
(SSLSocket) context.clientContext.getSocketFactory().createSocket();
assertThrows(IllegalArgumentException.class,
() -> client.setEnabledProtocols(new String[] {"SSLv3"}));
assertThrows(IllegalArgumentException.class,
() -> client.setEnabledProtocols(new String[] {"SSL"}));
}

// @TargetSdkVersion(34)
@Test
@Ignore("For platform CTS only")
Expand Down Expand Up @@ -1889,20 +1873,6 @@ public void test_TLSv1Filtered_34() throws Exception {
assertEquals("TLSv1.2", client.getEnabledProtocols()[0]);
}

// @TargetSdkVersion(35)
@Test
public void test_TLSv1Filtered_35() throws Exception {
assumeTrue(isTlsV1Filtered());
TestSSLContext context = new TestSSLContext.Builder()
.clientProtocol(clientVersion)
.serverProtocol(serverVersion)
.build();
final SSLSocket client =
(SSLSocket) context.clientContext.getSocketFactory().createSocket();
assertThrows(IllegalArgumentException.class, () ->
client.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"}));
}

@Test
public void test_TLSv1Unsupported_notEnabled() {
assumeTrue(!isTlsV1Supported());
Expand Down
19 changes: 14 additions & 5 deletions openjdk/src/main/java/org/conscrypt/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedTrustManager;
import javax.net.ssl.X509TrustManager;
import org.conscrypt.NativeCrypto;

/**
* Platform-specific methods for OpenJDK.
Expand All @@ -94,9 +95,12 @@
final public class Platform {
private static final int JAVA_VERSION = javaVersion0();
private static final Method GET_CURVE_NAME_METHOD;
static boolean DEPRECATED_TLS_V1 = true;
static boolean ENABLED_TLS_V1 = false;
private static boolean FILTERED_TLS_V1 = true;

static {

NativeCrypto.setTlsV1DeprecationStatus(DEPRECATED_TLS_V1, ENABLED_TLS_V1);
Method getCurveNameMethod = null;
try {
getCurveNameMethod = ECParameterSpec.class.getDeclaredMethod("getCurveName");
Expand All @@ -109,7 +113,12 @@ final public class Platform {

private Platform() {}

static void setup() {}
public static void setup(boolean deprecatedTlsV1, boolean enabledTlsV1) {
DEPRECATED_TLS_V1 = deprecatedTlsV1;
ENABLED_TLS_V1 = enabledTlsV1;
FILTERED_TLS_V1 = !enabledTlsV1;
NativeCrypto.setTlsV1DeprecationStatus(DEPRECATED_TLS_V1, ENABLED_TLS_V1);
}


/**
Expand Down Expand Up @@ -839,14 +848,14 @@ public static boolean isJavaxCertificateSupported() {
}

public static boolean isTlsV1Deprecated() {
return true;
return DEPRECATED_TLS_V1;
}

public static boolean isTlsV1Filtered() {
return false;
return FILTERED_TLS_V1;
}

public static boolean isTlsV1Supported() {
return true;
return ENABLED_TLS_V1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ public AbstractConscryptSocket createSocket(ServerSocket listener) throws IOExce
+ ": " + connection.clientException.getMessage(),
connection.clientException instanceof SSLHandshakeException);
assertTrue(
connection.clientException.getMessage().contains("SSLv3 is no longer supported"));
connection.clientException.getMessage().contains("SSLv3"));
assertTrue("Expected SSLHandshakeException, but got "
+ connection.serverException.getClass().getSimpleName()
+ ": " + connection.serverException.getMessage(),
Expand Down
46 changes: 29 additions & 17 deletions platform/src/main/java/org/conscrypt/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,30 @@
import javax.net.ssl.StandardConstants;
import javax.net.ssl.X509ExtendedTrustManager;
import javax.net.ssl.X509TrustManager;

import libcore.net.NetworkSecurityPolicy;
import org.conscrypt.NativeCrypto;
import sun.security.x509.AlgorithmId;

@Internal
final public class Platform {
private static class NoPreloadHolder { public static final Platform MAPPER = new Platform(); }
static boolean DEPRECATED_TLS_V1 = true;
static boolean ENABLED_TLS_V1 = false;
private static boolean FILTERED_TLS_V1 = true;

static {
NativeCrypto.setTlsV1DeprecationStatus(DEPRECATED_TLS_V1, ENABLED_TLS_V1);
}

/**
* Runs all the setup for the platform that only needs to run once.
*/
public static void setup() {
public static void setup(boolean deprecatedTlsV1, boolean enabledTlsV1) {
DEPRECATED_TLS_V1 = deprecatedTlsV1;
ENABLED_TLS_V1 = enabledTlsV1;
FILTERED_TLS_V1 = !enabledTlsV1;
NoPreloadHolder.MAPPER.ping();
NativeCrypto.setTlsV1DeprecationStatus(DEPRECATED_TLS_V1, ENABLED_TLS_V1);
}

/**
Expand Down Expand Up @@ -552,34 +564,34 @@ public static boolean isJavaxCertificateSupported() {
}

public static boolean isTlsV1Deprecated() {
return true;
return DEPRECATED_TLS_V1;
}

public static boolean isTlsV1Filtered() {
Object targetSdkVersion = getTargetSdkVersion();
if ((targetSdkVersion != null) && ((int) targetSdkVersion > 34))
if ((targetSdkVersion != null) && ((int) targetSdkVersion > 35)
&& ((int) targetSdkVersion < 100))
return false;
return true;
return FILTERED_TLS_V1;
}

public static boolean isTlsV1Supported() {
return false;
return ENABLED_TLS_V1;
}

static Object getTargetSdkVersion() {
try {
Class<?> vmRuntime = Class.forName("dalvik.system.VMRuntime");
if (vmRuntime == null) {
return null;
}
OptionalMethod getSdkVersion =
new OptionalMethod(vmRuntime,
"getTargetSdkVersion");
return getSdkVersion.invokeStatic();
} catch (ClassNotFoundException e) {
return null;
} catch (NullPointerException e) {
Class<?> vmRuntimeClass = Class.forName("dalvik.system.VMRuntime");
Method getRuntimeMethod = vmRuntimeClass.getDeclaredMethod("getRuntime");
Method getTargetSdkVersionMethod =
vmRuntimeClass.getDeclaredMethod("getTargetSdkVersion");
Object vmRuntime = getRuntimeMethod.invoke(null);
return getTargetSdkVersionMethod.invoke(vmRuntime);
} catch (IllegalAccessException |
NullPointerException | InvocationTargetException e) {
return null;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Loading

0 comments on commit 29fc037

Please sign in to comment.