public static @Nullable Platform buildIfSupported() { // Attempt to find Android 5+ APIs. Class<?> sslParametersClass; Class<?> sslSocketClass; try { sslParametersClass = Class.forName("com.android.org.conscrypt.SSLParametersImpl"); sslSocketClass = Class.forName("com.android.org.conscrypt.OpenSSLSocketImpl"); } catch (ClassNotFoundException ignored) { return null; // Not an Android runtime. } if (Build.VERSION.SDK_INT >= 21) { try { Method setUseSessionTickets = sslSocketClass.getDeclaredMethod( "setUseSessionTickets", boolean.class); Method setHostname = sslSocketClass.getMethod("setHostname", String.class); Method getAlpnSelectedProtocol = sslSocketClass.getMethod("getAlpnSelectedProtocol"); Method setAlpnProtocols = sslSocketClass.getMethod("setAlpnProtocols", byte[].class); return new AndroidPlatform(sslParametersClass, setUseSessionTickets, setHostname, getAlpnSelectedProtocol, setAlpnProtocols); } catch (NoSuchMethodException ignored) { } } throw new IllegalStateException( "Expected Android API level 21+ but was " + Build.VERSION.SDK_INT); }
private boolean api24IsCleartextTrafficPermitted(String hostname, Class<?> networkPolicyClass, Object networkSecurityPolicy) throws InvocationTargetException, IllegalAccessException { try { Method isCleartextTrafficPermittedMethod = networkPolicyClass .getMethod("isCleartextTrafficPermitted", String.class); return (boolean) isCleartextTrafficPermittedMethod.invoke(networkSecurityPolicy, hostname); } catch (NoSuchMethodException e) { return api23IsCleartextTrafficPermitted(hostname, networkPolicyClass, networkSecurityPolicy); } }
@Override public boolean isCleartextTrafficPermitted(String hostname) { try { Class<?> networkPolicyClass = Class.forName("android.security.NetworkSecurityPolicy"); Method getInstanceMethod = networkPolicyClass.getMethod("getInstance"); Object networkSecurityPolicy = getInstanceMethod.invoke(null); return api24IsCleartextTrafficPermitted(hostname, networkPolicyClass, networkSecurityPolicy); } catch (ClassNotFoundException | NoSuchMethodException e) { return super.isCleartextTrafficPermitted(hostname); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new AssertionError("unable to determine cleartext support", e); } }
public static Platform buildIfSupported() { // Attempt to find Android 2.3+ APIs. try { Class<?> sslParametersClass; try { sslParametersClass = Class.forName("com.android.org.conscrypt.SSLParametersImpl"); } catch (ClassNotFoundException e) { // Older platform before being unbundled. sslParametersClass = Class.forName( "org.apache.harmony.xnet.provider.jsse.SSLParametersImpl"); } OptionalMethod<Socket> setUseSessionTickets = new OptionalMethod<>( null, "setUseSessionTickets", boolean.class); OptionalMethod<Socket> setHostname = new OptionalMethod<>( null, "setHostname", String.class); OptionalMethod<Socket> getAlpnSelectedProtocol = null; OptionalMethod<Socket> setAlpnProtocols = null; if (supportsAlpn()) { getAlpnSelectedProtocol = new OptionalMethod<>(byte[].class, "getAlpnSelectedProtocol"); setAlpnProtocols = new OptionalMethod<>(null, "setAlpnProtocols", byte[].class); } return new AndroidPlatform(sslParametersClass, setUseSessionTickets, setHostname, getAlpnSelectedProtocol, setAlpnProtocols); } catch (ClassNotFoundException ignored) { // This isn't an Android runtime. } return null; }
@Override public void logCloseableLeak(String message, Object stackTrace) { boolean reported = closeGuard.warnIfOpen(stackTrace); if (!reported) { // Unable to report via CloseGuard. As a last-ditch effort, send it to the logger. log(WARN, message, null); } }
@Override public void configureTlsExtensions( SSLSocket sslSocket, String hostname, List<Protocol> protocols) { try { // Enable SNI and session tickets. if (hostname != null) { setUseSessionTickets.invoke(sslSocket, true); // This is SSLParameters.setServerNames() in API 24+. setHostname.invoke(sslSocket, hostname); } // Enable ALPN. setAlpnProtocols.invoke(sslSocket, concatLengthPrefixed(protocols)); } catch (IllegalAccessException | InvocationTargetException e) { throw new AssertionError(e); } }
@Override protected @Nullable X509TrustManager trustManager(SSLSocketFactory sslSocketFactory) { Object context = readFieldOrNull(sslSocketFactory, sslParametersClass, "sslParameters"); if (context == null) { // If that didn't work, try the Google Play Services SSL provider before giving up. This // must be loaded by the SSLSocketFactory's class loader. try { Class<?> gmsSslParametersClass = Class.forName( "com.google.android.gms.org.conscrypt.SSLParametersImpl", false, sslSocketFactory.getClass().getClassLoader()); context = readFieldOrNull(sslSocketFactory, gmsSslParametersClass, "sslParameters"); } catch (ClassNotFoundException e) { return super.trustManager(sslSocketFactory); } } X509TrustManager x509TrustManager = readFieldOrNull( context, X509TrustManager.class, "x509TrustManager"); if (x509TrustManager != null) return x509TrustManager; return readFieldOrNull(context, X509TrustManager.class, "trustManager"); }
/** Attempt to match the host runtime to a capable Platform implementation. */ private static Platform findPlatform() { Platform android = AndroidPlatform.buildIfSupported(); if (android != null) { return android; } if (isConscryptPreferred()) { Platform conscrypt = ConscryptPlatform.buildIfSupported(); if (conscrypt != null) { return conscrypt; } } Platform jdk9 = Jdk9Platform.buildIfSupported(); if (jdk9 != null) { return jdk9; } Platform jdkWithJettyBoot = Jdk8WithJettyBootPlatform.buildIfSupported(); if (jdkWithJettyBoot != null) { return jdkWithJettyBoot; } // Probably an Oracle JDK like OpenJDK. return new Platform(); }
public static Platform buildIfSupported() { // Attempt to find Android 2.3+ APIs. try { Class<?> sslParametersClass; try { sslParametersClass = Class.forName("com.android.org.conscrypt.SSLParametersImpl"); } catch (ClassNotFoundException e) { // Older platform before being unbundled. sslParametersClass = Class.forName( "org.apache.harmony.xnet.provider.jsse.SSLParametersImpl"); } OptionalMethod<Socket> setUseSessionTickets = new OptionalMethod<>( null, "setUseSessionTickets", boolean.class); OptionalMethod<Socket> setHostname = new OptionalMethod<>( null, "setHostname", String.class); OptionalMethod<Socket> getAlpnSelectedProtocol = null; OptionalMethod<Socket> setAlpnProtocols = null; if (supportsAlpn()) { getAlpnSelectedProtocol = new OptionalMethod<>(byte[].class, "getAlpnSelectedProtocol"); setAlpnProtocols = new OptionalMethod<>(null, "setAlpnProtocols", byte[].class); } return new AndroidPlatform(sslParametersClass, setUseSessionTickets, setHostname, getAlpnSelectedProtocol, setAlpnProtocols); } catch (ClassNotFoundException ignored) { // This isn't an Android runtime. } return null; }
@Override public void logCloseableLeak(String message, Object stackTrace) { boolean reported = closeGuard.warnIfOpen(stackTrace); if (!reported) { // Unable to report via CloseGuard. As a last-ditch effort, send it to the logger. log(WARN, message, null); } }
@Override public void configureTlsExtensions( SSLSocket sslSocket, String hostname, List<Protocol> protocols) { if (!sslSocketClass.isInstance(sslSocket)) { return; // No TLS extensions if the socket class is custom. } try { // Enable SNI and session tickets. if (hostname != null) { setUseSessionTickets.invoke(sslSocket, true); // This is SSLParameters.setServerNames() in API 24+. setHostname.invoke(sslSocket, hostname); } // Enable ALPN. setAlpnProtocols.invoke(sslSocket, concatLengthPrefixed(protocols)); } catch (IllegalAccessException | InvocationTargetException e) { throw new AssertionError(e); } }
@Override protected @Nullable X509TrustManager trustManager(SSLSocketFactory sslSocketFactory) { Object context = readFieldOrNull(sslSocketFactory, sslParametersClass, "sslParameters"); if (context == null) { // If that didn't work, try the Google Play Services SSL provider before giving up. This // must be loaded by the SSLSocketFactory's class loader. try { Class<?> gmsSslParametersClass = Class.forName( "com.google.android.gms.org.conscrypt.SSLParametersImpl", false, sslSocketFactory.getClass().getClassLoader()); context = readFieldOrNull(sslSocketFactory, gmsSslParametersClass, "sslParameters"); } catch (ClassNotFoundException e) { return super.trustManager(sslSocketFactory); } } X509TrustManager x509TrustManager = readFieldOrNull( context, X509TrustManager.class, "x509TrustManager"); if (x509TrustManager != null) return x509TrustManager; return readFieldOrNull(context, X509TrustManager.class, "trustManager"); }
/** Attempt to match the host runtime to a capable Platform implementation. */ private static Platform findPlatform() { Platform android = AndroidPlatform.buildIfSupported(); if (android != null) { return android; } if (isConscryptPreferred()) { Platform conscrypt = ConscryptPlatform.buildIfSupported(); if (conscrypt != null) { return conscrypt; } } Platform jdk9 = Jdk9Platform.buildIfSupported(); if (jdk9 != null) { return jdk9; } Platform jdkWithJettyBoot = Jdk8WithJettyBootPlatform.buildIfSupported(); if (jdkWithJettyBoot != null) { return jdkWithJettyBoot; } // Probably an Oracle JDK like OpenJDK. return new Platform(); }
@Override public boolean isCleartextTrafficPermitted(String hostname) { try { Class<?> networkPolicyClass = Class.forName("android.security.NetworkSecurityPolicy"); Method getInstanceMethod = networkPolicyClass.getMethod("getInstance"); Object networkSecurityPolicy = getInstanceMethod.invoke(null); return api24IsCleartextTrafficPermitted(hostname, networkPolicyClass, networkSecurityPolicy); } catch (ClassNotFoundException | NoSuchMethodException e) { return super.isCleartextTrafficPermitted(hostname); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new AssertionError("unable to determine cleartext support", e); } }
private boolean api24IsCleartextTrafficPermitted(String hostname, Class<?> networkPolicyClass, Object networkSecurityPolicy) throws InvocationTargetException, IllegalAccessException { try { Method isCleartextTrafficPermittedMethod = networkPolicyClass .getMethod("isCleartextTrafficPermitted", String.class); return (boolean) isCleartextTrafficPermittedMethod.invoke(networkSecurityPolicy, hostname); } catch (NoSuchMethodException e) { return api23IsCleartextTrafficPermitted(hostname, networkPolicyClass, networkSecurityPolicy); } }
@Override public void logCloseableLeak(String message, Object stackTrace) { boolean reported = closeGuard.warnIfOpen(stackTrace); if (!reported) { // Unable to report via CloseGuard. As a last-ditch effort, send it to the logger. log(WARN, message, null); } }
@Override public void configureTlsExtensions( SSLSocket sslSocket, String hostname, List<Protocol> protocols) { // Enable SNI and session tickets. if (hostname != null) { setUseSessionTickets.invokeOptionalWithoutCheckedException(sslSocket, true); setHostname.invokeOptionalWithoutCheckedException(sslSocket, hostname); } // Enable ALPN. if (setAlpnProtocols != null && setAlpnProtocols.isSupported(sslSocket)) { Object[] parameters = {concatLengthPrefixed(protocols)}; setAlpnProtocols.invokeWithoutCheckedException(sslSocket, parameters); } }
@Override protected X509TrustManager trustManager(SSLSocketFactory sslSocketFactory) { Object context = readFieldOrNull(sslSocketFactory, sslParametersClass, "sslParameters"); if (context == null) { // If that didn't work, try the Google Play Services SSL provider before giving up. This // must be loaded by the SSLSocketFactory's class loader. try { Class<?> gmsSslParametersClass = Class.forName( "com.google.android.gms.org.conscrypt.SSLParametersImpl", false, sslSocketFactory.getClass().getClassLoader()); context = readFieldOrNull(sslSocketFactory, gmsSslParametersClass, "sslParameters"); } catch (ClassNotFoundException e) { return super.trustManager(sslSocketFactory); } } X509TrustManager x509TrustManager = readFieldOrNull( context, X509TrustManager.class, "x509TrustManager"); if (x509TrustManager != null) return x509TrustManager; return readFieldOrNull(context, X509TrustManager.class, "trustManager"); }
/** Attempt to match the host runtime to a capable Platform implementation. */ private static Platform findPlatform() { Platform android = AndroidPlatform.buildIfSupported(); if (android != null) { return android; } Platform jdk9 = Jdk9Platform.buildIfSupported(); if (jdk9 != null) { return jdk9; } Platform jdkWithJettyBoot = JdkWithJettyBootPlatform.buildIfSupported(); if (jdkWithJettyBoot != null) { return jdkWithJettyBoot; } // Probably an Oracle JDK like OpenJDK. return new Platform(); }
public static @Nullable Platform buildIfSupported() { // Attempt to find Android 5+ APIs. Class<?> sslParametersClass; Class<?> sslSocketClass; try { sslParametersClass = Class.forName("com.android.org.conscrypt.SSLParametersImpl"); sslSocketClass = Class.forName("com.android.org.conscrypt.OpenSSLSocketImpl"); } catch (ClassNotFoundException ignored) { return null; // Not an Android runtime. } if (Build.VERSION.SDK_INT >= 21) { try { Method setUseSessionTickets = sslSocketClass.getDeclaredMethod( "setUseSessionTickets", boolean.class); Method setHostname = sslSocketClass.getMethod("setHostname", String.class); Method getAlpnSelectedProtocol = sslSocketClass.getMethod("getAlpnSelectedProtocol"); Method setAlpnProtocols = sslSocketClass.getMethod("setAlpnProtocols", byte[].class); return new AndroidPlatform(sslParametersClass, sslSocketClass, setUseSessionTickets, setHostname, getAlpnSelectedProtocol, setAlpnProtocols); } catch (NoSuchMethodException ignored) { } } throw new IllegalStateException( "Expected Android API level 21+ but was " + Build.VERSION.SDK_INT); }