Ensure we support ALPN when using java 8u251 (#10196)

Motivation:

ALPN support was backported to java 8 lately. Ensure we support it if the user uses the latest java 8 release

Modifications:

- Update logic to be able to detect if ALPN is supported out of the box when using Java8
- Update jetty alpn version

Result:

Be able to use ALPN out of the box when using java 8u251
This commit is contained in:
Norman Maurer 2020-04-21 15:01:59 +02:00 committed by GitHub
parent 232c669fa4
commit 5cd00d22d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 44 additions and 39 deletions

View File

@ -16,7 +16,6 @@
package io.netty.handler.ssl; package io.netty.handler.ssl;
import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufAllocator;
import io.netty.util.internal.PlatformDependent;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
@ -28,7 +27,7 @@ import javax.net.ssl.SSLEngine;
@Deprecated @Deprecated
public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicationProtocolNegotiator { public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicationProtocolNegotiator {
private static final boolean AVAILABLE = Conscrypt.isAvailable() || private static final boolean AVAILABLE = Conscrypt.isAvailable() ||
jdkAlpnSupported() || JdkAlpnSslUtils.supportsAlpn() ||
JettyAlpnSslEngine.isAvailable(); JettyAlpnSslEngine.isAvailable();
private static final SslEngineWrapperFactory ALPN_WRAPPER = AVAILABLE ? new AlpnWrapper() : new FailureWrapper(); private static final SslEngineWrapperFactory ALPN_WRAPPER = AVAILABLE ? new AlpnWrapper() : new FailureWrapper();
@ -134,8 +133,12 @@ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicati
return isServer ? ConscryptAlpnSslEngine.newServerEngine(engine, alloc, applicationNegotiator) return isServer ? ConscryptAlpnSslEngine.newServerEngine(engine, alloc, applicationNegotiator)
: ConscryptAlpnSslEngine.newClientEngine(engine, alloc, applicationNegotiator); : ConscryptAlpnSslEngine.newClientEngine(engine, alloc, applicationNegotiator);
} }
if (jdkAlpnSupported()) { // ALPN support was recently backported to Java8 as
return new Java9SslEngine(engine, applicationNegotiator, isServer); // https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8230977.
// Because of this lets not do a Java version runtime check but just depend on if the required methods are
// present
if (JdkAlpnSslUtils.supportsAlpn()) {
return new JdkAlpnSslEngine(engine, applicationNegotiator, isServer);
} }
if (JettyAlpnSslEngine.isAvailable()) { if (JettyAlpnSslEngine.isAvailable()) {
return isServer ? JettyAlpnSslEngine.newServerEngine(engine, applicationNegotiator) return isServer ? JettyAlpnSslEngine.newServerEngine(engine, applicationNegotiator)
@ -145,10 +148,6 @@ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicati
} }
} }
static boolean jdkAlpnSupported() {
return PlatformDependent.javaVersion() >= 9 && Java9SslUtils.supportsAlpn();
}
static boolean isAlpnSupported() { static boolean isAlpnSupported() {
return AVAILABLE; return AVAILABLE;
} }

View File

