Cleanup Conscrypt initialization (#10466)

Motivation:

How we init our static fields in Conscrypt was kind of error-prone and may even lead to NPE later on when methods were invoked out of order.

Modifications:

- Move all the init code to a static block
- Remove static field which is not needed anymore

Result:

Cleanup and also fixes https://github.com/netty/netty/issues/10413
This commit is contained in:
Norman Maurer 2020-08-11 21:00:51 +02:00 committed by GitHub
parent cfeda0fef2
commit 564e817cfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -27,49 +27,43 @@ import java.lang.reflect.Method;
final class Conscrypt { final class Conscrypt {
// This class exists to avoid loading other conscrypt related classes using features only available in JDK8+, // This class exists to avoid loading other conscrypt related classes using features only available in JDK8+,
// because we need to maintain JDK6+ runtime compatibility. // because we need to maintain JDK6+ runtime compatibility.
private static final Method IS_CONSCRYPT_SSLENGINE = loadIsConscryptEngine(); private static final Method IS_CONSCRYPT_SSLENGINE;
private static final boolean CAN_INSTANCE_PROVIDER = canInstanceProvider();
private static Method loadIsConscryptEngine() { static {
try { Method isConscryptSSLEngine = null;
Class<?> conscryptClass = Class.forName("org.conscrypt.Conscrypt", true,
ConscryptAlpnSslEngine.class.getClassLoader());
return conscryptClass.getMethod("isConscrypt", SSLEngine.class);
} catch (Throwable ignore) {
// Conscrypt was not loaded.
return null;
}
}
private static boolean canInstanceProvider() { if ((PlatformDependent.javaVersion() >= 8 &&
try { // Only works on Java14 and earlier for now
Class<?> providerClass = Class.forName("org.conscrypt.OpenSSLProvider", true, // See https://github.com/google/conscrypt/issues/838
ConscryptAlpnSslEngine.class.getClassLoader()); PlatformDependent.javaVersion() < 15) || PlatformDependent.isAndroid()) {
providerClass.newInstance(); try {
return true; Class<?> providerClass = Class.forName("org.conscrypt.OpenSSLProvider", true,
} catch (Throwable ignore) { PlatformDependent.getClassLoader(ConscryptAlpnSslEngine.class));
return false; providerClass.newInstance();
Class<?> conscryptClass = Class.forName("org.conscrypt.Conscrypt", true,
PlatformDependent.getClassLoader(ConscryptAlpnSslEngine.class));
isConscryptSSLEngine = conscryptClass.getMethod("isConscrypt", SSLEngine.class);
} catch (Throwable ignore) {
// ignore
}
} }
IS_CONSCRYPT_SSLENGINE = isConscryptSSLEngine;
} }
/** /**
* Indicates whether or not conscrypt is available on the current system. * Indicates whether or not conscrypt is available on the current system.
*/ */
static boolean isAvailable() { static boolean isAvailable() {
return CAN_INSTANCE_PROVIDER && IS_CONSCRYPT_SSLENGINE != null && return IS_CONSCRYPT_SSLENGINE != null;
((PlatformDependent.javaVersion() >= 8 &&
// Only works on Java14 and earlier for now
// See https://github.com/google/conscrypt/issues/838
PlatformDependent.javaVersion() < 15) || PlatformDependent.isAndroid());
} }
/**
* Returns {@code true} if the passed in {@link SSLEngine} is handled by Conscrypt, {@code false} otherwise.
*/
static boolean isEngineSupported(SSLEngine engine) { static boolean isEngineSupported(SSLEngine engine) {
return isAvailable() && isConscryptEngine(engine);
}
private static boolean isConscryptEngine(SSLEngine engine) {
try { try {
return (Boolean) IS_CONSCRYPT_SSLENGINE.invoke(null, engine); return IS_CONSCRYPT_SSLENGINE != null && (Boolean) IS_CONSCRYPT_SSLENGINE.invoke(null, engine);
} catch (IllegalAccessException ignore) { } catch (IllegalAccessException ignore) {
return false; return false;
} catch (InvocationTargetException ex) { } catch (InvocationTargetException ex) {