diff --git a/handler/src/main/java/io/netty/handler/ssl/Conscrypt.java b/handler/src/main/java/io/netty/handler/ssl/Conscrypt.java new file mode 100644 index 0000000000..d50333ea54 --- /dev/null +++ b/handler/src/main/java/io/netty/handler/ssl/Conscrypt.java @@ -0,0 +1,70 @@ +/* + * Copyright 2017 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.ssl; + +import io.netty.util.internal.PlatformDependent; + +import javax.net.ssl.SSLEngine; +import java.lang.reflect.Method; + +/** + * Contains methods that can be used to detect if conscrypt is usable. + */ +final class Conscrypt { + // This class exists to avoid loading other conscrypt related classes using features only available in JDK8+, + // because we need to maintain JDK6+ runtime compatibility. + private static final Class ENGINES_CLASS = getEnginesClass(); + + /** + * Indicates whether or not conscrypt is available on the current system. + */ + static boolean isAvailable() { + return ENGINES_CLASS != null && PlatformDependent.javaVersion() >= 8; + } + + static boolean isEngineSupported(SSLEngine engine) { + return isAvailable() && isConscryptEngine(engine, ENGINES_CLASS); + } + + private static Class getEnginesClass() { + try { + // Always use bootstrap class loader. + Class engineClass = Class.forName("org.conscrypt.Conscrypt$Engines", true, + ConscryptAlpnSslEngine.class.getClassLoader()); + // Ensure that it also has the isConscrypt method. + getIsConscryptMethod(engineClass); + return engineClass; + } catch (Throwable ignore) { + // Conscrypt was not loaded. + return null; + } + } + + private static boolean isConscryptEngine(SSLEngine engine, Class enginesClass) { + try { + Method method = getIsConscryptMethod(enginesClass); + return (Boolean) method.invoke(null, engine); + } catch (Throwable ignore) { + return false; + } + } + + private static Method getIsConscryptMethod(Class enginesClass) throws NoSuchMethodException { + return enginesClass.getMethod("isConscrypt", SSLEngine.class); + } + + private Conscrypt() { } +} diff --git a/handler/src/main/java/io/netty/handler/ssl/ConscryptAlpnSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/ConscryptAlpnSslEngine.java index a61a14aabe..edbe7be895 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ConscryptAlpnSslEngine.java +++ b/handler/src/main/java/io/netty/handler/ssl/ConscryptAlpnSslEngine.java @@ -23,7 +23,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelectionListener; import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector; -import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.util.Collections; import java.util.LinkedHashSet; @@ -32,7 +31,6 @@ import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLException; -import io.netty.util.internal.PlatformDependent; import io.netty.util.internal.SystemPropertyUtil; import org.conscrypt.AllocatedBuffer; import org.conscrypt.BufferAllocator; @@ -45,18 +43,6 @@ import org.conscrypt.HandshakeListener; abstract class ConscryptAlpnSslEngine extends JdkSslEngine { private static final boolean USE_BUFFER_ALLOCATOR = SystemPropertyUtil.getBoolean( "io.netty.handler.ssl.conscrypt.useBufferAllocator", true); - private static final Class ENGINES_CLASS = getEnginesClass(); - - /** - * Indicates whether or not conscrypt is available on the current system. - */ - static boolean isAvailable() { - return ENGINES_CLASS != null && PlatformDependent.javaVersion() >= 8; - } - - static boolean isEngineSupported(SSLEngine engine) { - return isAvailable() && isConscryptEngine(engine, ENGINES_CLASS); - } static ConscryptAlpnSslEngine newClientEngine(SSLEngine engine, ByteBufAllocator alloc, JdkApplicationProtocolNegotiator applicationNegotiator) { @@ -168,33 +154,6 @@ abstract class ConscryptAlpnSslEngine extends JdkSslEngine { } } - private static Class getEnginesClass() { - try { - // Always use bootstrap class loader. - Class engineClass = Class.forName("org.conscrypt.Conscrypt$Engines", true, - ConscryptAlpnSslEngine.class.getClassLoader()); - // Ensure that it also has the isConscrypt method. - getIsConscryptMethod(engineClass); - return engineClass; - } catch (Throwable ignore) { - // Conscrypt was not loaded. - return null; - } - } - - private static boolean isConscryptEngine(SSLEngine engine, Class enginesClass) { - try { - Method method = getIsConscryptMethod(enginesClass); - return (Boolean) method.invoke(null, engine); - } catch (Throwable ignore) { - return false; - } - } - - private static Method getIsConscryptMethod(Class enginesClass) throws NoSuchMethodException { - return enginesClass.getMethod("isConscrypt", SSLEngine.class); - } - private static final class BufferAllocatorAdapter extends BufferAllocator { private final ByteBufAllocator alloc; @@ -214,7 +173,7 @@ abstract class ConscryptAlpnSslEngine extends JdkSslEngine { BufferAdapter(ByteBuf nettyBuffer) { this.nettyBuffer = nettyBuffer; - this.buffer = nettyBuffer.nioBuffer(0, nettyBuffer.capacity()); + buffer = nettyBuffer.nioBuffer(0, nettyBuffer.capacity()); } @Override diff --git a/handler/src/main/java/io/netty/handler/ssl/JdkAlpnApplicationProtocolNegotiator.java b/handler/src/main/java/io/netty/handler/ssl/JdkAlpnApplicationProtocolNegotiator.java index 684d607015..66536f4901 100644 --- a/handler/src/main/java/io/netty/handler/ssl/JdkAlpnApplicationProtocolNegotiator.java +++ b/handler/src/main/java/io/netty/handler/ssl/JdkAlpnApplicationProtocolNegotiator.java @@ -22,7 +22,7 @@ import javax.net.ssl.SSLEngine; * The {@link JdkApplicationProtocolNegotiator} to use if you need ALPN and are using {@link SslProvider#JDK}. */ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicationProtocolNegotiator { - private static final boolean AVAILABLE = ConscryptAlpnSslEngine.isAvailable() || JettyAlpnSslEngine.isAvailable(); + private static final boolean AVAILABLE = Conscrypt.isAvailable() || JettyAlpnSslEngine.isAvailable(); private static final SslEngineWrapperFactory ALPN_WRAPPER = AVAILABLE ? new AlpnWrapper() : new FailureWrapper(); /** @@ -122,7 +122,7 @@ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicati @Override public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { - if (ConscryptAlpnSslEngine.isEngineSupported(engine)) { + if (Conscrypt.isEngineSupported(engine)) { return isServer ? ConscryptAlpnSslEngine.newServerEngine(engine, alloc, applicationNegotiator) : ConscryptAlpnSslEngine.newClientEngine(engine, alloc, applicationNegotiator); } diff --git a/handler/src/test/java/io/netty/handler/ssl/ConscryptJdkSslEngineInteropTest.java b/handler/src/test/java/io/netty/handler/ssl/ConscryptJdkSslEngineInteropTest.java index d51487a877..870f71ef36 100644 --- a/handler/src/test/java/io/netty/handler/ssl/ConscryptJdkSslEngineInteropTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/ConscryptJdkSslEngineInteropTest.java @@ -46,7 +46,7 @@ public class ConscryptJdkSslEngineInteropTest extends SSLEngineTest { @BeforeClass public static void checkConscrypt() { - assumeTrue(ConscryptAlpnSslEngine.isAvailable()); + assumeTrue(Conscrypt.isAvailable()); } @Override diff --git a/handler/src/test/java/io/netty/handler/ssl/JdkConscryptSslEngineInteropTest.java b/handler/src/test/java/io/netty/handler/ssl/JdkConscryptSslEngineInteropTest.java index 0625f7aed5..6d8862a0f2 100644 --- a/handler/src/test/java/io/netty/handler/ssl/JdkConscryptSslEngineInteropTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/JdkConscryptSslEngineInteropTest.java @@ -46,7 +46,7 @@ public class JdkConscryptSslEngineInteropTest extends SSLEngineTest { @BeforeClass public static void checkConscrypt() { - assumeTrue(ConscryptAlpnSslEngine.isAvailable()); + assumeTrue(Conscrypt.isAvailable()); } @Override diff --git a/handler/src/test/java/io/netty/handler/ssl/JdkSslEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/JdkSslEngineTest.java index d68e5ccec1..c1205130fc 100644 --- a/handler/src/test/java/io/netty/handler/ssl/JdkSslEngineTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/JdkSslEngineTest.java @@ -81,7 +81,7 @@ public class JdkSslEngineTest extends SSLEngineTest { @Override boolean isAvailable() { - return ConscryptAlpnSslEngine.isAvailable(); + return Conscrypt.isAvailable(); } @Override