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:
Alex Petrov 2015-11-26 08:45:56 +01:00 committed by Scott Mitchell
parent c1f3200c87
commit 43ebbc3fa0
3 changed files with 112 additions and 47 deletions

View File

@ -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);
}
}
}

View File

@ -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();

View File

@ -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