Update JDK SSL Tests to use SSL Context Builder.
Motivation: Use new / non-deprecated APIs for creating SSL Context in tests, in order to be able to implement OpenSsl tests with maximum code reuse. Modifications: Use `SslContextBuilder.(forServer|forClient)` instead of deprecated `JdkSslServerContext` constructor. Use `ApplicationProtocolConfig` instead of Protocol Negotiator. Use custom exception type for skipping tests to avoid swallowing exceptions arising from tests. Result: Exceptions from tests aren't swallowed. Using new APIs allows reusing same test code for OpenSsl tests.
This commit is contained in:
parent
c1f3200c87
commit
43ebbc3fa0
@ -31,6 +31,9 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector;
|
||||
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelectorFactory;
|
||||
import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol;
|
||||
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior;
|
||||
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
|
||||
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
import io.netty.util.NetUtil;
|
||||
@ -59,13 +62,13 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
// Check in this test just in case we have multiple tests that just the class and we already ignored the
|
||||
// initialization error.
|
||||
if (!JdkNpnSslEngine.isAvailable()) {
|
||||
throw new RuntimeException("NPN not on classpath");
|
||||
throw tlsExtensionNotFound(Protocol.NPN);
|
||||
}
|
||||
JdkApplicationProtocolNegotiator apn = new JdkNpnApplicationProtocolNegotiator(true, true,
|
||||
ApplicationProtocolConfig apn = failingNegotiator(Protocol.NPN,
|
||||
PREFERRED_APPLICATION_LEVEL_PROTOCOL);
|
||||
mySetup(apn);
|
||||
runTest();
|
||||
} catch (RuntimeException e) {
|
||||
} catch (SkipTestException e) {
|
||||
// NPN availability is dependent on the java version. If NPN is not available because of
|
||||
// java version incompatibility don't fail the test, but instead just skip the test
|
||||
assumeNoException(e);
|
||||
@ -79,15 +82,15 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
// Check in this test just in case we have multiple tests that just the class and we already ignored the
|
||||
// initialization error.
|
||||
if (!JdkNpnSslEngine.isAvailable()) {
|
||||
throw new RuntimeException("NPN not on classpath");
|
||||
throw tlsExtensionNotFound(Protocol.NPN);
|
||||
}
|
||||
JdkApplicationProtocolNegotiator clientApn = new JdkNpnApplicationProtocolNegotiator(false, false,
|
||||
ApplicationProtocolConfig clientApn = acceptingNegotiator(Protocol.NPN,
|
||||
PREFERRED_APPLICATION_LEVEL_PROTOCOL);
|
||||
JdkApplicationProtocolNegotiator serverApn = new JdkNpnApplicationProtocolNegotiator(false, false,
|
||||
ApplicationProtocolConfig serverApn = acceptingNegotiator(Protocol.NPN,
|
||||
APPLICATION_LEVEL_PROTOCOL_NOT_COMPATIBLE);
|
||||
mySetup(serverApn, clientApn);
|
||||
runTest(null);
|
||||
} catch (Exception e) {
|
||||
} catch (SkipTestException e) {
|
||||
// ALPN availability is dependent on the java version. If ALPN is not available because of
|
||||
// java version incompatibility don't fail the test, but instead just skip the test
|
||||
assumeNoException(e);
|
||||
@ -101,16 +104,16 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
// Check in this test just in case we have multiple tests that just the class and we already ignored the
|
||||
// initialization error.
|
||||
if (!JdkNpnSslEngine.isAvailable()) {
|
||||
throw new RuntimeException("NPN not on classpath");
|
||||
throw tlsExtensionNotFound(Protocol.NPN);
|
||||
}
|
||||
JdkApplicationProtocolNegotiator clientApn = new JdkNpnApplicationProtocolNegotiator(true, true,
|
||||
ApplicationProtocolConfig clientApn = failingNegotiator(Protocol.NPN,
|
||||
PREFERRED_APPLICATION_LEVEL_PROTOCOL);
|
||||
JdkApplicationProtocolNegotiator serverApn = new JdkNpnApplicationProtocolNegotiator(false, false,
|
||||
ApplicationProtocolConfig serverApn = acceptingNegotiator(Protocol.NPN,
|
||||
APPLICATION_LEVEL_PROTOCOL_NOT_COMPATIBLE);
|
||||
mySetup(serverApn, clientApn);
|
||||
assertTrue(clientLatch.await(2, TimeUnit.SECONDS));
|
||||
assertTrue(clientException instanceof SSLHandshakeException);
|
||||
} catch (RuntimeException e) {
|
||||
} catch (SkipTestException e) {
|
||||
// NPN availability is dependent on the java version. If NPN is not available because of
|
||||
// java version incompatibility don't fail the test, but instead just skip the test
|
||||
assumeNoException(e);
|
||||
@ -124,16 +127,16 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
// Check in this test just in case we have multiple tests that just the class and we already ignored the
|
||||
// initialization error.
|
||||
if (!JdkNpnSslEngine.isAvailable()) {
|
||||
throw new RuntimeException("NPN not on classpath");
|
||||
throw tlsExtensionNotFound(Protocol.NPN);
|
||||
}
|
||||
JdkApplicationProtocolNegotiator clientApn = new JdkNpnApplicationProtocolNegotiator(false, false,
|
||||
ApplicationProtocolConfig clientApn = acceptingNegotiator(Protocol.NPN,
|
||||
PREFERRED_APPLICATION_LEVEL_PROTOCOL);
|
||||
JdkApplicationProtocolNegotiator serverApn = new JdkNpnApplicationProtocolNegotiator(true, true,
|
||||
ApplicationProtocolConfig serverApn = failingNegotiator(Protocol.NPN,
|
||||
APPLICATION_LEVEL_PROTOCOL_NOT_COMPATIBLE);
|
||||
mySetup(serverApn, clientApn);
|
||||
assertTrue(serverLatch.await(2, TimeUnit.SECONDS));
|
||||
assertTrue(serverException instanceof SSLHandshakeException);
|
||||
} catch (RuntimeException e) {
|
||||
} catch (SkipTestException e) {
|
||||
// NPN availability is dependent on the java version. If NPN is not available because of
|
||||
// java version incompatibility don't fail the test, but instead just skip the test
|
||||
assumeNoException(e);
|
||||
@ -147,13 +150,13 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
// Check in this test just in case we have multiple tests that just the class and we already ignored the
|
||||
// initialization error.
|
||||
if (!JdkAlpnSslEngine.isAvailable()) {
|
||||
throw new RuntimeException("ALPN not on classpath");
|
||||
throw tlsExtensionNotFound(Protocol.ALPN);
|
||||
}
|
||||
JdkApplicationProtocolNegotiator apn = new JdkAlpnApplicationProtocolNegotiator(true, true,
|
||||
ApplicationProtocolConfig apn = failingNegotiator(Protocol.ALPN,
|
||||
PREFERRED_APPLICATION_LEVEL_PROTOCOL);
|
||||
mySetup(apn);
|
||||
runTest();
|
||||
} catch (Exception e) {
|
||||
} catch (SkipTestException e) {
|
||||
// ALPN availability is dependent on the java version. If ALPN is not available because of
|
||||
// java version incompatibility don't fail the test, but instead just skip the test
|
||||
assumeNoException(e);
|
||||
@ -167,15 +170,15 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
// Check in this test just in case we have multiple tests that just the class and we already ignored the
|
||||
// initialization error.
|
||||
if (!JdkAlpnSslEngine.isAvailable()) {
|
||||
throw new RuntimeException("ALPN not on classpath");
|
||||
throw tlsExtensionNotFound(Protocol.ALPN);
|
||||
}
|
||||
JdkApplicationProtocolNegotiator clientApn = new JdkAlpnApplicationProtocolNegotiator(false, false,
|
||||
ApplicationProtocolConfig clientApn = acceptingNegotiator(Protocol.ALPN,
|
||||
PREFERRED_APPLICATION_LEVEL_PROTOCOL);
|
||||
JdkApplicationProtocolNegotiator serverApn = new JdkAlpnApplicationProtocolNegotiator(false, false,
|
||||
ApplicationProtocolConfig serverApn = acceptingNegotiator(Protocol.ALPN,
|
||||
APPLICATION_LEVEL_PROTOCOL_NOT_COMPATIBLE);
|
||||
mySetup(serverApn, clientApn);
|
||||
runTest(null);
|
||||
} catch (Exception e) {
|
||||
} catch (SkipTestException e) {
|
||||
// ALPN availability is dependent on the java version. If ALPN is not available because of
|
||||
// java version incompatibility don't fail the test, but instead just skip the test
|
||||
assumeNoException(e);
|
||||
@ -189,16 +192,16 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
// Check in this test just in case we have multiple tests that just the class and we already ignored the
|
||||
// initialization error.
|
||||
if (!JdkAlpnSslEngine.isAvailable()) {
|
||||
throw new RuntimeException("ALPN not on classpath");
|
||||
throw tlsExtensionNotFound(Protocol.ALPN);
|
||||
}
|
||||
JdkApplicationProtocolNegotiator clientApn = new JdkAlpnApplicationProtocolNegotiator(false, false,
|
||||
ApplicationProtocolConfig clientApn = acceptingNegotiator(Protocol.ALPN,
|
||||
PREFERRED_APPLICATION_LEVEL_PROTOCOL);
|
||||
JdkApplicationProtocolNegotiator serverApn = new JdkAlpnApplicationProtocolNegotiator(true, true,
|
||||
ApplicationProtocolConfig serverApn = failingNegotiator(Protocol.ALPN,
|
||||
APPLICATION_LEVEL_PROTOCOL_NOT_COMPATIBLE);
|
||||
mySetup(serverApn, clientApn);
|
||||
assertTrue(serverLatch.await(2, TimeUnit.SECONDS));
|
||||
assertTrue(serverException instanceof SSLHandshakeException);
|
||||
} catch (Exception e) {
|
||||
} catch (SkipTestException e) {
|
||||
// ALPN availability is dependent on the java version. If ALPN is not available because of
|
||||
// java version incompatibility don't fail the test, but instead just skip the test
|
||||
assumeNoException(e);
|
||||
@ -212,18 +215,18 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
// Check in this test just in case we have multiple tests that just the class and we already ignored the
|
||||
// initialization error.
|
||||
if (!JdkAlpnSslEngine.isAvailable()) {
|
||||
throw new RuntimeException("ALPN not on classpath");
|
||||
throw tlsExtensionNotFound(Protocol.ALPN);
|
||||
}
|
||||
// Even the preferred application protocol appears second in the client's list, it will be picked
|
||||
// because it's the first one on server's list.
|
||||
JdkApplicationProtocolNegotiator clientApn = new JdkAlpnApplicationProtocolNegotiator(false, false,
|
||||
ApplicationProtocolConfig clientApn = acceptingNegotiator(Protocol.ALPN,
|
||||
FALLBACK_APPLICATION_LEVEL_PROTOCOL, PREFERRED_APPLICATION_LEVEL_PROTOCOL);
|
||||
JdkApplicationProtocolNegotiator serverApn = new JdkAlpnApplicationProtocolNegotiator(true, true,
|
||||
ApplicationProtocolConfig serverApn = failingNegotiator(Protocol.ALPN,
|
||||
PREFERRED_APPLICATION_LEVEL_PROTOCOL, FALLBACK_APPLICATION_LEVEL_PROTOCOL);
|
||||
mySetup(serverApn, clientApn);
|
||||
assertNull(serverException);
|
||||
runTest(PREFERRED_APPLICATION_LEVEL_PROTOCOL);
|
||||
} catch (Exception e) {
|
||||
} catch (SkipTestException e) {
|
||||
// ALPN availability is dependent on the java version. If ALPN is not available because of
|
||||
// java version incompatibility don't fail the test, but instead just skip the test
|
||||
assumeNoException(e);
|
||||
@ -237,8 +240,9 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
// Check in this test just in case we have multiple tests that just the class and we already ignored the
|
||||
// initialization error.
|
||||
if (!JdkAlpnSslEngine.isAvailable()) {
|
||||
throw new RuntimeException("ALPN not on classpath");
|
||||
throw tlsExtensionNotFound(Protocol.ALPN);
|
||||
}
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||
JdkApplicationProtocolNegotiator clientApn = new JdkAlpnApplicationProtocolNegotiator(true, true,
|
||||
PREFERRED_APPLICATION_LEVEL_PROTOCOL);
|
||||
JdkApplicationProtocolNegotiator serverApn = new JdkAlpnApplicationProtocolNegotiator(
|
||||
@ -258,28 +262,54 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
}
|
||||
}, JdkBaseApplicationProtocolNegotiator.FAIL_SELECTION_LISTENER_FACTORY,
|
||||
APPLICATION_LEVEL_PROTOCOL_NOT_COMPATIBLE);
|
||||
mySetup(serverApn, clientApn);
|
||||
|
||||
SslContext serverSslCtx = new JdkSslServerContext(ssc.certificate(), ssc.privateKey(), null, null,
|
||||
IdentityCipherSuiteFilter.INSTANCE, serverApn, 0, 0);
|
||||
SslContext clientSslCtx = new JdkSslClientContext(null, InsecureTrustManagerFactory.INSTANCE, null,
|
||||
IdentityCipherSuiteFilter.INSTANCE, clientApn, 0, 0);
|
||||
|
||||
mySetup(serverSslCtx, clientSslCtx);
|
||||
assertTrue(clientLatch.await(2, TimeUnit.SECONDS));
|
||||
assertTrue(clientException instanceof SSLHandshakeException);
|
||||
} catch (Exception e) {
|
||||
} catch (SkipTestException e) {
|
||||
// ALPN availability is dependent on the java version. If ALPN is not available because of
|
||||
// java version incompatibility don't fail the test, but instead just skip the test
|
||||
assumeNoException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void mySetup(JdkApplicationProtocolNegotiator apn) throws InterruptedException, SSLException,
|
||||
private void mySetup(ApplicationProtocolConfig apn) throws InterruptedException, SSLException,
|
||||
CertificateException {
|
||||
mySetup(apn, apn);
|
||||
}
|
||||
|
||||
private void mySetup(JdkApplicationProtocolNegotiator serverApn, JdkApplicationProtocolNegotiator clientApn)
|
||||
private void mySetup(ApplicationProtocolConfig serverApn, ApplicationProtocolConfig clientApn)
|
||||
throws InterruptedException, SSLException, CertificateException {
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||
serverSslCtx = new JdkSslServerContext(ssc.certificate(), ssc.privateKey(), null, null,
|
||||
IdentityCipherSuiteFilter.INSTANCE, serverApn, 0, 0);
|
||||
clientSslCtx = new JdkSslClientContext(null, InsecureTrustManagerFactory.INSTANCE, null,
|
||||
IdentityCipherSuiteFilter.INSTANCE, clientApn, 0, 0);
|
||||
|
||||
mySetup(SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey(), null)
|
||||
.sslProvider(sslProvider())
|
||||
.ciphers(null, IdentityCipherSuiteFilter.INSTANCE)
|
||||
.applicationProtocolConfig(serverApn)
|
||||
.sessionCacheSize(0)
|
||||
.sessionTimeout(0)
|
||||
.build(),
|
||||
|
||||
SslContextBuilder.forClient()
|
||||
.sslProvider(sslProvider())
|
||||
.applicationProtocolConfig(clientApn)
|
||||
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
||||
.ciphers(null, IdentityCipherSuiteFilter.INSTANCE)
|
||||
.sessionCacheSize(0)
|
||||
.sessionTimeout(0)
|
||||
.build());
|
||||
}
|
||||
|
||||
private void mySetup(SslContext serverCtx, SslContext clientCtx)
|
||||
throws InterruptedException, SSLException, CertificateException {
|
||||
|
||||
serverSslCtx = serverCtx;
|
||||
clientSslCtx = clientCtx;
|
||||
|
||||
serverConnectedChannel = null;
|
||||
sb = new ServerBootstrap();
|
||||
@ -346,4 +376,30 @@ public class JdkSslEngineTest extends SSLEngineTest {
|
||||
protected SslProvider sslProvider() {
|
||||
return SslProvider.JDK;
|
||||
}
|
||||
|
||||
private ApplicationProtocolConfig failingNegotiator(Protocol protocol,
|
||||
String... supportedProtocols) {
|
||||
return new ApplicationProtocolConfig(protocol,
|
||||
SelectorFailureBehavior.FATAL_ALERT,
|
||||
SelectedListenerFailureBehavior.FATAL_ALERT,
|
||||
supportedProtocols);
|
||||
}
|
||||
|
||||
private ApplicationProtocolConfig acceptingNegotiator(Protocol protocol,
|
||||
String... supportedProtocols) {
|
||||
return new ApplicationProtocolConfig(protocol,
|
||||
SelectorFailureBehavior.NO_ADVERTISE,
|
||||
SelectedListenerFailureBehavior.ACCEPT,
|
||||
supportedProtocols);
|
||||
}
|
||||
|
||||
private SkipTestException tlsExtensionNotFound(Protocol protocol) {
|
||||
throw new SkipTestException(protocol + " not on classpath");
|
||||
}
|
||||
|
||||
private static final class SkipTestException extends RuntimeException {
|
||||
public SkipTestException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,13 +180,22 @@ public abstract class SSLEngineTest {
|
||||
File servertTrustCrtFile, File serverKeyFile, File serverCrtFile, String serverKeyPassword,
|
||||
File clientTrustCrtFile, File clientKeyFile, File clientCrtFile, String clientKeyPassword)
|
||||
throws InterruptedException, SSLException {
|
||||
serverSslCtx = SslContext.newServerContext(sslProvider(), servertTrustCrtFile, null,
|
||||
serverCrtFile, serverKeyFile, serverKeyPassword, null,
|
||||
null, IdentityCipherSuiteFilter.INSTANCE, null, 0, 0);
|
||||
clientSslCtx = SslContext.newClientContext(sslProvider(), clientTrustCrtFile, null,
|
||||
clientCrtFile, clientKeyFile, clientKeyPassword, null,
|
||||
null, IdentityCipherSuiteFilter.INSTANCE,
|
||||
null, 0, 0);
|
||||
serverSslCtx = SslContextBuilder.forServer(serverCrtFile, serverKeyFile, serverKeyPassword)
|
||||
.sslProvider(sslProvider())
|
||||
.trustManager(servertTrustCrtFile)
|
||||
.ciphers(null, IdentityCipherSuiteFilter.INSTANCE)
|
||||
.sessionCacheSize(0)
|
||||
.sessionTimeout(0)
|
||||
.build();
|
||||
|
||||
clientSslCtx = SslContextBuilder.forClient()
|
||||
.sslProvider(sslProvider())
|
||||
.trustManager(clientTrustCrtFile)
|
||||
.keyManager(clientCrtFile, clientKeyFile, clientKeyPassword)
|
||||
.ciphers(null, IdentityCipherSuiteFilter.INSTANCE)
|
||||
.sessionCacheSize(0)
|
||||
.sessionTimeout(0)
|
||||
.build();
|
||||
|
||||
serverConnectedChannel = null;
|
||||
sb = new ServerBootstrap();
|
||||
|
@ -34,7 +34,7 @@ public class SniHandlerTest {
|
||||
File keyFile = new File(SniHandlerTest.class.getResource("test_encrypted.pem").getFile());
|
||||
File crtFile = new File(SniHandlerTest.class.getResource("test.crt").getFile());
|
||||
|
||||
return new JdkSslServerContext(crtFile, keyFile, "12345");
|
||||
return SslContextBuilder.forServer(crtFile, keyFile, "12345").build();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user