@ -32,7 +32,7 @@ import static io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSele
import static io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector; import static io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector;
@SuppressJava6Requirement(reason = "Usage guarded by java version check") @SuppressJava6Requirement(reason = "Usage guarded by java version check")
final class Java9SslEngine extends JdkSslEngine { final class JdkAlpnSslEngine extends JdkSslEngine {
private final ProtocolSelectionListener selectionListener; private final ProtocolSelectionListener selectionListener;
private final AlpnSelector alpnSelector; private final AlpnSelector alpnSelector;
@ -79,18 +79,20 @@ final class Java9SslEngine extends JdkSslEngine {
} }
} }
Java9SslEngine(SSLEngine engine, JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { JdkAlpnSslEngine(SSLEngine engine,
@SuppressWarnings("deprecation") JdkApplicationProtocolNegotiator applicationNegotiator,
boolean isServer) {
super(engine); super(engine);
if (isServer) { if (isServer) {
selectionListener = null; selectionListener = null;
alpnSelector = new AlpnSelector(applicationNegotiator.protocolSelectorFactory(). alpnSelector = new AlpnSelector(applicationNegotiator.protocolSelectorFactory().
newSelector(this, new LinkedHashSet<String>(applicationNegotiator.protocols()))); newSelector(this, new LinkedHashSet<String>(applicationNegotiator.protocols())));
Java9SslUtils.setHandshakeApplicationProtocolSelector(engine, alpnSelector); JdkAlpnSslUtils.setHandshakeApplicationProtocolSelector(engine, alpnSelector);
} else { } else {
selectionListener = applicationNegotiator.protocolListenerFactory() selectionListener = applicationNegotiator.protocolListenerFactory()
.newListener(this, applicationNegotiator.protocols()); .newListener(this, applicationNegotiator.protocols());
alpnSelector = null; alpnSelector = null;
Java9SslUtils.setApplicationProtocols(engine, applicationNegotiator.protocols()); JdkAlpnSslUtils.setApplicationProtocols(engine, applicationNegotiator.protocols());
} }
} }
@ -153,7 +155,7 @@ final class Java9SslEngine extends JdkSslEngine {
@Override @Override
void setNegotiatedApplicationProtocol(String applicationProtocol) { void setNegotiatedApplicationProtocol(String applicationProtocol) {
// Do nothing as this is handled internally by the Java9 implementation of SSLEngine. // Do nothing as this is handled internally by the Java8u251+ implementation of SSLEngine.
} }
@Override @Override
@ -162,24 +164,24 @@ final class Java9SslEngine extends JdkSslEngine {
if (protocol != null) { if (protocol != null) {
return protocol.isEmpty() ? null : protocol; return protocol.isEmpty() ? null : protocol;
} }
return protocol; return null;
} }
// These methods will override the methods defined by Java 9. As we compile with Java8 we can not add // These methods will override the methods defined by Java 8u251 and later. As we may compile with an earlier
// @Override annotations here. // java8 version we don't use @Override annotations here.
public String getApplicationProtocol() { public String getApplicationProtocol() {
return Java9SslUtils.getApplicationProtocol(getWrappedEngine()); return JdkAlpnSslUtils.getApplicationProtocol(getWrappedEngine());
} }
public String getHandshakeApplicationProtocol() { public String getHandshakeApplicationProtocol() {
return Java9SslUtils.getHandshakeApplicationProtocol(getWrappedEngine()); return JdkAlpnSslUtils.getHandshakeApplicationProtocol(getWrappedEngine());
} }
public void setHandshakeApplicationProtocolSelector(BiFunction<SSLEngine, List<String>, String> selector) { public void setHandshakeApplicationProtocolSelector(BiFunction<SSLEngine, List<String>, String> selector) {
Java9SslUtils.setHandshakeApplicationProtocolSelector(getWrappedEngine(), selector); JdkAlpnSslUtils.setHandshakeApplicationProtocolSelector(getWrappedEngine(), selector);
} }
public BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector() { public BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector() {
return Java9SslUtils.getHandshakeApplicationProtocolSelector(getWrappedEngine()); return JdkAlpnSslUtils.getHandshakeApplicationProtocolSelector(getWrappedEngine());
} }
} }

View File

