From d8e6fbb9c3656663f41797a15f38bb25fdcab834 Mon Sep 17 00:00:00 2001 From: Scott Mitchell Date: Thu, 16 Feb 2017 20:25:25 -0800 Subject: [PATCH] OpenSslEngine should respect hostname verification Motivation: OpenSSL doesn't automatically verify hostnames and requires extract method calls to enable this feature [1]. We should allow this to be configured. Modifications: - SSLParamaters#getEndpointIdentificationAlgorithm() should be respected and configured via tcnative interfaces. Result: OpenSslEngine respects hostname verification. [1] https://wiki.openssl.org/index.php/Hostname_validation --- .../handler/ssl/Java8SslParametersUtils.java | 4 + .../java/io/netty/handler/ssl/OpenSsl.java | 18 +++ .../ssl/ReferenceCountedOpenSslEngine.java | 22 ++- .../netty/handler/ssl/OpenSslEngineTest.java | 14 ++ .../ssl/OpenSslJdkSslEngineInteroptTest.java | 22 +++ .../io/netty/handler/ssl/SSLEngineTest.java | 142 ++++++++++++++++++ .../io/netty/handler/ssl/generate-certs.sh | 12 ++ .../io/netty/handler/ssl/localhost_server.key | 28 ++++ .../io/netty/handler/ssl/localhost_server.pem | 17 +++ .../io/netty/handler/ssl/mutual_auth_ca.pem | 32 ++-- .../netty/handler/ssl/mutual_auth_client.p12 | Bin 3997 -> 3997 bytes .../ssl/mutual_auth_invalid_client.p12 | Bin 3949 -> 3949 bytes .../netty/handler/ssl/mutual_auth_server.p12 | Bin 3141 -> 3149 bytes .../netty/handler/ssl/notlocalhost_server.key | 28 ++++ .../netty/handler/ssl/notlocalhost_server.pem | 17 +++ pom.xml | 2 +- 16 files changed, 337 insertions(+), 21 deletions(-) create mode 100644 handler/src/test/resources/io/netty/handler/ssl/localhost_server.key create mode 100644 handler/src/test/resources/io/netty/handler/ssl/localhost_server.pem create mode 100644 handler/src/test/resources/io/netty/handler/ssl/notlocalhost_server.key create mode 100644 handler/src/test/resources/io/netty/handler/ssl/notlocalhost_server.pem diff --git a/handler/src/main/java/io/netty/handler/ssl/Java8SslParametersUtils.java b/handler/src/main/java/io/netty/handler/ssl/Java8SslParametersUtils.java index 948bb8b5d8..45152689a3 100644 --- a/handler/src/main/java/io/netty/handler/ssl/Java8SslParametersUtils.java +++ b/handler/src/main/java/io/netty/handler/ssl/Java8SslParametersUtils.java @@ -19,6 +19,7 @@ import javax.net.ssl.SNIHostName; import javax.net.ssl.SNIServerName; import javax.net.ssl.SSLParameters; import java.util.ArrayList; +import java.util.Collections; import java.util.List; final class Java8SslParametersUtils { @@ -27,6 +28,9 @@ final class Java8SslParametersUtils { static List getSniHostNames(SSLParameters sslParameters) { List names = sslParameters.getServerNames(); + if (names == null || names.isEmpty()) { + return Collections.emptyList(); + } List strings = new ArrayList(names.size()); for (SNIServerName serverName : names) { diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java index 4e1a2d1111..c871f197a1 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java @@ -51,6 +51,7 @@ public final class OpenSsl { private static final Set AVAILABLE_OPENSSL_CIPHER_SUITES; private static final Set AVAILABLE_JAVA_CIPHER_SUITES; private static final boolean SUPPORTS_KEYMANAGER_FACTORY; + private static final boolean SUPPORTS_HOSTNAME_VALIDATION; private static final boolean USE_KEYMANAGER_FACTORY; // Protocols @@ -114,6 +115,7 @@ public final class OpenSsl { final Set availableOpenSslCipherSuites = new LinkedHashSet(128); boolean supportsKeyManagerFactory = false; boolean useKeyManagerFactory = false; + boolean supportsHostNameValidation = false; try { final long sslCtx = SSLContext.make(SSL.SSL_PROTOCOL_ALL, SSL.SSL_MODE_SERVER); long privateKeyBio = 0; @@ -129,6 +131,12 @@ public final class OpenSsl { } availableOpenSslCipherSuites.add(c); } + try { + SSL.setHostNameValidation(ssl, 0, "netty.io"); + supportsHostNameValidation = true; + } catch (Throwable ignore) { + logger.debug("Hostname Verification not supported."); + } try { SelfSignedCertificate cert = new SelfSignedCertificate(); certBio = ReferenceCountedOpenSslContext.toBIO(cert.cert()); @@ -180,6 +188,7 @@ public final class OpenSsl { } AVAILABLE_CIPHER_SUITES = availableCipherSuites; SUPPORTS_KEYMANAGER_FACTORY = supportsKeyManagerFactory; + SUPPORTS_HOSTNAME_VALIDATION = supportsHostNameValidation; USE_KEYMANAGER_FACTORY = useKeyManagerFactory; Set protocols = new LinkedHashSet(6); @@ -207,6 +216,7 @@ public final class OpenSsl { AVAILABLE_JAVA_CIPHER_SUITES = Collections.emptySet(); AVAILABLE_CIPHER_SUITES = Collections.emptySet(); SUPPORTS_KEYMANAGER_FACTORY = false; + SUPPORTS_HOSTNAME_VALIDATION = false; USE_KEYMANAGER_FACTORY = false; SUPPORTED_PROTOCOLS_SET = Collections.emptySet(); } @@ -331,6 +341,14 @@ public final class OpenSsl { return SUPPORTS_KEYMANAGER_FACTORY; } + /** + * Returns {@code true} if Hostname Validation + * is supported when using OpenSSL. + */ + public static boolean supportsHostnameValidation() { + return SUPPORTS_HOSTNAME_VALIDATION; + } + static boolean useKeyManagerFactory() { return USE_KEYMANAGER_FACTORY; } diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java index 4bb5d594fb..e3687640da 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java +++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java @@ -87,10 +87,12 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc new SSLException("engine closed"), ReferenceCountedOpenSslEngine.class, "handshake()"); private static final SSLException RENEGOTIATION_UNSUPPORTED = ThrowableUtil.unknownStackTrace( new SSLException("renegotiation unsupported"), ReferenceCountedOpenSslEngine.class, "beginHandshake()"); - private static final SSLException ENCRYPTED_PACKET_OVERSIZED = ThrowableUtil.unknownStackTrace( - new SSLException("encrypted packet oversized"), ReferenceCountedOpenSslEngine.class, "unwrap(...)"); private static final ResourceLeakDetector leakDetector = ResourceLeakDetectorFactory.instance().newResourceLeakDetector(ReferenceCountedOpenSslEngine.class); + /** + * The flags argument is usually 0. + */ + private static final int DEFAULT_HOSTNAME_VALIDATION_FLAGS = 0; static final int MAX_PLAINTEXT_LENGTH = 16 * 1024; // 2^14 @@ -1557,14 +1559,26 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc int version = PlatformDependent.javaVersion(); if (version >= 7) { - endPointIdentificationAlgorithm = sslParameters.getEndpointIdentificationAlgorithm(); + final String endPointIdentificationAlgorithm = sslParameters.getEndpointIdentificationAlgorithm(); + final boolean endPointVerificationEnabled = endPointIdentificationAlgorithm != null && + !endPointIdentificationAlgorithm.isEmpty(); + SSL.setHostNameValidation(ssl, DEFAULT_HOSTNAME_VALIDATION_FLAGS, + endPointVerificationEnabled ? getPeerHost() : null); + // If the user asks for hostname verification we must ensure we verify the peer. + // If the user disables hostname verification we leave it up to the user to change the mode manually. + if (clientMode && endPointVerificationEnabled) { + SSL.setVerify(ssl, SSL.SSL_CVERIFY_REQUIRED, -1); + } + + this.endPointIdentificationAlgorithm = endPointIdentificationAlgorithm; algorithmConstraints = sslParameters.getAlgorithmConstraints(); if (version >= 8 && !isDestroyed()) { if (clientMode) { - sniHostNames = Java8SslParametersUtils.getSniHostNames(sslParameters); + final List sniHostNames = Java8SslParametersUtils.getSniHostNames(sslParameters); for (String name: sniHostNames) { SSL.setTlsExtHostName(ssl, name); } + this.sniHostNames = sniHostNames; } if (Java8SslParametersUtils.getUseCipherSuitesOrder(sslParameters)) { SSL.setOptions(ssl, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE); diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java index 08a05cc7b1..5dfa7b6792 100644 --- a/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java @@ -89,6 +89,20 @@ public class OpenSslEngineTest extends SSLEngineTest { super.testMutualAuthValidClientCertChainTooLongFailRequireClientAuth(); } + @Override + @Test + public void testClientHostnameValidationSuccess() throws InterruptedException, SSLException { + assumeTrue(OpenSsl.supportsHostnameValidation()); + super.testClientHostnameValidationSuccess(); + } + + @Override + @Test + public void testClientHostnameValidationFail() throws InterruptedException, SSLException { + assumeTrue(OpenSsl.supportsHostnameValidation()); + super.testClientHostnameValidationFail(); + } + @Test public void testNpn() throws Exception { ApplicationProtocolConfig apn = acceptingNegotiator(Protocol.NPN, diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java index 34c8d2762f..5fa3b85ed1 100644 --- a/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java @@ -19,6 +19,8 @@ import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; +import javax.net.ssl.SSLException; + import static org.junit.Assume.assumeTrue; public class OpenSslJdkSslEngineInteroptTest extends SSLEngineTest { @@ -72,4 +74,24 @@ public class OpenSslJdkSslEngineInteroptTest extends SSLEngineTest { assumeTrue(OpenSsl.supportsKeyManagerFactory()); super.testMutualAuthInvalidIntermediateCAFailWithRequiredClientAuth(); } + + @Override + @Test + public void testClientHostnameValidationSuccess() throws InterruptedException, SSLException { + assumeTrue(OpenSsl.supportsHostnameValidation()); + super.testClientHostnameValidationSuccess(); + } + + @Override + @Test + public void testClientHostnameValidationFail() throws InterruptedException, SSLException { + assumeTrue(OpenSsl.supportsHostnameValidation()); + super.testClientHostnameValidationFail(); + } + + @Override + protected boolean mySetupMutualAuthServerIsValidServerException(Throwable cause) { + // TODO(scott): work around for a JDK issue. The exception should be SSLHandshakeException. + return super.mySetupMutualAuthServerIsValidServerException(cause) || cause instanceof SSLException; + } } diff --git a/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java index df72e07449..a3cfd66776 100644 --- a/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java @@ -63,15 +63,18 @@ import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SNIHostName; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSession; import javax.security.cert.X509Certificate; @@ -720,6 +723,145 @@ public abstract class SSLEngineTest { clientChannel = ccf.channel(); } + @Test + public void testClientHostnameValidationSuccess() throws InterruptedException, SSLException { + mySetupClientHostnameValidation(new File(getClass().getResource("localhost_server.pem").getFile()), + new File(getClass().getResource("localhost_server.key").getFile()), + new File(getClass().getResource("mutual_auth_ca.pem").getFile()), + false); + assertTrue(clientLatch.await(5, TimeUnit.SECONDS)); + assertNull(clientException); + assertTrue(serverLatch.await(5, TimeUnit.SECONDS)); + assertNull(serverException); + } + + @Test + public void testClientHostnameValidationFail() throws InterruptedException, SSLException { + mySetupClientHostnameValidation(new File(getClass().getResource("notlocalhost_server.pem").getFile()), + new File(getClass().getResource("notlocalhost_server.key").getFile()), + new File(getClass().getResource("mutual_auth_ca.pem").getFile()), + true); + assertTrue(clientLatch.await(5, TimeUnit.SECONDS)); + assertTrue("unexpected exception: " + clientException, + mySetupMutualAuthServerIsValidClientException(clientException)); + assertTrue(serverLatch.await(5, TimeUnit.SECONDS)); + assertTrue("unexpected exception: " + serverException, + mySetupMutualAuthServerIsValidServerException(serverException)); + } + + private void mySetupClientHostnameValidation(File serverCrtFile, File serverKeyFile, + File clientTrustCrtFile, + final boolean failureExpected) + throws SSLException, InterruptedException { + final String expectedHost = "localhost"; + serverSslCtx = SslContextBuilder.forServer(serverCrtFile, serverKeyFile, null) + .sslProvider(sslServerProvider()) + .trustManager(InsecureTrustManagerFactory.INSTANCE) + .ciphers(null, IdentityCipherSuiteFilter.INSTANCE) + .sessionCacheSize(0) + .sessionTimeout(0) + .build(); + + clientSslCtx = SslContextBuilder.forClient() + .sslProvider(sslClientProvider()) + .trustManager(clientTrustCrtFile) + .ciphers(null, IdentityCipherSuiteFilter.INSTANCE) + .sessionCacheSize(0) + .sessionTimeout(0) + .build(); + serverConnectedChannel = null; + sb = new ServerBootstrap(); + cb = new Bootstrap(); + + sb.group(new NioEventLoopGroup(), new NioEventLoopGroup()); + sb.channel(NioServerSocketChannel.class); + sb.childHandler(new ChannelInitializer() { + @Override + protected void initChannel(Channel ch) throws Exception { + ch.config().setAllocator(new TestByteBufAllocator(ch.config().getAllocator(), type)); + ChannelPipeline p = ch.pipeline(); + p.addLast(serverSslCtx.newHandler(ch.alloc())); + p.addLast(new MessageDelegatorChannelHandler(serverReceiver, serverLatch)); + p.addLast(new ChannelInboundHandlerAdapter() { + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (evt == SslHandshakeCompletionEvent.SUCCESS) { + if (failureExpected) { + serverException = new IllegalStateException("handshake complete. expected failure"); + } + serverLatch.countDown(); + } else if (evt instanceof SslHandshakeCompletionEvent) { + serverException = ((SslHandshakeCompletionEvent) evt).cause(); + serverLatch.countDown(); + } + ctx.fireUserEventTriggered(evt); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (cause.getCause() instanceof SSLHandshakeException) { + serverException = cause.getCause(); + serverLatch.countDown(); + } else { + serverException = cause; + ctx.fireExceptionCaught(cause); + } + } + }); + serverConnectedChannel = ch; + } + }); + + cb.group(new NioEventLoopGroup()); + cb.channel(NioSocketChannel.class); + cb.handler(new ChannelInitializer() { + @Override + protected void initChannel(Channel ch) throws Exception { + ch.config().setAllocator(new TestByteBufAllocator(ch.config().getAllocator(), type)); + ChannelPipeline p = ch.pipeline(); + InetSocketAddress remoteAddress = (InetSocketAddress) serverChannel.localAddress(); + SslHandler sslHandler = clientSslCtx.newHandler(ch.alloc(), expectedHost, 0); + SSLParameters parameters = sslHandler.engine().getSSLParameters(); + parameters.setEndpointIdentificationAlgorithm("HTTPS"); + sslHandler.engine().setSSLParameters(parameters); + p.addLast(sslHandler); + p.addLast(new MessageDelegatorChannelHandler(clientReceiver, clientLatch)); + p.addLast(new ChannelInboundHandlerAdapter() { + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (evt == SslHandshakeCompletionEvent.SUCCESS) { + if (failureExpected) { + clientException = new IllegalStateException("handshake complete. expected failure"); + } + clientLatch.countDown(); + } else if (evt instanceof SslHandshakeCompletionEvent) { + clientException = ((SslHandshakeCompletionEvent) evt).cause(); + clientLatch.countDown(); + } + ctx.fireUserEventTriggered(evt); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (cause.getCause() instanceof SSLHandshakeException) { + clientException = cause.getCause(); + clientLatch.countDown(); + } else { + ctx.fireExceptionCaught(cause); + } + } + }); + } + }); + + serverChannel = sb.bind(new InetSocketAddress(expectedHost, 0)).sync().channel(); + final int port = ((InetSocketAddress) serverChannel.localAddress()).getPort(); + + ChannelFuture ccf = cb.connect(new InetSocketAddress(expectedHost, port)); + assertTrue(ccf.awaitUninterruptibly().isSuccess()); + clientChannel = ccf.channel(); + } + private void mySetupMutualAuth(File keyFile, File crtFile, String keyPassword) throws SSLException, InterruptedException { mySetupMutualAuth(crtFile, keyFile, crtFile, keyPassword, crtFile, keyFile, crtFile, keyPassword); diff --git a/handler/src/test/resources/io/netty/handler/ssl/generate-certs.sh b/handler/src/test/resources/io/netty/handler/ssl/generate-certs.sh index 34ecb442af..9375b8d78c 100755 --- a/handler/src/test/resources/io/netty/handler/ssl/generate-certs.sh +++ b/handler/src/test/resources/io/netty/handler/ssl/generate-certs.sh @@ -7,6 +7,18 @@ openssl req -extensions v3_ca -new -x509 -days 30 -nodes -subj "/CN=NettyTestRoo openssl req -new -keyout mutual_auth_server.key -nodes -newkey rsa:2048 -subj "/CN=NettyTestServer" | \ openssl x509 -req -CAkey mutual_auth_ca.key -CA mutual_auth_ca.pem -days 36500 -set_serial $RANDOM -sha512 -out mutual_auth_server.pem +# Generate a certificate/key for the server to use for Hostname Verification via localhost +openssl req -new -keyout localhost_server_rsa.key -nodes -newkey rsa:2048 -subj "/CN=localhost" | \ + openssl x509 -req -CAkey mutual_auth_ca.key -CA mutual_auth_ca.pem -days 36500 -set_serial $RANDOM -sha512 -out localhost_server.pem +openssl pkcs8 -topk8 -inform PEM -outform PEM -in localhost_server_rsa.key -out localhost_server.key -nocrypt +rm localhost_server_rsa.key + +# Generate a certificate/key for the server to fail for Hostname Verification via localhost +openssl req -new -keyout notlocalhost_server_rsa.key -nodes -newkey rsa:2048 -subj "/CN=NOTlocalhost" | \ + openssl x509 -req -CAkey mutual_auth_ca.key -CA mutual_auth_ca.pem -days 36500 -set_serial $RANDOM -sha512 -out notlocalhost_server.pem +openssl pkcs8 -topk8 -inform PEM -outform PEM -in notlocalhost_server_rsa.key -out notlocalhost_server.key -nocrypt +rm notlocalhost_server_rsa.key + # Generate an invalid intermediate CA which will be used to sign the client certificate openssl req -new -keyout mutual_auth_invalid_intermediate_ca.key -nodes -newkey rsa:2048 -subj "/CN=NettyTestInvalidIntermediate" | \ openssl x509 -req -CAkey mutual_auth_ca.key -CA mutual_auth_ca.pem -days 36500 -set_serial $RANDOM -sha512 -out mutual_auth_invalid_intermediate_ca.pem diff --git a/handler/src/test/resources/io/netty/handler/ssl/localhost_server.key b/handler/src/test/resources/io/netty/handler/ssl/localhost_server.key new file mode 100644 index 0000000000..9aa6611400 --- /dev/null +++ b/handler/src/test/resources/io/netty/handler/ssl/localhost_server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDYrLtMlZzoe2BP +iCURF3So5XNLfsOLcAVERXXjnxqX6Mex55WdJiy6uWTFKbRHWJdbWELdZxVl5+GX +pMv3OdkKZt+19ZdSfByv6bB5RNdZOEGnKOHSY2XdnzYnF5JBaWEx0fvtvIPZOUlW +DWgsQzJk1UQhu+XnBc7P1hHYNvwsVNOR+HD9LGebDy+UcfiL34XwAyBdHUsbcIr8 +hltABcj6vNbqOLndpU86DxU9z9b1PDmkFVfisElhpDEhpxmTCwI22Us1GC8D81LM +ZzMlbWSzTfNPEuqNzJYGiFt/XPwPkPPyVvti0XWPBQpwzJFFUX5xKsOGERolELRT +0yNQYznFAgMBAAECggEAOFR/xSNITbB1k3ejm1PrwlUUqlXkZIXU+LDOO0UL1t5v +vDKm1Not2sWECzYSZlID132UtJauG3YzUgdH95gUcv3XvyiAFLOriZhJht181vcn +KlwYiWfJ/dn8bCFWpqbM2/TpeB8AcCLSjAqkQI2ftlMziUmeNXdvEt1mej2hRay1 +ULfoxlC0mftNRQptD5gBFzrc47O4mVpVEQt4yS3Qyzp2/9ds9UkhaCIFpXPVCalZ +ds7R+bDDP+wiYTkUcd8fvelaMkD3Wcy8DedGRShhILZvBYTDdWcpJ7+e5EkNlEq4 ++Ys4Y/u6aFDJD53g3zCaJhatmdAZcct2MMmWH1vewQKBgQD3Y2S245cad1D9AqYD +ChZGp95EfRo3EzXk4VkE50bjZXjHq9fD8T0CWEZGWQZrXJCR+vBpEURy0mrPD8se +QQ0Q5+I27RadtfPnMd6ry9nDGMPxyd/10vzU6LazzLNE+uf9ljF1RHZu1iDAvInR +r1cQGbn/wKBF6BurPPIXABZEuQKBgQDgN6JHbIfDzHKhwEoUTvRrYJsTXqplD+h0 +Whg+kSQyhtKdlpINFOoEj8FUNJvTjG8les1aoajyWIqikVdvHto/mrxrSIeRkEmt +X+KG+5ld2n466tzv1DmVcIGXSrBrH3lA0i6R8Ly26FLSqw0Z12fx5GUUa1qaVRqo +rwcrIZovbQKBgHa2mojs9AC+Sv3uvG1u9LuZKJ7jDaZqMI2R2d7xgOH0Op5Ohy6+ +39D1PVvasqroc3Op4J36rEcRVDHi2Uy+WJ/JNpO2+AhcXRuPodP88ZWel8C6aB+V +zL/6oFntnAU5BgR5g2hLny2W0YbLsrMNmhDe15O0AvUo6cYla+K/pu/5AoGACr/g +EdiMMcDthf+4DX0zjqpVBPq25J18oYdoPierOpjoJBIB8oqcJZfWxvi2t8+1zHA0 +xDGX7fZ8vwqEzJkIEaCTg/k4NqxaO+uq6pnJYoyFHMIB0aW1FQsNy3kTOC+MGqV5 +Ahoukf5VajA1MpX3L8upZO84qsmFu6yYhWLZB4kCgYBlgSD5G4q6rX4ELa3XG61h +fDtu75IYEsjWm4vgJzHjeYT2xPIm9OFFYXjPghto0f1oH37ODD3DoXmsnmddgpmn +tH7aRWWHsSpB5zVgftV4urNCIsm87LWw8mvUGgCwYV1CtCX8warKokfeoA2ltz4u +oeuUzo98hN+aKRU5RO6Bmg== +-----END PRIVATE KEY----- diff --git a/handler/src/test/resources/io/netty/handler/ssl/localhost_server.pem b/handler/src/test/resources/io/netty/handler/ssl/localhost_server.pem new file mode 100644 index 0000000000..70759b29e5 --- /dev/null +++ b/handler/src/test/resources/io/netty/handler/ssl/localhost_server.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICozCCAYsCAnS/MA0GCSqGSIb3DQEBDQUAMBgxFjAUBgNVBAMTDU5ldHR5VGVz +dFJvb3QwIBcNMTcwMjE3MDMzMzQ0WhgPMjExNzAxMjQwMzMzNDRaMBQxEjAQBgNV +BAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANis +u0yVnOh7YE+IJREXdKjlc0t+w4twBURFdeOfGpfox7HnlZ0mLLq5ZMUptEdYl1tY +Qt1nFWXn4Zeky/c52Qpm37X1l1J8HK/psHlE11k4Qaco4dJjZd2fNicXkkFpYTHR +++28g9k5SVYNaCxDMmTVRCG75ecFzs/WEdg2/CxU05H4cP0sZ5sPL5Rx+IvfhfAD +IF0dSxtwivyGW0AFyPq81uo4ud2lTzoPFT3P1vU8OaQVV+KwSWGkMSGnGZMLAjbZ +SzUYLwPzUsxnMyVtZLNN808S6o3MlgaIW39c/A+Q8/JW+2LRdY8FCnDMkUVRfnEq +w4YRGiUQtFPTI1BjOcUCAwEAATANBgkqhkiG9w0BAQ0FAAOCAQEAQNXnwE2MJFy5 +ti07xyi8h/mY0Kl1dwZUqx4F9D9eoxLCq2/p3h/Z18AlOmjdW06pvC2sGtQtyEqL +YjuQFbMjXRo9c+6+d+xwdDKTu7+XOTHvznJ8xJpKnFOlohGq/n3efBIJSsaeasTU +slFzmdKYABDZzbsQ4X6YCIOF4XVdEQqmXpS+uEbn5C2sVtG+LXI8srmkVGpCcRew +SuTGanwxLparhBBeN1ARjKzNxXUWuK2UKZ9p8c7n7TXGhd12ZNTcLhk4rCnOFq1J +ySFvP5YL2q29fpEt+Tq0zm3V7An2qtaNDp26cEdevtKPjRyOLkCJx8OlZxc9DZvJ +HjalFDoRUw== +-----END CERTIFICATE----- diff --git a/handler/src/test/resources/io/netty/handler/ssl/mutual_auth_ca.pem b/handler/src/test/resources/io/netty/handler/ssl/mutual_auth_ca.pem index 6b523e9862..9c9241bc65 100644 --- a/handler/src/test/resources/io/netty/handler/ssl/mutual_auth_ca.pem +++ b/handler/src/test/resources/io/netty/handler/ssl/mutual_auth_ca.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/handler/src/test/resources/io/netty/handler/ssl/mutual_auth_client.p12 b/handler/src/test/resources/io/netty/handler/ssl/mutual_auth_client.p12 index 94c105cc35c3a44c7a124518b0c02d2eacd6e51c..85e74daa26d54360070772fdda36fe19fc8263be 100644 GIT binary patch delta 3875 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 lrX!`+^1PC}`gI88mjI{y+2mp}sWCZ{K delta 3875 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 diff --git a/handler/src/test/resources/io/netty/handler/ssl/mutual_auth_invalid_client.p12 b/handler/src/test/resources/io/netty/handler/ssl/mutual_auth_invalid_client.p12 index dea0b647b9fd89b17b407cc261b36e24eb07ab0e..cfac6627c82881932e6f308ace0d93aab7280a53 100644 GIT binary patch delta 3827 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 diff --git a/handler/src/test/resources/io/netty/handler/ssl/mutual_auth_server.p12 b/handler/src/test/resources/io/netty/handler/ssl/mutual_auth_server.p12 index 62eb76e88847da6a20f94033942128bef1cbb7e8..368462a0e1e9081be7d5cc6d2eaeed12ee67da17 100644 GIT binary patch delta 3123 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 fedora netty-tcnative - 2.0.0.Beta4 + 2.0.0.Beta5 ${os.detected.classifier} ${os.detected.name}-${os.detected.arch} ${project.basedir}/../common/src/test/resources/logback-test.xml