Support JDK9-native ALPN

Motivation:

Netty is unable to use Java9s ALPN support atm.

Modifications:

When running on Java9+ we invoke the correct methods that are exposed on the Java9+ implementation of SSLEngine and so be able to support ALPN.
This patch is based on the work of @rschmitt and so https://github.com/netty/netty/pull/6992.

Result:

Fixes #6933.
This commit is contained in:
Norman Maurer 2017-08-18 20:22:01 +02:00
parent c93e58c453
commit 1065e0f26e
11 changed files with 421 additions and 188 deletions

View File

@ -0,0 +1,175 @@
/*
* 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.StringUtil;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException;
import java.nio.ByteBuffer;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.function.BiFunction;
import static io.netty.handler.ssl.SslUtils.toSSLHandshakeException;
import static io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelectionListener;
import static io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector;
final class Java9SslEngine extends JdkSslEngine {
private final ProtocolSelectionListener selectionListener;
private final AlpnSelector alpnSelector;
private final class AlpnSelector implements BiFunction<SSLEngine, List<String>, String> {
private final ProtocolSelector selector;
private boolean called;
AlpnSelector(ProtocolSelector selector) {
this.selector = selector;
}
@Override
public String apply(SSLEngine sslEngine, List<String> strings) {
assert !called;
called = true;
try {
String selected = selector.select(strings);
return selected == null ? StringUtil.EMPTY_STRING : selected;
} catch (Exception cause) {
// Returning null means we want to fail the handshake.
//
// See http://download.java.net/java/jdk9/docs/api/javax/net/ssl/
// SSLEngine.html#setHandshakeApplicationProtocolSelector-java.util.function.BiFunction-
return null;
}
}
void checkUnsupported() {
if (called) {
// ALPN message was received by peer and so apply(...) was called.
// See:
// http://hg.openjdk.java.net/jdk9/dev/jdk/file/65464a307408/src/
// java.base/share/classes/sun/security/ssl/ServerHandshaker.java#l933
return;
}
String protocol = getApplicationProtocol();
assert protocol != null;
if (protocol.isEmpty()) {
// ALPN is not supported
selector.unsupported();
}
}
}
Java9SslEngine(SSLEngine engine, JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) {
super(engine);
if (isServer) {
selectionListener = null;
alpnSelector = new AlpnSelector(applicationNegotiator.protocolSelectorFactory().
newSelector(this, new LinkedHashSet<String>(applicationNegotiator.protocols())));
Java9SslUtils.setHandshakeApplicationProtocolSelector(engine, alpnSelector);
} else {
selectionListener = applicationNegotiator.protocolListenerFactory()
.newListener(this, applicationNegotiator.protocols());
alpnSelector = null;
Java9SslUtils.setApplicationProtocols(engine, applicationNegotiator.protocols());
}
}
private SSLEngineResult verifyProtocolSelection(SSLEngineResult result) throws SSLException {
if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED) {
if (alpnSelector == null) {
// This means we are using client-side and
try {
String protocol = getApplicationProtocol();
assert protocol != null;
if (protocol.isEmpty()) {
// If empty the server did not announce ALPN:
// See:
// http://hg.openjdk.java.net/jdk9/dev/jdk/file/65464a307408/src/java.base/
// share/classes/sun/security/ssl/ClientHandshaker.java#l741
selectionListener.unsupported();
} else {
selectionListener.selected(protocol);
}
} catch (Throwable e) {
throw toSSLHandshakeException(e);
}
} else {
assert selectionListener == null;
alpnSelector.checkUnsupported();
}
}
return result;
}
@Override
public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
return verifyProtocolSelection(super.wrap(src, dst));
}
@Override
public SSLEngineResult wrap(ByteBuffer[] srcs, ByteBuffer dst) throws SSLException {
return verifyProtocolSelection(super.wrap(srcs, dst));
}
@Override
public SSLEngineResult wrap(ByteBuffer[] srcs, int offset, int len, ByteBuffer dst) throws SSLException {
return verifyProtocolSelection(super.wrap(srcs, offset, len, dst));
}
@Override
public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
return verifyProtocolSelection(super.unwrap(src, dst));
}
@Override
public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException {
return verifyProtocolSelection(super.unwrap(src, dsts));
}
@Override
public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dst, int offset, int len) throws SSLException {
return verifyProtocolSelection(super.unwrap(src, dst, offset, len));
}
@Override
void setApplicationProtocol(String applicationProtocol) {
// Do nothing as this is handled internally by the Java9 implementation of SSLEngine.
}
@Override
public String getApplicationProtocol() {
return Java9SslUtils.getApplicationProtocol(getWrappedEngine());
}
// These methods will override the methods defined by Java 9. As we compile with Java8 we can not add
// @Override annotations here.
public String getHandshakeApplicationProtocol() {
return Java9SslUtils.getHandshakeApplicationProtocol(getWrappedEngine());
}
public void setHandshakeApplicationProtocolSelector(BiFunction<SSLEngine, List<String>, String> selector) {
Java9SslUtils.setHandshakeApplicationProtocolSelector(getWrappedEngine(), selector);
}
public BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector() {
return Java9SslUtils.getHandshakeApplicationProtocolSelector(getWrappedEngine());
}
}

View File

@ -0,0 +1,175 @@
/*
* 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 javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.List;
import java.util.function.BiFunction;
import io.netty.util.internal.EmptyArrays;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
final class Java9SslUtils {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Java9SslUtils.class);
private static final Method SET_APPLICATION_PROTOCOLS;
private static final Method GET_APPLICATION_PROTOCOL;
private static final Method GET_HANDSHAKE_APPLICATION_PROTOCOL;
private static final Method SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR;
private static final Method GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR;
static {
Method getHandshakeApplicationProtocol = null;
Method getApplicationProtocol = null;
Method setApplicationProtocols = null;
Method setHandshakeApplicationProtocolSelector = null;
Method getHandshakeApplicationProtocolSelector = null;
try {
SSLContext context = SSLContext.getInstance(JdkSslContext.PROTOCOL);
context.init(null, null, null);
SSLEngine engine = context.createSSLEngine();
getHandshakeApplicationProtocol = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return SSLEngine.class.getMethod("getHandshakeApplicationProtocol");
}
});
getHandshakeApplicationProtocol.invoke(engine);
getApplicationProtocol = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return SSLEngine.class.getMethod("getApplicationProtocol");
}
});
getApplicationProtocol.invoke(engine);
setApplicationProtocols = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return SSLParameters.class.getMethod("setApplicationProtocols", String[].class);
}
});
setApplicationProtocols.invoke(engine.getSSLParameters(), new Object[]{EmptyArrays.EMPTY_STRINGS});
setHandshakeApplicationProtocolSelector =
AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return SSLEngine.class.getMethod("setHandshakeApplicationProtocolSelector", BiFunction.class);
}
});
setHandshakeApplicationProtocolSelector.invoke(engine, new BiFunction<SSLEngine, List<String>, String>() {
@Override
public String apply(SSLEngine sslEngine, List<String> strings) {
return null;
}
});
getHandshakeApplicationProtocolSelector =
AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return SSLEngine.class.getMethod("getHandshakeApplicationProtocolSelector");
}
});
getHandshakeApplicationProtocolSelector.invoke(engine);
} catch (Throwable t) {
logger.error("Unable to initialize Java9SslUtils, but the detected javaVersion was: {}",
PlatformDependent.javaVersion(), t);
getHandshakeApplicationProtocol = null;
getApplicationProtocol = null;
setApplicationProtocols = null;
setHandshakeApplicationProtocolSelector = null;
getHandshakeApplicationProtocolSelector = null;
}
GET_HANDSHAKE_APPLICATION_PROTOCOL = getHandshakeApplicationProtocol;
GET_APPLICATION_PROTOCOL = getApplicationProtocol;
SET_APPLICATION_PROTOCOLS = setApplicationProtocols;
SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = setHandshakeApplicationProtocolSelector;
GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getHandshakeApplicationProtocolSelector;
}
private Java9SslUtils() {
}
static boolean supportsAlpn() {
return GET_APPLICATION_PROTOCOL != null;
}
static String getApplicationProtocol(SSLEngine sslEngine) {
try {
return (String) GET_APPLICATION_PROTOCOL.invoke(sslEngine);
} catch (UnsupportedOperationException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
static String getHandshakeApplicationProtocol(SSLEngine sslEngine) {
try {
return (String) GET_HANDSHAKE_APPLICATION_PROTOCOL.invoke(sslEngine);
} catch (UnsupportedOperationException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
static void setApplicationProtocols(SSLEngine engine, List<String> supportedProtocols) {
SSLParameters parameters = engine.getSSLParameters();
String[] protocolArray = supportedProtocols.toArray(EmptyArrays.EMPTY_STRINGS);
try {
SET_APPLICATION_PROTOCOLS.invoke(parameters, new Object[]{protocolArray});
} catch (UnsupportedOperationException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
engine.setSSLParameters(parameters);
}
static void setHandshakeApplicationProtocolSelector(
SSLEngine engine, BiFunction<SSLEngine, List<String>, String> selector) {
try {
SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(engine, selector);
} catch (UnsupportedOperationException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
static BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector(SSLEngine engine) {
try {
return (BiFunction<SSLEngine, List<String>, String>)
GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(engine);
} catch (UnsupportedOperationException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
}

View File

@ -16,6 +16,8 @@
package io.netty.handler.ssl;
import io.netty.buffer.ByteBufAllocator;
import io.netty.util.internal.PlatformDependent;
import javax.net.ssl.SSLEngine;
/**
@ -25,7 +27,10 @@ import javax.net.ssl.SSLEngine;
*/
@Deprecated
public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicationProtocolNegotiator {
private static final boolean AVAILABLE = Conscrypt.isAvailable() || JettyAlpnSslEngine.isAvailable();
private static final boolean AVAILABLE = Conscrypt.isAvailable() ||
jdkAlpnSupported() ||
JettyAlpnSslEngine.isAvailable();
private static final SslEngineWrapperFactory ALPN_WRAPPER = AVAILABLE ? new AlpnWrapper() : new FailureWrapper();
/**
@ -129,6 +134,9 @@ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicati
return isServer ? ConscryptAlpnSslEngine.newServerEngine(engine, alloc, applicationNegotiator)
: ConscryptAlpnSslEngine.newClientEngine(engine, alloc, applicationNegotiator);
}
if (jdkAlpnSupported()) {
return new Java9SslEngine(engine, applicationNegotiator, isServer);
}
if (JettyAlpnSslEngine.isAvailable()) {
return isServer ? JettyAlpnSslEngine.newServerEngine(engine, applicationNegotiator)
: JettyAlpnSslEngine.newClientEngine(engine, applicationNegotiator);
@ -136,4 +144,8 @@ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicati
throw new RuntimeException("Unable to wrap SSLEngine of type " + engine.getClass().getName());
}
}
static boolean jdkAlpnSupported() {
return PlatformDependent.javaVersion() >= 9 && Java9SslUtils.supportsAlpn();
}
}

View File

@ -137,14 +137,14 @@ class JdkBaseApplicationProtocolNegotiator implements JdkApplicationProtocolNego
@Override
public void unsupported() {
engineWrapper.getSession().setApplicationProtocol(null);
engineWrapper.setApplicationProtocol(null);
}
@Override
public String select(List<String> protocols) throws Exception {
for (String p : supportedProtocols) {
if (protocols.contains(p)) {
engineWrapper.getSession().setApplicationProtocol(p);
engineWrapper.setApplicationProtocol(p);
return p;
}
}
@ -152,7 +152,7 @@ class JdkBaseApplicationProtocolNegotiator implements JdkApplicationProtocolNego
}
public String noSelectMatchFound() throws Exception {
engineWrapper.getSession().setApplicationProtocol(null);
engineWrapper.setApplicationProtocol(null);
return null;
}
}
@ -179,13 +179,13 @@ class JdkBaseApplicationProtocolNegotiator implements JdkApplicationProtocolNego
@Override
public void unsupported() {
engineWrapper.getSession().setApplicationProtocol(null);
engineWrapper.setApplicationProtocol(null);
}
@Override
public void selected(String protocol) throws Exception {
if (supportedProtocols.contains(protocol)) {
engineWrapper.getSession().setApplicationProtocol(protocol);
engineWrapper.setApplicationProtocol(protocol);
} else {
noSelectedMatchFound(protocol);
}

View File

@ -24,18 +24,26 @@ import javax.net.ssl.SSLException;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;
class JdkSslEngine extends SSLEngine {
class JdkSslEngine extends SSLEngine implements ApplicationProtocolAccessor {
private final SSLEngine engine;
private final JdkSslSession session;
private volatile String applicationProtocol;
JdkSslEngine(SSLEngine engine) {
this.engine = engine;
session = new JdkSslSession(engine);
}
@Override
public JdkSslSession getSession() {
return session;
public String getApplicationProtocol() {
return applicationProtocol;
}
void setApplicationProtocol(String applicationProtocol) {
this.applicationProtocol = applicationProtocol;
}
@Override
public SSLSession getSession() {
return engine.getSession();
}
public SSLEngine getWrappedEngine() {

View File

@ -1,152 +0,0 @@
/*
* Copyright 2014 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 javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.security.cert.X509Certificate;
import java.security.Principal;
import java.security.cert.Certificate;
final class JdkSslSession implements SSLSession, ApplicationProtocolAccessor {
private final SSLEngine engine;
private volatile String applicationProtocol;
JdkSslSession(SSLEngine engine) {
this.engine = engine;
}
private SSLSession unwrap() {
return engine.getSession();
}
@Override
public String getProtocol() {
return unwrap().getProtocol();
}
@Override
public String getApplicationProtocol() {
return applicationProtocol;
}
void setApplicationProtocol(String applicationProtocol) {
this.applicationProtocol = applicationProtocol;
}
@Override
public byte[] getId() {
return unwrap().getId();
}
@Override
public SSLSessionContext getSessionContext() {
return unwrap().getSessionContext();
}
@Override
public long getCreationTime() {
return unwrap().getCreationTime();
}
@Override
public long getLastAccessedTime() {
return unwrap().getLastAccessedTime();
}
@Override
public void invalidate() {
unwrap().invalidate();
}
@Override
public boolean isValid() {
return unwrap().isValid();
}
@Override
public void putValue(String s, Object o) {
unwrap().putValue(s, o);
}
@Override
public Object getValue(String s) {
return unwrap().getValue(s);
}
@Override
public void removeValue(String s) {
unwrap().removeValue(s);
}
@Override
public String[] getValueNames() {
return unwrap().getValueNames();
}
@Override
public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
return unwrap().getPeerCertificates();
}
@Override
public Certificate[] getLocalCertificates() {
return unwrap().getLocalCertificates();
}
@Override
public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
return unwrap().getPeerCertificateChain();
}
@Override
public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
return unwrap().getPeerPrincipal();
}
@Override
public Principal getLocalPrincipal() {
return unwrap().getLocalPrincipal();
}
@Override
public String getCipherSuite() {
return unwrap().getCipherSuite();
}
@Override
public String getPeerHost() {
return unwrap().getPeerHost();
}
@Override
public int getPeerPort() {
return unwrap().getPeerPort();
}
@Override
public int getPacketBufferSize() {
return unwrap().getPacketBufferSize();
}
@Override
public int getApplicationBufferSize() {
return unwrap().getApplicationBufferSize();
}
}

View File

@ -38,7 +38,6 @@ abstract class JettyAlpnSslEngine extends JdkSslEngine {
}
private static boolean initAvailable() {
// TODO: Add support for ALPN when using Java9 and still be able to configure it the Netty way.
if (PlatformDependent.javaVersion() <= 8) {
try {
// Always use bootstrap class loader.

View File

@ -87,7 +87,7 @@ import static javax.net.ssl.SSLEngineResult.Status.OK;
* the instance depends upon are released. Otherwise if any method of this class is called which uses the
* the {@link ReferenceCountedOpenSslContext} JNI resources the JVM may crash.
*/
public class ReferenceCountedOpenSslEngine extends SSLEngine implements ReferenceCounted {
public class ReferenceCountedOpenSslEngine extends SSLEngine implements ReferenceCounted, ApplicationProtocolAccessor {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ReferenceCountedOpenSslEngine.class);
@ -159,6 +159,7 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc
private boolean renegotiationPending;
private boolean receivedShutdown;
private volatile int destroyed;
private volatile String applicationProtocol;
// Reference Counting
private final ResourceLeakTracker<ReferenceCountedOpenSslEngine> leak;
@ -1827,7 +1828,12 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc
return Java8SslUtils.checkSniHostnameMatch(matchers, hostname);
}
private final class OpenSslSession implements SSLSession, ApplicationProtocolAccessor {
@Override
public String getApplicationProtocol() {
return applicationProtocol;
}
private final class OpenSslSession implements SSLSession {
private final OpenSslSessionContext sessionContext;
// These are guarded by synchronized(OpenSslEngine.this) as handshakeFinished() may be triggered by any
@ -1835,7 +1841,6 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc
private X509Certificate[] x509PeerCerts;
private Certificate[] peerCerts;
private String protocol;
private String applicationProtocol;
private String cipher;
private byte[] id;
private long creationTime;
@ -2043,14 +2048,14 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc
case ALPN:
applicationProtocol = SSL.getAlpnSelected(ssl);
if (applicationProtocol != null) {
this.applicationProtocol = selectApplicationProtocol(
ReferenceCountedOpenSslEngine.this.applicationProtocol = selectApplicationProtocol(
protocols, behavior, applicationProtocol);
}
break;
case NPN:
applicationProtocol = SSL.getNextProtoNegotiated(ssl);
if (applicationProtocol != null) {
this.applicationProtocol = selectApplicationProtocol(
ReferenceCountedOpenSslEngine.this.applicationProtocol = selectApplicationProtocol(
protocols, behavior, applicationProtocol);
}
break;
@ -2060,7 +2065,7 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc
applicationProtocol = SSL.getNextProtoNegotiated(ssl);
}
if (applicationProtocol != null) {
this.applicationProtocol = selectApplicationProtocol(
ReferenceCountedOpenSslEngine.this.applicationProtocol = selectApplicationProtocol(
protocols, behavior, applicationProtocol);
}
break;
@ -2159,13 +2164,6 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc
return protocol;
}
@Override
public String getApplicationProtocol() {
synchronized (ReferenceCountedOpenSslEngine.this) {
return applicationProtocol;
}
}
@Override
public String getPeerHost() {
return ReferenceCountedOpenSslEngine.this.getPeerHost();

View File

@ -573,12 +573,12 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
* @return the protocol name or {@code null} if application-level protocol has not been negotiated
*/
public String applicationProtocol() {
SSLSession sess = engine().getSession();
if (!(sess instanceof ApplicationProtocolAccessor)) {
SSLEngine engine = engine();
if (!(engine instanceof ApplicationProtocolAccessor)) {
return null;
}
return ((ApplicationProtocolAccessor) sess).getApplicationProtocol();
return ((ApplicationProtocolAccessor) engine).getApplicationProtocol();
}
/**

View File

@ -25,6 +25,8 @@ import io.netty.handler.ssl.util.SelfSignedCertificate;
import java.security.Provider;
import java.util.ArrayList;
import java.util.Collection;
import io.netty.util.internal.PlatformDependent;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -43,7 +45,7 @@ import static org.junit.Assume.assumeNoException;
@RunWith(Parameterized.class)
public class JdkSslEngineTest extends SSLEngineTest {
public enum ProviderType {
NPN_DEFAULT {
NPN_JETTY {
@Override
boolean isAvailable() {
return JettyNpnSslEngine.isAvailable();
@ -59,7 +61,7 @@ public class JdkSslEngineTest extends SSLEngineTest {
return null;
}
},
ALPN_DEFAULT {
ALPN_JETTY {
@Override
boolean isAvailable() {
return JettyAlpnSslEngine.isAvailable();
@ -76,6 +78,23 @@ public class JdkSslEngineTest extends SSLEngineTest {
return null;
}
},
ALPN_JAVA9 {
@Override
boolean isAvailable() {
return PlatformDependent.javaVersion() >= 9 && Java9SslUtils.supportsAlpn();
}
@Override
Protocol protocol() {
return Protocol.ALPN;
}
@Override
Provider provider() {
// Use the default provider.
return null;
}
},
ALPN_CONSCRYPT {
private Provider provider;
@ -178,7 +197,7 @@ public class JdkSslEngineTest extends SSLEngineTest {
public void testTlsExtensionNoCompatibleProtocolsClientHandshakeFailure() throws Exception {
try {
providerType.activate(this);
if (providerType == ProviderType.NPN_DEFAULT) {
if (providerType == ProviderType.NPN_JETTY) {
ApplicationProtocolConfig clientApn = failingNegotiator(providerType.protocol(),
PREFERRED_APPLICATION_LEVEL_PROTOCOL);
ApplicationProtocolConfig serverApn = acceptingNegotiator(providerType.protocol(),
@ -249,7 +268,7 @@ public class JdkSslEngineTest extends SSLEngineTest {
public void testAlpnCompatibleProtocolsDifferentClientOrder() throws Exception {
try {
providerType.activate(this);
if (providerType == ProviderType.NPN_DEFAULT) {
if (providerType == ProviderType.NPN_JETTY) {
// This test only applies to ALPN.
throw tlsExtensionNotFound(providerType.protocol());
}
@ -314,16 +333,14 @@ public class JdkSslEngineTest extends SSLEngineTest {
return provider;
}
private ApplicationProtocolConfig failingNegotiator(Protocol protocol,
String... supportedProtocols) {
private static ApplicationProtocolConfig failingNegotiator(Protocol protocol, String... supportedProtocols) {
return new ApplicationProtocolConfig(protocol,
SelectorFailureBehavior.FATAL_ALERT,
SelectedListenerFailureBehavior.FATAL_ALERT,
supportedProtocols);
}
private ApplicationProtocolConfig acceptingNegotiator(Protocol protocol,
String... supportedProtocols) {
private static ApplicationProtocolConfig acceptingNegotiator(Protocol protocol, String... supportedProtocols) {
return new ApplicationProtocolConfig(protocol,
SelectorFailureBehavior.NO_ADVERTISE,
SelectedListenerFailureBehavior.ACCEPT,

View File

@ -710,6 +710,7 @@
<!-- JDK 8 -->
<ignore>java.util.concurrent.atomic.LongAdder</ignore>
<ignore>java.util.function.BiFunction</ignore>
<!-- Resolver -->
<ignore>java.net.InetAddress</ignore>