@ -32,8 +32,8 @@ import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.InternalLoggerFactory;
@SuppressJava6Requirement(reason = "Usage guarded by java version check") @SuppressJava6Requirement(reason = "Usage guarded by java version check")
final class Java9SslUtils { final class JdkAlpnSslUtils {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Java9SslUtils.class); private static final InternalLogger logger = InternalLoggerFactory.getInstance(JdkAlpnSslUtils.class);
private static final Method SET_APPLICATION_PROTOCOLS; private static final Method SET_APPLICATION_PROTOCOLS;
private static final Method GET_APPLICATION_PROTOCOL; private static final Method GET_APPLICATION_PROTOCOL;
private static final Method GET_HANDSHAKE_APPLICATION_PROTOCOL; private static final Method GET_HANDSHAKE_APPLICATION_PROTOCOL;
@ -41,11 +41,11 @@ final class Java9SslUtils {
private static final Method GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR; private static final Method GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR;
static { static {
Method getHandshakeApplicationProtocol = null; Method getHandshakeApplicationProtocol;
Method getApplicationProtocol = null; Method getApplicationProtocol;
Method setApplicationProtocols = null; Method setApplicationProtocols;
Method setHandshakeApplicationProtocolSelector = null; Method setHandshakeApplicationProtocolSelector;
Method getHandshakeApplicationProtocolSelector = null; Method getHandshakeApplicationProtocolSelector;
try { try {
SSLContext context = SSLContext.getInstance(JdkSslContext.PROTOCOL); SSLContext context = SSLContext.getInstance(JdkSslContext.PROTOCOL);
@ -97,8 +97,11 @@ final class Java9SslUtils {
}); });
getHandshakeApplicationProtocolSelector.invoke(engine); getHandshakeApplicationProtocolSelector.invoke(engine);
} catch (Throwable t) { } catch (Throwable t) {
logger.error("Unable to initialize Java9SslUtils, but the detected javaVersion was: {}", int version = PlatformDependent.javaVersion();
PlatformDependent.javaVersion(), t); if (version >= 9) {
// We only log when run on java9+ as this is expected on some earlier java8 versions
logger.error("Unable to initialize JdkAlpnSslUtils, but the detected java version was: {}", version, t);
}
getHandshakeApplicationProtocol = null; getHandshakeApplicationProtocol = null;
getApplicationProtocol = null; getApplicationProtocol = null;
setApplicationProtocols = null; setApplicationProtocols = null;
@ -112,7 +115,7 @@ final class Java9SslUtils {
GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getHandshakeApplicationProtocolSelector; GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getHandshakeApplicationProtocolSelector;
} }
private Java9SslUtils() { private JdkAlpnSslUtils() {
} }
static boolean supportsAlpn() { static boolean supportsAlpn() {
@ -164,6 +167,7 @@ final class Java9SslUtils {
} }
} }
@SuppressWarnings("unchecked")
static BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector(SSLEngine engine) { static BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector(SSLEngine engine) {
try { try {
return (BiFunction<SSLEngine, List<String>, String>) return (BiFunction<SSLEngine, List<String>, String>)

View File

@ -79,10 +79,10 @@ public class JdkSslEngineTest extends SSLEngineTest {
return null; return null;
} }
}, },
ALPN_JAVA9 { ALPN_JAVA {
@Override @Override
boolean isAvailable() { boolean isAvailable() {
return PlatformDependent.javaVersion() >= 9 && Java9SslUtils.supportsAlpn(); return JdkAlpnSslUtils.supportsAlpn();
} }
@Override @Override

View File

@ -339,7 +339,7 @@ final class OpenSslErrorStackAssertSSLEngine extends JdkSslEngine implements Ref
public String getApplicationProtocol() { public String getApplicationProtocol() {
if (PlatformDependent.javaVersion() >= 9) { if (PlatformDependent.javaVersion() >= 9) {
try { try {
return Java9SslUtils.getApplicationProtocol(getWrappedEngine()); return JdkAlpnSslUtils.getApplicationProtocol(getWrappedEngine());
} finally { } finally {
assertErrorStackEmpty(); assertErrorStackEmpty();
} }
@ -350,7 +350,7 @@ final class OpenSslErrorStackAssertSSLEngine extends JdkSslEngine implements Ref
public String getHandshakeApplicationProtocol() { public String getHandshakeApplicationProtocol() {
if (PlatformDependent.javaVersion() >= 9) { if (PlatformDependent.javaVersion() >= 9) {
try { try {
return Java9SslUtils.getHandshakeApplicationProtocol(getWrappedEngine()); return JdkAlpnSslUtils.getHandshakeApplicationProtocol(getWrappedEngine());
} finally { } finally {
assertErrorStackEmpty(); assertErrorStackEmpty();
} }
@ -361,7 +361,7 @@ final class OpenSslErrorStackAssertSSLEngine extends JdkSslEngine implements Ref
public void setHandshakeApplicationProtocolSelector(BiFunction<SSLEngine, List<String>, String> selector) { public void setHandshakeApplicationProtocolSelector(BiFunction<SSLEngine, List<String>, String> selector) {
if (PlatformDependent.javaVersion() >= 9) { if (PlatformDependent.javaVersion() >= 9) {
try { try {
Java9SslUtils.setHandshakeApplicationProtocolSelector(getWrappedEngine(), selector); JdkAlpnSslUtils.setHandshakeApplicationProtocolSelector(getWrappedEngine(), selector);
} finally { } finally {
assertErrorStackEmpty(); assertErrorStackEmpty();
} }
@ -372,7 +372,7 @@ final class OpenSslErrorStackAssertSSLEngine extends JdkSslEngine implements Ref
public BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector() { public BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector() {
if (PlatformDependent.javaVersion() >= 9) { if (PlatformDependent.javaVersion() >= 9) {
try { try {
return Java9SslUtils.getHandshakeApplicationProtocolSelector(getWrappedEngine()); return JdkAlpnSslUtils.getHandshakeApplicationProtocolSelector(getWrappedEngine());
} finally { } finally {
assertErrorStackEmpty(); assertErrorStackEmpty();
} }

View File

@ -1157,9 +1157,9 @@ public abstract class SSLEngineTest {
assertEquals(expectedApplicationProtocol, appProto); assertEquals(expectedApplicationProtocol, appProto);
SSLEngine engine = handler.engine(); SSLEngine engine = handler.engine();
if (engine instanceof Java9SslEngine) { if (engine instanceof JdkAlpnSslEngine) {
// Also verify the Java9 exposed method. // Also verify the Java9 exposed method.
Java9SslEngine java9SslEngine = (Java9SslEngine) engine; JdkAlpnSslEngine java9SslEngine = (JdkAlpnSslEngine) engine;
assertEquals(expectedApplicationProtocol == null ? StringUtil.EMPTY_STRING : expectedApplicationProtocol, assertEquals(expectedApplicationProtocol == null ? StringUtil.EMPTY_STRING : expectedApplicationProtocol,
java9SslEngine.getApplicationProtocol()); java9SslEngine.getApplicationProtocol());
} }

View File

@ -314,7 +314,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<netty.build.version>26</netty.build.version> <netty.build.version>26</netty.build.version>
<jboss.marshalling.version>1.4.11.Final</jboss.marshalling.version> <jboss.marshalling.version>1.4.11.Final</jboss.marshalling.version>
<jetty.alpnAgent.version>2.0.8</jetty.alpnAgent.version> <jetty.alpnAgent.version>2.0.10</jetty.alpnAgent.version>
<jetty.alpnAgent.path>"${settings.localRepository}"/org/mortbay/jetty/alpn/jetty-alpn-agent/${jetty.alpnAgent.version}/jetty-alpn-agent-${jetty.alpnAgent.version}.jar</jetty.alpnAgent.path> <jetty.alpnAgent.path>"${settings.localRepository}"/org/mortbay/jetty/alpn/jetty-alpn-agent/${jetty.alpnAgent.version}/jetty-alpn-agent-${jetty.alpnAgent.version}.jar</jetty.alpnAgent.path>
<argLine.common> <argLine.common>
-server -server