From 9861da721195006ba5333052639850b058f0e3df Mon Sep 17 00:00:00 2001 From: Troy Dawson Date: Thu, 14 Apr 2022 12:48:10 -0700 Subject: [PATCH] netty package is retired on c9s for CS-731 --- .gitignore | 2 - 0001-Remove-optional-dep-Blockhound.patch | 633 -- 0002-Remove-optional-dep-conscrypt.patch | 444 - ...ove-optional-deps-jetty-alpn-and-npn.patch | 405 - 0004-Remove-optional-dep-tcnative.patch | 8567 ----------------- 0005-Remove-optional-dep-log4j.patch | 911 -- codegen.bash | 22 - dead.package | 1 + netty.spec | 424 - sources | 1 - 10 files changed, 1 insertion(+), 11409 deletions(-) delete mode 100644 .gitignore delete mode 100644 0001-Remove-optional-dep-Blockhound.patch delete mode 100644 0002-Remove-optional-dep-conscrypt.patch delete mode 100644 0003-Remove-optional-deps-jetty-alpn-and-npn.patch delete mode 100644 0004-Remove-optional-dep-tcnative.patch delete mode 100644 0005-Remove-optional-dep-log4j.patch delete mode 100755 codegen.bash create mode 100644 dead.package delete mode 100644 netty.spec delete mode 100644 sources diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 488860d..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/netty-*.tar.gz -/*.src.rpm diff --git a/0001-Remove-optional-dep-Blockhound.patch b/0001-Remove-optional-dep-Blockhound.patch deleted file mode 100644 index 783b2f8..0000000 --- a/0001-Remove-optional-dep-Blockhound.patch +++ /dev/null @@ -1,633 +0,0 @@ -From 14fa8d4afda0fa1a31a2591298dc5c18e08dab1f Mon Sep 17 00:00:00 2001 -From: Mat Booth -Date: Mon, 7 Sep 2020 12:17:31 +0100 -Subject: [PATCH 1/5] Remove optional dep Blockhound - ---- - common/pom.xml | 5 - - .../java/io/netty/util/internal/Hidden.java | 113 --------- - ...ockhound.integration.BlockHoundIntegration | 14 - - pom.xml | 7 - - transport-blockhound-tests/pom.xml | 92 ------- - .../NettyBlockHoundIntegrationTest.java | 239 ------------------ - .../netty/util/internal/localhost_server.key | 28 -- - .../netty/util/internal/localhost_server.pem | 17 -- - .../io/netty/util/internal/mutual_auth_ca.pem | 19 -- - 9 files changed, 534 deletions(-) - delete mode 100644 common/src/main/java/io/netty/util/internal/Hidden.java - delete mode 100644 common/src/main/resources/META-INF/services/reactor.blockhound.integration.BlockHoundIntegration - delete mode 100644 transport-blockhound-tests/pom.xml - delete mode 100644 transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java - delete mode 100644 transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.key - delete mode 100644 transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.pem - delete mode 100644 transport-blockhound-tests/src/test/resources/io/netty/util/internal/mutual_auth_ca.pem - -diff --git a/common/pom.xml b/common/pom.xml -index 706279177a..abc73161eb 100644 ---- a/common/pom.xml -+++ b/common/pom.xml -@@ -78,11 +78,6 @@ - log4j-core - test - -- -- io.projectreactor.tools -- blockhound -- true -- - - org.mockito - mockito-core -diff --git a/common/src/main/java/io/netty/util/internal/Hidden.java b/common/src/main/java/io/netty/util/internal/Hidden.java -deleted file mode 100644 -index 7fd6d08396..0000000000 ---- a/common/src/main/java/io/netty/util/internal/Hidden.java -+++ /dev/null -@@ -1,113 +0,0 @@ --/* -- * Copyright 2019 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.util.internal; -- --import io.netty.util.concurrent.FastThreadLocalThread; --import reactor.blockhound.BlockHound; --import reactor.blockhound.integration.BlockHoundIntegration; -- --import java.util.function.Function; --import java.util.function.Predicate; -- --/** -- * Contains classes that must be have public visibility but are not public API. -- */ --class Hidden { -- -- /** -- * This class integrates Netty with BlockHound. -- *

-- * It is public but only because of the ServiceLoader's limitations -- * and SHOULD NOT be considered a public API. -- */ -- @UnstableApi -- @SuppressJava6Requirement(reason = "BlockHound is Java 8+, but this class is only loaded by it's SPI") -- public static final class NettyBlockHoundIntegration implements BlockHoundIntegration { -- -- @Override -- public void applyTo(BlockHound.Builder builder) { -- builder.allowBlockingCallsInside( -- "io.netty.channel.nio.NioEventLoop", -- "handleLoopException" -- ); -- -- builder.allowBlockingCallsInside( -- "io.netty.channel.kqueue.KQueueEventLoop", -- "handleLoopException" -- ); -- -- builder.allowBlockingCallsInside( -- "io.netty.channel.epoll.EpollEventLoop", -- "handleLoopException" -- ); -- -- builder.allowBlockingCallsInside( -- "io.netty.util.HashedWheelTimer$Worker", -- "waitForNextTick" -- ); -- -- builder.allowBlockingCallsInside( -- "io.netty.util.concurrent.SingleThreadEventExecutor", -- "confirmShutdown" -- ); -- -- builder.allowBlockingCallsInside( -- "io.netty.handler.ssl.SslHandler", -- "handshake" -- ); -- -- builder.allowBlockingCallsInside( -- "io.netty.handler.ssl.SslHandler", -- "runAllDelegatedTasks" -- ); -- -- builder.allowBlockingCallsInside( -- "io.netty.util.concurrent.GlobalEventExecutor", -- "takeTask"); -- -- builder.allowBlockingCallsInside( -- "io.netty.util.concurrent.GlobalEventExecutor", -- "addTask"); -- -- builder.allowBlockingCallsInside( -- "io.netty.util.concurrent.SingleThreadEventExecutor", -- "takeTask"); -- -- builder.allowBlockingCallsInside( -- "io.netty.handler.ssl.ReferenceCountedOpenSslClientContext$ExtendedTrustManagerVerifyCallback", -- "verify"); -- -- builder.nonBlockingThreadPredicate(new Function, Predicate>() { -- @Override -- public Predicate apply(final Predicate p) { -- return new Predicate() { -- @Override -- @SuppressJava6Requirement(reason = "Predicate#test") -- public boolean test(Thread thread) { -- return p.test(thread) || thread instanceof FastThreadLocalThread; -- } -- }; -- } -- }); -- } -- -- @Override -- public int compareTo(BlockHoundIntegration o) { -- return 0; -- } -- } --} -diff --git a/common/src/main/resources/META-INF/services/reactor.blockhound.integration.BlockHoundIntegration b/common/src/main/resources/META-INF/services/reactor.blockhound.integration.BlockHoundIntegration -deleted file mode 100644 -index 5cf376dd8c..0000000000 ---- a/common/src/main/resources/META-INF/services/reactor.blockhound.integration.BlockHoundIntegration -+++ /dev/null -@@ -1,14 +0,0 @@ --# Copyright 2019 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. --io.netty.util.internal.Hidden$NettyBlockHoundIntegration -\ No newline at end of file -diff --git a/pom.xml b/pom.xml -index d00e3e88e0..d548aa5513 100644 ---- a/pom.xml -+++ b/pom.xml -@@ -416,7 +416,6 @@ - testsuite-osgi - testsuite-shading - testsuite-native-image -- transport-blockhound-tests - microbench - bom - -@@ -717,12 +716,6 @@ - test - - -- -- -- io.projectreactor.tools -- blockhound -- 1.0.3.RELEASE -- - - - -diff --git a/transport-blockhound-tests/pom.xml b/transport-blockhound-tests/pom.xml -deleted file mode 100644 -index 359accd3c4..0000000000 ---- a/transport-blockhound-tests/pom.xml -+++ /dev/null -@@ -1,92 +0,0 @@ -- -- -- -- -- 4.0.0 -- -- io.netty -- netty-parent -- 4.1.51.Final -- -- -- netty-transport-blockhound-tests -- jar -- -- Tests for the BlockHound integration. -- -- -- Netty/Transport/BlockHound/Tests -- -- -- -- java13 -- -- 13 -- -- -- -XX:+AllowRedefinitionToAddDeleteMethods -- -- -- -- java14 -- -- 14 -- -- -- -XX:+AllowRedefinitionToAddDeleteMethods -- -- -- -- -- -- 1.8 -- 1.8 -- -- --add-exports java.base/sun.security.x509=ALL-UNNAMED -- true -- -- -- -- -- ${project.groupId} -- netty-transport -- ${project.version} -- -- -- ${project.groupId} -- netty-handler -- ${project.version} -- -- -- ${project.groupId} -- ${tcnative.artifactId} -- ${tcnative.classifier} -- true -- -- -- -- org.bouncycastle -- bcpkix-jdk15on -- true -- -- -- io.projectreactor.tools -- blockhound -- test -- -- -- -diff --git a/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java b/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java -deleted file mode 100644 -index 58e9284370..0000000000 ---- a/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java -+++ /dev/null -@@ -1,239 +0,0 @@ --/* -- * Copyright 2019 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.util.internal; -- --import io.netty.bootstrap.Bootstrap; --import io.netty.bootstrap.ServerBootstrap; --import io.netty.buffer.UnpooledByteBufAllocator; --import io.netty.channel.Channel; --import io.netty.channel.ChannelFuture; --import io.netty.channel.ChannelHandlerContext; --import io.netty.channel.ChannelInboundHandlerAdapter; --import io.netty.channel.ChannelInitializer; --import io.netty.channel.EventLoopGroup; --import io.netty.channel.nio.NioEventLoopGroup; --import io.netty.channel.socket.nio.NioServerSocketChannel; --import io.netty.channel.socket.nio.NioSocketChannel; --import io.netty.handler.ssl.SslContext; --import io.netty.handler.ssl.SslContextBuilder; --import io.netty.handler.ssl.SslHandler; --import io.netty.handler.ssl.SslHandshakeCompletionEvent; --import io.netty.handler.ssl.SslProvider; --import io.netty.handler.ssl.util.InsecureTrustManagerFactory; --import io.netty.handler.ssl.util.SelfSignedCertificate; --import io.netty.util.ReferenceCountUtil; --import io.netty.util.concurrent.DefaultThreadFactory; --import io.netty.util.concurrent.EventExecutor; --import io.netty.util.concurrent.GlobalEventExecutor; --import io.netty.util.concurrent.ImmediateEventExecutor; --import io.netty.util.concurrent.ImmediateExecutor; --import io.netty.util.concurrent.ScheduledFuture; --import io.netty.util.concurrent.SingleThreadEventExecutor; --import io.netty.util.internal.Hidden.NettyBlockHoundIntegration; --import org.hamcrest.Matchers; --import org.junit.BeforeClass; --import org.junit.Test; --import reactor.blockhound.BlockHound; --import reactor.blockhound.BlockingOperationError; --import reactor.blockhound.integration.BlockHoundIntegration; -- --import java.net.InetSocketAddress; --import java.util.ServiceLoader; --import java.util.concurrent.CountDownLatch; --import java.util.concurrent.ExecutionException; --import java.util.concurrent.Executor; --import java.util.concurrent.ExecutorService; --import java.util.concurrent.Executors; --import java.util.concurrent.FutureTask; --import java.util.concurrent.TimeUnit; -- --import static org.junit.Assert.assertThat; --import static org.junit.Assert.assertTrue; --import static org.junit.Assert.fail; -- --public class NettyBlockHoundIntegrationTest { -- -- @BeforeClass -- public static void setUpClass() { -- BlockHound.install(); -- } -- -- @Test -- public void testServiceLoader() { -- for (BlockHoundIntegration integration : ServiceLoader.load(BlockHoundIntegration.class)) { -- if (integration instanceof NettyBlockHoundIntegration) { -- return; -- } -- } -- -- fail("NettyBlockHoundIntegration cannot be loaded with ServiceLoader"); -- } -- -- @Test -- public void testBlockingCallsInNettyThreads() throws Exception { -- final FutureTask future = new FutureTask<>(() -> { -- Thread.sleep(0); -- return null; -- }); -- GlobalEventExecutor.INSTANCE.execute(future); -- -- try { -- future.get(5, TimeUnit.SECONDS); -- fail("Expected an exception due to a blocking call but none was thrown"); -- } catch (ExecutionException e) { -- assertThat(e.getCause(), Matchers.instanceOf(BlockingOperationError.class)); -- } -- } -- -- @Test(timeout = 5000L) -- public void testGlobalEventExecutorTakeTask() throws InterruptedException { -- testEventExecutorTakeTask(GlobalEventExecutor.INSTANCE); -- } -- -- @Test(timeout = 5000L) -- public void testSingleThreadEventExecutorTakeTask() throws InterruptedException { -- SingleThreadEventExecutor executor = -- new SingleThreadEventExecutor(null, new DefaultThreadFactory("test"), true) { -- @Override -- protected void run() { -- while (!confirmShutdown()) { -- Runnable task = takeTask(); -- if (task != null) { -- task.run(); -- } -- } -- } -- }; -- testEventExecutorTakeTask(executor); -- } -- -- private static void testEventExecutorTakeTask(EventExecutor eventExecutor) throws InterruptedException { -- CountDownLatch latch = new CountDownLatch(1); -- ScheduledFuture f = eventExecutor.schedule(latch::countDown, 10, TimeUnit.MILLISECONDS); -- f.sync(); -- latch.await(); -- } -- -- // Tests copied from io.netty.handler.ssl.SslHandlerTest -- @Test -- public void testHandshakeWithExecutorThatExecuteDirectory() throws Exception { -- testHandshakeWithExecutor(Runnable::run); -- } -- -- @Test -- public void testHandshakeWithImmediateExecutor() throws Exception { -- testHandshakeWithExecutor(ImmediateExecutor.INSTANCE); -- } -- -- @Test -- public void testHandshakeWithImmediateEventExecutor() throws Exception { -- testHandshakeWithExecutor(ImmediateEventExecutor.INSTANCE); -- } -- -- @Test -- public void testHandshakeWithExecutor() throws Exception { -- ExecutorService executorService = Executors.newCachedThreadPool(); -- try { -- testHandshakeWithExecutor(executorService); -- } finally { -- executorService.shutdown(); -- } -- } -- -- @Test -- public void testTrustManagerVerify() throws Exception { -- final SslContext sslClientCtx = -- SslContextBuilder.forClient() -- .trustManager(ResourcesUtil.getFile(getClass(), "mutual_auth_ca.pem")) -- .build(); -- -- final SslContext sslServerCtx = -- SslContextBuilder.forServer(ResourcesUtil.getFile(getClass(), "localhost_server.pem"), -- ResourcesUtil.getFile(getClass(), "localhost_server.key"), -- null) -- .build(); -- -- final SslHandler clientSslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT); -- final SslHandler serverSslHandler = sslServerCtx.newHandler(UnpooledByteBufAllocator.DEFAULT); -- -- testHandshake(sslClientCtx, clientSslHandler, serverSslHandler); -- } -- -- private static void testHandshakeWithExecutor(Executor executor) throws Exception { -- String tlsVersion = "TLSv1.2"; -- final SslContext sslClientCtx = SslContextBuilder.forClient() -- .trustManager(InsecureTrustManagerFactory.INSTANCE) -- .sslProvider(SslProvider.JDK).protocols(tlsVersion).build(); -- -- final SelfSignedCertificate cert = new SelfSignedCertificate(); -- final SslContext sslServerCtx = SslContextBuilder.forServer(cert.key(), cert.cert()) -- .sslProvider(SslProvider.JDK).protocols(tlsVersion).build(); -- -- final SslHandler clientSslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT, executor); -- final SslHandler serverSslHandler = sslServerCtx.newHandler(UnpooledByteBufAllocator.DEFAULT, executor); -- -- testHandshake(sslClientCtx, clientSslHandler, serverSslHandler); -- } -- -- private static void testHandshake(SslContext sslClientCtx, SslHandler clientSslHandler, -- SslHandler serverSslHandler) throws Exception { -- EventLoopGroup group = new NioEventLoopGroup(); -- Channel sc = null; -- Channel cc = null; -- try { -- sc = new ServerBootstrap() -- .group(group) -- .channel(NioServerSocketChannel.class) -- .childHandler(serverSslHandler) -- .bind(new InetSocketAddress(0)).syncUninterruptibly().channel(); -- -- ChannelFuture future = new Bootstrap() -- .group(group) -- .channel(NioSocketChannel.class) -- .handler(new ChannelInitializer() { -- @Override -- protected void initChannel(Channel ch) { -- ch.pipeline() -- .addLast(clientSslHandler) -- .addLast(new ChannelInboundHandlerAdapter() { -- -- @Override -- public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { -- if (evt instanceof SslHandshakeCompletionEvent && -- ((SslHandshakeCompletionEvent) evt).cause() != null) { -- ((SslHandshakeCompletionEvent) evt).cause().printStackTrace(); -- } -- ctx.fireUserEventTriggered(evt); -- } -- }); -- } -- }).connect(sc.localAddress()); -- cc = future.syncUninterruptibly().channel(); -- -- assertTrue(clientSslHandler.handshakeFuture().await().isSuccess()); -- assertTrue(serverSslHandler.handshakeFuture().await().isSuccess()); -- } finally { -- if (cc != null) { -- cc.close().syncUninterruptibly(); -- } -- if (sc != null) { -- sc.close().syncUninterruptibly(); -- } -- group.shutdownGracefully(); -- ReferenceCountUtil.release(sslClientCtx); -- } -- } --} -diff --git a/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.key b/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.key -deleted file mode 100644 -index 9aa6611400..0000000000 ---- a/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.key -+++ /dev/null -@@ -1,28 +0,0 @@ -------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/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.pem b/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.pem -deleted file mode 100644 -index 70759b29e5..0000000000 ---- a/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.pem -+++ /dev/null -@@ -1,17 +0,0 @@ -------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/transport-blockhound-tests/src/test/resources/io/netty/util/internal/mutual_auth_ca.pem b/transport-blockhound-tests/src/test/resources/io/netty/util/internal/mutual_auth_ca.pem -deleted file mode 100644 -index 9c9241bc65..0000000000 ---- a/transport-blockhound-tests/src/test/resources/io/netty/util/internal/mutual_auth_ca.pem -+++ /dev/null -@@ -1,19 +0,0 @@ -------BEGIN CERTIFICATE----- --MIIDLDCCAhSgAwIBAgIJAO1m5pioZhLLMA0GCSqGSIb3DQEBDQUAMBgxFjAUBgNV --BAMTDU5ldHR5VGVzdFJvb3QwHhcNMTcwMjE3MDMzMzQ0WhcNMTcwMzE5MDMzMzQ0 --WjAYMRYwFAYDVQQDEw1OZXR0eVRlc3RSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC --AQ8AMIIBCgKCAQEAnC7Y/p/TSWI1KxBKETfFKaRWCPEkoYn5G973WbCF0VDT90PX --xK6yHvhqNdDQZPmddgfDAQfjekHeeIFkjCKlvQu0js0G4Bubz4NffNumd/Mgsix8 --SWJ13lPk+Ly4PDv0bK1zB6BxP1qQm1qxVwsPy9zNP8ylJrM0Div4TXHmnWOfc0JD --4/XPpfeUHH1tt/GMtsS2Gx6EpTVPD2w7LDKUza1/rQ7d9sqmFpgsNcI9Db/sAtFP --lK2iJku5WIXQkmHimn4bqZ9wkiXJ85pm5ggGQqGMPSbe+2Lh24AvZMIBiwPbkjEU --EDFXEJfKOC3Dl71JgWOthtHZ9vcCRDQ3Sky6AQIDAQABo3kwdzAdBgNVHQ4EFgQU --qT+cH8qrebiVPpKCBQDB6At2iOAwSAYDVR0jBEEwP4AUqT+cH8qrebiVPpKCBQDB --6At2iOChHKQaMBgxFjAUBgNVBAMTDU5ldHR5VGVzdFJvb3SCCQDtZuaYqGYSyzAM --BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQCEemXTIew4pR2cHEFpVsW2 --bLHXLAnC23wBMT46D3tqyxscukMYjFuWosCdEsgRW8d50BXy9o4dHWeg94+aDo3A --DX4OTRN/veQGIG7dgM6poDzFuVJlSN0ubKKg6gpDD60IhopZpMviFAOsmzr7OXwS --9hjbTqUWujMIEHQ95sPlQFdSaavYSFfqhSltWmVCPSbArxrw0lZ2QcnUqGN47EFp --whc5wFB+rSw/ojU1jBLMvgvgzf/8V8zr1IBTDSiHNlknGqGpOOaookzUh95YRiAT --hH82y9bBeflqroOeztqMpONpWoZjlz0sWbJNvXztXINL7LaNmVYOcoUrCcxPS54T -------END CERTIFICATE----- --- -2.26.2 - diff --git a/0002-Remove-optional-dep-conscrypt.patch b/0002-Remove-optional-dep-conscrypt.patch deleted file mode 100644 index 0a9cfef..0000000 --- a/0002-Remove-optional-dep-conscrypt.patch +++ /dev/null @@ -1,444 +0,0 @@ -From 1a72454998ec91895648443c176ec41e542903e8 Mon Sep 17 00:00:00 2001 -From: Mat Booth -Date: Mon, 7 Sep 2020 13:24:30 +0100 -Subject: [PATCH 2/5] Remove optional dep conscrypt - ---- - handler/pom.xml | 6 - - .../java/io/netty/handler/ssl/Conscrypt.java | 81 -------- - .../handler/ssl/ConscryptAlpnSslEngine.java | 196 ------------------ - .../JdkAlpnApplicationProtocolNegotiator.java | 8 +- - .../java/io/netty/handler/ssl/SslHandler.java | 47 +---- - pom.xml | 10 - - 6 files changed, 2 insertions(+), 346 deletions(-) - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/Conscrypt.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ConscryptAlpnSslEngine.java - -diff --git a/handler/pom.xml b/handler/pom.xml -index c8e26119bd..378aeda2fe 100644 ---- a/handler/pom.xml -+++ b/handler/pom.xml -@@ -81,12 +81,6 @@ - alpn-api - true - -- -- ${conscrypt.groupId} -- ${conscrypt.artifactId} -- ${conscrypt.classifier} -- true -- - - org.mockito - mockito-core -diff --git a/handler/src/main/java/io/netty/handler/ssl/Conscrypt.java b/handler/src/main/java/io/netty/handler/ssl/Conscrypt.java -deleted file mode 100644 -index d2f015f90f..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/Conscrypt.java -+++ /dev/null -@@ -1,81 +0,0 @@ --/* -- * 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.PlatformDependent; -- --import javax.net.ssl.SSLEngine; --import java.lang.reflect.InvocationTargetException; --import java.lang.reflect.Method; -- --/** -- * Contains methods that can be used to detect if conscrypt is usable. -- */ --final class Conscrypt { -- // This class exists to avoid loading other conscrypt related classes using features only available in JDK8+, -- // because we need to maintain JDK6+ runtime compatibility. -- private static final Method IS_CONSCRYPT_SSLENGINE = loadIsConscryptEngine(); -- private static final boolean CAN_INSTANCE_PROVIDER = canInstanceProvider(); -- -- private static Method loadIsConscryptEngine() { -- try { -- Class conscryptClass = Class.forName("org.conscrypt.Conscrypt", true, -- ConscryptAlpnSslEngine.class.getClassLoader()); -- return conscryptClass.getMethod("isConscrypt", SSLEngine.class); -- } catch (Throwable ignore) { -- // Conscrypt was not loaded. -- return null; -- } -- } -- -- private static boolean canInstanceProvider() { -- try { -- Class providerClass = Class.forName("org.conscrypt.OpenSSLProvider", true, -- ConscryptAlpnSslEngine.class.getClassLoader()); -- providerClass.newInstance(); -- return true; -- } catch (Throwable ignore) { -- return false; -- } -- } -- -- /** -- * Indicates whether or not conscrypt is available on the current system. -- */ -- static boolean isAvailable() { -- return CAN_INSTANCE_PROVIDER && IS_CONSCRYPT_SSLENGINE != null && -- ((PlatformDependent.javaVersion() >= 8 && -- // Only works on Java14 and earlier for now -- // See https://github.com/google/conscrypt/issues/838 -- PlatformDependent.javaVersion() < 15) || PlatformDependent.isAndroid()); -- } -- -- static boolean isEngineSupported(SSLEngine engine) { -- return isAvailable() && isConscryptEngine(engine); -- } -- -- private static boolean isConscryptEngine(SSLEngine engine) { -- try { -- return (Boolean) IS_CONSCRYPT_SSLENGINE.invoke(null, engine); -- } catch (IllegalAccessException ignore) { -- return false; -- } catch (InvocationTargetException ex) { -- throw new RuntimeException(ex); -- } -- } -- -- private Conscrypt() { } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/ConscryptAlpnSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/ConscryptAlpnSslEngine.java -deleted file mode 100644 -index d9767a7106..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/ConscryptAlpnSslEngine.java -+++ /dev/null -@@ -1,196 +0,0 @@ --/* -- * 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 static io.netty.handler.ssl.SslUtils.toSSLHandshakeException; --import static io.netty.util.internal.ObjectUtil.checkNotNull; --import static java.lang.Math.min; -- --import io.netty.buffer.ByteBuf; --import io.netty.buffer.ByteBufAllocator; --import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelectionListener; --import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector; --import java.nio.ByteBuffer; --import java.util.Collections; --import java.util.LinkedHashSet; --import java.util.List; --import javax.net.ssl.SSLEngine; --import javax.net.ssl.SSLEngineResult; --import javax.net.ssl.SSLException; -- --import io.netty.util.internal.SystemPropertyUtil; --import org.conscrypt.AllocatedBuffer; --import org.conscrypt.BufferAllocator; --import org.conscrypt.Conscrypt; --import org.conscrypt.HandshakeListener; -- --/** -- * A {@link JdkSslEngine} that uses the Conscrypt provider or SSL with ALPN. -- */ --abstract class ConscryptAlpnSslEngine extends JdkSslEngine { -- private static final boolean USE_BUFFER_ALLOCATOR = SystemPropertyUtil.getBoolean( -- "io.netty.handler.ssl.conscrypt.useBufferAllocator", true); -- -- static ConscryptAlpnSslEngine newClientEngine(SSLEngine engine, ByteBufAllocator alloc, -- JdkApplicationProtocolNegotiator applicationNegotiator) { -- return new ClientEngine(engine, alloc, applicationNegotiator); -- } -- -- static ConscryptAlpnSslEngine newServerEngine(SSLEngine engine, ByteBufAllocator alloc, -- JdkApplicationProtocolNegotiator applicationNegotiator) { -- return new ServerEngine(engine, alloc, applicationNegotiator); -- } -- -- private ConscryptAlpnSslEngine(SSLEngine engine, ByteBufAllocator alloc, List protocols) { -- super(engine); -- -- // Configure the Conscrypt engine to use Netty's buffer allocator. This is a trade-off of memory vs -- // performance. -- // -- // If no allocator is provided, the engine will internally allocate a direct buffer of max packet size in -- // order to optimize JNI calls (this happens the first time it is provided a non-direct buffer from the -- // application). -- // -- // Alternatively, if an allocator is provided, no internal buffer will be created and direct buffers will be -- // retrieved from the allocator on-demand. -- if (USE_BUFFER_ALLOCATOR) { -- Conscrypt.setBufferAllocator(engine, new BufferAllocatorAdapter(alloc)); -- } -- -- // Set the list of supported ALPN protocols on the engine. -- Conscrypt.setApplicationProtocols(engine, protocols.toArray(new String[0])); -- } -- -- /** -- * Calculates the maximum size of the encrypted output buffer required to wrap the given plaintext bytes. Assumes -- * as a worst case that there is one TLS record per buffer. -- * -- * @param plaintextBytes the number of plaintext bytes to be wrapped. -- * @param numBuffers the number of buffers that the plaintext bytes are spread across. -- * @return the maximum size of the encrypted output buffer required for the wrap operation. -- */ -- final int calculateOutNetBufSize(int plaintextBytes, int numBuffers) { -- // Assuming a max of one frame per component in a composite buffer. -- long maxOverhead = (long) Conscrypt.maxSealOverhead(getWrappedEngine()) * numBuffers; -- // TODO(nmittler): update this to use MAX_ENCRYPTED_PACKET_LENGTH instead of Integer.MAX_VALUE -- return (int) min(Integer.MAX_VALUE, plaintextBytes + maxOverhead); -- } -- -- final SSLEngineResult unwrap(ByteBuffer[] srcs, ByteBuffer[] dests) throws SSLException { -- return Conscrypt.unwrap(getWrappedEngine(), srcs, dests); -- } -- -- private static final class ClientEngine extends ConscryptAlpnSslEngine { -- private final ProtocolSelectionListener protocolListener; -- -- ClientEngine(SSLEngine engine, ByteBufAllocator alloc, -- JdkApplicationProtocolNegotiator applicationNegotiator) { -- super(engine, alloc, applicationNegotiator.protocols()); -- // Register for completion of the handshake. -- Conscrypt.setHandshakeListener(engine, new HandshakeListener() { -- @Override -- public void onHandshakeFinished() throws SSLException { -- selectProtocol(); -- } -- }); -- -- protocolListener = checkNotNull(applicationNegotiator -- .protocolListenerFactory().newListener(this, applicationNegotiator.protocols()), -- "protocolListener"); -- } -- -- private void selectProtocol() throws SSLException { -- String protocol = Conscrypt.getApplicationProtocol(getWrappedEngine()); -- try { -- protocolListener.selected(protocol); -- } catch (Throwable e) { -- throw toSSLHandshakeException(e); -- } -- } -- } -- -- private static final class ServerEngine extends ConscryptAlpnSslEngine { -- private final ProtocolSelector protocolSelector; -- -- ServerEngine(SSLEngine engine, ByteBufAllocator alloc, -- JdkApplicationProtocolNegotiator applicationNegotiator) { -- super(engine, alloc, applicationNegotiator.protocols()); -- -- // Register for completion of the handshake. -- Conscrypt.setHandshakeListener(engine, new HandshakeListener() { -- @Override -- public void onHandshakeFinished() throws SSLException { -- selectProtocol(); -- } -- }); -- -- protocolSelector = checkNotNull(applicationNegotiator.protocolSelectorFactory() -- .newSelector(this, -- new LinkedHashSet(applicationNegotiator.protocols())), -- "protocolSelector"); -- } -- -- private void selectProtocol() throws SSLException { -- try { -- String protocol = Conscrypt.getApplicationProtocol(getWrappedEngine()); -- protocolSelector.select(protocol != null ? Collections.singletonList(protocol) -- : Collections.emptyList()); -- } catch (Throwable e) { -- throw toSSLHandshakeException(e); -- } -- } -- } -- -- private static final class BufferAllocatorAdapter extends BufferAllocator { -- private final ByteBufAllocator alloc; -- -- BufferAllocatorAdapter(ByteBufAllocator alloc) { -- this.alloc = alloc; -- } -- -- @Override -- public AllocatedBuffer allocateDirectBuffer(int capacity) { -- return new BufferAdapter(alloc.directBuffer(capacity)); -- } -- } -- -- private static final class BufferAdapter extends AllocatedBuffer { -- private final ByteBuf nettyBuffer; -- private final ByteBuffer buffer; -- -- BufferAdapter(ByteBuf nettyBuffer) { -- this.nettyBuffer = nettyBuffer; -- buffer = nettyBuffer.nioBuffer(0, nettyBuffer.capacity()); -- } -- -- @Override -- public ByteBuffer nioBuffer() { -- return buffer; -- } -- -- @Override -- public AllocatedBuffer retain() { -- nettyBuffer.retain(); -- return this; -- } -- -- @Override -- public AllocatedBuffer release() { -- nettyBuffer.release(); -- return this; -- } -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/JdkAlpnApplicationProtocolNegotiator.java b/handler/src/main/java/io/netty/handler/ssl/JdkAlpnApplicationProtocolNegotiator.java -index c4ca7b9b8c..2ed83a313b 100644 ---- a/handler/src/main/java/io/netty/handler/ssl/JdkAlpnApplicationProtocolNegotiator.java -+++ b/handler/src/main/java/io/netty/handler/ssl/JdkAlpnApplicationProtocolNegotiator.java -@@ -26,8 +26,7 @@ import javax.net.ssl.SSLEngine; - */ - @Deprecated - public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicationProtocolNegotiator { -- private static final boolean AVAILABLE = Conscrypt.isAvailable() || -- JdkAlpnSslUtils.supportsAlpn() || -+ private static final boolean AVAILABLE = JdkAlpnSslUtils.supportsAlpn() || - JettyAlpnSslEngine.isAvailable(); - - private static final SslEngineWrapperFactory ALPN_WRAPPER = AVAILABLE ? new AlpnWrapper() : new FailureWrapper(); -@@ -119,7 +118,6 @@ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicati - public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, - JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { - throw new RuntimeException("ALPN unsupported. Is your classpath configured correctly?" -- + " For Conscrypt, add the appropriate Conscrypt JAR to classpath and set the security provider." - + " For Jetty-ALPN, see " - + "http://www.eclipse.org/jetty/documentation/current/alpn-chapter.html#alpn-starting"); - } -@@ -129,10 +127,6 @@ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicati - @Override - public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, - JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { -- if (Conscrypt.isEngineSupported(engine)) { -- return isServer ? ConscryptAlpnSslEngine.newServerEngine(engine, alloc, applicationNegotiator) -- : ConscryptAlpnSslEngine.newClientEngine(engine, alloc, applicationNegotiator); -- } - // ALPN support was recently backported to Java8 as - // 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 -diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java -index de101967ba..8e11bbf4cc 100644 ---- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java -+++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java -@@ -228,50 +228,6 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH - return ((ReferenceCountedOpenSslEngine) engine).jdkCompatibilityMode; - } - }, -- CONSCRYPT(true, COMPOSITE_CUMULATOR) { -- @Override -- SSLEngineResult unwrap(SslHandler handler, ByteBuf in, int readerIndex, int len, ByteBuf out) -- throws SSLException { -- int nioBufferCount = in.nioBufferCount(); -- int writerIndex = out.writerIndex(); -- final SSLEngineResult result; -- if (nioBufferCount > 1) { -- /* -- * Use a special unwrap method without additional memory copies. -- */ -- try { -- handler.singleBuffer[0] = toByteBuffer(out, writerIndex, out.writableBytes()); -- result = ((ConscryptAlpnSslEngine) handler.engine).unwrap( -- in.nioBuffers(readerIndex, len), -- handler.singleBuffer); -- } finally { -- handler.singleBuffer[0] = null; -- } -- } else { -- result = handler.engine.unwrap(toByteBuffer(in, readerIndex, len), -- toByteBuffer(out, writerIndex, out.writableBytes())); -- } -- out.writerIndex(writerIndex + result.bytesProduced()); -- return result; -- } -- -- @Override -- ByteBuf allocateWrapBuffer(SslHandler handler, ByteBufAllocator allocator, -- int pendingBytes, int numComponents) { -- return allocator.directBuffer( -- ((ConscryptAlpnSslEngine) handler.engine).calculateOutNetBufSize(pendingBytes, numComponents)); -- } -- -- @Override -- int calculatePendingData(SslHandler handler, int guess) { -- return guess; -- } -- -- @Override -- boolean jdkCompatibilityMode(SSLEngine engine) { -- return true; -- } -- }, - JDK(false, MERGE_CUMULATOR) { - @Override - SSLEngineResult unwrap(SslHandler handler, ByteBuf in, int readerIndex, int len, ByteBuf out) -@@ -324,8 +280,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH - }; - - static SslEngineType forEngine(SSLEngine engine) { -- return engine instanceof ReferenceCountedOpenSslEngine ? TCNATIVE : -- engine instanceof ConscryptAlpnSslEngine ? CONSCRYPT : JDK; -+ return engine instanceof ReferenceCountedOpenSslEngine ? TCNATIVE : JDK; - } - - SslEngineType(boolean wantsDirectBuffer, Cumulator cumulator) { -diff --git a/pom.xml b/pom.xml -index d548aa5513..db3d7b0d38 100644 ---- a/pom.xml -+++ b/pom.xml -@@ -489,16 +489,6 @@ - true - - -- -- -- ${conscrypt.groupId} -- ${conscrypt.artifactId} -- ${conscrypt.classifier} -- ${conscrypt.version} -- compile -- true -- -- - -- -- org.eclipse.jetty.npn -- npn-api -- 1.1.1.v20141010 -- provided -- -- -- org.eclipse.jetty.alpn -- alpn-api -- 1.1.2.v20150522 -- provided -- -- - - - com.google.protobuf --- -2.26.2 - diff --git a/0004-Remove-optional-dep-tcnative.patch b/0004-Remove-optional-dep-tcnative.patch deleted file mode 100644 index 6ed11bd..0000000 --- a/0004-Remove-optional-dep-tcnative.patch +++ /dev/null @@ -1,8567 +0,0 @@ -From c60f3b8d7ca0575bba15682a329dced786f898da Mon Sep 17 00:00:00 2001 -From: Mat Booth -Date: Mon, 7 Sep 2020 13:41:44 +0100 -Subject: [PATCH 4/5] Remove optional dep tcnative - ---- - handler/pom.xml | 6 - - .../handler/ssl/CipherSuiteConverter.java | 494 ---- - .../ssl/DefaultOpenSslKeyMaterial.java | 126 - - .../java/io/netty/handler/ssl/OpenSsl.java | 610 ---- - .../OpenSslCachingKeyMaterialProvider.java | 79 - - .../OpenSslCachingX509KeyManagerFactory.java | 81 - - .../ssl/OpenSslCertificateException.java | 81 - - .../handler/ssl/OpenSslClientContext.java | 208 -- - .../io/netty/handler/ssl/OpenSslContext.java | 58 - - .../io/netty/handler/ssl/OpenSslEngine.java | 41 - - .../netty/handler/ssl/OpenSslEngineMap.java | 35 - - .../ssl/OpenSslKeyMaterialManager.java | 127 - - .../ssl/OpenSslKeyMaterialProvider.java | 154 - - .../netty/handler/ssl/OpenSslPrivateKey.java | 191 -- - .../handler/ssl/OpenSslPrivateKeyMethod.java | 62 - - .../handler/ssl/OpenSslServerContext.java | 367 --- - .../ssl/OpenSslServerSessionContext.java | 124 - - .../handler/ssl/OpenSslSessionContext.java | 158 -- - .../handler/ssl/OpenSslSessionStats.java | 253 -- - .../handler/ssl/OpenSslSessionTicketKey.java | 78 - - ...OpenSslTlsv13X509ExtendedTrustManager.java | 240 -- - .../ssl/OpenSslX509KeyManagerFactory.java | 413 --- - .../ReferenceCountedOpenSslClientContext.java | 343 --- - .../ssl/ReferenceCountedOpenSslContext.java | 968 ------- - .../ssl/ReferenceCountedOpenSslEngine.java | 2467 ----------------- - .../ReferenceCountedOpenSslServerContext.java | 286 -- - .../java/io/netty/handler/ssl/SslContext.java | 30 +- - .../java/io/netty/handler/ssl/SslHandler.java | 49 +- - .../handler/ssl/SslMasterKeyHandler.java | 3 - - .../io/netty/handler/ssl/SslProvider.java | 14 +- - .../handler/ssl/ocsp/OcspClientHandler.java | 61 - - .../netty/handler/ssl/ocsp/package-info.java | 23 - - pom.xml | 10 - - 33 files changed, 3 insertions(+), 8237 deletions(-) - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/CipherSuiteConverter.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/DefaultOpenSslKeyMaterial.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSsl.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslCachingKeyMaterialProvider.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslCachingX509KeyManagerFactory.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslContext.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslEngine.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslEngineMap.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialProvider.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslPrivateKey.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslPrivateKeyMethod.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslTlsv13X509ExtendedTrustManager.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslX509KeyManagerFactory.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ocsp/OcspClientHandler.java - delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ocsp/package-info.java - -diff --git a/handler/pom.xml b/handler/pom.xml -index be8206dc89..e28cc6f7af 100644 ---- a/handler/pom.xml -+++ b/handler/pom.xml -@@ -60,12 +60,6 @@ - netty-codec - ${project.version} - -- -- ${project.groupId} -- ${tcnative.artifactId} -- ${tcnative.classifier} -- true -- - - org.bouncycastle - bcpkix-jdk15on -diff --git a/handler/src/main/java/io/netty/handler/ssl/CipherSuiteConverter.java b/handler/src/main/java/io/netty/handler/ssl/CipherSuiteConverter.java -deleted file mode 100644 -index 94e951f7f5..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/CipherSuiteConverter.java -+++ /dev/null -@@ -1,494 +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 io.netty.util.internal.PlatformDependent; --import io.netty.util.internal.logging.InternalLogger; --import io.netty.util.internal.logging.InternalLoggerFactory; -- --import java.util.Collections; --import java.util.HashMap; --import java.util.Map; --import java.util.concurrent.ConcurrentMap; --import java.util.regex.Matcher; --import java.util.regex.Pattern; -- --import static java.util.Collections.singletonMap; -- --/** -- * Converts a Java cipher suite string to an OpenSSL cipher suite string and vice versa. -- * -- * @see Wikipedia page about cipher suite -- */ --final class CipherSuiteConverter { -- -- private static final InternalLogger logger = InternalLoggerFactory.getInstance(CipherSuiteConverter.class); -- -- /** -- * A_B_WITH_C_D, where: -- * -- * A - TLS or SSL (protocol) -- * B - handshake algorithm (key exchange and authentication algorithms to be precise) -- * C - bulk cipher -- * D - HMAC algorithm -- * -- * This regular expression assumes that: -- * -- * 1) A is always TLS or SSL, and -- * 2) D is always a single word. -- */ -- private static final Pattern JAVA_CIPHERSUITE_PATTERN = -- Pattern.compile("^(?:TLS|SSL)_((?:(?!_WITH_).)+)_WITH_(.*)_(.*)$"); -- -- /** -- * A-B-C, where: -- * -- * A - handshake algorithm (key exchange and authentication algorithms to be precise) -- * B - bulk cipher -- * C - HMAC algorithm -- * -- * This regular expression assumes that: -- * -- * 1) A has some deterministic pattern as shown below, and -- * 2) C is always a single word -- */ -- private static final Pattern OPENSSL_CIPHERSUITE_PATTERN = -- // Be very careful not to break the indentation while editing. -- Pattern.compile( -- "^(?:(" + // BEGIN handshake algorithm -- "(?:(?:EXP-)?" + -- "(?:" + -- "(?:DHE|EDH|ECDH|ECDHE|SRP|RSA)-(?:DSS|RSA|ECDSA|PSK)|" + -- "(?:ADH|AECDH|KRB5|PSK|SRP)" + -- ')' + -- ")|" + -- "EXP" + -- ")-)?" + // END handshake algorithm -- "(.*)-(.*)$"); -- -- private static final Pattern JAVA_AES_CBC_PATTERN = Pattern.compile("^(AES)_([0-9]+)_CBC$"); -- private static final Pattern JAVA_AES_PATTERN = Pattern.compile("^(AES)_([0-9]+)_(.*)$"); -- private static final Pattern OPENSSL_AES_CBC_PATTERN = Pattern.compile("^(AES)([0-9]+)$"); -- private static final Pattern OPENSSL_AES_PATTERN = Pattern.compile("^(AES)([0-9]+)-(.*)$"); -- -- /** -- * Java-to-OpenSSL cipher suite conversion map -- * Note that the Java cipher suite has the protocol prefix (TLS_, SSL_) -- */ -- private static final ConcurrentMap j2o = PlatformDependent.newConcurrentHashMap(); -- -- /** -- * OpenSSL-to-Java cipher suite conversion map. -- * Note that one OpenSSL cipher suite can be converted to more than one Java cipher suites because -- * a Java cipher suite has the protocol name prefix (TLS_, SSL_) -- */ -- private static final ConcurrentMap> o2j = PlatformDependent.newConcurrentHashMap(); -- -- private static final Map j2oTls13; -- private static final Map> o2jTls13; -- -- static { -- Map j2oTls13Map = new HashMap(); -- j2oTls13Map.put("TLS_AES_128_GCM_SHA256", "AEAD-AES128-GCM-SHA256"); -- j2oTls13Map.put("TLS_AES_256_GCM_SHA384", "AEAD-AES256-GCM-SHA384"); -- j2oTls13Map.put("TLS_CHACHA20_POLY1305_SHA256", "AEAD-CHACHA20-POLY1305-SHA256"); -- j2oTls13 = Collections.unmodifiableMap(j2oTls13Map); -- -- Map> o2jTls13Map = new HashMap>(); -- o2jTls13Map.put("TLS_AES_128_GCM_SHA256", singletonMap("TLS", "TLS_AES_128_GCM_SHA256")); -- o2jTls13Map.put("TLS_AES_256_GCM_SHA384", singletonMap("TLS", "TLS_AES_256_GCM_SHA384")); -- o2jTls13Map.put("TLS_CHACHA20_POLY1305_SHA256", singletonMap("TLS", "TLS_CHACHA20_POLY1305_SHA256")); -- o2jTls13Map.put("AEAD-AES128-GCM-SHA256", singletonMap("TLS", "TLS_AES_128_GCM_SHA256")); -- o2jTls13Map.put("AEAD-AES256-GCM-SHA384", singletonMap("TLS", "TLS_AES_256_GCM_SHA384")); -- o2jTls13Map.put("AEAD-CHACHA20-POLY1305-SHA256", singletonMap("TLS", "TLS_CHACHA20_POLY1305_SHA256")); -- o2jTls13 = Collections.unmodifiableMap(o2jTls13Map); -- } -- -- /** -- * Clears the cache for testing purpose. -- */ -- static void clearCache() { -- j2o.clear(); -- o2j.clear(); -- } -- -- /** -- * Tests if the specified key-value pair has been cached in Java-to-OpenSSL cache. -- */ -- static boolean isJ2OCached(String key, String value) { -- return value.equals(j2o.get(key)); -- } -- -- /** -- * Tests if the specified key-value pair has been cached in OpenSSL-to-Java cache. -- */ -- static boolean isO2JCached(String key, String protocol, String value) { -- Map p2j = o2j.get(key); -- if (p2j == null) { -- return false; -- } else { -- return value.equals(p2j.get(protocol)); -- } -- } -- -- /** -- * Converts the specified Java cipher suite to its corresponding OpenSSL cipher suite name. -- * -- * @return {@code null} if the conversion has failed -- */ -- static String toOpenSsl(String javaCipherSuite, boolean boringSSL) { -- String converted = j2o.get(javaCipherSuite); -- if (converted != null) { -- return converted; -- } -- return cacheFromJava(javaCipherSuite, boringSSL); -- } -- -- private static String cacheFromJava(String javaCipherSuite, boolean boringSSL) { -- String converted = j2oTls13.get(javaCipherSuite); -- if (converted != null) { -- return boringSSL ? converted : javaCipherSuite; -- } -- -- String openSslCipherSuite = toOpenSslUncached(javaCipherSuite, boringSSL); -- if (openSslCipherSuite == null) { -- return null; -- } -- -- // Cache the mapping. -- j2o.putIfAbsent(javaCipherSuite, openSslCipherSuite); -- -- // Cache the reverse mapping after stripping the protocol prefix (TLS_ or SSL_) -- final String javaCipherSuiteSuffix = javaCipherSuite.substring(4); -- Map p2j = new HashMap(4); -- p2j.put("", javaCipherSuiteSuffix); -- p2j.put("SSL", "SSL_" + javaCipherSuiteSuffix); -- p2j.put("TLS", "TLS_" + javaCipherSuiteSuffix); -- o2j.put(openSslCipherSuite, p2j); -- -- logger.debug("Cipher suite mapping: {} => {}", javaCipherSuite, openSslCipherSuite); -- -- return openSslCipherSuite; -- } -- -- static String toOpenSslUncached(String javaCipherSuite, boolean boringSSL) { -- String converted = j2oTls13.get(javaCipherSuite); -- if (converted != null) { -- return boringSSL ? converted : javaCipherSuite; -- } -- -- Matcher m = JAVA_CIPHERSUITE_PATTERN.matcher(javaCipherSuite); -- if (!m.matches()) { -- return null; -- } -- -- String handshakeAlgo = toOpenSslHandshakeAlgo(m.group(1)); -- String bulkCipher = toOpenSslBulkCipher(m.group(2)); -- String hmacAlgo = toOpenSslHmacAlgo(m.group(3)); -- if (handshakeAlgo.isEmpty()) { -- return bulkCipher + '-' + hmacAlgo; -- } else if (bulkCipher.contains("CHACHA20")) { -- return handshakeAlgo + '-' + bulkCipher; -- } else { -- return handshakeAlgo + '-' + bulkCipher + '-' + hmacAlgo; -- } -- } -- -- private static String toOpenSslHandshakeAlgo(String handshakeAlgo) { -- final boolean export = handshakeAlgo.endsWith("_EXPORT"); -- if (export) { -- handshakeAlgo = handshakeAlgo.substring(0, handshakeAlgo.length() - 7); -- } -- -- if ("RSA".equals(handshakeAlgo)) { -- handshakeAlgo = ""; -- } else if (handshakeAlgo.endsWith("_anon")) { -- handshakeAlgo = 'A' + handshakeAlgo.substring(0, handshakeAlgo.length() - 5); -- } -- -- if (export) { -- if (handshakeAlgo.isEmpty()) { -- handshakeAlgo = "EXP"; -- } else { -- handshakeAlgo = "EXP-" + handshakeAlgo; -- } -- } -- -- return handshakeAlgo.replace('_', '-'); -- } -- -- private static String toOpenSslBulkCipher(String bulkCipher) { -- if (bulkCipher.startsWith("AES_")) { -- Matcher m = JAVA_AES_CBC_PATTERN.matcher(bulkCipher); -- if (m.matches()) { -- return m.replaceFirst("$1$2"); -- } -- -- m = JAVA_AES_PATTERN.matcher(bulkCipher); -- if (m.matches()) { -- return m.replaceFirst("$1$2-$3"); -- } -- } -- -- if ("3DES_EDE_CBC".equals(bulkCipher)) { -- return "DES-CBC3"; -- } -- -- if ("RC4_128".equals(bulkCipher) || "RC4_40".equals(bulkCipher)) { -- return "RC4"; -- } -- -- if ("DES40_CBC".equals(bulkCipher) || "DES_CBC_40".equals(bulkCipher)) { -- return "DES-CBC"; -- } -- -- if ("RC2_CBC_40".equals(bulkCipher)) { -- return "RC2-CBC"; -- } -- -- return bulkCipher.replace('_', '-'); -- } -- -- private static String toOpenSslHmacAlgo(String hmacAlgo) { -- // Java and OpenSSL use the same algorithm names for: -- // -- // * SHA -- // * SHA256 -- // * MD5 -- // -- return hmacAlgo; -- } -- -- /** -- * Convert from OpenSSL cipher suite name convention to java cipher suite name convention. -- * @param openSslCipherSuite An OpenSSL cipher suite name. -- * @param protocol The cryptographic protocol (i.e. SSL, TLS, ...). -- * @return The translated cipher suite name according to java conventions. This will not be {@code null}. -- */ -- static String toJava(String openSslCipherSuite, String protocol) { -- Map p2j = o2j.get(openSslCipherSuite); -- if (p2j == null) { -- p2j = cacheFromOpenSsl(openSslCipherSuite); -- // This may happen if this method is queried when OpenSSL doesn't yet have a cipher setup. It will return -- // "(NONE)" in this case. -- if (p2j == null) { -- return null; -- } -- } -- -- String javaCipherSuite = p2j.get(protocol); -- if (javaCipherSuite == null) { -- String cipher = p2j.get(""); -- if (cipher == null) { -- return null; -- } -- javaCipherSuite = protocol + '_' + cipher; -- } -- -- return javaCipherSuite; -- } -- -- private static Map cacheFromOpenSsl(String openSslCipherSuite) { -- Map converted = o2jTls13.get(openSslCipherSuite); -- if (converted != null) { -- return converted; -- } -- -- String javaCipherSuiteSuffix = toJavaUncached0(openSslCipherSuite, false); -- if (javaCipherSuiteSuffix == null) { -- return null; -- } -- -- final String javaCipherSuiteSsl = "SSL_" + javaCipherSuiteSuffix; -- final String javaCipherSuiteTls = "TLS_" + javaCipherSuiteSuffix; -- -- // Cache the mapping. -- final Map p2j = new HashMap(4); -- p2j.put("", javaCipherSuiteSuffix); -- p2j.put("SSL", javaCipherSuiteSsl); -- p2j.put("TLS", javaCipherSuiteTls); -- o2j.putIfAbsent(openSslCipherSuite, p2j); -- -- // Cache the reverse mapping after adding the protocol prefix (TLS_ or SSL_) -- j2o.putIfAbsent(javaCipherSuiteTls, openSslCipherSuite); -- j2o.putIfAbsent(javaCipherSuiteSsl, openSslCipherSuite); -- -- logger.debug("Cipher suite mapping: {} => {}", javaCipherSuiteTls, openSslCipherSuite); -- logger.debug("Cipher suite mapping: {} => {}", javaCipherSuiteSsl, openSslCipherSuite); -- -- return p2j; -- } -- -- static String toJavaUncached(String openSslCipherSuite) { -- return toJavaUncached0(openSslCipherSuite, true); -- } -- -- private static String toJavaUncached0(String openSslCipherSuite, boolean checkTls13) { -- if (checkTls13) { -- Map converted = o2jTls13.get(openSslCipherSuite); -- if (converted != null) { -- return converted.get("TLS"); -- } -- } -- -- Matcher m = OPENSSL_CIPHERSUITE_PATTERN.matcher(openSslCipherSuite); -- if (!m.matches()) { -- return null; -- } -- -- String handshakeAlgo = m.group(1); -- final boolean export; -- if (handshakeAlgo == null) { -- handshakeAlgo = ""; -- export = false; -- } else if (handshakeAlgo.startsWith("EXP-")) { -- handshakeAlgo = handshakeAlgo.substring(4); -- export = true; -- } else if ("EXP".equals(handshakeAlgo)) { -- handshakeAlgo = ""; -- export = true; -- } else { -- export = false; -- } -- -- handshakeAlgo = toJavaHandshakeAlgo(handshakeAlgo, export); -- String bulkCipher = toJavaBulkCipher(m.group(2), export); -- String hmacAlgo = toJavaHmacAlgo(m.group(3)); -- -- String javaCipherSuite = handshakeAlgo + "_WITH_" + bulkCipher + '_' + hmacAlgo; -- // For historical reasons the CHACHA20 ciphers do not follow OpenSSL's custom naming convention and omits the -- // HMAC algorithm portion of the name. There is currently no way to derive this information because it is -- // omitted from the OpenSSL cipher name, but they currently all use SHA256 for HMAC [1]. -- // [1] https://www.openssl.org/docs/man1.1.0/apps/ciphers.html -- return bulkCipher.contains("CHACHA20") ? javaCipherSuite + "_SHA256" : javaCipherSuite; -- } -- -- private static String toJavaHandshakeAlgo(String handshakeAlgo, boolean export) { -- if (handshakeAlgo.isEmpty()) { -- handshakeAlgo = "RSA"; -- } else if ("ADH".equals(handshakeAlgo)) { -- handshakeAlgo = "DH_anon"; -- } else if ("AECDH".equals(handshakeAlgo)) { -- handshakeAlgo = "ECDH_anon"; -- } -- -- handshakeAlgo = handshakeAlgo.replace('-', '_'); -- if (export) { -- return handshakeAlgo + "_EXPORT"; -- } else { -- return handshakeAlgo; -- } -- } -- -- private static String toJavaBulkCipher(String bulkCipher, boolean export) { -- if (bulkCipher.startsWith("AES")) { -- Matcher m = OPENSSL_AES_CBC_PATTERN.matcher(bulkCipher); -- if (m.matches()) { -- return m.replaceFirst("$1_$2_CBC"); -- } -- -- m = OPENSSL_AES_PATTERN.matcher(bulkCipher); -- if (m.matches()) { -- return m.replaceFirst("$1_$2_$3"); -- } -- } -- -- if ("DES-CBC3".equals(bulkCipher)) { -- return "3DES_EDE_CBC"; -- } -- -- if ("RC4".equals(bulkCipher)) { -- if (export) { -- return "RC4_40"; -- } else { -- return "RC4_128"; -- } -- } -- -- if ("DES-CBC".equals(bulkCipher)) { -- if (export) { -- return "DES_CBC_40"; -- } else { -- return "DES_CBC"; -- } -- } -- -- if ("RC2-CBC".equals(bulkCipher)) { -- if (export) { -- return "RC2_CBC_40"; -- } else { -- return "RC2_CBC"; -- } -- } -- -- return bulkCipher.replace('-', '_'); -- } -- -- private static String toJavaHmacAlgo(String hmacAlgo) { -- // Java and OpenSSL use the same algorithm names for: -- // -- // * SHA -- // * SHA256 -- // * MD5 -- // -- return hmacAlgo; -- } -- -- /** -- * Convert the given ciphers if needed to OpenSSL format and append them to the correct {@link StringBuilder} -- * depending on if its a TLSv1.3 cipher or not. If this methods returns without throwing an exception its -- * guaranteed that at least one of the {@link StringBuilder}s contain some ciphers that can be used to configure -- * OpenSSL. -- */ -- static void convertToCipherStrings(Iterable cipherSuites, StringBuilder cipherBuilder, -- StringBuilder cipherTLSv13Builder, boolean boringSSL) { -- for (String c: cipherSuites) { -- if (c == null) { -- break; -- } -- -- String converted = toOpenSsl(c, boringSSL); -- if (converted == null) { -- converted = c; -- } -- -- if (!OpenSsl.isCipherSuiteAvailable(converted)) { -- throw new IllegalArgumentException("unsupported cipher suite: " + c + '(' + converted + ')'); -- } -- -- if (SslUtils.isTLSv13Cipher(converted) || SslUtils.isTLSv13Cipher(c)) { -- cipherTLSv13Builder.append(converted); -- cipherTLSv13Builder.append(':'); -- } else { -- cipherBuilder.append(converted); -- cipherBuilder.append(':'); -- } -- } -- -- if (cipherBuilder.length() == 0 && cipherTLSv13Builder.length() == 0) { -- throw new IllegalArgumentException("empty cipher suites"); -- } -- if (cipherBuilder.length() > 0) { -- cipherBuilder.setLength(cipherBuilder.length() - 1); -- } -- if (cipherTLSv13Builder.length() > 0) { -- cipherTLSv13Builder.setLength(cipherTLSv13Builder.length() - 1); -- } -- } -- -- private CipherSuiteConverter() { } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/DefaultOpenSslKeyMaterial.java b/handler/src/main/java/io/netty/handler/ssl/DefaultOpenSslKeyMaterial.java -deleted file mode 100644 -index fcea5266f2..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/DefaultOpenSslKeyMaterial.java -+++ /dev/null -@@ -1,126 +0,0 @@ --/* -- * Copyright 2018 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.internal.tcnative.SSL; --import io.netty.util.AbstractReferenceCounted; --import io.netty.util.IllegalReferenceCountException; --import io.netty.util.ResourceLeakDetector; --import io.netty.util.ResourceLeakDetectorFactory; --import io.netty.util.ResourceLeakTracker; -- --import java.security.cert.X509Certificate; -- --final class DefaultOpenSslKeyMaterial extends AbstractReferenceCounted implements OpenSslKeyMaterial { -- -- private static final ResourceLeakDetector leakDetector = -- ResourceLeakDetectorFactory.instance().newResourceLeakDetector(DefaultOpenSslKeyMaterial.class); -- private final ResourceLeakTracker leak; -- private final X509Certificate[] x509CertificateChain; -- private long chain; -- private long privateKey; -- -- DefaultOpenSslKeyMaterial(long chain, long privateKey, X509Certificate[] x509CertificateChain) { -- this.chain = chain; -- this.privateKey = privateKey; -- this.x509CertificateChain = x509CertificateChain; -- leak = leakDetector.track(this); -- } -- -- @Override -- public X509Certificate[] certificateChain() { -- return x509CertificateChain.clone(); -- } -- -- @Override -- public long certificateChainAddress() { -- if (refCnt() <= 0) { -- throw new IllegalReferenceCountException(); -- } -- return chain; -- } -- -- @Override -- public long privateKeyAddress() { -- if (refCnt() <= 0) { -- throw new IllegalReferenceCountException(); -- } -- return privateKey; -- } -- -- @Override -- protected void deallocate() { -- SSL.freeX509Chain(chain); -- chain = 0; -- SSL.freePrivateKey(privateKey); -- privateKey = 0; -- if (leak != null) { -- boolean closed = leak.close(this); -- assert closed; -- } -- } -- -- @Override -- public DefaultOpenSslKeyMaterial retain() { -- if (leak != null) { -- leak.record(); -- } -- super.retain(); -- return this; -- } -- -- @Override -- public DefaultOpenSslKeyMaterial retain(int increment) { -- if (leak != null) { -- leak.record(); -- } -- super.retain(increment); -- return this; -- } -- -- @Override -- public DefaultOpenSslKeyMaterial touch() { -- if (leak != null) { -- leak.record(); -- } -- super.touch(); -- return this; -- } -- -- @Override -- public DefaultOpenSslKeyMaterial touch(Object hint) { -- if (leak != null) { -- leak.record(hint); -- } -- return this; -- } -- -- @Override -- public boolean release() { -- if (leak != null) { -- leak.record(); -- } -- return super.release(); -- } -- -- @Override -- public boolean release(int decrement) { -- if (leak != null) { -- leak.record(); -- } -- return super.release(decrement); -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java -deleted file mode 100644 -index d7d44cf3e7..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java -+++ /dev/null -@@ -1,610 +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 io.netty.buffer.ByteBuf; --import io.netty.buffer.ByteBufAllocator; --import io.netty.buffer.UnpooledByteBufAllocator; --import io.netty.internal.tcnative.Buffer; --import io.netty.internal.tcnative.Library; --import io.netty.internal.tcnative.SSL; --import io.netty.internal.tcnative.SSLContext; --import io.netty.util.CharsetUtil; --import io.netty.util.ReferenceCountUtil; --import io.netty.util.ReferenceCounted; --import io.netty.util.internal.EmptyArrays; --import io.netty.util.internal.NativeLibraryLoader; --import io.netty.util.internal.PlatformDependent; --import io.netty.util.internal.SystemPropertyUtil; --import io.netty.util.internal.logging.InternalLogger; --import io.netty.util.internal.logging.InternalLoggerFactory; -- --import java.io.ByteArrayInputStream; --import java.security.cert.CertificateException; --import java.security.cert.X509Certificate; --import java.util.ArrayList; --import java.util.Collections; --import java.util.LinkedHashSet; --import java.util.List; --import java.util.Set; -- --import static io.netty.handler.ssl.SslUtils.*; -- --/** -- * Tells if {@code netty-tcnative} and its OpenSSL support -- * are available. -- */ --public final class OpenSsl { -- -- private static final InternalLogger logger = InternalLoggerFactory.getInstance(OpenSsl.class); -- private static final Throwable UNAVAILABILITY_CAUSE; -- -- static final List DEFAULT_CIPHERS; -- static final Set AVAILABLE_CIPHER_SUITES; -- 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 USE_KEYMANAGER_FACTORY; -- private static final boolean SUPPORTS_OCSP; -- private static final boolean TLSV13_SUPPORTED; -- private static final boolean IS_BORINGSSL; -- static final Set SUPPORTED_PROTOCOLS_SET; -- static final String[] EXTRA_SUPPORTED_TLS_1_3_CIPHERS; -- -- // self-signed certificate for netty.io and the matching private-key -- private static final String CERT = "-----BEGIN CERTIFICATE-----\n" + -- "MIICrjCCAZagAwIBAgIIdSvQPv1QAZQwDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAxMLZXhhbXBs\n" + -- "ZS5jb20wIBcNMTgwNDA2MjIwNjU5WhgPOTk5OTEyMzEyMzU5NTlaMBYxFDASBgNVBAMTC2V4YW1w\n" + -- "bGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAggbWsmDQ6zNzRZ5AW8E3eoGl\n" + -- "qWvOBDb5Fs1oBRrVQHuYmVAoaqwDzXYJ0LOwa293AgWEQ1jpcbZ2hpoYQzqEZBTLnFhMrhRFlH6K\n" + -- "bJND8Y33kZ/iSVBBDuGbdSbJShlM+4WwQ9IAso4MZ4vW3S1iv5fGGpLgbtXRmBf/RU8omN0Gijlv\n" + -- "WlLWHWijLN8xQtySFuBQ7ssW8RcKAary3pUm6UUQB+Co6lnfti0Tzag8PgjhAJq2Z3wbsGRnP2YS\n" + -- "vYoaK6qzmHXRYlp/PxrjBAZAmkLJs4YTm/XFF+fkeYx4i9zqHbyone5yerRibsHaXZWLnUL+rFoe\n" + -- "MdKvr0VS3sGmhQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQADQi441pKmXf9FvUV5EHU4v8nJT9Iq\n" + -- "yqwsKwXnr7AsUlDGHBD7jGrjAXnG5rGxuNKBQ35wRxJATKrUtyaquFUL6H8O6aGQehiFTk6zmPbe\n" + -- "12Gu44vqqTgIUxnv3JQJiox8S2hMxsSddpeCmSdvmalvD6WG4NthH6B9ZaBEiep1+0s0RUaBYn73\n" + -- "I7CCUaAtbjfR6pcJjrFk5ei7uwdQZFSJtkP2z8r7zfeANJddAKFlkaMWn7u+OIVuB4XPooWicObk\n" + -- "NAHFtP65bocUYnDpTVdiyvn8DdqyZ/EO8n1bBKBzuSLplk2msW4pdgaFgY7Vw/0wzcFXfUXmL1uy\n" + -- "G8sQD/wx\n" + -- "-----END CERTIFICATE-----"; -- -- private static final String KEY = "-----BEGIN PRIVATE KEY-----\n" + -- "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCCBtayYNDrM3NFnkBbwTd6gaWp\n" + -- "a84ENvkWzWgFGtVAe5iZUChqrAPNdgnQs7Brb3cCBYRDWOlxtnaGmhhDOoRkFMucWEyuFEWUfops\n" + -- "k0PxjfeRn+JJUEEO4Zt1JslKGUz7hbBD0gCyjgxni9bdLWK/l8YakuBu1dGYF/9FTyiY3QaKOW9a\n" + -- "UtYdaKMs3zFC3JIW4FDuyxbxFwoBqvLelSbpRRAH4KjqWd+2LRPNqDw+COEAmrZnfBuwZGc/ZhK9\n" + -- "ihorqrOYddFiWn8/GuMEBkCaQsmzhhOb9cUX5+R5jHiL3OodvKid7nJ6tGJuwdpdlYudQv6sWh4x\n" + -- "0q+vRVLewaaFAgMBAAECggEAP8tPJvFtTxhNJAkCloHz0D0vpDHqQBMgntlkgayqmBqLwhyb18pR\n" + -- "i0qwgh7HHc7wWqOOQuSqlEnrWRrdcI6TSe8R/sErzfTQNoznKWIPYcI/hskk4sdnQ//Yn9/Jvnsv\n" + -- "U/BBjOTJxtD+sQbhAl80JcA3R+5sArURQkfzzHOL/YMqzAsn5hTzp7HZCxUqBk3KaHRxV7NefeOE\n" + -- "xlZuWSmxYWfbFIs4kx19/1t7h8CHQWezw+G60G2VBtSBBxDnhBWvqG6R/wpzJ3nEhPLLY9T+XIHe\n" + -- "ipzdMOOOUZorfIg7M+pyYPji+ZIZxIpY5OjrOzXHciAjRtr5Y7l99K1CG1LguQKBgQDrQfIMxxtZ\n" + -- "vxU/1cRmUV9l7pt5bjV5R6byXq178LxPKVYNjdZ840Q0/OpZEVqaT1xKVi35ohP1QfNjxPLlHD+K\n" + -- "iDAR9z6zkwjIrbwPCnb5kuXy4lpwPcmmmkva25fI7qlpHtbcuQdoBdCfr/KkKaUCMPyY89LCXgEw\n" + -- "5KTDj64UywKBgQCNfbO+eZLGzhiHhtNJurresCsIGWlInv322gL8CSfBMYl6eNfUTZvUDdFhPISL\n" + -- "UljKWzXDrjw0ujFSPR0XhUGtiq89H+HUTuPPYv25gVXO+HTgBFZEPl4PpA+BUsSVZy0NddneyqLk\n" + -- "42Wey9omY9Q8WsdNQS5cbUvy0uG6WFoX7wKBgQDZ1jpW8pa0x2bZsQsm4vo+3G5CRnZlUp+XlWt2\n" + -- "dDcp5dC0xD1zbs1dc0NcLeGDOTDv9FSl7hok42iHXXq8AygjEm/QcuwwQ1nC2HxmQP5holAiUs4D\n" + -- "WHM8PWs3wFYPzE459EBoKTxeaeP/uWAn+he8q7d5uWvSZlEcANs/6e77eQKBgD21Ar0hfFfj7mK8\n" + -- "9E0FeRZBsqK3omkfnhcYgZC11Xa2SgT1yvs2Va2n0RcdM5kncr3eBZav2GYOhhAdwyBM55XuE/sO\n" + -- "eokDVutNeuZ6d5fqV96TRaRBpvgfTvvRwxZ9hvKF4Vz+9wfn/JvCwANaKmegF6ejs7pvmF3whq2k\n" + -- "drZVAoGAX5YxQ5XMTD0QbMAl7/6qp6S58xNoVdfCkmkj1ZLKaHKIjS/benkKGlySVQVPexPfnkZx\n" + -- "p/Vv9yyphBoudiTBS9Uog66ueLYZqpgxlM/6OhYg86Gm3U2ycvMxYjBM1NFiyze21AqAhI+HX+Ot\n" + -- "mraV2/guSgDgZAhukRZzeQ2RucI=\n" + -- "-----END PRIVATE KEY-----"; -- -- static { -- Throwable cause = null; -- -- if (SystemPropertyUtil.getBoolean("io.netty.handler.ssl.noOpenSsl", false)) { -- cause = new UnsupportedOperationException( -- "OpenSSL was explicit disabled with -Dio.netty.handler.ssl.noOpenSsl=true"); -- -- logger.debug( -- "netty-tcnative explicit disabled; " + -- OpenSslEngine.class.getSimpleName() + " will be unavailable.", cause); -- } else { -- // Test if netty-tcnative is in the classpath first. -- try { -- Class.forName("io.netty.internal.tcnative.SSLContext", false, OpenSsl.class.getClassLoader()); -- } catch (ClassNotFoundException t) { -- cause = t; -- logger.debug( -- "netty-tcnative not in the classpath; " + -- OpenSslEngine.class.getSimpleName() + " will be unavailable."); -- } -- -- // If in the classpath, try to load the native library and initialize netty-tcnative. -- if (cause == null) { -- try { -- // The JNI library was not already loaded. Load it now. -- loadTcNative(); -- } catch (Throwable t) { -- cause = t; -- logger.debug( -- "Failed to load netty-tcnative; " + -- OpenSslEngine.class.getSimpleName() + " will be unavailable, unless the " + -- "application has already loaded the symbols by some other means. " + -- "See https://netty.io/wiki/forked-tomcat-native.html for more information.", t); -- } -- -- try { -- String engine = SystemPropertyUtil.get("io.netty.handler.ssl.openssl.engine", null); -- if (engine == null) { -- logger.debug("Initialize netty-tcnative using engine: 'default'"); -- } else { -- logger.debug("Initialize netty-tcnative using engine: '{}'", engine); -- } -- initializeTcNative(engine); -- -- // The library was initialized successfully. If loading the library failed above, -- // reset the cause now since it appears that the library was loaded by some other -- // means. -- cause = null; -- } catch (Throwable t) { -- if (cause == null) { -- cause = t; -- } -- logger.debug( -- "Failed to initialize netty-tcnative; " + -- OpenSslEngine.class.getSimpleName() + " will be unavailable. " + -- "See https://netty.io/wiki/forked-tomcat-native.html for more information.", t); -- } -- } -- } -- -- UNAVAILABILITY_CAUSE = cause; -- -- if (cause == null) { -- logger.debug("netty-tcnative using native library: {}", SSL.versionString()); -- -- final List defaultCiphers = new ArrayList(); -- final Set availableOpenSslCipherSuites = new LinkedHashSet(128); -- boolean supportsKeyManagerFactory = false; -- boolean useKeyManagerFactory = false; -- boolean tlsv13Supported = false; -- -- IS_BORINGSSL = "BoringSSL".equals(versionString()); -- if (IS_BORINGSSL) { -- EXTRA_SUPPORTED_TLS_1_3_CIPHERS = new String [] { "TLS_AES_128_GCM_SHA256", -- "TLS_AES_256_GCM_SHA384" , -- "TLS_CHACHA20_POLY1305_SHA256" }; -- } else { -- EXTRA_SUPPORTED_TLS_1_3_CIPHERS = EmptyArrays.EMPTY_STRINGS; -- } -- -- try { -- final long sslCtx = SSLContext.make(SSL.SSL_PROTOCOL_ALL, SSL.SSL_MODE_SERVER); -- long certBio = 0; -- long keyBio = 0; -- long cert = 0; -- long key = 0; -- try { -- try { -- StringBuilder tlsv13Ciphers = new StringBuilder(); -- -- for (String cipher: TLSV13_CIPHERS) { -- String converted = CipherSuiteConverter.toOpenSsl(cipher, IS_BORINGSSL); -- if (converted != null) { -- tlsv13Ciphers.append(converted).append(':'); -- } -- } -- if (tlsv13Ciphers.length() == 0) { -- tlsv13Supported = false; -- } else { -- tlsv13Ciphers.setLength(tlsv13Ciphers.length() - 1); -- SSLContext.setCipherSuite(sslCtx, tlsv13Ciphers.toString() , true); -- tlsv13Supported = true; -- } -- -- } catch (Exception ignore) { -- tlsv13Supported = false; -- } -- -- SSLContext.setCipherSuite(sslCtx, "ALL", false); -- -- final long ssl = SSL.newSSL(sslCtx, true); -- try { -- for (String c: SSL.getCiphers(ssl)) { -- // Filter out bad input. -- if (c == null || c.isEmpty() || availableOpenSslCipherSuites.contains(c) || -- // Filter out TLSv1.3 ciphers if not supported. -- !tlsv13Supported && isTLSv13Cipher(c)) { -- continue; -- } -- availableOpenSslCipherSuites.add(c); -- } -- if (IS_BORINGSSL) { -- // Currently BoringSSL does not include these when calling SSL.getCiphers() even when these -- // are supported. -- Collections.addAll(availableOpenSslCipherSuites, EXTRA_SUPPORTED_TLS_1_3_CIPHERS); -- Collections.addAll(availableOpenSslCipherSuites, -- "AEAD-AES128-GCM-SHA256", -- "AEAD-AES256-GCM-SHA384", -- "AEAD-CHACHA20-POLY1305-SHA256"); -- } -- -- PemEncoded privateKey = PemPrivateKey.valueOf(KEY.getBytes(CharsetUtil.US_ASCII)); -- try { -- // Let's check if we can set a callback, which may not work if the used OpenSSL version -- // is to old. -- SSLContext.setCertificateCallback(sslCtx, null); -- -- X509Certificate certificate = selfSignedCertificate(); -- certBio = ReferenceCountedOpenSslContext.toBIO(ByteBufAllocator.DEFAULT, certificate); -- cert = SSL.parseX509Chain(certBio); -- -- keyBio = ReferenceCountedOpenSslContext.toBIO( -- UnpooledByteBufAllocator.DEFAULT, privateKey.retain()); -- key = SSL.parsePrivateKey(keyBio, null); -- -- SSL.setKeyMaterial(ssl, cert, key); -- supportsKeyManagerFactory = true; -- try { -- boolean propertySet = SystemPropertyUtil.contains( -- "io.netty.handler.ssl.openssl.useKeyManagerFactory"); -- if (!IS_BORINGSSL) { -- useKeyManagerFactory = SystemPropertyUtil.getBoolean( -- "io.netty.handler.ssl.openssl.useKeyManagerFactory", true); -- -- if (propertySet) { -- logger.info("System property " + -- "'io.netty.handler.ssl.openssl.useKeyManagerFactory'" + -- " is deprecated and so will be ignored in the future"); -- } -- } else { -- useKeyManagerFactory = true; -- if (propertySet) { -- logger.info("System property " + -- "'io.netty.handler.ssl.openssl.useKeyManagerFactory'" + -- " is deprecated and will be ignored when using BoringSSL"); -- } -- } -- } catch (Throwable ignore) { -- logger.debug("Failed to get useKeyManagerFactory system property."); -- } -- } catch (Error ignore) { -- logger.debug("KeyManagerFactory not supported."); -- } finally { -- privateKey.release(); -- } -- } finally { -- SSL.freeSSL(ssl); -- if (certBio != 0) { -- SSL.freeBIO(certBio); -- } -- if (keyBio != 0) { -- SSL.freeBIO(keyBio); -- } -- if (cert != 0) { -- SSL.freeX509Chain(cert); -- } -- if (key != 0) { -- SSL.freePrivateKey(key); -- } -- } -- } finally { -- SSLContext.free(sslCtx); -- } -- } catch (Exception e) { -- logger.warn("Failed to get the list of available OpenSSL cipher suites.", e); -- } -- AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.unmodifiableSet(availableOpenSslCipherSuites); -- final Set availableJavaCipherSuites = new LinkedHashSet( -- AVAILABLE_OPENSSL_CIPHER_SUITES.size() * 2); -- for (String cipher: AVAILABLE_OPENSSL_CIPHER_SUITES) { -- // Included converted but also openssl cipher name -- if (!isTLSv13Cipher(cipher)) { -- availableJavaCipherSuites.add(CipherSuiteConverter.toJava(cipher, "TLS")); -- availableJavaCipherSuites.add(CipherSuiteConverter.toJava(cipher, "SSL")); -- } else { -- // TLSv1.3 ciphers have the correct format. -- availableJavaCipherSuites.add(cipher); -- } -- } -- -- addIfSupported(availableJavaCipherSuites, defaultCiphers, DEFAULT_CIPHER_SUITES); -- addIfSupported(availableJavaCipherSuites, defaultCiphers, TLSV13_CIPHER_SUITES); -- -- useFallbackCiphersIfDefaultIsEmpty(defaultCiphers, availableJavaCipherSuites); -- DEFAULT_CIPHERS = Collections.unmodifiableList(defaultCiphers); -- -- AVAILABLE_JAVA_CIPHER_SUITES = Collections.unmodifiableSet(availableJavaCipherSuites); -- -- final Set availableCipherSuites = new LinkedHashSet( -- AVAILABLE_OPENSSL_CIPHER_SUITES.size() + AVAILABLE_JAVA_CIPHER_SUITES.size()); -- availableCipherSuites.addAll(AVAILABLE_OPENSSL_CIPHER_SUITES); -- availableCipherSuites.addAll(AVAILABLE_JAVA_CIPHER_SUITES); -- -- AVAILABLE_CIPHER_SUITES = availableCipherSuites; -- SUPPORTS_KEYMANAGER_FACTORY = supportsKeyManagerFactory; -- USE_KEYMANAGER_FACTORY = useKeyManagerFactory; -- -- Set protocols = new LinkedHashSet(6); -- // Seems like there is no way to explicitly disable SSLv2Hello in openssl so it is always enabled -- protocols.add(PROTOCOL_SSL_V2_HELLO); -- if (doesSupportProtocol(SSL.SSL_PROTOCOL_SSLV2, SSL.SSL_OP_NO_SSLv2)) { -- protocols.add(PROTOCOL_SSL_V2); -- } -- if (doesSupportProtocol(SSL.SSL_PROTOCOL_SSLV3, SSL.SSL_OP_NO_SSLv3)) { -- protocols.add(PROTOCOL_SSL_V3); -- } -- if (doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1, SSL.SSL_OP_NO_TLSv1)) { -- protocols.add(PROTOCOL_TLS_V1); -- } -- if (doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1_1, SSL.SSL_OP_NO_TLSv1_1)) { -- protocols.add(PROTOCOL_TLS_V1_1); -- } -- if (doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1_2, SSL.SSL_OP_NO_TLSv1_2)) { -- protocols.add(PROTOCOL_TLS_V1_2); -- } -- -- // This is only supported by java11 and later. -- if (tlsv13Supported && doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1_3, SSL.SSL_OP_NO_TLSv1_3)) { -- protocols.add(PROTOCOL_TLS_V1_3); -- TLSV13_SUPPORTED = true; -- } else { -- TLSV13_SUPPORTED = false; -- } -- -- SUPPORTED_PROTOCOLS_SET = Collections.unmodifiableSet(protocols); -- SUPPORTS_OCSP = doesSupportOcsp(); -- -- if (logger.isDebugEnabled()) { -- logger.debug("Supported protocols (OpenSSL): {} ", SUPPORTED_PROTOCOLS_SET); -- logger.debug("Default cipher suites (OpenSSL): {}", DEFAULT_CIPHERS); -- } -- } else { -- DEFAULT_CIPHERS = Collections.emptyList(); -- AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.emptySet(); -- AVAILABLE_JAVA_CIPHER_SUITES = Collections.emptySet(); -- AVAILABLE_CIPHER_SUITES = Collections.emptySet(); -- SUPPORTS_KEYMANAGER_FACTORY = false; -- USE_KEYMANAGER_FACTORY = false; -- SUPPORTED_PROTOCOLS_SET = Collections.emptySet(); -- SUPPORTS_OCSP = false; -- TLSV13_SUPPORTED = false; -- IS_BORINGSSL = false; -- EXTRA_SUPPORTED_TLS_1_3_CIPHERS = EmptyArrays.EMPTY_STRINGS; -- } -- } -- -- /** -- * Returns a self-signed {@link X509Certificate} for {@code netty.io}. -- */ -- static X509Certificate selfSignedCertificate() throws CertificateException { -- return (X509Certificate) SslContext.X509_CERT_FACTORY.generateCertificate( -- new ByteArrayInputStream(CERT.getBytes(CharsetUtil.US_ASCII)) -- ); -- } -- -- private static boolean doesSupportOcsp() { -- boolean supportsOcsp = false; -- if (version() >= 0x10002000L) { -- long sslCtx = -1; -- try { -- sslCtx = SSLContext.make(SSL.SSL_PROTOCOL_TLSV1_2, SSL.SSL_MODE_SERVER); -- SSLContext.enableOcsp(sslCtx, false); -- supportsOcsp = true; -- } catch (Exception ignore) { -- // ignore -- } finally { -- if (sslCtx != -1) { -- SSLContext.free(sslCtx); -- } -- } -- } -- return supportsOcsp; -- } -- private static boolean doesSupportProtocol(int protocol, int opt) { -- if (opt == 0) { -- // If the opt is 0 the protocol is not supported. This is for example the case with BoringSSL and SSLv2. -- return false; -- } -- long sslCtx = -1; -- try { -- sslCtx = SSLContext.make(protocol, SSL.SSL_MODE_COMBINED); -- return true; -- } catch (Exception ignore) { -- return false; -- } finally { -- if (sslCtx != -1) { -- SSLContext.free(sslCtx); -- } -- } -- } -- -- /** -- * Returns {@code true} if and only if -- * {@code netty-tcnative} and its OpenSSL support -- * are available. -- */ -- public static boolean isAvailable() { -- return UNAVAILABILITY_CAUSE == null; -- } -- -- /** -- * Returns {@code true} if the used version of openssl supports -- * ALPN. -- * -- * @deprecated use {@link SslProvider#isAlpnSupported(SslProvider)} with {@link SslProvider#OPENSSL}. -- */ -- @Deprecated -- public static boolean isAlpnSupported() { -- return version() >= 0x10002000L; -- } -- -- /** -- * Returns {@code true} if the used version of OpenSSL supports OCSP stapling. -- */ -- public static boolean isOcspSupported() { -- return SUPPORTS_OCSP; -- } -- -- /** -- * Returns the version of the used available OpenSSL library or {@code -1} if {@link #isAvailable()} -- * returns {@code false}. -- */ -- public static int version() { -- return isAvailable() ? SSL.version() : -1; -- } -- -- /** -- * Returns the version string of the used available OpenSSL library or {@code null} if {@link #isAvailable()} -- * returns {@code false}. -- */ -- public static String versionString() { -- return isAvailable() ? SSL.versionString() : null; -- } -- -- /** -- * Ensure that {@code netty-tcnative} and -- * its OpenSSL support are available. -- * -- * @throws UnsatisfiedLinkError if unavailable -- */ -- public static void ensureAvailability() { -- if (UNAVAILABILITY_CAUSE != null) { -- throw (Error) new UnsatisfiedLinkError( -- "failed to load the required native library").initCause(UNAVAILABILITY_CAUSE); -- } -- } -- -- /** -- * Returns the cause of unavailability of -- * {@code netty-tcnative} and its OpenSSL support. -- * -- * @return the cause if unavailable. {@code null} if available. -- */ -- public static Throwable unavailabilityCause() { -- return UNAVAILABILITY_CAUSE; -- } -- -- /** -- * @deprecated use {@link #availableOpenSslCipherSuites()} -- */ -- @Deprecated -- public static Set availableCipherSuites() { -- return availableOpenSslCipherSuites(); -- } -- -- /** -- * Returns all the available OpenSSL cipher suites. -- * Please note that the returned array may include the cipher suites that are insecure or non-functional. -- */ -- public static Set availableOpenSslCipherSuites() { -- return AVAILABLE_OPENSSL_CIPHER_SUITES; -- } -- -- /** -- * Returns all the available cipher suites (Java-style). -- * Please note that the returned array may include the cipher suites that are insecure or non-functional. -- */ -- public static Set availableJavaCipherSuites() { -- return AVAILABLE_JAVA_CIPHER_SUITES; -- } -- -- /** -- * Returns {@code true} if and only if the specified cipher suite is available in OpenSSL. -- * Both Java-style cipher suite and OpenSSL-style cipher suite are accepted. -- */ -- public static boolean isCipherSuiteAvailable(String cipherSuite) { -- String converted = CipherSuiteConverter.toOpenSsl(cipherSuite, IS_BORINGSSL); -- if (converted != null) { -- cipherSuite = converted; -- } -- return AVAILABLE_OPENSSL_CIPHER_SUITES.contains(cipherSuite); -- } -- -- /** -- * Returns {@code true} if {@link javax.net.ssl.KeyManagerFactory} is supported when using OpenSSL. -- */ -- public static boolean supportsKeyManagerFactory() { -- return SUPPORTS_KEYMANAGER_FACTORY; -- } -- -- /** -- * Always returns {@code true} if {@link #isAvailable()} returns {@code true}. -- * -- * @deprecated Will be removed because hostname validation is always done by a -- * {@link javax.net.ssl.TrustManager} implementation. -- */ -- @Deprecated -- public static boolean supportsHostnameValidation() { -- return isAvailable(); -- } -- -- static boolean useKeyManagerFactory() { -- return USE_KEYMANAGER_FACTORY; -- } -- -- static long memoryAddress(ByteBuf buf) { -- assert buf.isDirect(); -- return buf.hasMemoryAddress() ? buf.memoryAddress() : Buffer.address(buf.nioBuffer()); -- } -- -- private OpenSsl() { } -- -- private static void loadTcNative() throws Exception { -- String os = PlatformDependent.normalizedOs(); -- String arch = PlatformDependent.normalizedArch(); -- -- Set libNames = new LinkedHashSet(5); -- String staticLibName = "netty_tcnative"; -- -- // First, try loading the platform-specific library. Platform-specific -- // libraries will be available if using a tcnative uber jar. -- if ("linux".equalsIgnoreCase(os)) { -- Set classifiers = PlatformDependent.normalizedLinuxClassifiers(); -- for (String classifier : classifiers) { -- libNames.add(staticLibName + "_" + os + '_' + arch + "_" + classifier); -- } -- // generic arch-dependent library -- libNames.add(staticLibName + "_" + os + '_' + arch); -- -- // Fedora SSL lib so naming (libssl.so.10 vs libssl.so.1.0.0). -- // note: should already be included from the classifiers but if not, we use this as an -- // additional fallback option here -- libNames.add(staticLibName + "_" + os + '_' + arch + "_fedora"); -- } else { -- libNames.add(staticLibName + "_" + os + '_' + arch); -- } -- libNames.add(staticLibName + "_" + arch); -- libNames.add(staticLibName); -- -- NativeLibraryLoader.loadFirstAvailable(SSLContext.class.getClassLoader(), -- libNames.toArray(new String[0])); -- } -- -- private static boolean initializeTcNative(String engine) throws Exception { -- return Library.initialize("provided", engine); -- } -- -- static void releaseIfNeeded(ReferenceCounted counted) { -- if (counted.refCnt() > 0) { -- ReferenceCountUtil.safeRelease(counted); -- } -- } -- -- static boolean isTlsv13Supported() { -- return TLSV13_SUPPORTED; -- } -- -- static boolean isBoringSSL() { -- return IS_BORINGSSL; -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslCachingKeyMaterialProvider.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslCachingKeyMaterialProvider.java -deleted file mode 100644 -index 07b67d9fa7..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslCachingKeyMaterialProvider.java -+++ /dev/null -@@ -1,79 +0,0 @@ --/* -- * Copyright 2018 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.buffer.ByteBufAllocator; -- --import javax.net.ssl.X509KeyManager; --import java.util.Iterator; --import java.util.concurrent.ConcurrentHashMap; --import java.util.concurrent.ConcurrentMap; -- --/** -- * {@link OpenSslKeyMaterialProvider} that will cache the {@link OpenSslKeyMaterial} to reduce the overhead -- * of parsing the chain and the key for generation of the material. -- */ --final class OpenSslCachingKeyMaterialProvider extends OpenSslKeyMaterialProvider { -- -- private final int maxCachedEntries; -- private volatile boolean full; -- private final ConcurrentMap cache = new ConcurrentHashMap(); -- -- OpenSslCachingKeyMaterialProvider(X509KeyManager keyManager, String password, int maxCachedEntries) { -- super(keyManager, password); -- this.maxCachedEntries = maxCachedEntries; -- } -- -- @Override -- OpenSslKeyMaterial chooseKeyMaterial(ByteBufAllocator allocator, String alias) throws Exception { -- OpenSslKeyMaterial material = cache.get(alias); -- if (material == null) { -- material = super.chooseKeyMaterial(allocator, alias); -- if (material == null) { -- // No keymaterial should be used. -- return null; -- } -- -- if (full) { -- return material; -- } -- if (cache.size() > maxCachedEntries) { -- full = true; -- // Do not cache... -- return material; -- } -- OpenSslKeyMaterial old = cache.putIfAbsent(alias, material); -- if (old != null) { -- material.release(); -- material = old; -- } -- } -- // We need to call retain() as we want to always have at least a refCnt() of 1 before destroy() was called. -- return material.retain(); -- } -- -- @Override -- void destroy() { -- // Remove and release all entries. -- do { -- Iterator iterator = cache.values().iterator(); -- while (iterator.hasNext()) { -- iterator.next().release(); -- iterator.remove(); -- } -- } while (!cache.isEmpty()); -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslCachingX509KeyManagerFactory.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslCachingX509KeyManagerFactory.java -deleted file mode 100644 -index 7f67bc8198..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslCachingX509KeyManagerFactory.java -+++ /dev/null -@@ -1,81 +0,0 @@ --/* -- * Copyright 2018 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.ObjectUtil; -- --import javax.net.ssl.KeyManager; --import javax.net.ssl.KeyManagerFactory; --import javax.net.ssl.KeyManagerFactorySpi; --import javax.net.ssl.ManagerFactoryParameters; --import javax.net.ssl.X509ExtendedKeyManager; --import javax.net.ssl.X509KeyManager; --import java.security.InvalidAlgorithmParameterException; --import java.security.KeyStore; --import java.security.KeyStoreException; --import java.security.NoSuchAlgorithmException; --import java.security.PrivateKey; --import java.security.UnrecoverableKeyException; --import java.security.cert.X509Certificate; -- --/** -- * Wraps another {@link KeyManagerFactory} and caches its chains / certs for an alias for better performance when using -- * {@link SslProvider#OPENSSL} or {@link SslProvider#OPENSSL_REFCNT}. -- * -- * Because of the caching its important that the wrapped {@link KeyManagerFactory}s {@link X509KeyManager}s always -- * return the same {@link X509Certificate} chain and {@link PrivateKey} for the same alias. -- */ --public final class OpenSslCachingX509KeyManagerFactory extends KeyManagerFactory { -- -- private final int maxCachedEntries; -- -- public OpenSslCachingX509KeyManagerFactory(final KeyManagerFactory factory) { -- this(factory, 1024); -- } -- -- public OpenSslCachingX509KeyManagerFactory(final KeyManagerFactory factory, int maxCachedEntries) { -- super(new KeyManagerFactorySpi() { -- @Override -- protected void engineInit(KeyStore keyStore, char[] chars) -- throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { -- factory.init(keyStore, chars); -- } -- -- @Override -- protected void engineInit(ManagerFactoryParameters managerFactoryParameters) -- throws InvalidAlgorithmParameterException { -- factory.init(managerFactoryParameters); -- } -- -- @Override -- protected KeyManager[] engineGetKeyManagers() { -- return factory.getKeyManagers(); -- } -- }, factory.getProvider(), factory.getAlgorithm()); -- this.maxCachedEntries = ObjectUtil.checkPositive(maxCachedEntries, "maxCachedEntries"); -- } -- -- OpenSslKeyMaterialProvider newProvider(String password) { -- X509KeyManager keyManager = ReferenceCountedOpenSslContext.chooseX509KeyManager(getKeyManagers()); -- if ("sun.security.ssl.X509KeyManagerImpl".equals(keyManager.getClass().getName())) { -- // Don't do caching if X509KeyManagerImpl is used as the returned aliases are not stable and will change -- // between invocations. -- return new OpenSslKeyMaterialProvider(keyManager, password); -- } -- return new OpenSslCachingKeyMaterialProvider( -- ReferenceCountedOpenSslContext.chooseX509KeyManager(getKeyManagers()), password, maxCachedEntries); -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java -deleted file mode 100644 -index f20b2d3ba0..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java -+++ /dev/null -@@ -1,81 +0,0 @@ --/* -- * Copyright 2016 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.internal.tcnative.CertificateVerifier; -- --import java.security.cert.CertificateException; -- --/** -- * A special {@link CertificateException} which allows to specify which error code is included in the -- * SSL Record. This only work when {@link SslProvider#OPENSSL} or {@link SslProvider#OPENSSL_REFCNT} is used. -- */ --public final class OpenSslCertificateException extends CertificateException { -- private static final long serialVersionUID = 5542675253797129798L; -- -- private final int errorCode; -- -- /** -- * Construct a new exception with the -- * error code. -- */ -- public OpenSslCertificateException(int errorCode) { -- this((String) null, errorCode); -- } -- -- /** -- * Construct a new exception with the msg and -- * error code . -- */ -- public OpenSslCertificateException(String msg, int errorCode) { -- super(msg); -- this.errorCode = checkErrorCode(errorCode); -- } -- -- /** -- * Construct a new exception with the msg, cause and -- * error code . -- */ -- public OpenSslCertificateException(String message, Throwable cause, int errorCode) { -- super(message, cause); -- this.errorCode = checkErrorCode(errorCode); -- } -- -- /** -- * Construct a new exception with the cause and -- * error code . -- */ -- public OpenSslCertificateException(Throwable cause, int errorCode) { -- this(null, cause, errorCode); -- } -- -- /** -- * Return the error code to use. -- */ -- public int errorCode() { -- return errorCode; -- } -- -- private static int checkErrorCode(int errorCode) { -- // Call OpenSsl.isAvailable() to ensure we try to load the native lib as CertificateVerifier.isValid(...) -- // will depend on it. If loading fails we will just skip the validation. -- if (OpenSsl.isAvailable() && !CertificateVerifier.isValid(errorCode)) { -- throw new IllegalArgumentException("errorCode '" + errorCode + -- "' invalid, see https://www.openssl.org/docs/man1.0.2/apps/verify.html."); -- } -- return errorCode; -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java -deleted file mode 100644 -index 7f9b39a8dd..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java -+++ /dev/null -@@ -1,208 +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 io.netty.internal.tcnative.SSL; -- --import java.io.File; --import java.security.KeyStore; --import java.security.PrivateKey; --import java.security.cert.X509Certificate; -- --import javax.net.ssl.KeyManagerFactory; --import javax.net.ssl.SSLException; --import javax.net.ssl.TrustManager; --import javax.net.ssl.TrustManagerFactory; -- --import static io.netty.handler.ssl.ReferenceCountedOpenSslClientContext.newSessionContext; -- --/** -- * A client-side {@link SslContext} which uses OpenSSL's SSL/TLS implementation. -- *

This class will use a finalizer to ensure native resources are automatically cleaned up. To avoid finalizers -- * and manually release the native memory see {@link ReferenceCountedOpenSslClientContext}. -- */ --public final class OpenSslClientContext extends OpenSslContext { -- private final OpenSslSessionContext sessionContext; -- -- /** -- * Creates a new instance. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslClientContext() throws SSLException { -- this(null, null, null, null, null, null, null, IdentityCipherSuiteFilter.INSTANCE, null, 0, 0); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format. -- * {@code null} to use the system default -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslClientContext(File certChainFile) throws SSLException { -- this(certChainFile, null); -- } -- -- /** -- * Creates a new instance. -- * -- * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s -- * that verifies the certificates sent from servers. -- * {@code null} to use the default. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslClientContext(TrustManagerFactory trustManagerFactory) throws SSLException { -- this(null, trustManagerFactory); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format. -- * {@code null} to use the system default -- * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s -- * that verifies the certificates sent from servers. -- * {@code null} to use the default. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslClientContext(File certChainFile, TrustManagerFactory trustManagerFactory) throws SSLException { -- this(certChainFile, trustManagerFactory, null, null, null, null, null, -- IdentityCipherSuiteFilter.INSTANCE, null, 0, 0); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s -- * that verifies the certificates sent from servers. -- * {@code null} to use the default.. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param apn Provides a means to configure parameters related to application protocol negotiation. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslClientContext(File certChainFile, TrustManagerFactory trustManagerFactory, Iterable ciphers, -- ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout) -- throws SSLException { -- this(certChainFile, trustManagerFactory, null, null, null, null, ciphers, IdentityCipherSuiteFilter.INSTANCE, -- apn, sessionCacheSize, sessionTimeout); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s -- * that verifies the certificates sent from servers. -- * {@code null} to use the default.. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param cipherFilter a filter to apply over the supplied list of ciphers -- * @param apn Provides a means to configure parameters related to application protocol negotiation. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslClientContext(File certChainFile, TrustManagerFactory trustManagerFactory, Iterable ciphers, -- CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, -- long sessionCacheSize, long sessionTimeout) throws SSLException { -- this(certChainFile, trustManagerFactory, null, null, null, null, -- ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout); -- } -- -- /** -- * Creates a new instance. -- * @param trustCertCollectionFile an X.509 certificate collection file in PEM format. -- * {@code null} to use the system default -- * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s -- * that verifies the certificates sent from servers. -- * {@code null} to use the default or the results of parsing -- * {@code trustCertCollectionFile} -- * @param keyCertChainFile an X.509 certificate chain file in PEM format. -- * This provides the public key for mutual authentication. -- * {@code null} to use the system default -- * @param keyFile a PKCS#8 private key file in PEM format. -- * This provides the private key for mutual authentication. -- * {@code null} for no mutual authentication. -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * Ignored if {@code keyFile} is {@code null}. -- * @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link javax.net.ssl.KeyManager}s -- * that is used to encrypt data being sent to servers. -- * {@code null} to use the default or the results of parsing -- * {@code keyCertChainFile} and {@code keyFile}. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param cipherFilter a filter to apply over the supplied list of ciphers -- * @param apn Application Protocol Negotiator object. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslClientContext(File trustCertCollectionFile, TrustManagerFactory trustManagerFactory, -- File keyCertChainFile, File keyFile, String keyPassword, -- KeyManagerFactory keyManagerFactory, Iterable ciphers, -- CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, -- long sessionCacheSize, long sessionTimeout) -- throws SSLException { -- this(toX509CertificatesInternal(trustCertCollectionFile), trustManagerFactory, -- toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword), -- keyPassword, keyManagerFactory, ciphers, cipherFilter, apn, null, sessionCacheSize, -- sessionTimeout, false, KeyStore.getDefaultType()); -- } -- -- OpenSslClientContext(X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, -- X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, -- KeyManagerFactory keyManagerFactory, Iterable ciphers, -- CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, -- long sessionCacheSize, long sessionTimeout, boolean enableOcsp, String keyStore) -- throws SSLException { -- super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_CLIENT, keyCertChain, -- ClientAuth.NONE, protocols, false, enableOcsp); -- boolean success = false; -- try { -- OpenSslKeyMaterialProvider.validateKeyMaterialSupported(keyCertChain, key, keyPassword); -- sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory, -- keyCertChain, key, keyPassword, keyManagerFactory, keyStore); -- success = true; -- } finally { -- if (!success) { -- release(); -- } -- } -- } -- -- @Override -- public OpenSslSessionContext sessionContext() { -- return sessionContext; -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslContext.java -deleted file mode 100644 -index f18c0643fc..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslContext.java -+++ /dev/null -@@ -1,58 +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 io.netty.buffer.ByteBufAllocator; -- --import java.security.cert.Certificate; -- --import javax.net.ssl.SSLEngine; --import javax.net.ssl.SSLException; -- --/** -- * This class will use a finalizer to ensure native resources are automatically cleaned up. To avoid finalizers -- * and manually release the native memory see {@link ReferenceCountedOpenSslContext}. -- */ --public abstract class OpenSslContext extends ReferenceCountedOpenSslContext { -- OpenSslContext(Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apnCfg, -- long sessionCacheSize, long sessionTimeout, int mode, Certificate[] keyCertChain, -- ClientAuth clientAuth, String[] protocols, boolean startTls, boolean enableOcsp) -- throws SSLException { -- super(ciphers, cipherFilter, apnCfg, sessionCacheSize, sessionTimeout, mode, keyCertChain, -- clientAuth, protocols, startTls, enableOcsp, false); -- } -- -- OpenSslContext(Iterable ciphers, CipherSuiteFilter cipherFilter, -- OpenSslApplicationProtocolNegotiator apn, long sessionCacheSize, -- long sessionTimeout, int mode, Certificate[] keyCertChain, -- ClientAuth clientAuth, String[] protocols, boolean startTls, -- boolean enableOcsp) throws SSLException { -- super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, mode, keyCertChain, clientAuth, protocols, -- startTls, enableOcsp, false); -- } -- -- @Override -- final SSLEngine newEngine0(ByteBufAllocator alloc, String peerHost, int peerPort, boolean jdkCompatibilityMode) { -- return new OpenSslEngine(this, alloc, peerHost, peerPort, jdkCompatibilityMode); -- } -- -- @Override -- @SuppressWarnings("FinalizeDeclaration") -- protected final void finalize() throws Throwable { -- super.finalize(); -- OpenSsl.releaseIfNeeded(this); -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslEngine.java -deleted file mode 100644 -index a700dabf39..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslEngine.java -+++ /dev/null -@@ -1,41 +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 io.netty.buffer.ByteBufAllocator; -- --import javax.net.ssl.SSLEngine; -- --/** -- * Implements a {@link SSLEngine} using -- * OpenSSL BIO abstractions. -- *

-- * This class will use a finalizer to ensure native resources are automatically cleaned up. To avoid finalizers -- * and manually release the native memory see {@link ReferenceCountedOpenSslEngine}. -- */ --public final class OpenSslEngine extends ReferenceCountedOpenSslEngine { -- OpenSslEngine(OpenSslContext context, ByteBufAllocator alloc, String peerHost, int peerPort, -- boolean jdkCompatibilityMode) { -- super(context, alloc, peerHost, peerPort, jdkCompatibilityMode, false); -- } -- -- @Override -- @SuppressWarnings("FinalizeDeclaration") -- protected void finalize() throws Throwable { -- super.finalize(); -- OpenSsl.releaseIfNeeded(this); -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslEngineMap.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslEngineMap.java -deleted file mode 100644 -index 02131b4b26..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslEngineMap.java -+++ /dev/null -@@ -1,35 +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; -- --interface OpenSslEngineMap { -- -- /** -- * Remove the {@link OpenSslEngine} with the given {@code ssl} address and -- * return it. -- */ -- ReferenceCountedOpenSslEngine remove(long ssl); -- -- /** -- * Add a {@link OpenSslEngine} to this {@link OpenSslEngineMap}. -- */ -- void add(ReferenceCountedOpenSslEngine engine); -- -- /** -- * Get the {@link OpenSslEngine} for the given {@code ssl} address. -- */ -- ReferenceCountedOpenSslEngine get(long ssl); --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java -deleted file mode 100644 -index 7acbf70cfe..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java -+++ /dev/null -@@ -1,127 +0,0 @@ --/* -- * Copyright 2016 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.SSLException; --import javax.net.ssl.X509ExtendedKeyManager; --import javax.net.ssl.X509KeyManager; --import javax.security.auth.x500.X500Principal; --import java.security.PrivateKey; --import java.security.cert.X509Certificate; --import java.util.HashMap; --import java.util.HashSet; --import java.util.Map; --import java.util.Set; -- -- --/** -- * Manages key material for {@link OpenSslEngine}s and so set the right {@link PrivateKey}s and -- * {@link X509Certificate}s. -- */ --final class OpenSslKeyMaterialManager { -- -- // Code in this class is inspired by code of conscrypts: -- // - https://android.googlesource.com/platform/external/ -- // conscrypt/+/master/src/main/java/org/conscrypt/OpenSSLEngineImpl.java -- // - https://android.googlesource.com/platform/external/ -- // conscrypt/+/master/src/main/java/org/conscrypt/SSLParametersImpl.java -- // -- static final String KEY_TYPE_RSA = "RSA"; -- static final String KEY_TYPE_DH_RSA = "DH_RSA"; -- static final String KEY_TYPE_EC = "EC"; -- static final String KEY_TYPE_EC_EC = "EC_EC"; -- static final String KEY_TYPE_EC_RSA = "EC_RSA"; -- -- // key type mappings for types. -- private static final Map KEY_TYPES = new HashMap(); -- static { -- KEY_TYPES.put("RSA", KEY_TYPE_RSA); -- KEY_TYPES.put("DHE_RSA", KEY_TYPE_RSA); -- KEY_TYPES.put("ECDHE_RSA", KEY_TYPE_RSA); -- KEY_TYPES.put("ECDHE_ECDSA", KEY_TYPE_EC); -- KEY_TYPES.put("ECDH_RSA", KEY_TYPE_EC_RSA); -- KEY_TYPES.put("ECDH_ECDSA", KEY_TYPE_EC_EC); -- KEY_TYPES.put("DH_RSA", KEY_TYPE_DH_RSA); -- } -- -- private final OpenSslKeyMaterialProvider provider; -- -- OpenSslKeyMaterialManager(OpenSslKeyMaterialProvider provider) { -- this.provider = provider; -- } -- -- void setKeyMaterialServerSide(ReferenceCountedOpenSslEngine engine) throws SSLException { -- String[] authMethods = engine.authMethods(); -- if (authMethods.length == 0) { -- return; -- } -- Set aliases = new HashSet(authMethods.length); -- for (String authMethod : authMethods) { -- String type = KEY_TYPES.get(authMethod); -- if (type != null) { -- String alias = chooseServerAlias(engine, type); -- if (alias != null && aliases.add(alias)) { -- if (!setKeyMaterial(engine, alias)) { -- return; -- } -- } -- } -- } -- } -- -- void setKeyMaterialClientSide(ReferenceCountedOpenSslEngine engine, String[] keyTypes, -- X500Principal[] issuer) throws SSLException { -- String alias = chooseClientAlias(engine, keyTypes, issuer); -- // Only try to set the keymaterial if we have a match. This is also consistent with what OpenJDK does: -- // http://hg.openjdk.java.net/jdk/jdk11/file/76072a077ee1/ -- // src/java.base/share/classes/sun/security/ssl/CertificateRequest.java#l362 -- if (alias != null) { -- setKeyMaterial(engine, alias); -- } -- } -- -- private boolean setKeyMaterial(ReferenceCountedOpenSslEngine engine, String alias) throws SSLException { -- OpenSslKeyMaterial keyMaterial = null; -- try { -- keyMaterial = provider.chooseKeyMaterial(engine.alloc, alias); -- return keyMaterial == null || engine.setKeyMaterial(keyMaterial); -- } catch (SSLException e) { -- throw e; -- } catch (Exception e) { -- throw new SSLException(e); -- } finally { -- if (keyMaterial != null) { -- keyMaterial.release(); -- } -- } -- } -- private String chooseClientAlias(ReferenceCountedOpenSslEngine engine, -- String[] keyTypes, X500Principal[] issuer) { -- X509KeyManager manager = provider.keyManager(); -- if (manager instanceof X509ExtendedKeyManager) { -- return ((X509ExtendedKeyManager) manager).chooseEngineClientAlias(keyTypes, issuer, engine); -- } -- return manager.chooseClientAlias(keyTypes, issuer, null); -- } -- -- private String chooseServerAlias(ReferenceCountedOpenSslEngine engine, String type) { -- X509KeyManager manager = provider.keyManager(); -- if (manager instanceof X509ExtendedKeyManager) { -- return ((X509ExtendedKeyManager) manager).chooseEngineServerAlias(type, null, engine); -- } -- return manager.chooseServerAlias(type, null, null); -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialProvider.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialProvider.java -deleted file mode 100644 -index f931fcfdbb..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialProvider.java -+++ /dev/null -@@ -1,154 +0,0 @@ --/* -- * Copyright 2018 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.buffer.ByteBufAllocator; --import io.netty.buffer.UnpooledByteBufAllocator; --import io.netty.internal.tcnative.SSL; -- --import javax.net.ssl.SSLException; --import javax.net.ssl.X509KeyManager; --import java.security.PrivateKey; --import java.security.cert.X509Certificate; -- --import static io.netty.handler.ssl.ReferenceCountedOpenSslContext.toBIO; -- --/** -- * Provides {@link OpenSslKeyMaterial} for a given alias. -- */ --class OpenSslKeyMaterialProvider { -- -- private final X509KeyManager keyManager; -- private final String password; -- -- OpenSslKeyMaterialProvider(X509KeyManager keyManager, String password) { -- this.keyManager = keyManager; -- this.password = password; -- } -- -- static void validateKeyMaterialSupported(X509Certificate[] keyCertChain, PrivateKey key, String keyPassword) -- throws SSLException { -- validateSupported(keyCertChain); -- validateSupported(key, keyPassword); -- } -- -- private static void validateSupported(PrivateKey key, String password) throws SSLException { -- if (key == null) { -- return; -- } -- -- long pkeyBio = 0; -- long pkey = 0; -- -- try { -- pkeyBio = toBIO(UnpooledByteBufAllocator.DEFAULT, key); -- pkey = SSL.parsePrivateKey(pkeyBio, password); -- } catch (Exception e) { -- throw new SSLException("PrivateKey type not supported " + key.getFormat(), e); -- } finally { -- SSL.freeBIO(pkeyBio); -- if (pkey != 0) { -- SSL.freePrivateKey(pkey); -- } -- } -- } -- -- private static void validateSupported(X509Certificate[] certificates) throws SSLException { -- if (certificates == null || certificates.length == 0) { -- return; -- } -- -- long chainBio = 0; -- long chain = 0; -- PemEncoded encoded = null; -- try { -- encoded = PemX509Certificate.toPEM(UnpooledByteBufAllocator.DEFAULT, true, certificates); -- chainBio = toBIO(UnpooledByteBufAllocator.DEFAULT, encoded.retain()); -- chain = SSL.parseX509Chain(chainBio); -- } catch (Exception e) { -- throw new SSLException("Certificate type not supported", e); -- } finally { -- SSL.freeBIO(chainBio); -- if (chain != 0) { -- SSL.freeX509Chain(chain); -- } -- if (encoded != null) { -- encoded.release(); -- } -- } -- } -- -- /** -- * Returns the underlying {@link X509KeyManager} that is used. -- */ -- X509KeyManager keyManager() { -- return keyManager; -- } -- -- /** -- * Returns the {@link OpenSslKeyMaterial} or {@code null} (if none) that should be used during the handshake by -- * OpenSSL. -- */ -- OpenSslKeyMaterial chooseKeyMaterial(ByteBufAllocator allocator, String alias) throws Exception { -- X509Certificate[] certificates = keyManager.getCertificateChain(alias); -- if (certificates == null || certificates.length == 0) { -- return null; -- } -- -- PrivateKey key = keyManager.getPrivateKey(alias); -- PemEncoded encoded = PemX509Certificate.toPEM(allocator, true, certificates); -- long chainBio = 0; -- long pkeyBio = 0; -- long chain = 0; -- long pkey = 0; -- try { -- chainBio = toBIO(allocator, encoded.retain()); -- chain = SSL.parseX509Chain(chainBio); -- -- OpenSslKeyMaterial keyMaterial; -- if (key instanceof OpenSslPrivateKey) { -- keyMaterial = ((OpenSslPrivateKey) key).newKeyMaterial(chain, certificates); -- } else { -- pkeyBio = toBIO(allocator, key); -- pkey = key == null ? 0 : SSL.parsePrivateKey(pkeyBio, password); -- keyMaterial = new DefaultOpenSslKeyMaterial(chain, pkey, certificates); -- } -- -- // See the chain and pkey to 0 so we will not release it as the ownership was -- // transferred to OpenSslKeyMaterial. -- chain = 0; -- pkey = 0; -- return keyMaterial; -- } finally { -- SSL.freeBIO(chainBio); -- SSL.freeBIO(pkeyBio); -- if (chain != 0) { -- SSL.freeX509Chain(chain); -- } -- if (pkey != 0) { -- SSL.freePrivateKey(pkey); -- } -- encoded.release(); -- } -- } -- -- /** -- * Will be invoked once the provider should be destroyed. -- */ -- void destroy() { -- // NOOP. -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslPrivateKey.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslPrivateKey.java -deleted file mode 100644 -index c2e4f108b7..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslPrivateKey.java -+++ /dev/null -@@ -1,191 +0,0 @@ --/* -- * Copyright 2018 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.internal.tcnative.SSL; --import io.netty.util.AbstractReferenceCounted; --import io.netty.util.IllegalReferenceCountException; --import io.netty.util.internal.EmptyArrays; -- --import javax.security.auth.Destroyable; --import java.security.PrivateKey; --import java.security.cert.X509Certificate; -- --final class OpenSslPrivateKey extends AbstractReferenceCounted implements PrivateKey { -- -- private long privateKeyAddress; -- -- OpenSslPrivateKey(long privateKeyAddress) { -- this.privateKeyAddress = privateKeyAddress; -- } -- -- @Override -- public String getAlgorithm() { -- return "unknown"; -- } -- -- @Override -- public String getFormat() { -- // As we do not support encoding we should return null as stated in the javadocs of PrivateKey. -- return null; -- } -- -- @Override -- public byte[] getEncoded() { -- return null; -- } -- -- private long privateKeyAddress() { -- if (refCnt() <= 0) { -- throw new IllegalReferenceCountException(); -- } -- return privateKeyAddress; -- } -- -- @Override -- protected void deallocate() { -- SSL.freePrivateKey(privateKeyAddress); -- privateKeyAddress = 0; -- } -- -- @Override -- public OpenSslPrivateKey retain() { -- super.retain(); -- return this; -- } -- -- @Override -- public OpenSslPrivateKey retain(int increment) { -- super.retain(increment); -- return this; -- } -- -- @Override -- public OpenSslPrivateKey touch() { -- super.touch(); -- return this; -- } -- -- @Override -- public OpenSslPrivateKey touch(Object hint) { -- return this; -- } -- -- /** -- * NOTE: This is a JDK8 interface/method. Due to backwards compatibility -- * reasons it's not possible to slap the {@code @Override} annotation onto -- * this method. -- * -- * @see Destroyable#destroy() -- */ -- @Override -- public void destroy() { -- release(refCnt()); -- } -- -- /** -- * NOTE: This is a JDK8 interface/method. Due to backwards compatibility -- * reasons it's not possible to slap the {@code @Override} annotation onto -- * this method. -- * -- * @see Destroyable#isDestroyed() -- */ -- @Override -- public boolean isDestroyed() { -- return refCnt() == 0; -- } -- -- /** -- * Create a new {@link OpenSslKeyMaterial} which uses the private key that is held by {@link OpenSslPrivateKey}. -- * -- * When the material is created we increment the reference count of the enclosing {@link OpenSslPrivateKey} and -- * decrement it again when the reference count of the {@link OpenSslKeyMaterial} reaches {@code 0}. -- */ -- OpenSslKeyMaterial newKeyMaterial(long certificateChain, X509Certificate[] chain) { -- return new OpenSslPrivateKeyMaterial(certificateChain, chain); -- } -- -- // Package-private for unit-test only -- final class OpenSslPrivateKeyMaterial extends AbstractReferenceCounted implements OpenSslKeyMaterial { -- -- // Package-private for unit-test only -- long certificateChain; -- private final X509Certificate[] x509CertificateChain; -- -- OpenSslPrivateKeyMaterial(long certificateChain, X509Certificate[] x509CertificateChain) { -- this.certificateChain = certificateChain; -- this.x509CertificateChain = x509CertificateChain == null ? -- EmptyArrays.EMPTY_X509_CERTIFICATES : x509CertificateChain; -- OpenSslPrivateKey.this.retain(); -- } -- -- @Override -- public X509Certificate[] certificateChain() { -- return x509CertificateChain.clone(); -- } -- -- @Override -- public long certificateChainAddress() { -- if (refCnt() <= 0) { -- throw new IllegalReferenceCountException(); -- } -- return certificateChain; -- } -- -- @Override -- public long privateKeyAddress() { -- if (refCnt() <= 0) { -- throw new IllegalReferenceCountException(); -- } -- return OpenSslPrivateKey.this.privateKeyAddress(); -- } -- -- @Override -- public OpenSslKeyMaterial touch(Object hint) { -- OpenSslPrivateKey.this.touch(hint); -- return this; -- } -- -- @Override -- public OpenSslKeyMaterial retain() { -- super.retain(); -- return this; -- } -- -- @Override -- public OpenSslKeyMaterial retain(int increment) { -- super.retain(increment); -- return this; -- } -- -- @Override -- public OpenSslKeyMaterial touch() { -- OpenSslPrivateKey.this.touch(); -- return this; -- } -- -- @Override -- protected void deallocate() { -- releaseChain(); -- OpenSslPrivateKey.this.release(); -- } -- -- private void releaseChain() { -- SSL.freeX509Chain(certificateChain); -- certificateChain = 0; -- } -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslPrivateKeyMethod.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslPrivateKeyMethod.java -deleted file mode 100644 -index d9fc877269..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslPrivateKeyMethod.java -+++ /dev/null -@@ -1,62 +0,0 @@ --/* -- * Copyright 2019 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.internal.tcnative.SSLPrivateKeyMethod; --import io.netty.util.internal.UnstableApi; -- --import javax.net.ssl.SSLEngine; -- --/** -- * Allow to customize private key signing / decrypting (when using RSA). Only supported when using BoringSSL atm. -- */ --@UnstableApi --public interface OpenSslPrivateKeyMethod { -- int SSL_SIGN_RSA_PKCS1_SHA1 = SSLPrivateKeyMethod.SSL_SIGN_RSA_PKCS1_SHA1; -- int SSL_SIGN_RSA_PKCS1_SHA256 = SSLPrivateKeyMethod.SSL_SIGN_RSA_PKCS1_SHA256; -- int SSL_SIGN_RSA_PKCS1_SHA384 = SSLPrivateKeyMethod.SSL_SIGN_RSA_PKCS1_SHA384; -- int SSL_SIGN_RSA_PKCS1_SHA512 = SSLPrivateKeyMethod.SSL_SIGN_RSA_PKCS1_SHA512; -- int SSL_SIGN_ECDSA_SHA1 = SSLPrivateKeyMethod.SSL_SIGN_ECDSA_SHA1; -- int SSL_SIGN_ECDSA_SECP256R1_SHA256 = SSLPrivateKeyMethod.SSL_SIGN_ECDSA_SECP256R1_SHA256; -- int SSL_SIGN_ECDSA_SECP384R1_SHA384 = SSLPrivateKeyMethod.SSL_SIGN_ECDSA_SECP384R1_SHA384; -- int SSL_SIGN_ECDSA_SECP521R1_SHA512 = SSLPrivateKeyMethod.SSL_SIGN_ECDSA_SECP521R1_SHA512; -- int SSL_SIGN_RSA_PSS_RSAE_SHA256 = SSLPrivateKeyMethod.SSL_SIGN_RSA_PSS_RSAE_SHA256; -- int SSL_SIGN_RSA_PSS_RSAE_SHA384 = SSLPrivateKeyMethod.SSL_SIGN_RSA_PSS_RSAE_SHA384; -- int SSL_SIGN_RSA_PSS_RSAE_SHA512 = SSLPrivateKeyMethod.SSL_SIGN_RSA_PSS_RSAE_SHA512; -- int SSL_SIGN_ED25519 = SSLPrivateKeyMethod.SSL_SIGN_ED25519; -- int SSL_SIGN_RSA_PKCS1_MD5_SHA1 = SSLPrivateKeyMethod.SSL_SIGN_RSA_PKCS1_MD5_SHA1; -- -- /** -- * Signs the input with the given key and returns the signed bytes. -- * -- * @param engine the {@link SSLEngine} -- * @param signatureAlgorithm the algorithm to use for signing -- * @param input the digest itself -- * @return the signed data (must not be {@code null}) -- * @throws Exception thrown if an error is encountered during the signing -- */ -- byte[] sign(SSLEngine engine, int signatureAlgorithm, byte[] input) throws Exception; -- -- /** -- * Decrypts the input with the given key and returns the decrypted bytes. -- * -- * @param engine the {@link SSLEngine} -- * @param input the input which should be decrypted -- * @return the decrypted data (must not be {@code null}) -- * @throws Exception thrown if an error is encountered during the decrypting -- */ -- byte[] decrypt(SSLEngine engine, byte[] input) throws Exception; --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java -deleted file mode 100644 -index da342de0f2..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java -+++ /dev/null -@@ -1,367 +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 io.netty.internal.tcnative.SSL; -- --import java.io.File; --import java.security.KeyStore; --import java.security.PrivateKey; --import java.security.cert.X509Certificate; -- --import javax.net.ssl.KeyManager; --import javax.net.ssl.KeyManagerFactory; --import javax.net.ssl.SSLException; --import javax.net.ssl.TrustManager; --import javax.net.ssl.TrustManagerFactory; -- --import static io.netty.handler.ssl.ReferenceCountedOpenSslServerContext.newSessionContext; -- --/** -- * A server-side {@link SslContext} which uses OpenSSL's SSL/TLS implementation. -- *

This class will use a finalizer to ensure native resources are automatically cleaned up. To avoid finalizers -- * and manually release the native memory see {@link ReferenceCountedOpenSslServerContext}. -- */ --public final class OpenSslServerContext extends OpenSslContext { -- private final OpenSslServerSessionContext sessionContext; -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslServerContext(File certChainFile, File keyFile) throws SSLException { -- this(certChainFile, keyFile, null); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslServerContext(File certChainFile, File keyFile, String keyPassword) throws SSLException { -- this(certChainFile, keyFile, keyPassword, null, IdentityCipherSuiteFilter.INSTANCE, -- ApplicationProtocolConfig.DISABLED, 0, 0); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param apn Provides a means to configure parameters related to application protocol negotiation. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslServerContext( -- File certChainFile, File keyFile, String keyPassword, -- Iterable ciphers, ApplicationProtocolConfig apn, -- long sessionCacheSize, long sessionTimeout) throws SSLException { -- this(certChainFile, keyFile, keyPassword, ciphers, IdentityCipherSuiteFilter.INSTANCE, -- apn, sessionCacheSize, sessionTimeout); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param nextProtocols the application layer protocols to accept, in the order of preference. -- * {@code null} to disable TLS NPN/ALPN extension. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslServerContext( -- File certChainFile, File keyFile, String keyPassword, -- Iterable ciphers, Iterable nextProtocols, -- long sessionCacheSize, long sessionTimeout) throws SSLException { -- this(certChainFile, keyFile, keyPassword, ciphers, -- toApplicationProtocolConfig(nextProtocols), sessionCacheSize, sessionTimeout); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param config Application protocol config. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslServerContext( -- File certChainFile, File keyFile, String keyPassword, TrustManagerFactory trustManagerFactory, -- Iterable ciphers, ApplicationProtocolConfig config, -- long sessionCacheSize, long sessionTimeout) throws SSLException { -- this(certChainFile, keyFile, keyPassword, trustManagerFactory, ciphers, -- toNegotiator(config), sessionCacheSize, sessionTimeout); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param apn Application protocol negotiator. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslServerContext( -- File certChainFile, File keyFile, String keyPassword, TrustManagerFactory trustManagerFactory, -- Iterable ciphers, OpenSslApplicationProtocolNegotiator apn, -- long sessionCacheSize, long sessionTimeout) throws SSLException { -- this(null, trustManagerFactory, certChainFile, keyFile, keyPassword, null, -- ciphers, null, apn, sessionCacheSize, sessionTimeout); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param cipherFilter a filter to apply over the supplied list of ciphers -- * @param apn Provides a means to configure parameters related to application protocol negotiation. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslServerContext( -- File certChainFile, File keyFile, String keyPassword, -- Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, -- long sessionCacheSize, long sessionTimeout) throws SSLException { -- this(null, null, certChainFile, keyFile, keyPassword, null, -- ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout); -- } -- -- /** -- * Creates a new instance. -- * -- * @param trustCertCollectionFile an X.509 certificate collection file in PEM format. -- * This provides the certificate collection used for mutual authentication. -- * {@code null} to use the system default -- * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s -- * that verifies the certificates sent from clients. -- * {@code null} to use the default or the results of parsing -- * {@code trustCertCollectionFile}. -- * @param keyCertChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link KeyManager}s -- * that is used to encrypt data being sent to clients. -- * {@code null} to use the default or the results of parsing -- * {@code keyCertChainFile} and {@code keyFile}. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param cipherFilter a filter to apply over the supplied list of ciphers -- * Only required if {@code provider} is {@link SslProvider#JDK} -- * @param config Provides a means to configure parameters related to application protocol negotiation. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslServerContext( -- File trustCertCollectionFile, TrustManagerFactory trustManagerFactory, -- File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory, -- Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig config, -- long sessionCacheSize, long sessionTimeout) throws SSLException { -- this(trustCertCollectionFile, trustManagerFactory, keyCertChainFile, keyFile, keyPassword, keyManagerFactory, -- ciphers, cipherFilter, toNegotiator(config), sessionCacheSize, sessionTimeout); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param cipherFilter a filter to apply over the supplied list of ciphers -- * @param config Application protocol config. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslServerContext(File certChainFile, File keyFile, String keyPassword, -- TrustManagerFactory trustManagerFactory, Iterable ciphers, -- CipherSuiteFilter cipherFilter, ApplicationProtocolConfig config, -- long sessionCacheSize, long sessionTimeout) throws SSLException { -- this(null, trustManagerFactory, certChainFile, keyFile, keyPassword, null, ciphers, cipherFilter, -- toNegotiator(config), sessionCacheSize, sessionTimeout); -- } -- -- /** -- * Creates a new instance. -- * -- * @param certChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param cipherFilter a filter to apply over the supplied list of ciphers -- * @param apn Application protocol negotiator. -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder}} -- */ -- @Deprecated -- public OpenSslServerContext( -- File certChainFile, File keyFile, String keyPassword, TrustManagerFactory trustManagerFactory, -- Iterable ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn, -- long sessionCacheSize, long sessionTimeout) throws SSLException { -- this(null, trustManagerFactory, certChainFile, keyFile, keyPassword, null, ciphers, cipherFilter, -- apn, sessionCacheSize, sessionTimeout); -- } -- -- /** -- * Creates a new instance. -- * -- * -- * @param trustCertCollectionFile an X.509 certificate collection file in PEM format. -- * This provides the certificate collection used for mutual authentication. -- * {@code null} to use the system default -- * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s -- * that verifies the certificates sent from clients. -- * {@code null} to use the default or the results of parsing -- * {@code trustCertCollectionFile}. -- * @param keyCertChainFile an X.509 certificate chain file in PEM format -- * @param keyFile a PKCS#8 private key file in PEM format -- * @param keyPassword the password of the {@code keyFile}. -- * {@code null} if it's not password-protected. -- * @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link KeyManager}s -- * that is used to encrypt data being sent to clients. -- * {@code null} to use the default or the results of parsing -- * {@code keyCertChainFile} and {@code keyFile}. -- * @param ciphers the cipher suites to enable, in the order of preference. -- * {@code null} to use the default cipher suites. -- * @param cipherFilter a filter to apply over the supplied list of ciphers -- * Only required if {@code provider} is {@link SslProvider#JDK} -- * @param apn Application Protocol Negotiator object -- * @param sessionCacheSize the size of the cache used for storing SSL session objects. -- * {@code 0} to use the default value. -- * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. -- * {@code 0} to use the default value. -- * @deprecated use {@link SslContextBuilder} -- */ -- @Deprecated -- public OpenSslServerContext( -- File trustCertCollectionFile, TrustManagerFactory trustManagerFactory, -- File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory, -- Iterable ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn, -- long sessionCacheSize, long sessionTimeout) throws SSLException { -- this(toX509CertificatesInternal(trustCertCollectionFile), trustManagerFactory, -- toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword), -- keyPassword, keyManagerFactory, ciphers, cipherFilter, -- apn, sessionCacheSize, sessionTimeout, ClientAuth.NONE, null, false, false, KeyStore.getDefaultType()); -- } -- -- OpenSslServerContext( -- X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, -- X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, -- Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, -- long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls, -- boolean enableOcsp, String keyStore) throws SSLException { -- this(trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory, ciphers, -- cipherFilter, toNegotiator(apn), sessionCacheSize, sessionTimeout, clientAuth, protocols, startTls, -- enableOcsp, keyStore); -- } -- -- @SuppressWarnings("deprecation") -- private OpenSslServerContext( -- X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, -- X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, -- Iterable ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn, -- long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls, -- boolean enableOcsp, String keyStore) throws SSLException { -- super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_SERVER, keyCertChain, -- clientAuth, protocols, startTls, enableOcsp); -- -- // Create a new SSL_CTX and configure it. -- boolean success = false; -- try { -- OpenSslKeyMaterialProvider.validateKeyMaterialSupported(keyCertChain, key, keyPassword); -- sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory, -- keyCertChain, key, keyPassword, keyManagerFactory, keyStore); -- success = true; -- } finally { -- if (!success) { -- release(); -- } -- } -- } -- -- @Override -- public OpenSslServerSessionContext sessionContext() { -- return sessionContext; -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java -deleted file mode 100644 -index 691ee0b661..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java -+++ /dev/null -@@ -1,124 +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 io.netty.internal.tcnative.SSL; --import io.netty.internal.tcnative.SSLContext; -- --import java.util.concurrent.locks.Lock; -- -- --/** -- * {@link OpenSslSessionContext} implementation which offers extra methods which are only useful for the server-side. -- */ --public final class OpenSslServerSessionContext extends OpenSslSessionContext { -- OpenSslServerSessionContext(ReferenceCountedOpenSslContext context, OpenSslKeyMaterialProvider provider) { -- super(context, provider); -- } -- -- @Override -- public void setSessionTimeout(int seconds) { -- if (seconds < 0) { -- throw new IllegalArgumentException(); -- } -- Lock writerLock = context.ctxLock.writeLock(); -- writerLock.lock(); -- try { -- SSLContext.setSessionCacheTimeout(context.ctx, seconds); -- } finally { -- writerLock.unlock(); -- } -- } -- -- @Override -- public int getSessionTimeout() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return (int) SSLContext.getSessionCacheTimeout(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- @Override -- public void setSessionCacheSize(int size) { -- if (size < 0) { -- throw new IllegalArgumentException(); -- } -- Lock writerLock = context.ctxLock.writeLock(); -- writerLock.lock(); -- try { -- SSLContext.setSessionCacheSize(context.ctx, size); -- } finally { -- writerLock.unlock(); -- } -- } -- -- @Override -- public int getSessionCacheSize() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return (int) SSLContext.getSessionCacheSize(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- @Override -- public void setSessionCacheEnabled(boolean enabled) { -- long mode = enabled ? SSL.SSL_SESS_CACHE_SERVER : SSL.SSL_SESS_CACHE_OFF; -- -- Lock writerLock = context.ctxLock.writeLock(); -- writerLock.lock(); -- try { -- SSLContext.setSessionCacheMode(context.ctx, mode); -- } finally { -- writerLock.unlock(); -- } -- } -- -- @Override -- public boolean isSessionCacheEnabled() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.getSessionCacheMode(context.ctx) == SSL.SSL_SESS_CACHE_SERVER; -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Set the context within which session be reused (server side only) -- * See -- * man SSL_CTX_set_session_id_context -- * -- * @param sidCtx can be any kind of binary data, it is therefore possible to use e.g. the name -- * of the application and/or the hostname and/or service name -- * @return {@code true} if success, {@code false} otherwise. -- */ -- public boolean setSessionIdContext(byte[] sidCtx) { -- Lock writerLock = context.ctxLock.writeLock(); -- writerLock.lock(); -- try { -- return SSLContext.setSessionIdContext(context.ctx, sidCtx); -- } finally { -- writerLock.unlock(); -- } -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java -deleted file mode 100644 -index 5d471d34fb..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java -+++ /dev/null -@@ -1,158 +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 io.netty.internal.tcnative.SSL; --import io.netty.internal.tcnative.SSLContext; --import io.netty.internal.tcnative.SessionTicketKey; --import io.netty.util.internal.ObjectUtil; -- --import javax.net.ssl.SSLSession; --import javax.net.ssl.SSLSessionContext; --import java.util.Arrays; --import java.util.Enumeration; --import java.util.NoSuchElementException; --import java.util.concurrent.locks.Lock; -- --/** -- * OpenSSL specific {@link SSLSessionContext} implementation. -- */ --public abstract class OpenSslSessionContext implements SSLSessionContext { -- private static final Enumeration EMPTY = new EmptyEnumeration(); -- -- private final OpenSslSessionStats stats; -- -- // The OpenSslKeyMaterialProvider is not really used by the OpenSslSessionContext but only be stored here -- // to make it easier to destroy it later because the ReferenceCountedOpenSslContext will hold a reference -- // to OpenSslSessionContext. -- private final OpenSslKeyMaterialProvider provider; -- -- final ReferenceCountedOpenSslContext context; -- -- // IMPORTANT: We take the OpenSslContext and not just the long (which points the native instance) to prevent -- // the GC to collect OpenSslContext as this would also free the pointer and so could result in a -- // segfault when the user calls any of the methods here that try to pass the pointer down to the native -- // level. -- OpenSslSessionContext(ReferenceCountedOpenSslContext context, OpenSslKeyMaterialProvider provider) { -- this.context = context; -- this.provider = provider; -- stats = new OpenSslSessionStats(context); -- } -- -- final boolean useKeyManager() { -- return provider != null; -- } -- -- @Override -- public SSLSession getSession(byte[] bytes) { -- ObjectUtil.checkNotNull(bytes, "bytes"); -- return null; -- } -- -- @Override -- public Enumeration getIds() { -- return EMPTY; -- } -- -- /** -- * Sets the SSL session ticket keys of this context. -- * @deprecated use {@link #setTicketKeys(OpenSslSessionTicketKey...)}. -- */ -- @Deprecated -- public void setTicketKeys(byte[] keys) { -- if (keys.length % SessionTicketKey.TICKET_KEY_SIZE != 0) { -- throw new IllegalArgumentException("keys.length % " + SessionTicketKey.TICKET_KEY_SIZE + " != 0"); -- } -- SessionTicketKey[] tickets = new SessionTicketKey[keys.length / SessionTicketKey.TICKET_KEY_SIZE]; -- for (int i = 0, a = 0; i < tickets.length; i++) { -- byte[] name = Arrays.copyOfRange(keys, a, SessionTicketKey.NAME_SIZE); -- a += SessionTicketKey.NAME_SIZE; -- byte[] hmacKey = Arrays.copyOfRange(keys, a, SessionTicketKey.HMAC_KEY_SIZE); -- i += SessionTicketKey.HMAC_KEY_SIZE; -- byte[] aesKey = Arrays.copyOfRange(keys, a, SessionTicketKey.AES_KEY_SIZE); -- a += SessionTicketKey.AES_KEY_SIZE; -- tickets[i] = new SessionTicketKey(name, hmacKey, aesKey); -- } -- Lock writerLock = context.ctxLock.writeLock(); -- writerLock.lock(); -- try { -- SSLContext.clearOptions(context.ctx, SSL.SSL_OP_NO_TICKET); -- SSLContext.setSessionTicketKeys(context.ctx, tickets); -- } finally { -- writerLock.unlock(); -- } -- } -- -- /** -- * Sets the SSL session ticket keys of this context. Depending on the underlying native library you may omit the -- * argument or pass an empty array and so let the native library handle the key generation and rotating for you. -- * If this is supported by the underlying native library should be checked in this case. For example -- * -- * BoringSSL is known to support this. -- */ -- public void setTicketKeys(OpenSslSessionTicketKey... keys) { -- ObjectUtil.checkNotNull(keys, "keys"); -- SessionTicketKey[] ticketKeys = new SessionTicketKey[keys.length]; -- for (int i = 0; i < ticketKeys.length; i++) { -- ticketKeys[i] = keys[i].key; -- } -- Lock writerLock = context.ctxLock.writeLock(); -- writerLock.lock(); -- try { -- SSLContext.clearOptions(context.ctx, SSL.SSL_OP_NO_TICKET); -- if (ticketKeys.length > 0) { -- SSLContext.setSessionTicketKeys(context.ctx, ticketKeys); -- } -- } finally { -- writerLock.unlock(); -- } -- } -- -- /** -- * Enable or disable caching of SSL sessions. -- */ -- public abstract void setSessionCacheEnabled(boolean enabled); -- -- /** -- * Return {@code true} if caching of SSL sessions is enabled, {@code false} otherwise. -- */ -- public abstract boolean isSessionCacheEnabled(); -- -- /** -- * Returns the stats of this context. -- */ -- public OpenSslSessionStats stats() { -- return stats; -- } -- -- final void destroy() { -- if (provider != null) { -- provider.destroy(); -- } -- } -- -- private static final class EmptyEnumeration implements Enumeration { -- @Override -- public boolean hasMoreElements() { -- return false; -- } -- -- @Override -- public byte[] nextElement() { -- throw new NoSuchElementException(); -- } -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java -deleted file mode 100644 -index f49b95f3ba..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java -+++ /dev/null -@@ -1,253 +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 io.netty.internal.tcnative.SSLContext; -- --import java.util.concurrent.locks.Lock; -- --/** -- * Stats exposed by an OpenSSL session context. -- * -- * @see SSL_CTX_sess_number -- */ --public final class OpenSslSessionStats { -- -- private final ReferenceCountedOpenSslContext context; -- -- // IMPORTANT: We take the OpenSslContext and not just the long (which points the native instance) to prevent -- // the GC to collect OpenSslContext as this would also free the pointer and so could result in a -- // segfault when the user calls any of the methods here that try to pass the pointer down to the native -- // level. -- OpenSslSessionStats(ReferenceCountedOpenSslContext context) { -- this.context = context; -- } -- -- /** -- * Returns the current number of sessions in the internal session cache. -- */ -- public long number() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionNumber(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of started SSL/TLS handshakes in client mode. -- */ -- public long connect() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionConnect(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of successfully established SSL/TLS sessions in client mode. -- */ -- public long connectGood() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionConnectGood(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of start renegotiations in client mode. -- */ -- public long connectRenegotiate() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionConnectRenegotiate(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of started SSL/TLS handshakes in server mode. -- */ -- public long accept() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionAccept(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of successfully established SSL/TLS sessions in server mode. -- */ -- public long acceptGood() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionAcceptGood(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of start renegotiations in server mode. -- */ -- public long acceptRenegotiate() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionAcceptRenegotiate(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of successfully reused sessions. In client mode, a session set with {@code SSL_set_session} -- * successfully reused is counted as a hit. In server mode, a session successfully retrieved from internal or -- * external cache is counted as a hit. -- */ -- public long hits() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionHits(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of successfully retrieved sessions from the external session cache in server mode. -- */ -- public long cbHits() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionCbHits(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of sessions proposed by clients that were not found in the internal session cache -- * in server mode. -- */ -- public long misses() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionMisses(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of sessions proposed by clients and either found in the internal or external session cache -- * in server mode, but that were invalid due to timeout. These sessions are not included in the {@link #hits()} -- * count. -- */ -- public long timeouts() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionTimeouts(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of sessions that were removed because the maximum session cache size was exceeded. -- */ -- public long cacheFull() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionCacheFull(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of times a client presented a ticket that did not match any key in the list. -- */ -- public long ticketKeyFail() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionTicketKeyFail(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of times a client did not present a ticket and we issued a new one -- */ -- public long ticketKeyNew() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionTicketKeyNew(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of times a client presented a ticket derived from an older key, -- * and we upgraded to the primary key. -- */ -- public long ticketKeyRenew() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionTicketKeyRenew(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Returns the number of times a client presented a ticket derived from the primary key. -- */ -- public long ticketKeyResume() { -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.sessionTicketKeyResume(context.ctx); -- } finally { -- readerLock.unlock(); -- } -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java -deleted file mode 100644 -index 79f71a65a3..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java -+++ /dev/null -@@ -1,78 +0,0 @@ --/* -- * Copyright 2015 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.internal.tcnative.SessionTicketKey; -- --/** -- * Session Ticket Key -- */ --public final class OpenSslSessionTicketKey { -- -- /** -- * Size of session ticket key name -- */ -- public static final int NAME_SIZE = SessionTicketKey.NAME_SIZE; -- /** -- * Size of session ticket key HMAC key -- */ -- public static final int HMAC_KEY_SIZE = SessionTicketKey.HMAC_KEY_SIZE; -- /** -- * Size of session ticket key AES key -- */ -- public static final int AES_KEY_SIZE = SessionTicketKey.AES_KEY_SIZE; -- /** -- * Size of session ticker key -- */ -- public static final int TICKET_KEY_SIZE = SessionTicketKey.TICKET_KEY_SIZE; -- -- final SessionTicketKey key; -- -- /** -- * Construct a OpenSslSessionTicketKey. -- * -- * @param name the name of the session ticket key -- * @param hmacKey the HMAC key of the session ticket key -- * @param aesKey the AES key of the session ticket key -- */ -- public OpenSslSessionTicketKey(byte[] name, byte[] hmacKey, byte[] aesKey) { -- key = new SessionTicketKey(name.clone(), hmacKey.clone(), aesKey.clone()); -- } -- -- /** -- * Get name. -- * @return the name of the session ticket key -- */ -- public byte[] name() { -- return key.getName().clone(); -- } -- -- /** -- * Get HMAC key. -- * @return the HMAC key of the session ticket key -- */ -- public byte[] hmacKey() { -- return key.getHmacKey().clone(); -- } -- -- /** -- * Get AES Key. -- * @return the AES key of the session ticket key -- */ -- public byte[] aesKey() { -- return key.getAesKey().clone(); -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslTlsv13X509ExtendedTrustManager.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslTlsv13X509ExtendedTrustManager.java -deleted file mode 100644 -index a5a84f2793..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslTlsv13X509ExtendedTrustManager.java -+++ /dev/null -@@ -1,240 +0,0 @@ --/* -- * Copyright 2018 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.PlatformDependent; --import io.netty.util.internal.SuppressJava6Requirement; -- --import javax.net.ssl.SSLEngine; --import javax.net.ssl.SSLPeerUnverifiedException; --import javax.net.ssl.SSLSession; --import javax.net.ssl.SSLSessionContext; --import javax.net.ssl.X509ExtendedTrustManager; --import java.net.Socket; --import java.security.Principal; --import java.security.cert.Certificate; --import java.security.cert.CertificateException; --import java.security.cert.X509Certificate; --import java.util.List; -- --/** -- * Provide a way to use {@code TLSv1.3} with Java versions prior to 11 by adding a -- * = 7 && session instanceof ExtendedOpenSslSession) { -- final ExtendedOpenSslSession extendedOpenSslSession = (ExtendedOpenSslSession) session; -- return new ExtendedOpenSslSession(extendedOpenSslSession) { -- @Override -- public List getRequestedServerNames() { -- return extendedOpenSslSession.getRequestedServerNames(); -- } -- -- @Override -- public String[] getPeerSupportedSignatureAlgorithms() { -- return extendedOpenSslSession.getPeerSupportedSignatureAlgorithms(); -- } -- -- @Override -- public String getProtocol() { -- return SslUtils.PROTOCOL_TLS_V1_2; -- } -- }; -- } else { -- return new SSLSession() { -- @Override -- public byte[] getId() { -- return session.getId(); -- } -- -- @Override -- public SSLSessionContext getSessionContext() { -- return session.getSessionContext(); -- } -- -- @Override -- public long getCreationTime() { -- return session.getCreationTime(); -- } -- -- @Override -- public long getLastAccessedTime() { -- return session.getLastAccessedTime(); -- } -- -- @Override -- public void invalidate() { -- session.invalidate(); -- } -- -- @Override -- public boolean isValid() { -- return session.isValid(); -- } -- -- @Override -- public void putValue(String s, Object o) { -- session.putValue(s, o); -- } -- -- @Override -- public Object getValue(String s) { -- return session.getValue(s); -- } -- -- @Override -- public void removeValue(String s) { -- session.removeValue(s); -- } -- -- @Override -- public String[] getValueNames() { -- return session.getValueNames(); -- } -- -- @Override -- public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { -- return session.getPeerCertificates(); -- } -- -- @Override -- public Certificate[] getLocalCertificates() { -- return session.getLocalCertificates(); -- } -- -- @Override -- public javax.security.cert.X509Certificate[] getPeerCertificateChain() -- throws SSLPeerUnverifiedException { -- return session.getPeerCertificateChain(); -- } -- -- @Override -- public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { -- return session.getPeerPrincipal(); -- } -- -- @Override -- public Principal getLocalPrincipal() { -- return session.getLocalPrincipal(); -- } -- -- @Override -- public String getCipherSuite() { -- return session.getCipherSuite(); -- } -- -- @Override -- public String getProtocol() { -- return SslUtils.PROTOCOL_TLS_V1_2; -- } -- -- @Override -- public String getPeerHost() { -- return session.getPeerHost(); -- } -- -- @Override -- public int getPeerPort() { -- return session.getPeerPort(); -- } -- -- @Override -- public int getPacketBufferSize() { -- return session.getPacketBufferSize(); -- } -- -- @Override -- public int getApplicationBufferSize() { -- return session.getApplicationBufferSize(); -- } -- }; -- } -- } -- }; -- } -- return engine; -- } -- -- @Override -- public void checkClientTrusted(X509Certificate[] x509Certificates, final String s, SSLEngine sslEngine) -- throws CertificateException { -- tm.checkClientTrusted(x509Certificates, s, wrapEngine(sslEngine)); -- } -- -- @Override -- public void checkServerTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) -- throws CertificateException { -- tm.checkServerTrusted(x509Certificates, s, wrapEngine(sslEngine)); -- } -- -- @Override -- public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { -- tm.checkClientTrusted(x509Certificates, s); -- } -- -- @Override -- public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { -- tm.checkServerTrusted(x509Certificates, s); -- } -- -- @Override -- public X509Certificate[] getAcceptedIssuers() { -- return tm.getAcceptedIssuers(); -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslX509KeyManagerFactory.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslX509KeyManagerFactory.java -deleted file mode 100644 -index 2a86332fe1..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/OpenSslX509KeyManagerFactory.java -+++ /dev/null -@@ -1,413 +0,0 @@ --/* -- * Copyright 2018 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.buffer.ByteBufAllocator; --import io.netty.buffer.UnpooledByteBufAllocator; --import io.netty.internal.tcnative.SSL; --import io.netty.util.ReferenceCountUtil; --import io.netty.util.internal.ObjectUtil; -- --import javax.net.ssl.KeyManager; --import javax.net.ssl.KeyManagerFactory; --import javax.net.ssl.KeyManagerFactorySpi; --import javax.net.ssl.ManagerFactoryParameters; --import javax.net.ssl.X509KeyManager; --import java.io.File; --import java.io.IOException; --import java.io.InputStream; --import java.io.OutputStream; --import java.security.InvalidAlgorithmParameterException; --import java.security.Key; --import java.security.KeyStore; --import java.security.KeyStoreException; --import java.security.KeyStoreSpi; --import java.security.NoSuchAlgorithmException; --import java.security.PrivateKey; --import java.security.Provider; --import java.security.UnrecoverableKeyException; --import java.security.cert.Certificate; --import java.security.cert.CertificateException; --import java.security.cert.X509Certificate; --import java.util.Collections; --import java.util.Date; --import java.util.Enumeration; --import java.util.HashMap; --import java.util.Map; -- --/** -- * Special {@link KeyManagerFactory} that pre-compute the keymaterial used when {@link SslProvider#OPENSSL} or -- * {@link SslProvider#OPENSSL_REFCNT} is used and so will improve handshake times and its performance. -- * -- * -- * -- * Because the keymaterial is pre-computed any modification to the {@link KeyStore} is ignored after -- * {@link #init(KeyStore, char[])} is called. -- * -- * {@link #init(ManagerFactoryParameters)} is not supported by this implementation and so a call to it will always -- * result in an {@link InvalidAlgorithmParameterException}. -- */ --public final class OpenSslX509KeyManagerFactory extends KeyManagerFactory { -- -- private final OpenSslKeyManagerFactorySpi spi; -- -- public OpenSslX509KeyManagerFactory() { -- this(newOpenSslKeyManagerFactorySpi(null)); -- } -- -- public OpenSslX509KeyManagerFactory(Provider provider) { -- this(newOpenSslKeyManagerFactorySpi(provider)); -- } -- -- public OpenSslX509KeyManagerFactory(String algorithm, Provider provider) throws NoSuchAlgorithmException { -- this(newOpenSslKeyManagerFactorySpi(algorithm, provider)); -- } -- -- private OpenSslX509KeyManagerFactory(OpenSslKeyManagerFactorySpi spi) { -- super(spi, spi.kmf.getProvider(), spi.kmf.getAlgorithm()); -- this.spi = spi; -- } -- -- private static OpenSslKeyManagerFactorySpi newOpenSslKeyManagerFactorySpi(Provider provider) { -- try { -- return newOpenSslKeyManagerFactorySpi(null, provider); -- } catch (NoSuchAlgorithmException e) { -- // This should never happen as we use the default algorithm. -- throw new IllegalStateException(e); -- } -- } -- -- private static OpenSslKeyManagerFactorySpi newOpenSslKeyManagerFactorySpi(String algorithm, Provider provider) -- throws NoSuchAlgorithmException { -- if (algorithm == null) { -- algorithm = KeyManagerFactory.getDefaultAlgorithm(); -- } -- return new OpenSslKeyManagerFactorySpi( -- provider == null ? KeyManagerFactory.getInstance(algorithm) : -- KeyManagerFactory.getInstance(algorithm, provider)); -- } -- -- OpenSslKeyMaterialProvider newProvider() { -- return spi.newProvider(); -- } -- -- private static final class OpenSslKeyManagerFactorySpi extends KeyManagerFactorySpi { -- final KeyManagerFactory kmf; -- private volatile ProviderFactory providerFactory; -- -- OpenSslKeyManagerFactorySpi(KeyManagerFactory kmf) { -- this.kmf = ObjectUtil.checkNotNull(kmf, "kmf"); -- } -- -- @Override -- protected synchronized void engineInit(KeyStore keyStore, char[] chars) -- throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { -- if (providerFactory != null) { -- throw new KeyStoreException("Already initialized"); -- } -- if (!keyStore.aliases().hasMoreElements()) { -- throw new KeyStoreException("No aliases found"); -- } -- -- kmf.init(keyStore, chars); -- providerFactory = new ProviderFactory(ReferenceCountedOpenSslContext.chooseX509KeyManager( -- kmf.getKeyManagers()), password(chars), Collections.list(keyStore.aliases())); -- } -- -- private static String password(char[] password) { -- if (password == null || password.length == 0) { -- return null; -- } -- return new String(password); -- } -- -- @Override -- protected void engineInit(ManagerFactoryParameters managerFactoryParameters) -- throws InvalidAlgorithmParameterException { -- throw new InvalidAlgorithmParameterException("Not supported"); -- } -- -- @Override -- protected KeyManager[] engineGetKeyManagers() { -- ProviderFactory providerFactory = this.providerFactory; -- if (providerFactory == null) { -- throw new IllegalStateException("engineInit(...) not called yet"); -- } -- return new KeyManager[] { providerFactory.keyManager }; -- } -- -- OpenSslKeyMaterialProvider newProvider() { -- ProviderFactory providerFactory = this.providerFactory; -- if (providerFactory == null) { -- throw new IllegalStateException("engineInit(...) not called yet"); -- } -- return providerFactory.newProvider(); -- } -- -- private static final class ProviderFactory { -- private final X509KeyManager keyManager; -- private final String password; -- private final Iterable aliases; -- -- ProviderFactory(X509KeyManager keyManager, String password, Iterable aliases) { -- this.keyManager = keyManager; -- this.password = password; -- this.aliases = aliases; -- } -- -- OpenSslKeyMaterialProvider newProvider() { -- return new OpenSslPopulatedKeyMaterialProvider(keyManager, -- password, aliases); -- } -- -- /** -- * {@link OpenSslKeyMaterialProvider} implementation that pre-compute the {@link OpenSslKeyMaterial} for -- * all aliases. -- */ -- private static final class OpenSslPopulatedKeyMaterialProvider extends OpenSslKeyMaterialProvider { -- private final Map materialMap; -- -- OpenSslPopulatedKeyMaterialProvider( -- X509KeyManager keyManager, String password, Iterable aliases) { -- super(keyManager, password); -- materialMap = new HashMap(); -- boolean initComplete = false; -- try { -- for (String alias: aliases) { -- if (alias != null && !materialMap.containsKey(alias)) { -- try { -- materialMap.put(alias, super.chooseKeyMaterial( -- UnpooledByteBufAllocator.DEFAULT, alias)); -- } catch (Exception e) { -- // Just store the exception and rethrow it when we try to choose the keymaterial -- // for this alias later on. -- materialMap.put(alias, e); -- } -- } -- } -- initComplete = true; -- } finally { -- if (!initComplete) { -- destroy(); -- } -- } -- if (materialMap.isEmpty()) { -- throw new IllegalArgumentException("aliases must be non-empty"); -- } -- } -- -- @Override -- OpenSslKeyMaterial chooseKeyMaterial(ByteBufAllocator allocator, String alias) throws Exception { -- Object value = materialMap.get(alias); -- if (value == null) { -- // There is no keymaterial for the requested alias, return null -- return null; -- } -- if (value instanceof OpenSslKeyMaterial) { -- return ((OpenSslKeyMaterial) value).retain(); -- } -- throw (Exception) value; -- } -- -- @Override -- void destroy() { -- for (Object material: materialMap.values()) { -- ReferenceCountUtil.release(material); -- } -- materialMap.clear(); -- } -- } -- } -- } -- -- /** -- * Create a new initialized {@link OpenSslX509KeyManagerFactory} which loads its {@link PrivateKey} directly from -- * an {@code OpenSSL engine} via the -- * ENGINE_load_private_key -- * function. -- */ -- public static OpenSslX509KeyManagerFactory newEngineBased(File certificateChain, String password) -- throws CertificateException, IOException, -- KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { -- return newEngineBased(SslContext.toX509Certificates(certificateChain), password); -- } -- -- /** -- * Create a new initialized {@link OpenSslX509KeyManagerFactory} which loads its {@link PrivateKey} directly from -- * an {@code OpenSSL engine} via the -- * ENGINE_load_private_key -- * function. -- */ -- public static OpenSslX509KeyManagerFactory newEngineBased(X509Certificate[] certificateChain, String password) -- throws CertificateException, IOException, -- KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { -- KeyStore store = new OpenSslKeyStore(certificateChain.clone(), false); -- store.load(null, null); -- OpenSslX509KeyManagerFactory factory = new OpenSslX509KeyManagerFactory(); -- factory.init(store, password == null ? null : password.toCharArray()); -- return factory; -- } -- -- /** -- * See {@link OpenSslX509KeyManagerFactory#newEngineBased(X509Certificate[], String)}. -- */ -- public static OpenSslX509KeyManagerFactory newKeyless(File chain) -- throws CertificateException, IOException, -- KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { -- return newKeyless(SslContext.toX509Certificates(chain)); -- } -- -- /** -- * See {@link OpenSslX509KeyManagerFactory#newEngineBased(X509Certificate[], String)}. -- */ -- public static OpenSslX509KeyManagerFactory newKeyless(InputStream chain) -- throws CertificateException, IOException, -- KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { -- return newKeyless(SslContext.toX509Certificates(chain)); -- } -- -- /** -- * Returns a new initialized {@link OpenSslX509KeyManagerFactory} which will provide its private key by using the -- * {@link OpenSslPrivateKeyMethod}. -- */ -- public static OpenSslX509KeyManagerFactory newKeyless(X509Certificate... certificateChain) -- throws CertificateException, IOException, -- KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { -- KeyStore store = new OpenSslKeyStore(certificateChain.clone(), true); -- store.load(null, null); -- OpenSslX509KeyManagerFactory factory = new OpenSslX509KeyManagerFactory(); -- factory.init(store, null); -- return factory; -- } -- -- private static final class OpenSslKeyStore extends KeyStore { -- private OpenSslKeyStore(final X509Certificate[] certificateChain, final boolean keyless) { -- super(new KeyStoreSpi() { -- -- private final Date creationDate = new Date(); -- -- @Override -- public Key engineGetKey(String alias, char[] password) throws UnrecoverableKeyException { -- if (engineContainsAlias(alias)) { -- final long privateKeyAddress; -- if (keyless) { -- privateKeyAddress = 0; -- } else { -- try { -- privateKeyAddress = SSL.loadPrivateKeyFromEngine( -- alias, password == null ? null : new String(password)); -- } catch (Exception e) { -- UnrecoverableKeyException keyException = -- new UnrecoverableKeyException("Unable to load key from engine"); -- keyException.initCause(e); -- throw keyException; -- } -- } -- return new OpenSslPrivateKey(privateKeyAddress); -- } -- return null; -- } -- -- @Override -- public Certificate[] engineGetCertificateChain(String alias) { -- return engineContainsAlias(alias)? certificateChain.clone() : null; -- } -- -- @Override -- public Certificate engineGetCertificate(String alias) { -- return engineContainsAlias(alias)? certificateChain[0] : null; -- } -- -- @Override -- public Date engineGetCreationDate(String alias) { -- return engineContainsAlias(alias)? creationDate : null; -- } -- -- @Override -- public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) -- throws KeyStoreException { -- throw new KeyStoreException("Not supported"); -- } -- -- @Override -- public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException { -- throw new KeyStoreException("Not supported"); -- } -- -- @Override -- public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException { -- throw new KeyStoreException("Not supported"); -- } -- -- @Override -- public void engineDeleteEntry(String alias) throws KeyStoreException { -- throw new KeyStoreException("Not supported"); -- } -- -- @Override -- public Enumeration engineAliases() { -- return Collections.enumeration(Collections.singleton(SslContext.ALIAS)); -- } -- -- @Override -- public boolean engineContainsAlias(String alias) { -- return SslContext.ALIAS.equals(alias); -- } -- -- @Override -- public int engineSize() { -- return 1; -- } -- -- @Override -- public boolean engineIsKeyEntry(String alias) { -- return engineContainsAlias(alias); -- } -- -- @Override -- public boolean engineIsCertificateEntry(String alias) { -- return engineContainsAlias(alias); -- } -- -- @Override -- public String engineGetCertificateAlias(Certificate cert) { -- if (cert instanceof X509Certificate) { -- for (X509Certificate x509Certificate : certificateChain) { -- if (x509Certificate.equals(cert)) { -- return SslContext.ALIAS; -- } -- } -- } -- return null; -- } -- -- @Override -- public void engineStore(OutputStream stream, char[] password) { -- throw new UnsupportedOperationException(); -- } -- -- @Override -- public void engineLoad(InputStream stream, char[] password) { -- if (stream != null && password != null) { -- throw new UnsupportedOperationException(); -- } -- } -- }, null, "native"); -- -- OpenSsl.ensureAvailability(); -- } -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java -deleted file mode 100644 -index 6b945506b9..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java -+++ /dev/null -@@ -1,343 +0,0 @@ --/* -- * Copyright 2016 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.internal.tcnative.CertificateCallback; --import io.netty.util.internal.SuppressJava6Requirement; --import io.netty.util.internal.SystemPropertyUtil; --import io.netty.util.internal.logging.InternalLogger; --import io.netty.util.internal.logging.InternalLoggerFactory; --import io.netty.internal.tcnative.SSL; --import io.netty.internal.tcnative.SSLContext; -- --import java.security.KeyStore; --import java.security.PrivateKey; --import java.security.cert.X509Certificate; -- --import java.util.Arrays; --import java.util.Collections; --import java.util.HashSet; --import java.util.LinkedHashSet; --import java.util.Set; -- --import javax.net.ssl.KeyManagerFactory; --import javax.net.ssl.SSLException; --import javax.net.ssl.TrustManagerFactory; --import javax.net.ssl.X509ExtendedTrustManager; --import javax.net.ssl.X509TrustManager; --import javax.security.auth.x500.X500Principal; -- --/** -- * A client-side {@link SslContext} which uses OpenSSL's SSL/TLS implementation. -- *

Instances of this class must be {@link #release() released} or else native memory will leak! -- * -- *

Instances of this class must not be released before any {@link ReferenceCountedOpenSslEngine} -- * which depends upon the instance of this class is released. Otherwise if any method of -- * {@link ReferenceCountedOpenSslEngine} is called which uses this class's JNI resources the JVM may crash. -- */ --public final class ReferenceCountedOpenSslClientContext extends ReferenceCountedOpenSslContext { -- private static final InternalLogger logger = -- InternalLoggerFactory.getInstance(ReferenceCountedOpenSslClientContext.class); -- private static final Set SUPPORTED_KEY_TYPES = Collections.unmodifiableSet(new LinkedHashSet( -- Arrays.asList(OpenSslKeyMaterialManager.KEY_TYPE_RSA, -- OpenSslKeyMaterialManager.KEY_TYPE_DH_RSA, -- OpenSslKeyMaterialManager.KEY_TYPE_EC, -- OpenSslKeyMaterialManager.KEY_TYPE_EC_RSA, -- OpenSslKeyMaterialManager.KEY_TYPE_EC_EC))); -- private static final boolean ENABLE_SESSION_TICKET = -- SystemPropertyUtil.getBoolean("jdk.tls.client.enableSessionTicketExtension", false); -- private final OpenSslSessionContext sessionContext; -- -- ReferenceCountedOpenSslClientContext(X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, -- X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, -- KeyManagerFactory keyManagerFactory, Iterable ciphers, -- CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, -- String[] protocols, long sessionCacheSize, long sessionTimeout, -- boolean enableOcsp, String keyStore) throws SSLException { -- super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_CLIENT, keyCertChain, -- ClientAuth.NONE, protocols, false, enableOcsp, true); -- boolean success = false; -- try { -- sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory, -- keyCertChain, key, keyPassword, keyManagerFactory, keyStore); -- if (ENABLE_SESSION_TICKET) { -- sessionContext.setTicketKeys(); -- } -- success = true; -- } finally { -- if (!success) { -- release(); -- } -- } -- } -- -- @Override -- public OpenSslSessionContext sessionContext() { -- return sessionContext; -- } -- -- static OpenSslSessionContext newSessionContext(ReferenceCountedOpenSslContext thiz, long ctx, -- OpenSslEngineMap engineMap, -- X509Certificate[] trustCertCollection, -- TrustManagerFactory trustManagerFactory, -- X509Certificate[] keyCertChain, PrivateKey key, -- String keyPassword, KeyManagerFactory keyManagerFactory, -- String keyStore) throws SSLException { -- if (key == null && keyCertChain != null || key != null && keyCertChain == null) { -- throw new IllegalArgumentException( -- "Either both keyCertChain and key needs to be null or none of them"); -- } -- OpenSslKeyMaterialProvider keyMaterialProvider = null; -- try { -- try { -- if (!OpenSsl.useKeyManagerFactory()) { -- if (keyManagerFactory != null) { -- throw new IllegalArgumentException( -- "KeyManagerFactory not supported"); -- } -- if (keyCertChain != null/* && key != null*/) { -- setKeyMaterial(ctx, keyCertChain, key, keyPassword); -- } -- } else { -- // javadocs state that keyManagerFactory has precedent over keyCertChain -- if (keyManagerFactory == null && keyCertChain != null) { -- char[] keyPasswordChars = keyStorePassword(keyPassword); -- KeyStore ks = buildKeyStore(keyCertChain, key, keyPasswordChars, keyStore); -- if (ks.aliases().hasMoreElements()) { -- keyManagerFactory = new OpenSslX509KeyManagerFactory(); -- } else { -- keyManagerFactory = new OpenSslCachingX509KeyManagerFactory( -- KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())); -- } -- keyManagerFactory.init(ks, keyPasswordChars); -- keyMaterialProvider = providerFor(keyManagerFactory, keyPassword); -- } else if (keyManagerFactory != null) { -- keyMaterialProvider = providerFor(keyManagerFactory, keyPassword); -- } -- -- if (keyMaterialProvider != null) { -- OpenSslKeyMaterialManager materialManager = new OpenSslKeyMaterialManager(keyMaterialProvider); -- SSLContext.setCertificateCallback(ctx, new OpenSslClientCertificateCallback( -- engineMap, materialManager)); -- } -- } -- } catch (Exception e) { -- throw new SSLException("failed to set certificate and key", e); -- } -- -- // On the client side we always need to use SSL_CVERIFY_OPTIONAL (which will translate to SSL_VERIFY_PEER) -- // to ensure that when the TrustManager throws we will produce the correct alert back to the server. -- // -- // See: -- // - https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_verify.html -- // - https://github.com/netty/netty/issues/8942 -- SSLContext.setVerify(ctx, SSL.SSL_CVERIFY_OPTIONAL, VERIFY_DEPTH); -- -- try { -- if (trustCertCollection != null) { -- trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore); -- } else if (trustManagerFactory == null) { -- trustManagerFactory = TrustManagerFactory.getInstance( -- TrustManagerFactory.getDefaultAlgorithm()); -- trustManagerFactory.init((KeyStore) null); -- } -- final X509TrustManager manager = chooseTrustManager(trustManagerFactory.getTrustManagers()); -- -- // IMPORTANT: The callbacks set for verification must be static to prevent memory leak as -- // otherwise the context can never be collected. This is because the JNI code holds -- // a global reference to the callbacks. -- // -- // See https://github.com/netty/netty/issues/5372 -- -- setVerifyCallback(ctx, engineMap, manager); -- } catch (Exception e) { -- if (keyMaterialProvider != null) { -- keyMaterialProvider.destroy(); -- } -- throw new SSLException("unable to setup trustmanager", e); -- } -- OpenSslClientSessionContext context = new OpenSslClientSessionContext(thiz, keyMaterialProvider); -- keyMaterialProvider = null; -- return context; -- } finally { -- if (keyMaterialProvider != null) { -- keyMaterialProvider.destroy(); -- } -- } -- } -- -- @SuppressJava6Requirement(reason = "Guarded by java version check") -- private static void setVerifyCallback(long ctx, OpenSslEngineMap engineMap, X509TrustManager manager) { -- // Use this to prevent an error when running on java < 7 -- if (useExtendedTrustManager(manager)) { -- SSLContext.setCertVerifyCallback(ctx, -- new ExtendedTrustManagerVerifyCallback(engineMap, (X509ExtendedTrustManager) manager)); -- } else { -- SSLContext.setCertVerifyCallback(ctx, new TrustManagerVerifyCallback(engineMap, manager)); -- } -- } -- -- // No cache is currently supported for client side mode. -- static final class OpenSslClientSessionContext extends OpenSslSessionContext { -- OpenSslClientSessionContext(ReferenceCountedOpenSslContext context, OpenSslKeyMaterialProvider provider) { -- super(context, provider); -- } -- -- @Override -- public void setSessionTimeout(int seconds) { -- if (seconds < 0) { -- throw new IllegalArgumentException(); -- } -- } -- -- @Override -- public int getSessionTimeout() { -- return 0; -- } -- -- @Override -- public void setSessionCacheSize(int size) { -- if (size < 0) { -- throw new IllegalArgumentException(); -- } -- } -- -- @Override -- public int getSessionCacheSize() { -- return 0; -- } -- -- @Override -- public void setSessionCacheEnabled(boolean enabled) { -- // ignored -- } -- -- @Override -- public boolean isSessionCacheEnabled() { -- return false; -- } -- } -- -- private static final class TrustManagerVerifyCallback extends AbstractCertificateVerifier { -- private final X509TrustManager manager; -- -- TrustManagerVerifyCallback(OpenSslEngineMap engineMap, X509TrustManager manager) { -- super(engineMap); -- this.manager = manager; -- } -- -- @Override -- void verify(ReferenceCountedOpenSslEngine engine, X509Certificate[] peerCerts, String auth) -- throws Exception { -- manager.checkServerTrusted(peerCerts, auth); -- } -- } -- -- @SuppressJava6Requirement(reason = "Usage guarded by java version check") -- private static final class ExtendedTrustManagerVerifyCallback extends AbstractCertificateVerifier { -- private final X509ExtendedTrustManager manager; -- -- ExtendedTrustManagerVerifyCallback(OpenSslEngineMap engineMap, X509ExtendedTrustManager manager) { -- super(engineMap); -- this.manager = OpenSslTlsv13X509ExtendedTrustManager.wrap(manager); -- } -- -- @Override -- void verify(ReferenceCountedOpenSslEngine engine, X509Certificate[] peerCerts, String auth) -- throws Exception { -- manager.checkServerTrusted(peerCerts, auth, engine); -- } -- } -- -- private static final class OpenSslClientCertificateCallback implements CertificateCallback { -- private final OpenSslEngineMap engineMap; -- private final OpenSslKeyMaterialManager keyManagerHolder; -- -- OpenSslClientCertificateCallback(OpenSslEngineMap engineMap, OpenSslKeyMaterialManager keyManagerHolder) { -- this.engineMap = engineMap; -- this.keyManagerHolder = keyManagerHolder; -- } -- -- @Override -- public void handle(long ssl, byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals) throws Exception { -- final ReferenceCountedOpenSslEngine engine = engineMap.get(ssl); -- // May be null if it was destroyed in the meantime. -- if (engine == null) { -- return; -- } -- try { -- final Set keyTypesSet = supportedClientKeyTypes(keyTypeBytes); -- final String[] keyTypes = keyTypesSet.toArray(new String[0]); -- final X500Principal[] issuers; -- if (asn1DerEncodedPrincipals == null) { -- issuers = null; -- } else { -- issuers = new X500Principal[asn1DerEncodedPrincipals.length]; -- for (int i = 0; i < asn1DerEncodedPrincipals.length; i++) { -- issuers[i] = new X500Principal(asn1DerEncodedPrincipals[i]); -- } -- } -- keyManagerHolder.setKeyMaterialClientSide(engine, keyTypes, issuers); -- } catch (Throwable cause) { -- logger.debug("request of key failed", cause); -- engine.initHandshakeException(cause); -- } -- } -- -- /** -- * Gets the supported key types for client certificates. -- * -- * @param clientCertificateTypes {@code ClientCertificateType} values provided by the server. -- * See https://www.ietf.org/assignments/tls-parameters/tls-parameters.xml. -- * @return supported key types that can be used in {@code X509KeyManager.chooseClientAlias} and -- * {@code X509ExtendedKeyManager.chooseEngineClientAlias}. -- */ -- private static Set supportedClientKeyTypes(byte[] clientCertificateTypes) { -- if (clientCertificateTypes == null) { -- // Try all of the supported key types. -- return SUPPORTED_KEY_TYPES; -- } -- Set result = new HashSet(clientCertificateTypes.length); -- for (byte keyTypeCode : clientCertificateTypes) { -- String keyType = clientKeyType(keyTypeCode); -- if (keyType == null) { -- // Unsupported client key type -- ignore -- continue; -- } -- result.add(keyType); -- } -- return result; -- } -- -- private static String clientKeyType(byte clientCertificateType) { -- // See also http://www.ietf.org/assignments/tls-parameters/tls-parameters.xml -- switch (clientCertificateType) { -- case CertificateCallback.TLS_CT_RSA_SIGN: -- return OpenSslKeyMaterialManager.KEY_TYPE_RSA; // RFC rsa_sign -- case CertificateCallback.TLS_CT_RSA_FIXED_DH: -- return OpenSslKeyMaterialManager.KEY_TYPE_DH_RSA; // RFC rsa_fixed_dh -- case CertificateCallback.TLS_CT_ECDSA_SIGN: -- return OpenSslKeyMaterialManager.KEY_TYPE_EC; // RFC ecdsa_sign -- case CertificateCallback.TLS_CT_RSA_FIXED_ECDH: -- return OpenSslKeyMaterialManager.KEY_TYPE_EC_RSA; // RFC rsa_fixed_ecdh -- case CertificateCallback.TLS_CT_ECDSA_FIXED_ECDH: -- return OpenSslKeyMaterialManager.KEY_TYPE_EC_EC; // RFC ecdsa_fixed_ecdh -- default: -- return null; -- } -- } -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java -deleted file mode 100644 -index 27eb43574c..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java -+++ /dev/null -@@ -1,968 +0,0 @@ --/* -- * Copyright 2016 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.buffer.ByteBuf; --import io.netty.buffer.ByteBufAllocator; --import io.netty.internal.tcnative.CertificateVerifier; --import io.netty.internal.tcnative.SSL; --import io.netty.internal.tcnative.SSLContext; --import io.netty.internal.tcnative.SSLPrivateKeyMethod; --import io.netty.util.AbstractReferenceCounted; --import io.netty.util.ReferenceCounted; --import io.netty.util.ResourceLeakDetector; --import io.netty.util.ResourceLeakDetectorFactory; --import io.netty.util.ResourceLeakTracker; --import io.netty.util.internal.ObjectUtil; --import io.netty.util.internal.PlatformDependent; --import io.netty.util.internal.StringUtil; --import io.netty.util.internal.SuppressJava6Requirement; --import io.netty.util.internal.SystemPropertyUtil; --import io.netty.util.internal.UnstableApi; --import io.netty.util.internal.logging.InternalLogger; --import io.netty.util.internal.logging.InternalLoggerFactory; -- --import java.security.PrivateKey; --import java.security.SignatureException; --import java.security.cert.CertPathValidatorException; --import java.security.cert.Certificate; --import java.security.cert.CertificateExpiredException; --import java.security.cert.CertificateNotYetValidException; --import java.security.cert.CertificateRevokedException; --import java.security.cert.X509Certificate; --import java.util.Arrays; --import java.util.Collections; --import java.util.List; --import java.util.Map; --import java.util.concurrent.Executor; --import java.util.concurrent.locks.Lock; --import java.util.concurrent.locks.ReadWriteLock; --import java.util.concurrent.locks.ReentrantReadWriteLock; -- --import javax.net.ssl.KeyManager; --import javax.net.ssl.KeyManagerFactory; --import javax.net.ssl.SSLEngine; --import javax.net.ssl.SSLException; --import javax.net.ssl.SSLHandshakeException; --import javax.net.ssl.TrustManager; --import javax.net.ssl.X509ExtendedTrustManager; --import javax.net.ssl.X509KeyManager; --import javax.net.ssl.X509TrustManager; -- --import static io.netty.handler.ssl.OpenSsl.DEFAULT_CIPHERS; --import static io.netty.handler.ssl.OpenSsl.availableJavaCipherSuites; --import static io.netty.util.internal.ObjectUtil.checkNotNull; --import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero; -- --/** -- * An implementation of {@link SslContext} which works with libraries that support the -- * OpenSsl C library API. -- *

Instances of this class must be {@link #release() released} or else native memory will leak! -- * -- *

Instances of this class must not be released before any {@link ReferenceCountedOpenSslEngine} -- * which depends upon the instance of this class is released. Otherwise if any method of -- * {@link ReferenceCountedOpenSslEngine} is called which uses this class's JNI resources the JVM may crash. -- */ --public abstract class ReferenceCountedOpenSslContext extends SslContext implements ReferenceCounted { -- private static final InternalLogger logger = -- InternalLoggerFactory.getInstance(ReferenceCountedOpenSslContext.class); -- -- private static final int DEFAULT_BIO_NON_APPLICATION_BUFFER_SIZE = Math.max(1, -- SystemPropertyUtil.getInt("io.netty.handler.ssl.openssl.bioNonApplicationBufferSize", -- 2048)); -- static final boolean USE_TASKS = -- SystemPropertyUtil.getBoolean("io.netty.handler.ssl.openssl.useTasks", false); -- private static final Integer DH_KEY_LENGTH; -- private static final ResourceLeakDetector leakDetector = -- ResourceLeakDetectorFactory.instance().newResourceLeakDetector(ReferenceCountedOpenSslContext.class); -- -- // TODO: Maybe make configurable ? -- protected static final int VERIFY_DEPTH = 10; -- -- /** -- * The OpenSSL SSL_CTX object. -- * -- * {@link #ctxLock} must be hold while using ctx! -- */ -- protected long ctx; -- private final List unmodifiableCiphers; -- private final long sessionCacheSize; -- private final long sessionTimeout; -- private final OpenSslApplicationProtocolNegotiator apn; -- private final int mode; -- -- // Reference Counting -- private final ResourceLeakTracker leak; -- private final AbstractReferenceCounted refCnt = new AbstractReferenceCounted() { -- @Override -- public ReferenceCounted touch(Object hint) { -- if (leak != null) { -- leak.record(hint); -- } -- -- return ReferenceCountedOpenSslContext.this; -- } -- -- @Override -- protected void deallocate() { -- destroy(); -- if (leak != null) { -- boolean closed = leak.close(ReferenceCountedOpenSslContext.this); -- assert closed; -- } -- } -- }; -- -- final Certificate[] keyCertChain; -- final ClientAuth clientAuth; -- final String[] protocols; -- final boolean enableOcsp; -- final OpenSslEngineMap engineMap = new DefaultOpenSslEngineMap(); -- final ReadWriteLock ctxLock = new ReentrantReadWriteLock(); -- -- private volatile int bioNonApplicationBufferSize = DEFAULT_BIO_NON_APPLICATION_BUFFER_SIZE; -- -- @SuppressWarnings("deprecation") -- static final OpenSslApplicationProtocolNegotiator NONE_PROTOCOL_NEGOTIATOR = -- new OpenSslApplicationProtocolNegotiator() { -- @Override -- public ApplicationProtocolConfig.Protocol protocol() { -- return ApplicationProtocolConfig.Protocol.NONE; -- } -- -- @Override -- public List protocols() { -- return Collections.emptyList(); -- } -- -- @Override -- public ApplicationProtocolConfig.SelectorFailureBehavior selectorFailureBehavior() { -- return ApplicationProtocolConfig.SelectorFailureBehavior.CHOOSE_MY_LAST_PROTOCOL; -- } -- -- @Override -- public ApplicationProtocolConfig.SelectedListenerFailureBehavior selectedListenerFailureBehavior() { -- return ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT; -- } -- }; -- -- static { -- Integer dhLen = null; -- -- try { -- String dhKeySize = SystemPropertyUtil.get("jdk.tls.ephemeralDHKeySize"); -- if (dhKeySize != null) { -- try { -- dhLen = Integer.valueOf(dhKeySize); -- } catch (NumberFormatException e) { -- logger.debug("ReferenceCountedOpenSslContext supports -Djdk.tls.ephemeralDHKeySize={int}, but got: " -- + dhKeySize); -- } -- } -- } catch (Throwable ignore) { -- // ignore -- } -- DH_KEY_LENGTH = dhLen; -- } -- -- ReferenceCountedOpenSslContext(Iterable ciphers, CipherSuiteFilter cipherFilter, -- ApplicationProtocolConfig apnCfg, long sessionCacheSize, long sessionTimeout, -- int mode, Certificate[] keyCertChain, ClientAuth clientAuth, String[] protocols, -- boolean startTls, boolean enableOcsp, boolean leakDetection) throws SSLException { -- this(ciphers, cipherFilter, toNegotiator(apnCfg), sessionCacheSize, sessionTimeout, mode, keyCertChain, -- clientAuth, protocols, startTls, enableOcsp, leakDetection); -- } -- -- ReferenceCountedOpenSslContext(Iterable ciphers, CipherSuiteFilter cipherFilter, -- OpenSslApplicationProtocolNegotiator apn, long sessionCacheSize, -- long sessionTimeout, int mode, Certificate[] keyCertChain, -- ClientAuth clientAuth, String[] protocols, boolean startTls, boolean enableOcsp, -- boolean leakDetection) throws SSLException { -- super(startTls); -- -- OpenSsl.ensureAvailability(); -- -- if (enableOcsp && !OpenSsl.isOcspSupported()) { -- throw new IllegalStateException("OCSP is not supported."); -- } -- -- if (mode != SSL.SSL_MODE_SERVER && mode != SSL.SSL_MODE_CLIENT) { -- throw new IllegalArgumentException("mode most be either SSL.SSL_MODE_SERVER or SSL.SSL_MODE_CLIENT"); -- } -- leak = leakDetection ? leakDetector.track(this) : null; -- this.mode = mode; -- this.clientAuth = isServer() ? checkNotNull(clientAuth, "clientAuth") : ClientAuth.NONE; -- this.protocols = protocols; -- this.enableOcsp = enableOcsp; -- -- this.keyCertChain = keyCertChain == null ? null : keyCertChain.clone(); -- -- unmodifiableCiphers = Arrays.asList(checkNotNull(cipherFilter, "cipherFilter").filterCipherSuites( -- ciphers, DEFAULT_CIPHERS, availableJavaCipherSuites())); -- -- this.apn = checkNotNull(apn, "apn"); -- -- // Create a new SSL_CTX and configure it. -- boolean success = false; -- try { -- try { -- int protocolOpts = SSL.SSL_PROTOCOL_SSLV3 | SSL.SSL_PROTOCOL_TLSV1 | -- SSL.SSL_PROTOCOL_TLSV1_1 | SSL.SSL_PROTOCOL_TLSV1_2; -- if (OpenSsl.isTlsv13Supported()) { -- protocolOpts |= SSL.SSL_PROTOCOL_TLSV1_3; -- } -- ctx = SSLContext.make(protocolOpts, mode); -- } catch (Exception e) { -- throw new SSLException("failed to create an SSL_CTX", e); -- } -- -- boolean tlsv13Supported = OpenSsl.isTlsv13Supported(); -- StringBuilder cipherBuilder = new StringBuilder(); -- StringBuilder cipherTLSv13Builder = new StringBuilder(); -- -- /* List the ciphers that are permitted to negotiate. */ -- try { -- if (unmodifiableCiphers.isEmpty()) { -- // Set non TLSv1.3 ciphers. -- SSLContext.setCipherSuite(ctx, StringUtil.EMPTY_STRING, false); -- if (tlsv13Supported) { -- // Set TLSv1.3 ciphers. -- SSLContext.setCipherSuite(ctx, StringUtil.EMPTY_STRING, true); -- } -- } else { -- CipherSuiteConverter.convertToCipherStrings( -- unmodifiableCiphers, cipherBuilder, cipherTLSv13Builder, OpenSsl.isBoringSSL()); -- -- // Set non TLSv1.3 ciphers. -- SSLContext.setCipherSuite(ctx, cipherBuilder.toString(), false); -- if (tlsv13Supported) { -- // Set TLSv1.3 ciphers. -- SSLContext.setCipherSuite(ctx, cipherTLSv13Builder.toString(), true); -- } -- } -- } catch (SSLException e) { -- throw e; -- } catch (Exception e) { -- throw new SSLException("failed to set cipher suite: " + unmodifiableCiphers, e); -- } -- -- int options = SSLContext.getOptions(ctx) | -- SSL.SSL_OP_NO_SSLv2 | -- SSL.SSL_OP_NO_SSLv3 | -- // Disable TLSv1.3 by default for now. Even if TLSv1.3 is not supported this will -- // work fine as in this case SSL_OP_NO_TLSv1_3 will be 0. -- SSL.SSL_OP_NO_TLSv1_3 | -- -- SSL.SSL_OP_CIPHER_SERVER_PREFERENCE | -- -- // We do not support compression at the moment so we should explicitly disable it. -- SSL.SSL_OP_NO_COMPRESSION | -- -- // Disable ticket support by default to be more inline with SSLEngineImpl of the JDK. -- // This also let SSLSession.getId() work the same way for the JDK implementation and the -- // OpenSSLEngine. If tickets are supported SSLSession.getId() will only return an ID on the -- // server-side if it could make use of tickets. -- SSL.SSL_OP_NO_TICKET; -- -- if (cipherBuilder.length() == 0) { -- // No ciphers that are compatible with SSLv2 / SSLv3 / TLSv1 / TLSv1.1 / TLSv1.2 -- options |= SSL.SSL_OP_NO_SSLv2 | SSL.SSL_OP_NO_SSLv3 | SSL.SSL_OP_NO_TLSv1 -- | SSL.SSL_OP_NO_TLSv1_1 | SSL.SSL_OP_NO_TLSv1_2; -- } -- -- SSLContext.setOptions(ctx, options); -- -- // We need to enable SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER as the memory address may change between -- // calling OpenSSLEngine.wrap(...). -- // See https://github.com/netty/netty-tcnative/issues/100 -- SSLContext.setMode(ctx, SSLContext.getMode(ctx) | SSL.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); -- -- if (DH_KEY_LENGTH != null) { -- SSLContext.setTmpDHLength(ctx, DH_KEY_LENGTH); -- } -- -- List nextProtoList = apn.protocols(); -- /* Set next protocols for next protocol negotiation extension, if specified */ -- if (!nextProtoList.isEmpty()) { -- String[] appProtocols = nextProtoList.toArray(new String[0]); -- int selectorBehavior = opensslSelectorFailureBehavior(apn.selectorFailureBehavior()); -- -- switch (apn.protocol()) { -- case NPN: -- SSLContext.setNpnProtos(ctx, appProtocols, selectorBehavior); -- break; -- case ALPN: -- SSLContext.setAlpnProtos(ctx, appProtocols, selectorBehavior); -- break; -- case NPN_AND_ALPN: -- SSLContext.setNpnProtos(ctx, appProtocols, selectorBehavior); -- SSLContext.setAlpnProtos(ctx, appProtocols, selectorBehavior); -- break; -- default: -- throw new Error(); -- } -- } -- -- /* Set session cache size, if specified */ -- if (sessionCacheSize <= 0) { -- // Get the default session cache size using SSLContext.setSessionCacheSize() -- sessionCacheSize = SSLContext.setSessionCacheSize(ctx, 20480); -- } -- this.sessionCacheSize = sessionCacheSize; -- SSLContext.setSessionCacheSize(ctx, sessionCacheSize); -- -- /* Set session timeout, if specified */ -- if (sessionTimeout <= 0) { -- // Get the default session timeout using SSLContext.setSessionCacheTimeout() -- sessionTimeout = SSLContext.setSessionCacheTimeout(ctx, 300); -- } -- this.sessionTimeout = sessionTimeout; -- SSLContext.setSessionCacheTimeout(ctx, sessionTimeout); -- -- if (enableOcsp) { -- SSLContext.enableOcsp(ctx, isClient()); -- } -- -- SSLContext.setUseTasks(ctx, USE_TASKS); -- success = true; -- } finally { -- if (!success) { -- release(); -- } -- } -- } -- -- private static int opensslSelectorFailureBehavior(ApplicationProtocolConfig.SelectorFailureBehavior behavior) { -- switch (behavior) { -- case NO_ADVERTISE: -- return SSL.SSL_SELECTOR_FAILURE_NO_ADVERTISE; -- case CHOOSE_MY_LAST_PROTOCOL: -- return SSL.SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL; -- default: -- throw new Error(); -- } -- } -- -- @Override -- public final List cipherSuites() { -- return unmodifiableCiphers; -- } -- -- @Override -- public final long sessionCacheSize() { -- return sessionCacheSize; -- } -- -- @Override -- public final long sessionTimeout() { -- return sessionTimeout; -- } -- -- @Override -- public ApplicationProtocolNegotiator applicationProtocolNegotiator() { -- return apn; -- } -- -- @Override -- public final boolean isClient() { -- return mode == SSL.SSL_MODE_CLIENT; -- } -- -- @Override -- public final SSLEngine newEngine(ByteBufAllocator alloc, String peerHost, int peerPort) { -- return newEngine0(alloc, peerHost, peerPort, true); -- } -- -- @Override -- protected final SslHandler newHandler(ByteBufAllocator alloc, boolean startTls) { -- return new SslHandler(newEngine0(alloc, null, -1, false), startTls); -- } -- -- @Override -- protected final SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort, boolean startTls) { -- return new SslHandler(newEngine0(alloc, peerHost, peerPort, false), startTls); -- } -- -- @Override -- protected SslHandler newHandler(ByteBufAllocator alloc, boolean startTls, Executor executor) { -- return new SslHandler(newEngine0(alloc, null, -1, false), startTls, executor); -- } -- -- @Override -- protected SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort, -- boolean startTls, Executor executor) { -- return new SslHandler(newEngine0(alloc, peerHost, peerPort, false), executor); -- } -- -- SSLEngine newEngine0(ByteBufAllocator alloc, String peerHost, int peerPort, boolean jdkCompatibilityMode) { -- return new ReferenceCountedOpenSslEngine(this, alloc, peerHost, peerPort, jdkCompatibilityMode, true); -- } -- -- /** -- * Returns a new server-side {@link SSLEngine} with the current configuration. -- */ -- @Override -- public final SSLEngine newEngine(ByteBufAllocator alloc) { -- return newEngine(alloc, null, -1); -- } -- -- /** -- * Returns the pointer to the {@code SSL_CTX} object for this {@link ReferenceCountedOpenSslContext}. -- * Be aware that it is freed as soon as the {@link #finalize()} method is called. -- * At this point {@code 0} will be returned. -- * -- * @deprecated this method is considered unsafe as the returned pointer may be released later. Dont use it! -- */ -- @Deprecated -- public final long context() { -- return sslCtxPointer(); -- } -- -- /** -- * Returns the stats of this context. -- * -- * @deprecated use {@link #sessionContext#stats()} -- */ -- @Deprecated -- public final OpenSslSessionStats stats() { -- return sessionContext().stats(); -- } -- -- /** -- * {@deprecated Renegotiation is not supported} -- * Specify if remote initiated renegotiation is supported or not. If not supported and the remote side tries -- * to initiate a renegotiation a {@link SSLHandshakeException} will be thrown during decoding. -- */ -- @Deprecated -- public void setRejectRemoteInitiatedRenegotiation(boolean rejectRemoteInitiatedRenegotiation) { -- if (!rejectRemoteInitiatedRenegotiation) { -- throw new UnsupportedOperationException("Renegotiation is not supported"); -- } -- } -- -- /** -- * {@deprecated Renegotiation is not supported} -- * @return {@code true} because renegotiation is not supported. -- */ -- @Deprecated -- public boolean getRejectRemoteInitiatedRenegotiation() { -- return true; -- } -- -- /** -- * Set the size of the buffer used by the BIO for non-application based writes -- * (e.g. handshake, renegotiation, etc...). -- */ -- public void setBioNonApplicationBufferSize(int bioNonApplicationBufferSize) { -- this.bioNonApplicationBufferSize = -- checkPositiveOrZero(bioNonApplicationBufferSize, "bioNonApplicationBufferSize"); -- } -- -- /** -- * Returns the size of the buffer used by the BIO for non-application based writes -- */ -- public int getBioNonApplicationBufferSize() { -- return bioNonApplicationBufferSize; -- } -- -- /** -- * Sets the SSL session ticket keys of this context. -- * -- * @deprecated use {@link OpenSslSessionContext#setTicketKeys(byte[])} -- */ -- @Deprecated -- public final void setTicketKeys(byte[] keys) { -- sessionContext().setTicketKeys(keys); -- } -- -- @Override -- public abstract OpenSslSessionContext sessionContext(); -- -- /** -- * Returns the pointer to the {@code SSL_CTX} object for this {@link ReferenceCountedOpenSslContext}. -- * Be aware that it is freed as soon as the {@link #release()} method is called. -- * At this point {@code 0} will be returned. -- * -- * @deprecated this method is considered unsafe as the returned pointer may be released later. Dont use it! -- */ -- @Deprecated -- public final long sslCtxPointer() { -- Lock readerLock = ctxLock.readLock(); -- readerLock.lock(); -- try { -- return SSLContext.getSslCtx(ctx); -- } finally { -- readerLock.unlock(); -- } -- } -- -- /** -- * Set the {@link OpenSslPrivateKeyMethod} to use. This allows to offload private-key operations -- * if needed. -- * -- * This method is currently only supported when {@code BoringSSL} is used. -- * -- * @param method method to use. -- */ -- @UnstableApi -- public final void setPrivateKeyMethod(OpenSslPrivateKeyMethod method) { -- ObjectUtil.checkNotNull(method, "method"); -- Lock writerLock = ctxLock.writeLock(); -- writerLock.lock(); -- try { -- SSLContext.setPrivateKeyMethod(ctx, new PrivateKeyMethod(engineMap, method)); -- } finally { -- writerLock.unlock(); -- } -- } -- -- public final void setUseTasks(boolean useTasks) { -- Lock writerLock = ctxLock.writeLock(); -- writerLock.lock(); -- try { -- SSLContext.setUseTasks(ctx, useTasks); -- } finally { -- writerLock.unlock(); -- } -- } -- -- // IMPORTANT: This method must only be called from either the constructor or the finalizer as a user MUST never -- // get access to an OpenSslSessionContext after this method was called to prevent the user from -- // producing a segfault. -- private void destroy() { -- Lock writerLock = ctxLock.writeLock(); -- writerLock.lock(); -- try { -- if (ctx != 0) { -- if (enableOcsp) { -- SSLContext.disableOcsp(ctx); -- } -- -- SSLContext.free(ctx); -- ctx = 0; -- -- OpenSslSessionContext context = sessionContext(); -- if (context != null) { -- context.destroy(); -- } -- } -- } finally { -- writerLock.unlock(); -- } -- } -- -- protected static X509Certificate[] certificates(byte[][] chain) { -- X509Certificate[] peerCerts = new X509Certificate[chain.length]; -- for (int i = 0; i < peerCerts.length; i++) { -- peerCerts[i] = new OpenSslX509Certificate(chain[i]); -- } -- return peerCerts; -- } -- -- protected static X509TrustManager chooseTrustManager(TrustManager[] managers) { -- for (TrustManager m : managers) { -- if (m instanceof X509TrustManager) { -- if (PlatformDependent.javaVersion() >= 7) { -- return OpenSslX509TrustManagerWrapper.wrapIfNeeded((X509TrustManager) m); -- } -- return (X509TrustManager) m; -- } -- } -- throw new IllegalStateException("no X509TrustManager found"); -- } -- -- protected static X509KeyManager chooseX509KeyManager(KeyManager[] kms) { -- for (KeyManager km : kms) { -- if (km instanceof X509KeyManager) { -- return (X509KeyManager) km; -- } -- } -- throw new IllegalStateException("no X509KeyManager found"); -- } -- -- /** -- * Translate a {@link ApplicationProtocolConfig} object to a -- * {@link OpenSslApplicationProtocolNegotiator} object. -- * -- * @param config The configuration which defines the translation -- * @return The results of the translation -- */ -- @SuppressWarnings("deprecation") -- static OpenSslApplicationProtocolNegotiator toNegotiator(ApplicationProtocolConfig config) { -- if (config == null) { -- return NONE_PROTOCOL_NEGOTIATOR; -- } -- -- switch (config.protocol()) { -- case NONE: -- return NONE_PROTOCOL_NEGOTIATOR; -- case ALPN: -- case NPN: -- case NPN_AND_ALPN: -- switch (config.selectedListenerFailureBehavior()) { -- case CHOOSE_MY_LAST_PROTOCOL: -- case ACCEPT: -- switch (config.selectorFailureBehavior()) { -- case CHOOSE_MY_LAST_PROTOCOL: -- case NO_ADVERTISE: -- return new OpenSslDefaultApplicationProtocolNegotiator( -- config); -- default: -- throw new UnsupportedOperationException( -- new StringBuilder("OpenSSL provider does not support ") -- .append(config.selectorFailureBehavior()) -- .append(" behavior").toString()); -- } -- default: -- throw new UnsupportedOperationException( -- new StringBuilder("OpenSSL provider does not support ") -- .append(config.selectedListenerFailureBehavior()) -- .append(" behavior").toString()); -- } -- default: -- throw new Error(); -- } -- } -- -- @SuppressJava6Requirement(reason = "Guarded by java version check") -- static boolean useExtendedTrustManager(X509TrustManager trustManager) { -- return PlatformDependent.javaVersion() >= 7 && trustManager instanceof X509ExtendedTrustManager; -- } -- -- @Override -- public final int refCnt() { -- return refCnt.refCnt(); -- } -- -- @Override -- public final ReferenceCounted retain() { -- refCnt.retain(); -- return this; -- } -- -- @Override -- public final ReferenceCounted retain(int increment) { -- refCnt.retain(increment); -- return this; -- } -- -- @Override -- public final ReferenceCounted touch() { -- refCnt.touch(); -- return this; -- } -- -- @Override -- public final ReferenceCounted touch(Object hint) { -- refCnt.touch(hint); -- return this; -- } -- -- @Override -- public final boolean release() { -- return refCnt.release(); -- } -- -- @Override -- public final boolean release(int decrement) { -- return refCnt.release(decrement); -- } -- -- abstract static class AbstractCertificateVerifier extends CertificateVerifier { -- private final OpenSslEngineMap engineMap; -- -- AbstractCertificateVerifier(OpenSslEngineMap engineMap) { -- this.engineMap = engineMap; -- } -- -- @Override -- public final int verify(long ssl, byte[][] chain, String auth) { -- final ReferenceCountedOpenSslEngine engine = engineMap.get(ssl); -- if (engine == null) { -- // May be null if it was destroyed in the meantime. -- return CertificateVerifier.X509_V_ERR_UNSPECIFIED; -- } -- X509Certificate[] peerCerts = certificates(chain); -- try { -- verify(engine, peerCerts, auth); -- return CertificateVerifier.X509_V_OK; -- } catch (Throwable cause) { -- logger.debug("verification of certificate failed", cause); -- engine.initHandshakeException(cause); -- -- // Try to extract the correct error code that should be used. -- if (cause instanceof OpenSslCertificateException) { -- // This will never return a negative error code as its validated when constructing the -- // OpenSslCertificateException. -- return ((OpenSslCertificateException) cause).errorCode(); -- } -- if (cause instanceof CertificateExpiredException) { -- return CertificateVerifier.X509_V_ERR_CERT_HAS_EXPIRED; -- } -- if (cause instanceof CertificateNotYetValidException) { -- return CertificateVerifier.X509_V_ERR_CERT_NOT_YET_VALID; -- } -- if (PlatformDependent.javaVersion() >= 7) { -- return translateToError(cause); -- } -- -- // Could not detect a specific error code to use, so fallback to a default code. -- return CertificateVerifier.X509_V_ERR_UNSPECIFIED; -- } -- } -- -- @SuppressJava6Requirement(reason = "Usage guarded by java version check") -- private static int translateToError(Throwable cause) { -- if (cause instanceof CertificateRevokedException) { -- return CertificateVerifier.X509_V_ERR_CERT_REVOKED; -- } -- -- // The X509TrustManagerImpl uses a Validator which wraps a CertPathValidatorException into -- // an CertificateException. So we need to handle the wrapped CertPathValidatorException to be -- // able to send the correct alert. -- Throwable wrapped = cause.getCause(); -- while (wrapped != null) { -- if (wrapped instanceof CertPathValidatorException) { -- CertPathValidatorException ex = (CertPathValidatorException) wrapped; -- CertPathValidatorException.Reason reason = ex.getReason(); -- if (reason == CertPathValidatorException.BasicReason.EXPIRED) { -- return CertificateVerifier.X509_V_ERR_CERT_HAS_EXPIRED; -- } -- if (reason == CertPathValidatorException.BasicReason.NOT_YET_VALID) { -- return CertificateVerifier.X509_V_ERR_CERT_NOT_YET_VALID; -- } -- if (reason == CertPathValidatorException.BasicReason.REVOKED) { -- return CertificateVerifier.X509_V_ERR_CERT_REVOKED; -- } -- } -- wrapped = wrapped.getCause(); -- } -- return CertificateVerifier.X509_V_ERR_UNSPECIFIED; -- } -- -- abstract void verify(ReferenceCountedOpenSslEngine engine, X509Certificate[] peerCerts, -- String auth) throws Exception; -- } -- -- private static final class DefaultOpenSslEngineMap implements OpenSslEngineMap { -- private final Map engines = PlatformDependent.newConcurrentHashMap(); -- -- @Override -- public ReferenceCountedOpenSslEngine remove(long ssl) { -- return engines.remove(ssl); -- } -- -- @Override -- public void add(ReferenceCountedOpenSslEngine engine) { -- engines.put(engine.sslPointer(), engine); -- } -- -- @Override -- public ReferenceCountedOpenSslEngine get(long ssl) { -- return engines.get(ssl); -- } -- } -- -- static void setKeyMaterial(long ctx, X509Certificate[] keyCertChain, PrivateKey key, String keyPassword) -- throws SSLException { -- /* Load the certificate file and private key. */ -- long keyBio = 0; -- long keyCertChainBio = 0; -- long keyCertChainBio2 = 0; -- PemEncoded encoded = null; -- try { -- // Only encode one time -- encoded = PemX509Certificate.toPEM(ByteBufAllocator.DEFAULT, true, keyCertChain); -- keyCertChainBio = toBIO(ByteBufAllocator.DEFAULT, encoded.retain()); -- keyCertChainBio2 = toBIO(ByteBufAllocator.DEFAULT, encoded.retain()); -- -- if (key != null) { -- keyBio = toBIO(ByteBufAllocator.DEFAULT, key); -- } -- -- SSLContext.setCertificateBio( -- ctx, keyCertChainBio, keyBio, -- keyPassword == null ? StringUtil.EMPTY_STRING : keyPassword); -- // We may have more then one cert in the chain so add all of them now. -- SSLContext.setCertificateChainBio(ctx, keyCertChainBio2, true); -- } catch (SSLException e) { -- throw e; -- } catch (Exception e) { -- throw new SSLException("failed to set certificate and key", e); -- } finally { -- freeBio(keyBio); -- freeBio(keyCertChainBio); -- freeBio(keyCertChainBio2); -- if (encoded != null) { -- encoded.release(); -- } -- } -- } -- -- static void freeBio(long bio) { -- if (bio != 0) { -- SSL.freeBIO(bio); -- } -- } -- -- /** -- * Return the pointer to a in-memory BIO -- * or {@code 0} if the {@code key} is {@code null}. The BIO contains the content of the {@code key}. -- */ -- static long toBIO(ByteBufAllocator allocator, PrivateKey key) throws Exception { -- if (key == null) { -- return 0; -- } -- -- PemEncoded pem = PemPrivateKey.toPEM(allocator, true, key); -- try { -- return toBIO(allocator, pem.retain()); -- } finally { -- pem.release(); -- } -- } -- -- /** -- * Return the pointer to a in-memory BIO -- * or {@code 0} if the {@code certChain} is {@code null}. The BIO contains the content of the {@code certChain}. -- */ -- static long toBIO(ByteBufAllocator allocator, X509Certificate... certChain) throws Exception { -- if (certChain == null) { -- return 0; -- } -- -- if (certChain.length == 0) { -- throw new IllegalArgumentException("certChain can't be empty"); -- } -- -- PemEncoded pem = PemX509Certificate.toPEM(allocator, true, certChain); -- try { -- return toBIO(allocator, pem.retain()); -- } finally { -- pem.release(); -- } -- } -- -- static long toBIO(ByteBufAllocator allocator, PemEncoded pem) throws Exception { -- try { -- // We can turn direct buffers straight into BIOs. No need to -- // make a yet another copy. -- ByteBuf content = pem.content(); -- -- if (content.isDirect()) { -- return newBIO(content.retainedSlice()); -- } -- -- ByteBuf buffer = allocator.directBuffer(content.readableBytes()); -- try { -- buffer.writeBytes(content, content.readerIndex(), content.readableBytes()); -- return newBIO(buffer.retainedSlice()); -- } finally { -- try { -- // If the contents of the ByteBuf is sensitive (e.g. a PrivateKey) we -- // need to zero out the bytes of the copy before we're releasing it. -- if (pem.isSensitive()) { -- SslUtils.zeroout(buffer); -- } -- } finally { -- buffer.release(); -- } -- } -- } finally { -- pem.release(); -- } -- } -- -- private static long newBIO(ByteBuf buffer) throws Exception { -- try { -- long bio = SSL.newMemBIO(); -- int readable = buffer.readableBytes(); -- if (SSL.bioWrite(bio, OpenSsl.memoryAddress(buffer) + buffer.readerIndex(), readable) != readable) { -- SSL.freeBIO(bio); -- throw new IllegalStateException("Could not write data to memory BIO"); -- } -- return bio; -- } finally { -- buffer.release(); -- } -- } -- -- /** -- * Returns the {@link OpenSslKeyMaterialProvider} that should be used for OpenSSL. Depending on the given -- * {@link KeyManagerFactory} this may cache the {@link OpenSslKeyMaterial} for better performance if it can -- * ensure that the same material is always returned for the same alias. -- */ -- static OpenSslKeyMaterialProvider providerFor(KeyManagerFactory factory, String password) { -- if (factory instanceof OpenSslX509KeyManagerFactory) { -- return ((OpenSslX509KeyManagerFactory) factory).newProvider(); -- } -- -- if (factory instanceof OpenSslCachingX509KeyManagerFactory) { -- // The user explicit used OpenSslCachingX509KeyManagerFactory which signals us that its fine to cache. -- return ((OpenSslCachingX509KeyManagerFactory) factory).newProvider(password); -- } -- // We can not be sure if the material may change at runtime so we will not cache it. -- return new OpenSslKeyMaterialProvider(chooseX509KeyManager(factory.getKeyManagers()), password); -- } -- -- private static final class PrivateKeyMethod implements SSLPrivateKeyMethod { -- -- private final OpenSslEngineMap engineMap; -- private final OpenSslPrivateKeyMethod keyMethod; -- PrivateKeyMethod(OpenSslEngineMap engineMap, OpenSslPrivateKeyMethod keyMethod) { -- this.engineMap = engineMap; -- this.keyMethod = keyMethod; -- } -- -- private ReferenceCountedOpenSslEngine retrieveEngine(long ssl) throws SSLException { -- ReferenceCountedOpenSslEngine engine = engineMap.get(ssl); -- if (engine == null) { -- throw new SSLException("Could not find a " + -- StringUtil.simpleClassName(ReferenceCountedOpenSslEngine.class) + " for sslPointer " + ssl); -- } -- return engine; -- } -- -- @Override -- public byte[] sign(long ssl, int signatureAlgorithm, byte[] digest) throws Exception { -- ReferenceCountedOpenSslEngine engine = retrieveEngine(ssl); -- try { -- return verifyResult(keyMethod.sign(engine, signatureAlgorithm, digest)); -- } catch (Exception e) { -- engine.initHandshakeException(e); -- throw e; -- } -- } -- -- @Override -- public byte[] decrypt(long ssl, byte[] input) throws Exception { -- ReferenceCountedOpenSslEngine engine = retrieveEngine(ssl); -- try { -- return verifyResult(keyMethod.decrypt(engine, input)); -- } catch (Exception e) { -- engine.initHandshakeException(e); -- throw e; -- } -- } -- -- private static byte[] verifyResult(byte[] result) throws SignatureException { -- if (result == null) { -- throw new SignatureException(); -- } -- return result; -- } -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java -deleted file mode 100644 -index b404a1076b..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java -+++ /dev/null -@@ -1,2467 +0,0 @@ --/* -- * Copyright 2016 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.buffer.ByteBuf; --import io.netty.buffer.ByteBufAllocator; --import io.netty.internal.tcnative.Buffer; --import io.netty.internal.tcnative.SSL; --import io.netty.util.AbstractReferenceCounted; --import io.netty.util.CharsetUtil; --import io.netty.util.ReferenceCounted; --import io.netty.util.ResourceLeakDetector; --import io.netty.util.ResourceLeakDetectorFactory; --import io.netty.util.ResourceLeakTracker; --import io.netty.util.internal.EmptyArrays; --import io.netty.util.internal.ObjectUtil; --import io.netty.util.internal.PlatformDependent; --import io.netty.util.internal.StringUtil; --import io.netty.util.internal.SuppressJava6Requirement; --import io.netty.util.internal.ThrowableUtil; --import io.netty.util.internal.UnstableApi; --import io.netty.util.internal.logging.InternalLogger; --import io.netty.util.internal.logging.InternalLoggerFactory; -- --import java.nio.ByteBuffer; --import java.nio.ReadOnlyBufferException; --import java.security.Principal; --import java.security.cert.Certificate; --import java.util.ArrayList; --import java.util.Arrays; --import java.util.Collection; --import java.util.Collections; --import java.util.HashMap; --import java.util.LinkedHashSet; --import java.util.List; --import java.util.Map; --import java.util.Set; --import java.util.concurrent.locks.Lock; -- --import javax.crypto.spec.SecretKeySpec; --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.SSLPeerUnverifiedException; --import javax.net.ssl.SSLSession; --import javax.net.ssl.SSLSessionBindingEvent; --import javax.net.ssl.SSLSessionBindingListener; --import javax.net.ssl.SSLSessionContext; --import javax.security.cert.X509Certificate; -- --import static io.netty.handler.ssl.OpenSsl.memoryAddress; --import static io.netty.handler.ssl.SslUtils.PROTOCOL_SSL_V2; --import static io.netty.handler.ssl.SslUtils.PROTOCOL_SSL_V2_HELLO; --import static io.netty.handler.ssl.SslUtils.PROTOCOL_SSL_V3; --import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1; --import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1_1; --import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1_2; --import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1_3; --import static io.netty.handler.ssl.SslUtils.SSL_RECORD_HEADER_LENGTH; --import static io.netty.util.internal.ObjectUtil.checkNotNull; --import static java.lang.Integer.MAX_VALUE; --import static java.lang.Math.min; --import static javax.net.ssl.SSLEngineResult.HandshakeStatus.FINISHED; --import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_TASK; --import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_UNWRAP; --import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_WRAP; --import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING; --import static javax.net.ssl.SSLEngineResult.Status.BUFFER_OVERFLOW; --import static javax.net.ssl.SSLEngineResult.Status.BUFFER_UNDERFLOW; --import static javax.net.ssl.SSLEngineResult.Status.CLOSED; --import static javax.net.ssl.SSLEngineResult.Status.OK; -- --/** -- * Implements a {@link SSLEngine} using -- * OpenSSL BIO abstractions. -- *

Instances of this class must be {@link #release() released} or else native memory will leak! -- * -- *

Instances of this class must be released before the {@link ReferenceCountedOpenSslContext} -- * 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, ApplicationProtocolAccessor { -- -- private static final InternalLogger logger = InternalLoggerFactory.getInstance(ReferenceCountedOpenSslEngine.class); -- -- private static final ResourceLeakDetector leakDetector = -- ResourceLeakDetectorFactory.instance().newResourceLeakDetector(ReferenceCountedOpenSslEngine.class); -- private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV2 = 0; -- private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV3 = 1; -- private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1 = 2; -- private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_1 = 3; -- private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_2 = 4; -- private static final int OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_3 = 5; -- private static final int[] OPENSSL_OP_NO_PROTOCOLS = { -- SSL.SSL_OP_NO_SSLv2, -- SSL.SSL_OP_NO_SSLv3, -- SSL.SSL_OP_NO_TLSv1, -- SSL.SSL_OP_NO_TLSv1_1, -- SSL.SSL_OP_NO_TLSv1_2, -- SSL.SSL_OP_NO_TLSv1_3 -- }; -- -- /** -- * Depends upon tcnative ... only use if tcnative is available! -- */ -- static final int MAX_PLAINTEXT_LENGTH = SSL.SSL_MAX_PLAINTEXT_LENGTH; -- /** -- * Depends upon tcnative ... only use if tcnative is available! -- */ -- private static final int MAX_RECORD_SIZE = SSL.SSL_MAX_RECORD_LENGTH; -- -- private static final SSLEngineResult NEED_UNWRAP_OK = new SSLEngineResult(OK, NEED_UNWRAP, 0, 0); -- private static final SSLEngineResult NEED_UNWRAP_CLOSED = new SSLEngineResult(CLOSED, NEED_UNWRAP, 0, 0); -- private static final SSLEngineResult NEED_WRAP_OK = new SSLEngineResult(OK, NEED_WRAP, 0, 0); -- private static final SSLEngineResult NEED_WRAP_CLOSED = new SSLEngineResult(CLOSED, NEED_WRAP, 0, 0); -- private static final SSLEngineResult CLOSED_NOT_HANDSHAKING = new SSLEngineResult(CLOSED, NOT_HANDSHAKING, 0, 0); -- -- // OpenSSL state -- private long ssl; -- private long networkBIO; -- -- private enum HandshakeState { -- /** -- * Not started yet. -- */ -- NOT_STARTED, -- /** -- * Started via unwrap/wrap. -- */ -- STARTED_IMPLICITLY, -- /** -- * Started via {@link #beginHandshake()}. -- */ -- STARTED_EXPLICITLY, -- /** -- * Handshake is finished. -- */ -- FINISHED -- } -- -- private HandshakeState handshakeState = HandshakeState.NOT_STARTED; -- private boolean receivedShutdown; -- private volatile boolean destroyed; -- private volatile String applicationProtocol; -- private volatile boolean needTask; -- -- // Reference Counting -- private final ResourceLeakTracker leak; -- private final AbstractReferenceCounted refCnt = new AbstractReferenceCounted() { -- @Override -- public ReferenceCounted touch(Object hint) { -- if (leak != null) { -- leak.record(hint); -- } -- -- return ReferenceCountedOpenSslEngine.this; -- } -- -- @Override -- protected void deallocate() { -- shutdown(); -- if (leak != null) { -- boolean closed = leak.close(ReferenceCountedOpenSslEngine.this); -- assert closed; -- } -- parentContext.release(); -- } -- }; -- -- private volatile ClientAuth clientAuth = ClientAuth.NONE; -- private volatile Certificate[] localCertificateChain; -- -- // Updated once a new handshake is started and so the SSLSession reused. -- private volatile long lastAccessed = -1; -- -- private String endPointIdentificationAlgorithm; -- // Store as object as AlgorithmConstraints only exists since java 7. -- private Object algorithmConstraints; -- private List sniHostNames; -- -- // Mark as volatile as accessed by checkSniHostnameMatch(...) and also not specify the SNIMatcher type to allow us -- // using it with java7. -- private volatile Collection matchers; -- -- // SSL Engine status variables -- private boolean isInboundDone; -- private boolean outboundClosed; -- -- final boolean jdkCompatibilityMode; -- private final boolean clientMode; -- final ByteBufAllocator alloc; -- private final OpenSslEngineMap engineMap; -- private final OpenSslApplicationProtocolNegotiator apn; -- private final ReferenceCountedOpenSslContext parentContext; -- private final OpenSslSession session; -- private final ByteBuffer[] singleSrcBuffer = new ByteBuffer[1]; -- private final ByteBuffer[] singleDstBuffer = new ByteBuffer[1]; -- private final boolean enableOcsp; -- private int maxWrapOverhead; -- private int maxWrapBufferSize; -- private Throwable pendingException; -- -- /** -- * Create a new instance. -- * @param context Reference count release responsibility is not transferred! The callee still owns this object. -- * @param alloc The allocator to use. -- * @param peerHost The peer host name. -- * @param peerPort The peer port. -- * @param jdkCompatibilityMode {@code true} to behave like described in -- * https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLEngine.html. -- * {@code false} allows for partial and/or multiple packets to be process in a single -- * wrap or unwrap call. -- * @param leakDetection {@code true} to enable leak detection of this object. -- */ -- ReferenceCountedOpenSslEngine(ReferenceCountedOpenSslContext context, final ByteBufAllocator alloc, String peerHost, -- int peerPort, boolean jdkCompatibilityMode, boolean leakDetection) { -- super(peerHost, peerPort); -- OpenSsl.ensureAvailability(); -- this.alloc = checkNotNull(alloc, "alloc"); -- apn = (OpenSslApplicationProtocolNegotiator) context.applicationProtocolNegotiator(); -- clientMode = context.isClient(); -- if (PlatformDependent.javaVersion() >= 7) { -- session = new ExtendedOpenSslSession(new DefaultOpenSslSession(context.sessionContext())) { -- private String[] peerSupportedSignatureAlgorithms; -- private List requestedServerNames; -- -- @Override -- public List getRequestedServerNames() { -- if (clientMode) { -- return Java8SslUtils.getSniHostNames(sniHostNames); -- } else { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (requestedServerNames == null) { -- if (isDestroyed()) { -- requestedServerNames = Collections.emptyList(); -- } else { -- String name = SSL.getSniHostname(ssl); -- if (name == null) { -- requestedServerNames = Collections.emptyList(); -- } else { -- // Convert to bytes as we do not want to do any strict validation of the -- // SNIHostName while creating it. -- requestedServerNames = -- Java8SslUtils.getSniHostName( -- SSL.getSniHostname(ssl).getBytes(CharsetUtil.UTF_8)); -- } -- } -- } -- return requestedServerNames; -- } -- } -- } -- -- @Override -- public String[] getPeerSupportedSignatureAlgorithms() { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (peerSupportedSignatureAlgorithms == null) { -- if (isDestroyed()) { -- peerSupportedSignatureAlgorithms = EmptyArrays.EMPTY_STRINGS; -- } else { -- String[] algs = SSL.getSigAlgs(ssl); -- if (algs == null) { -- peerSupportedSignatureAlgorithms = EmptyArrays.EMPTY_STRINGS; -- } else { -- Set algorithmList = new LinkedHashSet(algs.length); -- for (String alg: algs) { -- String converted = SignatureAlgorithmConverter.toJavaName(alg); -- -- if (converted != null) { -- algorithmList.add(converted); -- } -- } -- peerSupportedSignatureAlgorithms = algorithmList.toArray(new String[0]); -- } -- } -- } -- return peerSupportedSignatureAlgorithms.clone(); -- } -- } -- -- @Override -- public List getStatusResponses() { -- byte[] ocspResponse = null; -- if (enableOcsp && clientMode) { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (!isDestroyed()) { -- ocspResponse = SSL.getOcspResponse(ssl); -- } -- } -- } -- return ocspResponse == null ? -- Collections.emptyList() : Collections.singletonList(ocspResponse); -- } -- }; -- } else { -- session = new DefaultOpenSslSession(context.sessionContext()); -- } -- engineMap = context.engineMap; -- enableOcsp = context.enableOcsp; -- if (!context.sessionContext().useKeyManager()) { -- // If we do not use the KeyManagerFactory we need to set localCertificateChain now. -- // When we use a KeyManagerFactory it will be set during setKeyMaterial(...). -- localCertificateChain = context.keyCertChain; -- } -- -- this.jdkCompatibilityMode = jdkCompatibilityMode; -- Lock readerLock = context.ctxLock.readLock(); -- readerLock.lock(); -- final long finalSsl; -- try { -- finalSsl = SSL.newSSL(context.ctx, !context.isClient()); -- } finally { -- readerLock.unlock(); -- } -- synchronized (this) { -- ssl = finalSsl; -- try { -- networkBIO = SSL.bioNewByteBuffer(ssl, context.getBioNonApplicationBufferSize()); -- -- // Set the client auth mode, this needs to be done via setClientAuth(...) method so we actually call the -- // needed JNI methods. -- setClientAuth(clientMode ? ClientAuth.NONE : context.clientAuth); -- -- if (context.protocols != null) { -- setEnabledProtocols(context.protocols); -- } -- -- // Use SNI if peerHost was specified and a valid hostname -- // See https://github.com/netty/netty/issues/4746 -- if (clientMode && SslUtils.isValidHostNameForSNI(peerHost)) { -- SSL.setTlsExtHostName(ssl, peerHost); -- sniHostNames = Collections.singletonList(peerHost); -- } -- -- if (enableOcsp) { -- SSL.enableOcsp(ssl); -- } -- -- if (!jdkCompatibilityMode) { -- SSL.setMode(ssl, SSL.getMode(ssl) | SSL.SSL_MODE_ENABLE_PARTIAL_WRITE); -- } -- -- // setMode may impact the overhead. -- calculateMaxWrapOverhead(); -- } catch (Throwable cause) { -- // Call shutdown so we are sure we correctly release all native memory and also guard against the -- // case when shutdown() will be called by the finalizer again. -- shutdown(); -- -- PlatformDependent.throwException(cause); -- } -- } -- -- // Now that everything looks good and we're going to successfully return the -- // object so we need to retain a reference to the parent context. -- parentContext = context; -- parentContext.retain(); -- -- // Only create the leak after everything else was executed and so ensure we don't produce a false-positive for -- // the ResourceLeakDetector. -- leak = leakDetection ? leakDetector.track(this) : null; -- } -- -- final synchronized String[] authMethods() { -- if (isDestroyed()) { -- return EmptyArrays.EMPTY_STRINGS; -- } -- return SSL.authenticationMethods(ssl); -- } -- -- final boolean setKeyMaterial(OpenSslKeyMaterial keyMaterial) throws Exception { -- synchronized (this) { -- if (isDestroyed()) { -- return false; -- } -- SSL.setKeyMaterial(ssl, keyMaterial.certificateChainAddress(), keyMaterial.privateKeyAddress()); -- } -- localCertificateChain = keyMaterial.certificateChain(); -- return true; -- } -- -- final synchronized SecretKeySpec masterKey() { -- if (isDestroyed()) { -- return null; -- } -- return new SecretKeySpec(SSL.getMasterKey(ssl), "AES"); -- } -- -- /** -- * Sets the OCSP response. -- */ -- @UnstableApi -- public void setOcspResponse(byte[] response) { -- if (!enableOcsp) { -- throw new IllegalStateException("OCSP stapling is not enabled"); -- } -- -- if (clientMode) { -- throw new IllegalStateException("Not a server SSLEngine"); -- } -- -- synchronized (this) { -- if (!isDestroyed()) { -- SSL.setOcspResponse(ssl, response); -- } -- } -- } -- -- /** -- * Returns the OCSP response or {@code null} if the server didn't provide a stapled OCSP response. -- */ -- @UnstableApi -- public byte[] getOcspResponse() { -- if (!enableOcsp) { -- throw new IllegalStateException("OCSP stapling is not enabled"); -- } -- -- if (!clientMode) { -- throw new IllegalStateException("Not a client SSLEngine"); -- } -- -- synchronized (this) { -- if (isDestroyed()) { -- return EmptyArrays.EMPTY_BYTES; -- } -- return SSL.getOcspResponse(ssl); -- } -- } -- -- @Override -- public final int refCnt() { -- return refCnt.refCnt(); -- } -- -- @Override -- public final ReferenceCounted retain() { -- refCnt.retain(); -- return this; -- } -- -- @Override -- public final ReferenceCounted retain(int increment) { -- refCnt.retain(increment); -- return this; -- } -- -- @Override -- public final ReferenceCounted touch() { -- refCnt.touch(); -- return this; -- } -- -- @Override -- public final ReferenceCounted touch(Object hint) { -- refCnt.touch(hint); -- return this; -- } -- -- @Override -- public final boolean release() { -- return refCnt.release(); -- } -- -- @Override -- public final boolean release(int decrement) { -- return refCnt.release(decrement); -- } -- -- @Override -- public final synchronized SSLSession getHandshakeSession() { -- // Javadocs state return value should be: -- // null if this instance is not currently handshaking, or if the current handshake has not -- // progressed far enough to create a basic SSLSession. Otherwise, this method returns the -- // SSLSession currently being negotiated. -- switch(handshakeState) { -- case NOT_STARTED: -- case FINISHED: -- return null; -- default: -- return session; -- } -- } -- -- /** -- * Returns the pointer to the {@code SSL} object for this {@link ReferenceCountedOpenSslEngine}. -- * Be aware that it is freed as soon as the {@link #release()} or {@link #shutdown()} methods are called. -- * At this point {@code 0} will be returned. -- */ -- public final synchronized long sslPointer() { -- return ssl; -- } -- -- /** -- * Destroys this engine. -- */ -- public final synchronized void shutdown() { -- if (!destroyed) { -- destroyed = true; -- engineMap.remove(ssl); -- SSL.freeSSL(ssl); -- ssl = networkBIO = 0; -- -- isInboundDone = outboundClosed = true; -- } -- -- // On shutdown clear all errors -- SSL.clearError(); -- } -- -- /** -- * Write plaintext data to the OpenSSL internal BIO -- * -- * Calling this function with src.remaining == 0 is undefined. -- */ -- private int writePlaintextData(final ByteBuffer src, int len) { -- final int pos = src.position(); -- final int limit = src.limit(); -- final int sslWrote; -- -- if (src.isDirect()) { -- sslWrote = SSL.writeToSSL(ssl, bufferAddress(src) + pos, len); -- if (sslWrote > 0) { -- src.position(pos + sslWrote); -- } -- } else { -- ByteBuf buf = alloc.directBuffer(len); -- try { -- src.limit(pos + len); -- -- buf.setBytes(0, src); -- src.limit(limit); -- -- sslWrote = SSL.writeToSSL(ssl, memoryAddress(buf), len); -- if (sslWrote > 0) { -- src.position(pos + sslWrote); -- } else { -- src.position(pos); -- } -- } finally { -- buf.release(); -- } -- } -- return sslWrote; -- } -- -- /** -- * Write encrypted data to the OpenSSL network BIO. -- */ -- private ByteBuf writeEncryptedData(final ByteBuffer src, int len) { -- final int pos = src.position(); -- if (src.isDirect()) { -- SSL.bioSetByteBuffer(networkBIO, bufferAddress(src) + pos, len, false); -- } else { -- final ByteBuf buf = alloc.directBuffer(len); -- try { -- final int limit = src.limit(); -- src.limit(pos + len); -- buf.writeBytes(src); -- // Restore the original position and limit because we don't want to consume from `src`. -- src.position(pos); -- src.limit(limit); -- -- SSL.bioSetByteBuffer(networkBIO, memoryAddress(buf), len, false); -- return buf; -- } catch (Throwable cause) { -- buf.release(); -- PlatformDependent.throwException(cause); -- } -- } -- return null; -- } -- -- /** -- * Read plaintext data from the OpenSSL internal BIO -- */ -- private int readPlaintextData(final ByteBuffer dst) { -- final int sslRead; -- final int pos = dst.position(); -- if (dst.isDirect()) { -- sslRead = SSL.readFromSSL(ssl, bufferAddress(dst) + pos, dst.limit() - pos); -- if (sslRead > 0) { -- dst.position(pos + sslRead); -- } -- } else { -- final int limit = dst.limit(); -- final int len = min(maxEncryptedPacketLength0(), limit - pos); -- final ByteBuf buf = alloc.directBuffer(len); -- try { -- sslRead = SSL.readFromSSL(ssl, memoryAddress(buf), len); -- if (sslRead > 0) { -- dst.limit(pos + sslRead); -- buf.getBytes(buf.readerIndex(), dst); -- dst.limit(limit); -- } -- } finally { -- buf.release(); -- } -- } -- -- return sslRead; -- } -- -- /** -- * Visible only for testing! -- */ -- final synchronized int maxWrapOverhead() { -- return maxWrapOverhead; -- } -- -- /** -- * Visible only for testing! -- */ -- final synchronized int maxEncryptedPacketLength() { -- return maxEncryptedPacketLength0(); -- } -- -- /** -- * This method is intentionally not synchronized, only use if you know you are in the EventLoop -- * thread and visibility on {@link #maxWrapOverhead} is achieved via other synchronized blocks. -- */ -- final int maxEncryptedPacketLength0() { -- return maxWrapOverhead + MAX_PLAINTEXT_LENGTH; -- } -- -- /** -- * This method is intentionally not synchronized, only use if you know you are in the EventLoop -- * thread and visibility on {@link #maxWrapBufferSize} and {@link #maxWrapOverhead} is achieved -- * via other synchronized blocks. -- */ -- final int calculateMaxLengthForWrap(int plaintextLength, int numComponents) { -- return (int) min(maxWrapBufferSize, plaintextLength + (long) maxWrapOverhead * numComponents); -- } -- -- final synchronized int sslPending() { -- return sslPending0(); -- } -- -- /** -- * It is assumed this method is called in a synchronized block (or the constructor)! -- */ -- private void calculateMaxWrapOverhead() { -- maxWrapOverhead = SSL.getMaxWrapOverhead(ssl); -- -- // maxWrapBufferSize must be set after maxWrapOverhead because there is a dependency on this value. -- // If jdkCompatibility mode is off we allow enough space to encrypt 16 buffers at a time. This could be -- // configurable in the future if necessary. -- maxWrapBufferSize = jdkCompatibilityMode ? maxEncryptedPacketLength0() : maxEncryptedPacketLength0() << 4; -- } -- -- private int sslPending0() { -- // OpenSSL has a limitation where if you call SSL_pending before the handshake is complete OpenSSL will throw a -- // "called a function you should not call" error. Using the TLS_method instead of SSLv23_method may solve this -- // issue but this API is only available in 1.1.0+ [1]. -- // [1] https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_new.html -- return handshakeState != HandshakeState.FINISHED ? 0 : SSL.sslPending(ssl); -- } -- -- private boolean isBytesAvailableEnoughForWrap(int bytesAvailable, int plaintextLength, int numComponents) { -- return bytesAvailable - (long) maxWrapOverhead * numComponents >= plaintextLength; -- } -- -- @Override -- public final SSLEngineResult wrap( -- final ByteBuffer[] srcs, int offset, final int length, final ByteBuffer dst) throws SSLException { -- // Throw required runtime exceptions -- if (srcs == null) { -- throw new IllegalArgumentException("srcs is null"); -- } -- if (dst == null) { -- throw new IllegalArgumentException("dst is null"); -- } -- -- if (offset >= srcs.length || offset + length > srcs.length) { -- throw new IndexOutOfBoundsException( -- "offset: " + offset + ", length: " + length + -- " (expected: offset <= offset + length <= srcs.length (" + srcs.length + "))"); -- } -- -- if (dst.isReadOnly()) { -- throw new ReadOnlyBufferException(); -- } -- -- synchronized (this) { -- if (isOutboundDone()) { -- // All drained in the outbound buffer -- return isInboundDone() || isDestroyed() ? CLOSED_NOT_HANDSHAKING : NEED_UNWRAP_CLOSED; -- } -- -- int bytesProduced = 0; -- ByteBuf bioReadCopyBuf = null; -- try { -- // Setup the BIO buffer so that we directly write the encryption results into dst. -- if (dst.isDirect()) { -- SSL.bioSetByteBuffer(networkBIO, bufferAddress(dst) + dst.position(), dst.remaining(), -- true); -- } else { -- bioReadCopyBuf = alloc.directBuffer(dst.remaining()); -- SSL.bioSetByteBuffer(networkBIO, memoryAddress(bioReadCopyBuf), bioReadCopyBuf.writableBytes(), -- true); -- } -- -- int bioLengthBefore = SSL.bioLengthByteBuffer(networkBIO); -- -- // Explicitly use outboundClosed as we want to drain any bytes that are still present. -- if (outboundClosed) { -- // If the outbound was closed we want to ensure we can produce the alert to the destination buffer. -- // This is true even if we not using jdkCompatibilityMode. -- // -- // We use a plaintextLength of 2 as we at least want to have an alert fit into it. -- // https://tools.ietf.org/html/rfc5246#section-7.2 -- if (!isBytesAvailableEnoughForWrap(dst.remaining(), 2, 1)) { -- return new SSLEngineResult(BUFFER_OVERFLOW, getHandshakeStatus(), 0, 0); -- } -- -- // There is something left to drain. -- // See https://github.com/netty/netty/issues/6260 -- bytesProduced = SSL.bioFlushByteBuffer(networkBIO); -- if (bytesProduced <= 0) { -- return newResultMayFinishHandshake(NOT_HANDSHAKING, 0, 0); -- } -- // It is possible when the outbound was closed there was not enough room in the non-application -- // buffers to hold the close_notify. We should keep trying to close until we consume all the data -- // OpenSSL can give us. -- if (!doSSLShutdown()) { -- return newResultMayFinishHandshake(NOT_HANDSHAKING, 0, bytesProduced); -- } -- bytesProduced = bioLengthBefore - SSL.bioLengthByteBuffer(networkBIO); -- return newResultMayFinishHandshake(NEED_WRAP, 0, bytesProduced); -- } -- -- // Flush any data that may be implicitly generated by OpenSSL (handshake, close, etc..). -- SSLEngineResult.HandshakeStatus status = NOT_HANDSHAKING; -- // Prepare OpenSSL to work in server mode and receive handshake -- if (handshakeState != HandshakeState.FINISHED) { -- if (handshakeState != HandshakeState.STARTED_EXPLICITLY) { -- // Update accepted so we know we triggered the handshake via wrap -- handshakeState = HandshakeState.STARTED_IMPLICITLY; -- } -- -- // Flush any data that may have been written implicitly during the handshake by OpenSSL. -- bytesProduced = SSL.bioFlushByteBuffer(networkBIO); -- -- if (pendingException != null) { -- // TODO(scott): It is possible that when the handshake failed there was not enough room in the -- // non-application buffers to hold the alert. We should get all the data before progressing on. -- // However I'm not aware of a way to do this with the OpenSSL APIs. -- // See https://github.com/netty/netty/issues/6385. -- -- // We produced / consumed some data during the handshake, signal back to the caller. -- // If there is a handshake exception and we have produced data, we should send the data before -- // we allow handshake() to throw the handshake exception. -- // -- // When the user calls wrap() again we will propagate the handshake error back to the user as -- // soon as there is no more data to was produced (as part of an alert etc). -- if (bytesProduced > 0) { -- return newResult(NEED_WRAP, 0, bytesProduced); -- } -- // Nothing was produced see if there is a handshakeException that needs to be propagated -- // to the caller by calling handshakeException() which will return the right HandshakeStatus -- // if it can "recover" from the exception for now. -- return newResult(handshakeException(), 0, 0); -- } -- -- status = handshake(); -- -- // Handshake may have generated more data, for example if the internal SSL buffer is small -- // we may have freed up space by flushing above. -- bytesProduced = bioLengthBefore - SSL.bioLengthByteBuffer(networkBIO); -- -- if (status == NEED_TASK) { -- return newResult(status, 0, bytesProduced); -- } -- -- if (bytesProduced > 0) { -- // If we have filled up the dst buffer and we have not finished the handshake we should try to -- // wrap again. Otherwise we should only try to wrap again if there is still data pending in -- // SSL buffers. -- return newResult(mayFinishHandshake(status != FINISHED ? -- bytesProduced == bioLengthBefore ? NEED_WRAP : -- getHandshakeStatus(SSL.bioLengthNonApplication(networkBIO)) : FINISHED), -- 0, bytesProduced); -- } -- -- if (status == NEED_UNWRAP) { -- // Signal if the outbound is done or not. -- return isOutboundDone() ? NEED_UNWRAP_CLOSED : NEED_UNWRAP_OK; -- } -- -- // Explicit use outboundClosed and not outboundClosed() as we want to drain any bytes that are -- // still present. -- if (outboundClosed) { -- bytesProduced = SSL.bioFlushByteBuffer(networkBIO); -- return newResultMayFinishHandshake(status, 0, bytesProduced); -- } -- } -- -- final int endOffset = offset + length; -- if (jdkCompatibilityMode) { -- int srcsLen = 0; -- for (int i = offset; i < endOffset; ++i) { -- final ByteBuffer src = srcs[i]; -- if (src == null) { -- throw new IllegalArgumentException("srcs[" + i + "] is null"); -- } -- if (srcsLen == MAX_PLAINTEXT_LENGTH) { -- continue; -- } -- -- srcsLen += src.remaining(); -- if (srcsLen > MAX_PLAINTEXT_LENGTH || srcsLen < 0) { -- // If srcLen > MAX_PLAINTEXT_LENGTH or secLen < 0 just set it to MAX_PLAINTEXT_LENGTH. -- // This also help us to guard against overflow. -- // We not break out here as we still need to check for null entries in srcs[]. -- srcsLen = MAX_PLAINTEXT_LENGTH; -- } -- } -- -- // jdkCompatibilityMode will only produce a single TLS packet, and we don't aggregate src buffers, -- // so we always fix the number of buffers to 1 when checking if the dst buffer is large enough. -- if (!isBytesAvailableEnoughForWrap(dst.remaining(), srcsLen, 1)) { -- return new SSLEngineResult(BUFFER_OVERFLOW, getHandshakeStatus(), 0, 0); -- } -- } -- -- // There was no pending data in the network BIO -- encrypt any application data -- int bytesConsumed = 0; -- assert bytesProduced == 0; -- -- // Flush any data that may have been written implicitly by OpenSSL in case a shutdown/alert occurs. -- bytesProduced = SSL.bioFlushByteBuffer(networkBIO); -- -- if (bytesProduced > 0) { -- return newResultMayFinishHandshake(status, bytesConsumed, bytesProduced); -- } -- // There was a pending exception that we just delayed because there was something to produce left. -- // Throw it now and shutdown the engine. -- if (pendingException != null) { -- Throwable error = pendingException; -- pendingException = null; -- shutdown(); -- // Throw a new exception wrapping the pending exception, so the stacktrace is meaningful and -- // contains all the details. -- throw new SSLException(error); -- } -- -- for (; offset < endOffset; ++offset) { -- final ByteBuffer src = srcs[offset]; -- final int remaining = src.remaining(); -- if (remaining == 0) { -- continue; -- } -- -- final int bytesWritten; -- if (jdkCompatibilityMode) { -- // Write plaintext application data to the SSL engine. We don't have to worry about checking -- // if there is enough space if jdkCompatibilityMode because we only wrap at most -- // MAX_PLAINTEXT_LENGTH and we loop over the input before hand and check if there is space. -- bytesWritten = writePlaintextData(src, min(remaining, MAX_PLAINTEXT_LENGTH - bytesConsumed)); -- } else { -- // OpenSSL's SSL_write keeps state between calls. We should make sure the amount we attempt to -- // write is guaranteed to succeed so we don't have to worry about keeping state consistent -- // between calls. -- final int availableCapacityForWrap = dst.remaining() - bytesProduced - maxWrapOverhead; -- if (availableCapacityForWrap <= 0) { -- return new SSLEngineResult(BUFFER_OVERFLOW, getHandshakeStatus(), bytesConsumed, -- bytesProduced); -- } -- bytesWritten = writePlaintextData(src, min(remaining, availableCapacityForWrap)); -- } -- -- // Determine how much encrypted data was generated. -- // -- // Even if SSL_write doesn't consume any application data it is possible that OpenSSL will -- // produce non-application data into the BIO. For example session tickets.... -- // See https://github.com/netty/netty/issues/10041 -- final int pendingNow = SSL.bioLengthByteBuffer(networkBIO); -- bytesProduced += bioLengthBefore - pendingNow; -- bioLengthBefore = pendingNow; -- -- if (bytesWritten > 0) { -- bytesConsumed += bytesWritten; -- -- if (jdkCompatibilityMode || bytesProduced == dst.remaining()) { -- return newResultMayFinishHandshake(status, bytesConsumed, bytesProduced); -- } -- } else { -- int sslError = SSL.getError(ssl, bytesWritten); -- if (sslError == SSL.SSL_ERROR_ZERO_RETURN) { -- // This means the connection was shutdown correctly, close inbound and outbound -- if (!receivedShutdown) { -- closeAll(); -- -- bytesProduced += bioLengthBefore - SSL.bioLengthByteBuffer(networkBIO); -- -- // If we have filled up the dst buffer and we have not finished the handshake we should -- // try to wrap again. Otherwise we should only try to wrap again if there is still data -- // pending in SSL buffers. -- SSLEngineResult.HandshakeStatus hs = mayFinishHandshake( -- status != FINISHED ? bytesProduced == dst.remaining() ? NEED_WRAP -- : getHandshakeStatus(SSL.bioLengthNonApplication(networkBIO)) -- : FINISHED); -- return newResult(hs, bytesConsumed, bytesProduced); -- } -- -- return newResult(NOT_HANDSHAKING, bytesConsumed, bytesProduced); -- } else if (sslError == SSL.SSL_ERROR_WANT_READ) { -- // If there is no pending data to read from BIO we should go back to event loop and try -- // to read more data [1]. It is also possible that event loop will detect the socket has -- // been closed. [1] https://www.openssl.org/docs/manmaster/ssl/SSL_write.html -- return newResult(NEED_UNWRAP, bytesConsumed, bytesProduced); -- } else if (sslError == SSL.SSL_ERROR_WANT_WRITE) { -- // SSL_ERROR_WANT_WRITE typically means that the underlying transport is not writable -- // and we should set the "want write" flag on the selector and try again when the -- // underlying transport is writable [1]. However we are not directly writing to the -- // underlying transport and instead writing to a BIO buffer. The OpenSsl documentation -- // says we should do the following [1]: -- // -- // "When using a buffering BIO, like a BIO pair, data must be written into or retrieved -- // out of the BIO before being able to continue." -- // -- // In practice this means the destination buffer doesn't have enough space for OpenSSL -- // to write encrypted data to. This is an OVERFLOW condition. -- // [1] https://www.openssl.org/docs/manmaster/ssl/SSL_write.html -- if (bytesProduced > 0) { -- // If we produced something we should report this back and let the user call -- // wrap again. -- return newResult(NEED_WRAP, bytesConsumed, bytesProduced); -- } -- return newResult(BUFFER_OVERFLOW, status, bytesConsumed, bytesProduced); -- } else if (sslError == SSL.SSL_ERROR_WANT_X509_LOOKUP || -- sslError == SSL.SSL_ERROR_WANT_CERTIFICATE_VERIFY || -- sslError == SSL.SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) { -- -- return newResult(NEED_TASK, bytesConsumed, bytesProduced); -- } else { -- // Everything else is considered as error -- throw shutdownWithError("SSL_write", sslError); -- } -- } -- } -- return newResultMayFinishHandshake(status, bytesConsumed, bytesProduced); -- } finally { -- SSL.bioClearByteBuffer(networkBIO); -- if (bioReadCopyBuf == null) { -- dst.position(dst.position() + bytesProduced); -- } else { -- assert bioReadCopyBuf.readableBytes() <= dst.remaining() : "The destination buffer " + dst + -- " didn't have enough remaining space to hold the encrypted content in " + bioReadCopyBuf; -- dst.put(bioReadCopyBuf.internalNioBuffer(bioReadCopyBuf.readerIndex(), bytesProduced)); -- bioReadCopyBuf.release(); -- } -- } -- } -- } -- -- private SSLEngineResult newResult(SSLEngineResult.HandshakeStatus hs, int bytesConsumed, int bytesProduced) { -- return newResult(OK, hs, bytesConsumed, bytesProduced); -- } -- -- private SSLEngineResult newResult(SSLEngineResult.Status status, SSLEngineResult.HandshakeStatus hs, -- int bytesConsumed, int bytesProduced) { -- // If isOutboundDone, then the data from the network BIO -- // was the close_notify message and all was consumed we are not required to wait -- // for the receipt the peer's close_notify message -- shutdown. -- if (isOutboundDone()) { -- if (isInboundDone()) { -- // If the inbound was done as well, we need to ensure we return NOT_HANDSHAKING to signal we are done. -- hs = NOT_HANDSHAKING; -- -- // As the inbound and the outbound is done we can shutdown the engine now. -- shutdown(); -- } -- return new SSLEngineResult(CLOSED, hs, bytesConsumed, bytesProduced); -- } -- if (hs == NEED_TASK) { -- // Set needTask to true so getHandshakeStatus() will return the correct value. -- needTask = true; -- } -- return new SSLEngineResult(status, hs, bytesConsumed, bytesProduced); -- } -- -- private SSLEngineResult newResultMayFinishHandshake(SSLEngineResult.HandshakeStatus hs, -- int bytesConsumed, int bytesProduced) throws SSLException { -- return newResult(mayFinishHandshake(hs != FINISHED ? getHandshakeStatus() : FINISHED), -- bytesConsumed, bytesProduced); -- } -- -- private SSLEngineResult newResultMayFinishHandshake(SSLEngineResult.Status status, -- SSLEngineResult.HandshakeStatus hs, -- int bytesConsumed, int bytesProduced) throws SSLException { -- return newResult(status, mayFinishHandshake(hs != FINISHED ? getHandshakeStatus() : FINISHED), -- bytesConsumed, bytesProduced); -- } -- -- /** -- * Log the error, shutdown the engine and throw an exception. -- */ -- private SSLException shutdownWithError(String operations, int sslError) { -- return shutdownWithError(operations, sslError, SSL.getLastErrorNumber()); -- } -- -- private SSLException shutdownWithError(String operation, int sslError, int error) { -- String errorString = SSL.getErrorString(error); -- if (logger.isDebugEnabled()) { -- logger.debug("{} failed with {}: OpenSSL error: {} {}", -- operation, sslError, error, errorString); -- } -- -- // There was an internal error -- shutdown -- shutdown(); -- if (handshakeState == HandshakeState.FINISHED) { -- return new SSLException(errorString); -- } -- -- SSLHandshakeException exception = new SSLHandshakeException(errorString); -- // If we have a handshakeException stored already we should include it as well to help the user debug things. -- if (pendingException != null) { -- exception.initCause(pendingException); -- pendingException = null; -- } -- return exception; -- } -- -- public final SSLEngineResult unwrap( -- final ByteBuffer[] srcs, int srcsOffset, final int srcsLength, -- final ByteBuffer[] dsts, int dstsOffset, final int dstsLength) throws SSLException { -- -- // Throw required runtime exceptions -- ObjectUtil.checkNotNull(srcs, "srcs"); -- if (srcsOffset >= srcs.length -- || srcsOffset + srcsLength > srcs.length) { -- throw new IndexOutOfBoundsException( -- "offset: " + srcsOffset + ", length: " + srcsLength + -- " (expected: offset <= offset + length <= srcs.length (" + srcs.length + "))"); -- } -- if (dsts == null) { -- throw new IllegalArgumentException("dsts is null"); -- } -- if (dstsOffset >= dsts.length || dstsOffset + dstsLength > dsts.length) { -- throw new IndexOutOfBoundsException( -- "offset: " + dstsOffset + ", length: " + dstsLength + -- " (expected: offset <= offset + length <= dsts.length (" + dsts.length + "))"); -- } -- long capacity = 0; -- final int dstsEndOffset = dstsOffset + dstsLength; -- for (int i = dstsOffset; i < dstsEndOffset; i ++) { -- ByteBuffer dst = dsts[i]; -- if (dst == null) { -- throw new IllegalArgumentException("dsts[" + i + "] is null"); -- } -- if (dst.isReadOnly()) { -- throw new ReadOnlyBufferException(); -- } -- capacity += dst.remaining(); -- } -- -- final int srcsEndOffset = srcsOffset + srcsLength; -- long len = 0; -- for (int i = srcsOffset; i < srcsEndOffset; i++) { -- ByteBuffer src = srcs[i]; -- if (src == null) { -- throw new IllegalArgumentException("srcs[" + i + "] is null"); -- } -- len += src.remaining(); -- } -- -- synchronized (this) { -- if (isInboundDone()) { -- return isOutboundDone() || isDestroyed() ? CLOSED_NOT_HANDSHAKING : NEED_WRAP_CLOSED; -- } -- -- SSLEngineResult.HandshakeStatus status = NOT_HANDSHAKING; -- // Prepare OpenSSL to work in server mode and receive handshake -- if (handshakeState != HandshakeState.FINISHED) { -- if (handshakeState != HandshakeState.STARTED_EXPLICITLY) { -- // Update accepted so we know we triggered the handshake via wrap -- handshakeState = HandshakeState.STARTED_IMPLICITLY; -- } -- -- status = handshake(); -- -- if (status == NEED_TASK) { -- return newResult(status, 0, 0); -- } -- -- if (status == NEED_WRAP) { -- return NEED_WRAP_OK; -- } -- // Check if the inbound is considered to be closed if so let us try to wrap again. -- if (isInboundDone) { -- return NEED_WRAP_CLOSED; -- } -- } -- -- int sslPending = sslPending0(); -- int packetLength; -- // The JDK implies that only a single SSL packet should be processed per unwrap call [1]. If we are in -- // JDK compatibility mode then we should honor this, but if not we just wrap as much as possible. If there -- // are multiple records or partial records this may reduce thrashing events through the pipeline. -- // [1] https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLEngine.html -- if (jdkCompatibilityMode) { -- if (len < SSL_RECORD_HEADER_LENGTH) { -- return newResultMayFinishHandshake(BUFFER_UNDERFLOW, status, 0, 0); -- } -- -- packetLength = SslUtils.getEncryptedPacketLength(srcs, srcsOffset); -- if (packetLength == SslUtils.NOT_ENCRYPTED) { -- throw new NotSslRecordException("not an SSL/TLS record"); -- } -- -- final int packetLengthDataOnly = packetLength - SSL_RECORD_HEADER_LENGTH; -- if (packetLengthDataOnly > capacity) { -- // Not enough space in the destination buffer so signal the caller that the buffer needs to be -- // increased. -- if (packetLengthDataOnly > MAX_RECORD_SIZE) { -- // The packet length MUST NOT exceed 2^14 [1]. However we do accommodate more data to support -- // legacy use cases which may violate this condition (e.g. OpenJDK's SslEngineImpl). If the max -- // length is exceeded we fail fast here to avoid an infinite loop due to the fact that we -- // won't allocate a buffer large enough. -- // [1] https://tools.ietf.org/html/rfc5246#section-6.2.1 -- throw new SSLException("Illegal packet length: " + packetLengthDataOnly + " > " + -- session.getApplicationBufferSize()); -- } else { -- session.tryExpandApplicationBufferSize(packetLengthDataOnly); -- } -- return newResultMayFinishHandshake(BUFFER_OVERFLOW, status, 0, 0); -- } -- -- if (len < packetLength) { -- // We either don't have enough data to read the packet length or not enough for reading the whole -- // packet. -- return newResultMayFinishHandshake(BUFFER_UNDERFLOW, status, 0, 0); -- } -- } else if (len == 0 && sslPending <= 0) { -- return newResultMayFinishHandshake(BUFFER_UNDERFLOW, status, 0, 0); -- } else if (capacity == 0) { -- return newResultMayFinishHandshake(BUFFER_OVERFLOW, status, 0, 0); -- } else { -- packetLength = (int) min(MAX_VALUE, len); -- } -- -- // This must always be the case when we reached here as if not we returned BUFFER_UNDERFLOW. -- assert srcsOffset < srcsEndOffset; -- -- // This must always be the case if we reached here. -- assert capacity > 0; -- -- // Number of produced bytes -- int bytesProduced = 0; -- int bytesConsumed = 0; -- try { -- srcLoop: -- for (;;) { -- ByteBuffer src = srcs[srcsOffset]; -- int remaining = src.remaining(); -- final ByteBuf bioWriteCopyBuf; -- int pendingEncryptedBytes; -- if (remaining == 0) { -- if (sslPending <= 0) { -- // We must skip empty buffers as BIO_write will return 0 if asked to write something -- // with length 0. -- if (++srcsOffset >= srcsEndOffset) { -- break; -- } -- continue; -- } else { -- bioWriteCopyBuf = null; -- pendingEncryptedBytes = SSL.bioLengthByteBuffer(networkBIO); -- } -- } else { -- // Write more encrypted data into the BIO. Ensure we only read one packet at a time as -- // stated in the SSLEngine javadocs. -- pendingEncryptedBytes = min(packetLength, remaining); -- bioWriteCopyBuf = writeEncryptedData(src, pendingEncryptedBytes); -- } -- try { -- for (;;) { -- ByteBuffer dst = dsts[dstsOffset]; -- if (!dst.hasRemaining()) { -- // No space left in the destination buffer, skip it. -- if (++dstsOffset >= dstsEndOffset) { -- break srcLoop; -- } -- continue; -- } -- -- int bytesRead = readPlaintextData(dst); -- // We are directly using the ByteBuffer memory for the write, and so we only know what has -- // been consumed after we let SSL decrypt the data. At this point we should update the -- // number of bytes consumed, update the ByteBuffer position, and release temp ByteBuf. -- int localBytesConsumed = pendingEncryptedBytes - SSL.bioLengthByteBuffer(networkBIO); -- bytesConsumed += localBytesConsumed; -- packetLength -= localBytesConsumed; -- pendingEncryptedBytes -= localBytesConsumed; -- src.position(src.position() + localBytesConsumed); -- -- if (bytesRead > 0) { -- bytesProduced += bytesRead; -- -- if (!dst.hasRemaining()) { -- sslPending = sslPending0(); -- // Move to the next dst buffer as this one is full. -- if (++dstsOffset >= dstsEndOffset) { -- return sslPending > 0 ? -- newResult(BUFFER_OVERFLOW, status, bytesConsumed, bytesProduced) : -- newResultMayFinishHandshake(isInboundDone() ? CLOSED : OK, status, -- bytesConsumed, bytesProduced); -- } -- } else if (packetLength == 0 || jdkCompatibilityMode) { -- // We either consumed all data or we are in jdkCompatibilityMode and have consumed -- // a single TLS packet and should stop consuming until this method is called again. -- break srcLoop; -- } -- } else { -- int sslError = SSL.getError(ssl, bytesRead); -- if (sslError == SSL.SSL_ERROR_WANT_READ || sslError == SSL.SSL_ERROR_WANT_WRITE) { -- // break to the outer loop as we want to read more data which means we need to -- // write more to the BIO. -- break; -- } else if (sslError == SSL.SSL_ERROR_ZERO_RETURN) { -- // This means the connection was shutdown correctly, close inbound and outbound -- if (!receivedShutdown) { -- closeAll(); -- } -- return newResultMayFinishHandshake(isInboundDone() ? CLOSED : OK, status, -- bytesConsumed, bytesProduced); -- } else if (sslError == SSL.SSL_ERROR_WANT_X509_LOOKUP || -- sslError == SSL.SSL_ERROR_WANT_CERTIFICATE_VERIFY || -- sslError == SSL.SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) { -- return newResult(isInboundDone() ? CLOSED : OK, -- NEED_TASK, bytesConsumed, bytesProduced); -- } else { -- return sslReadErrorResult(sslError, SSL.getLastErrorNumber(), bytesConsumed, -- bytesProduced); -- } -- } -- } -- -- if (++srcsOffset >= srcsEndOffset) { -- break; -- } -- } finally { -- if (bioWriteCopyBuf != null) { -- bioWriteCopyBuf.release(); -- } -- } -- } -- } finally { -- SSL.bioClearByteBuffer(networkBIO); -- rejectRemoteInitiatedRenegotiation(); -- } -- -- // Check to see if we received a close_notify message from the peer. -- if (!receivedShutdown && (SSL.getShutdown(ssl) & SSL.SSL_RECEIVED_SHUTDOWN) == SSL.SSL_RECEIVED_SHUTDOWN) { -- closeAll(); -- } -- -- return newResultMayFinishHandshake(isInboundDone() ? CLOSED : OK, status, bytesConsumed, bytesProduced); -- } -- } -- -- private SSLEngineResult sslReadErrorResult(int error, int stackError, int bytesConsumed, int bytesProduced) -- throws SSLException { -- // Check if we have a pending handshakeException and if so see if we need to consume all pending data from the -- // BIO first or can just shutdown and throw it now. -- // This is needed so we ensure close_notify etc is correctly send to the remote peer. -- // See https://github.com/netty/netty/issues/3900 -- if (SSL.bioLengthNonApplication(networkBIO) > 0) { -- // we seems to have data left that needs to be transferred and so the user needs -- // call wrap(...). Store the error so we can pick it up later. -- String message = SSL.getErrorString(stackError); -- SSLException exception = handshakeState == HandshakeState.FINISHED ? -- new SSLException(message) : new SSLHandshakeException(message); -- if (pendingException == null) { -- pendingException = exception; -- } else { -- ThrowableUtil.addSuppressed(pendingException, exception); -- } -- // We need to clear all errors so we not pick up anything that was left on the stack on the next -- // operation. Note that shutdownWithError(...) will cleanup the stack as well so its only needed here. -- SSL.clearError(); -- return new SSLEngineResult(OK, NEED_WRAP, bytesConsumed, bytesProduced); -- } -- throw shutdownWithError("SSL_read", error, stackError); -- } -- -- private void closeAll() throws SSLException { -- receivedShutdown = true; -- closeOutbound(); -- closeInbound(); -- } -- -- private void rejectRemoteInitiatedRenegotiation() throws SSLHandshakeException { -- // As rejectRemoteInitiatedRenegotiation() is called in a finally block we also need to check if we shutdown -- // the engine before as otherwise SSL.getHandshakeCount(ssl) will throw an NPE if the passed in ssl is 0. -- // See https://github.com/netty/netty/issues/7353 -- if (!isDestroyed() && SSL.getHandshakeCount(ssl) > 1 && -- // As we may count multiple handshakes when TLSv1.3 is used we should just ignore this here as -- // renegotiation is not supported in TLSv1.3 as per spec. -- !SslUtils.PROTOCOL_TLS_V1_3.equals(session.getProtocol()) && handshakeState == HandshakeState.FINISHED) { -- // TODO: In future versions me may also want to send a fatal_alert to the client and so notify it -- // that the renegotiation failed. -- shutdown(); -- throw new SSLHandshakeException("remote-initiated renegotiation not allowed"); -- } -- } -- -- public final SSLEngineResult unwrap(final ByteBuffer[] srcs, final ByteBuffer[] dsts) throws SSLException { -- return unwrap(srcs, 0, srcs.length, dsts, 0, dsts.length); -- } -- -- private ByteBuffer[] singleSrcBuffer(ByteBuffer src) { -- singleSrcBuffer[0] = src; -- return singleSrcBuffer; -- } -- -- private void resetSingleSrcBuffer() { -- singleSrcBuffer[0] = null; -- } -- -- private ByteBuffer[] singleDstBuffer(ByteBuffer src) { -- singleDstBuffer[0] = src; -- return singleDstBuffer; -- } -- -- private void resetSingleDstBuffer() { -- singleDstBuffer[0] = null; -- } -- -- @Override -- public final synchronized SSLEngineResult unwrap( -- final ByteBuffer src, final ByteBuffer[] dsts, final int offset, final int length) throws SSLException { -- try { -- return unwrap(singleSrcBuffer(src), 0, 1, dsts, offset, length); -- } finally { -- resetSingleSrcBuffer(); -- } -- } -- -- @Override -- public final synchronized SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException { -- try { -- return wrap(singleSrcBuffer(src), dst); -- } finally { -- resetSingleSrcBuffer(); -- } -- } -- -- @Override -- public final synchronized SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException { -- try { -- return unwrap(singleSrcBuffer(src), singleDstBuffer(dst)); -- } finally { -- resetSingleSrcBuffer(); -- resetSingleDstBuffer(); -- } -- } -- -- @Override -- public final synchronized SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException { -- try { -- return unwrap(singleSrcBuffer(src), dsts); -- } finally { -- resetSingleSrcBuffer(); -- } -- } -- -- @Override -- public final synchronized Runnable getDelegatedTask() { -- if (isDestroyed()) { -- return null; -- } -- final Runnable task = SSL.getTask(ssl); -- if (task == null) { -- return null; -- } -- return new Runnable() { -- @Override -- public void run() { -- if (isDestroyed()) { -- // The engine was destroyed in the meantime, just return. -- return; -- } -- try { -- task.run(); -- } finally { -- // The task was run, reset needTask to false so getHandshakeStatus() returns the correct value. -- needTask = false; -- } -- } -- }; -- } -- -- @Override -- public final synchronized void closeInbound() throws SSLException { -- if (isInboundDone) { -- return; -- } -- -- isInboundDone = true; -- -- if (isOutboundDone()) { -- // Only call shutdown if there is no outbound data pending. -- // See https://github.com/netty/netty/issues/6167 -- shutdown(); -- } -- -- if (handshakeState != HandshakeState.NOT_STARTED && !receivedShutdown) { -- throw new SSLException( -- "Inbound closed before receiving peer's close_notify: possible truncation attack?"); -- } -- } -- -- @Override -- public final synchronized boolean isInboundDone() { -- return isInboundDone; -- } -- -- @Override -- public final synchronized void closeOutbound() { -- if (outboundClosed) { -- return; -- } -- -- outboundClosed = true; -- -- if (handshakeState != HandshakeState.NOT_STARTED && !isDestroyed()) { -- int mode = SSL.getShutdown(ssl); -- if ((mode & SSL.SSL_SENT_SHUTDOWN) != SSL.SSL_SENT_SHUTDOWN) { -- doSSLShutdown(); -- } -- } else { -- // engine closing before initial handshake -- shutdown(); -- } -- } -- -- /** -- * Attempt to call {@link SSL#shutdownSSL(long)}. -- * @return {@code false} if the call to {@link SSL#shutdownSSL(long)} was not attempted or returned an error. -- */ -- private boolean doSSLShutdown() { -- if (SSL.isInInit(ssl) != 0) { -- // Only try to call SSL_shutdown if we are not in the init state anymore. -- // Otherwise we will see 'error:140E0197:SSL routines:SSL_shutdown:shutdown while in init' in our logs. -- // -- // See also http://hg.nginx.org/nginx/rev/062c189fee20 -- return false; -- } -- int err = SSL.shutdownSSL(ssl); -- if (err < 0) { -- int sslErr = SSL.getError(ssl, err); -- if (sslErr == SSL.SSL_ERROR_SYSCALL || sslErr == SSL.SSL_ERROR_SSL) { -- if (logger.isDebugEnabled()) { -- int error = SSL.getLastErrorNumber(); -- logger.debug("SSL_shutdown failed: OpenSSL error: {} {}", error, SSL.getErrorString(error)); -- } -- // There was an internal error -- shutdown -- shutdown(); -- return false; -- } -- SSL.clearError(); -- } -- return true; -- } -- -- @Override -- public final synchronized boolean isOutboundDone() { -- // Check if there is anything left in the outbound buffer. -- // We need to ensure we only call SSL.pendingWrittenBytesInBIO(...) if the engine was not destroyed yet. -- return outboundClosed && (networkBIO == 0 || SSL.bioLengthNonApplication(networkBIO) == 0); -- } -- -- @Override -- public final String[] getSupportedCipherSuites() { -- return OpenSsl.AVAILABLE_CIPHER_SUITES.toArray(new String[0]); -- } -- -- @Override -- public final String[] getEnabledCipherSuites() { -- final String[] extraCiphers; -- final String[] enabled; -- synchronized (this) { -- if (!isDestroyed()) { -- enabled = SSL.getCiphers(ssl); -- int opts = SSL.getOptions(ssl); -- if (isProtocolEnabled(opts, SSL.SSL_OP_NO_TLSv1_3, PROTOCOL_TLS_V1_3)) { -- extraCiphers = OpenSsl.EXTRA_SUPPORTED_TLS_1_3_CIPHERS; -- } else { -- extraCiphers = EmptyArrays.EMPTY_STRINGS; -- } -- } else { -- return EmptyArrays.EMPTY_STRINGS; -- } -- } -- if (enabled == null) { -- return EmptyArrays.EMPTY_STRINGS; -- } else { -- Set enabledSet = new LinkedHashSet(enabled.length + extraCiphers.length); -- synchronized (this) { -- for (int i = 0; i < enabled.length; i++) { -- String mapped = toJavaCipherSuite(enabled[i]); -- final String cipher = mapped == null ? enabled[i] : mapped; -- if (!OpenSsl.isTlsv13Supported() && SslUtils.isTLSv13Cipher(cipher)) { -- continue; -- } -- enabledSet.add(cipher); -- } -- Collections.addAll(enabledSet, extraCiphers); -- } -- return enabledSet.toArray(new String[0]); -- } -- } -- -- @Override -- public final void setEnabledCipherSuites(String[] cipherSuites) { -- checkNotNull(cipherSuites, "cipherSuites"); -- -- final StringBuilder buf = new StringBuilder(); -- final StringBuilder bufTLSv13 = new StringBuilder(); -- -- CipherSuiteConverter.convertToCipherStrings(Arrays.asList(cipherSuites), buf, bufTLSv13, OpenSsl.isBoringSSL()); -- final String cipherSuiteSpec = buf.toString(); -- final String cipherSuiteSpecTLSv13 = bufTLSv13.toString(); -- -- if (!OpenSsl.isTlsv13Supported() && !cipherSuiteSpecTLSv13.isEmpty()) { -- throw new IllegalArgumentException("TLSv1.3 is not supported by this java version."); -- } -- synchronized (this) { -- if (!isDestroyed()) { -- // TODO: Should we also adjust the protocols based on if there are any ciphers left that can be used -- // for TLSv1.3 or for previor SSL/TLS versions ? -- try { -- // Set non TLSv1.3 ciphers. -- SSL.setCipherSuites(ssl, cipherSuiteSpec, false); -- -- if (OpenSsl.isTlsv13Supported()) { -- // Set TLSv1.3 ciphers. -- SSL.setCipherSuites(ssl, cipherSuiteSpecTLSv13, true); -- } -- -- } catch (Exception e) { -- throw new IllegalStateException("failed to enable cipher suites: " + cipherSuiteSpec, e); -- } -- } else { -- throw new IllegalStateException("failed to enable cipher suites: " + cipherSuiteSpec); -- } -- } -- } -- -- @Override -- public final String[] getSupportedProtocols() { -- return OpenSsl.SUPPORTED_PROTOCOLS_SET.toArray(new String[0]); -- } -- -- @Override -- public final String[] getEnabledProtocols() { -- List enabled = new ArrayList(6); -- // Seems like there is no way to explicit disable SSLv2Hello in openssl so it is always enabled -- enabled.add(PROTOCOL_SSL_V2_HELLO); -- -- int opts; -- synchronized (this) { -- if (!isDestroyed()) { -- opts = SSL.getOptions(ssl); -- } else { -- return enabled.toArray(new String[0]); -- } -- } -- if (isProtocolEnabled(opts, SSL.SSL_OP_NO_TLSv1, PROTOCOL_TLS_V1)) { -- enabled.add(PROTOCOL_TLS_V1); -- } -- if (isProtocolEnabled(opts, SSL.SSL_OP_NO_TLSv1_1, PROTOCOL_TLS_V1_1)) { -- enabled.add(PROTOCOL_TLS_V1_1); -- } -- if (isProtocolEnabled(opts, SSL.SSL_OP_NO_TLSv1_2, PROTOCOL_TLS_V1_2)) { -- enabled.add(PROTOCOL_TLS_V1_2); -- } -- if (isProtocolEnabled(opts, SSL.SSL_OP_NO_TLSv1_3, PROTOCOL_TLS_V1_3)) { -- enabled.add(PROTOCOL_TLS_V1_3); -- } -- if (isProtocolEnabled(opts, SSL.SSL_OP_NO_SSLv2, PROTOCOL_SSL_V2)) { -- enabled.add(PROTOCOL_SSL_V2); -- } -- if (isProtocolEnabled(opts, SSL.SSL_OP_NO_SSLv3, PROTOCOL_SSL_V3)) { -- enabled.add(PROTOCOL_SSL_V3); -- } -- return enabled.toArray(new String[0]); -- } -- -- private static boolean isProtocolEnabled(int opts, int disableMask, String protocolString) { -- // We also need to check if the actual protocolString is supported as depending on the openssl API -- // implementations it may use a disableMask of 0 (BoringSSL is doing this for example). -- return (opts & disableMask) == 0 && OpenSsl.SUPPORTED_PROTOCOLS_SET.contains(protocolString); -- } -- -- /** -- * {@inheritDoc} -- * TLS doesn't support a way to advertise non-contiguous versions from the client's perspective, and the client -- * just advertises the max supported version. The TLS protocol also doesn't support all different combinations of -- * discrete protocols, and instead assumes contiguous ranges. OpenSSL has some unexpected behavior -- * (e.g. handshake failures) if non-contiguous protocols are used even where there is a compatible set of protocols -- * and ciphers. For these reasons this method will determine the minimum protocol and the maximum protocol and -- * enabled a contiguous range from [min protocol, max protocol] in OpenSSL. -- */ -- @Override -- public final void setEnabledProtocols(String[] protocols) { -- if (protocols == null) { -- // This is correct from the API docs -- throw new IllegalArgumentException(); -- } -- int minProtocolIndex = OPENSSL_OP_NO_PROTOCOLS.length; -- int maxProtocolIndex = 0; -- for (String p: protocols) { -- if (!OpenSsl.SUPPORTED_PROTOCOLS_SET.contains(p)) { -- throw new IllegalArgumentException("Protocol " + p + " is not supported."); -- } -- if (p.equals(PROTOCOL_SSL_V2)) { -- if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV2) { -- minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV2; -- } -- if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV2) { -- maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV2; -- } -- } else if (p.equals(PROTOCOL_SSL_V3)) { -- if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV3) { -- minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV3; -- } -- if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV3) { -- maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_SSLV3; -- } -- } else if (p.equals(PROTOCOL_TLS_V1)) { -- if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1) { -- minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1; -- } -- if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1) { -- maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1; -- } -- } else if (p.equals(PROTOCOL_TLS_V1_1)) { -- if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_1) { -- minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_1; -- } -- if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_1) { -- maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_1; -- } -- } else if (p.equals(PROTOCOL_TLS_V1_2)) { -- if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_2) { -- minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_2; -- } -- if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_2) { -- maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_2; -- } -- } else if (p.equals(PROTOCOL_TLS_V1_3)) { -- if (minProtocolIndex > OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_3) { -- minProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_3; -- } -- if (maxProtocolIndex < OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_3) { -- maxProtocolIndex = OPENSSL_OP_NO_PROTOCOL_INDEX_TLSv1_3; -- } -- } -- } -- synchronized (this) { -- if (!isDestroyed()) { -- // Clear out options which disable protocols -- SSL.clearOptions(ssl, SSL.SSL_OP_NO_SSLv2 | SSL.SSL_OP_NO_SSLv3 | SSL.SSL_OP_NO_TLSv1 | -- SSL.SSL_OP_NO_TLSv1_1 | SSL.SSL_OP_NO_TLSv1_2 | SSL.SSL_OP_NO_TLSv1_3); -- -- int opts = 0; -- for (int i = 0; i < minProtocolIndex; ++i) { -- opts |= OPENSSL_OP_NO_PROTOCOLS[i]; -- } -- assert maxProtocolIndex != MAX_VALUE; -- for (int i = maxProtocolIndex + 1; i < OPENSSL_OP_NO_PROTOCOLS.length; ++i) { -- opts |= OPENSSL_OP_NO_PROTOCOLS[i]; -- } -- -- // Disable protocols we do not want -- SSL.setOptions(ssl, opts); -- } else { -- throw new IllegalStateException("failed to enable protocols: " + Arrays.asList(protocols)); -- } -- } -- } -- -- @Override -- public final SSLSession getSession() { -- return session; -- } -- -- @Override -- public final synchronized void beginHandshake() throws SSLException { -- switch (handshakeState) { -- case STARTED_IMPLICITLY: -- checkEngineClosed(); -- -- // A user did not start handshake by calling this method by him/herself, -- // but handshake has been started already by wrap() or unwrap() implicitly. -- // Because it's the user's first time to call this method, it is unfair to -- // raise an exception. From the user's standpoint, he or she never asked -- // for renegotiation. -- -- handshakeState = HandshakeState.STARTED_EXPLICITLY; // Next time this method is invoked by the user, -- calculateMaxWrapOverhead(); -- // we should raise an exception. -- break; -- case STARTED_EXPLICITLY: -- // Nothing to do as the handshake is not done yet. -- break; -- case FINISHED: -- throw new SSLException("renegotiation unsupported"); -- case NOT_STARTED: -- handshakeState = HandshakeState.STARTED_EXPLICITLY; -- if (handshake() == NEED_TASK) { -- // Set needTask to true so getHandshakeStatus() will return the correct value. -- needTask = true; -- } -- calculateMaxWrapOverhead(); -- break; -- default: -- throw new Error(); -- } -- } -- -- private void checkEngineClosed() throws SSLException { -- if (isDestroyed()) { -- throw new SSLException("engine closed"); -- } -- } -- -- private static SSLEngineResult.HandshakeStatus pendingStatus(int pendingStatus) { -- // Depending on if there is something left in the BIO we need to WRAP or UNWRAP -- return pendingStatus > 0 ? NEED_WRAP : NEED_UNWRAP; -- } -- -- private static boolean isEmpty(Object[] arr) { -- return arr == null || arr.length == 0; -- } -- -- private static boolean isEmpty(byte[] cert) { -- return cert == null || cert.length == 0; -- } -- -- private SSLEngineResult.HandshakeStatus handshakeException() throws SSLException { -- if (SSL.bioLengthNonApplication(networkBIO) > 0) { -- // There is something pending, we need to consume it first via a WRAP so we don't loose anything. -- return NEED_WRAP; -- } -- -- Throwable exception = pendingException; -- assert exception != null; -- pendingException = null; -- shutdown(); -- if (exception instanceof SSLHandshakeException) { -- throw (SSLHandshakeException) exception; -- } -- SSLHandshakeException e = new SSLHandshakeException("General OpenSslEngine problem"); -- e.initCause(exception); -- throw e; -- } -- -- /** -- * Should be called if the handshake will be failed due a callback that throws an exception. -- * This cause will then be used to give more details as part of the {@link SSLHandshakeException}. -- */ -- final void initHandshakeException(Throwable cause) { -- if (pendingException == null) { -- pendingException = cause; -- } else { -- ThrowableUtil.addSuppressed(pendingException, cause); -- } -- } -- -- private SSLEngineResult.HandshakeStatus handshake() throws SSLException { -- if (needTask) { -- return NEED_TASK; -- } -- if (handshakeState == HandshakeState.FINISHED) { -- return FINISHED; -- } -- -- checkEngineClosed(); -- -- if (pendingException != null) { -- // Let's call SSL.doHandshake(...) again in case there is some async operation pending that would fill the -- // outbound buffer. -- if (SSL.doHandshake(ssl) <= 0) { -- // Clear any error that was put on the stack by the handshake -- SSL.clearError(); -- } -- return handshakeException(); -- } -- -- // Adding the OpenSslEngine to the OpenSslEngineMap so it can be used in the AbstractCertificateVerifier. -- engineMap.add(this); -- if (lastAccessed == -1) { -- lastAccessed = System.currentTimeMillis(); -- } -- -- int code = SSL.doHandshake(ssl); -- if (code <= 0) { -- int sslError = SSL.getError(ssl, code); -- if (sslError == SSL.SSL_ERROR_WANT_READ || sslError == SSL.SSL_ERROR_WANT_WRITE) { -- return pendingStatus(SSL.bioLengthNonApplication(networkBIO)); -- } -- -- if (sslError == SSL.SSL_ERROR_WANT_X509_LOOKUP || -- sslError == SSL.SSL_ERROR_WANT_CERTIFICATE_VERIFY || -- sslError == SSL.SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) { -- return NEED_TASK; -- } -- -- // Check if we have a pending exception that was created during the handshake and if so throw it after -- // shutdown the connection. -- if (pendingException != null) { -- return handshakeException(); -- } -- -- // Everything else is considered as error -- throw shutdownWithError("SSL_do_handshake", sslError); -- } -- // We have produced more data as part of the handshake if this is the case the user should call wrap(...) -- if (SSL.bioLengthNonApplication(networkBIO) > 0) { -- return NEED_WRAP; -- } -- // if SSL_do_handshake returns > 0 or sslError == SSL.SSL_ERROR_NAME it means the handshake was finished. -- session.handshakeFinished(); -- return FINISHED; -- } -- -- private SSLEngineResult.HandshakeStatus mayFinishHandshake(SSLEngineResult.HandshakeStatus status) -- throws SSLException { -- if (status == NOT_HANDSHAKING && handshakeState != HandshakeState.FINISHED) { -- // If the status was NOT_HANDSHAKING and we not finished the handshake we need to call -- // SSL_do_handshake() again -- return handshake(); -- } -- return status; -- } -- -- @Override -- public final synchronized SSLEngineResult.HandshakeStatus getHandshakeStatus() { -- // Check if we are in the initial handshake phase or shutdown phase -- if (needPendingStatus()) { -- if (needTask) { -- // There is a task outstanding -- return NEED_TASK; -- } -- return pendingStatus(SSL.bioLengthNonApplication(networkBIO)); -- } -- return NOT_HANDSHAKING; -- } -- -- private SSLEngineResult.HandshakeStatus getHandshakeStatus(int pending) { -- // Check if we are in the initial handshake phase or shutdown phase -- if (needPendingStatus()) { -- if (needTask) { -- // There is a task outstanding -- return NEED_TASK; -- } -- return pendingStatus(pending); -- } -- return NOT_HANDSHAKING; -- } -- -- private boolean needPendingStatus() { -- return handshakeState != HandshakeState.NOT_STARTED && !isDestroyed() -- && (handshakeState != HandshakeState.FINISHED || isInboundDone() || isOutboundDone()); -- } -- -- /** -- * Converts the specified OpenSSL cipher suite to the Java cipher suite. -- */ -- private String toJavaCipherSuite(String openSslCipherSuite) { -- if (openSslCipherSuite == null) { -- return null; -- } -- -- String version = SSL.getVersion(ssl); -- String prefix = toJavaCipherSuitePrefix(version); -- return CipherSuiteConverter.toJava(openSslCipherSuite, prefix); -- } -- -- /** -- * Converts the protocol version string returned by {@link SSL#getVersion(long)} to protocol family string. -- */ -- private static String toJavaCipherSuitePrefix(String protocolVersion) { -- final char c; -- if (protocolVersion == null || protocolVersion.isEmpty()) { -- c = 0; -- } else { -- c = protocolVersion.charAt(0); -- } -- -- switch (c) { -- case 'T': -- return "TLS"; -- case 'S': -- return "SSL"; -- default: -- return "UNKNOWN"; -- } -- } -- -- @Override -- public final void setUseClientMode(boolean clientMode) { -- if (clientMode != this.clientMode) { -- throw new UnsupportedOperationException(); -- } -- } -- -- @Override -- public final boolean getUseClientMode() { -- return clientMode; -- } -- -- @Override -- public final void setNeedClientAuth(boolean b) { -- setClientAuth(b ? ClientAuth.REQUIRE : ClientAuth.NONE); -- } -- -- @Override -- public final boolean getNeedClientAuth() { -- return clientAuth == ClientAuth.REQUIRE; -- } -- -- @Override -- public final void setWantClientAuth(boolean b) { -- setClientAuth(b ? ClientAuth.OPTIONAL : ClientAuth.NONE); -- } -- -- @Override -- public final boolean getWantClientAuth() { -- return clientAuth == ClientAuth.OPTIONAL; -- } -- -- /** -- * See SSL_set_verify and -- * {@link SSL#setVerify(long, int, int)}. -- */ -- @UnstableApi -- public final synchronized void setVerify(int verifyMode, int depth) { -- if (!isDestroyed()) { -- SSL.setVerify(ssl, verifyMode, depth); -- } -- } -- -- private void setClientAuth(ClientAuth mode) { -- if (clientMode) { -- return; -- } -- synchronized (this) { -- if (clientAuth == mode) { -- // No need to issue any JNI calls if the mode is the same -- return; -- } -- if (!isDestroyed()) { -- switch (mode) { -- case NONE: -- SSL.setVerify(ssl, SSL.SSL_CVERIFY_NONE, ReferenceCountedOpenSslContext.VERIFY_DEPTH); -- break; -- case REQUIRE: -- SSL.setVerify(ssl, SSL.SSL_CVERIFY_REQUIRED, ReferenceCountedOpenSslContext.VERIFY_DEPTH); -- break; -- case OPTIONAL: -- SSL.setVerify(ssl, SSL.SSL_CVERIFY_OPTIONAL, ReferenceCountedOpenSslContext.VERIFY_DEPTH); -- break; -- default: -- throw new Error(mode.toString()); -- } -- } -- clientAuth = mode; -- } -- } -- -- @Override -- public final void setEnableSessionCreation(boolean b) { -- if (b) { -- throw new UnsupportedOperationException(); -- } -- } -- -- @Override -- public final boolean getEnableSessionCreation() { -- return false; -- } -- -- @SuppressJava6Requirement(reason = "Usage guarded by java version check") -- @Override -- public final synchronized SSLParameters getSSLParameters() { -- SSLParameters sslParameters = super.getSSLParameters(); -- -- int version = PlatformDependent.javaVersion(); -- if (version >= 7) { -- sslParameters.setEndpointIdentificationAlgorithm(endPointIdentificationAlgorithm); -- Java7SslParametersUtils.setAlgorithmConstraints(sslParameters, algorithmConstraints); -- if (version >= 8) { -- if (sniHostNames != null) { -- Java8SslUtils.setSniHostNames(sslParameters, sniHostNames); -- } -- if (!isDestroyed()) { -- Java8SslUtils.setUseCipherSuitesOrder( -- sslParameters, (SSL.getOptions(ssl) & SSL.SSL_OP_CIPHER_SERVER_PREFERENCE) != 0); -- } -- -- Java8SslUtils.setSNIMatchers(sslParameters, matchers); -- } -- } -- return sslParameters; -- } -- -- @SuppressJava6Requirement(reason = "Usage guarded by java version check") -- @Override -- public final synchronized void setSSLParameters(SSLParameters sslParameters) { -- int version = PlatformDependent.javaVersion(); -- if (version >= 7) { -- if (sslParameters.getAlgorithmConstraints() != null) { -- throw new IllegalArgumentException("AlgorithmConstraints are not supported."); -- } -- -- boolean isDestroyed = isDestroyed(); -- if (version >= 8) { -- if (!isDestroyed) { -- if (clientMode) { -- final List sniHostNames = Java8SslUtils.getSniHostNames(sslParameters); -- for (String name: sniHostNames) { -- SSL.setTlsExtHostName(ssl, name); -- } -- this.sniHostNames = sniHostNames; -- } -- if (Java8SslUtils.getUseCipherSuitesOrder(sslParameters)) { -- SSL.setOptions(ssl, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE); -- } else { -- SSL.clearOptions(ssl, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE); -- } -- } -- matchers = sslParameters.getSNIMatchers(); -- } -- -- final String endPointIdentificationAlgorithm = sslParameters.getEndpointIdentificationAlgorithm(); -- if (!isDestroyed) { -- // 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 && isEndPointVerificationEnabled(endPointIdentificationAlgorithm)) { -- SSL.setVerify(ssl, SSL.SSL_CVERIFY_REQUIRED, -1); -- } -- } -- this.endPointIdentificationAlgorithm = endPointIdentificationAlgorithm; -- algorithmConstraints = sslParameters.getAlgorithmConstraints(); -- } -- super.setSSLParameters(sslParameters); -- } -- -- private static boolean isEndPointVerificationEnabled(String endPointIdentificationAlgorithm) { -- return endPointIdentificationAlgorithm != null && !endPointIdentificationAlgorithm.isEmpty(); -- } -- -- private boolean isDestroyed() { -- return destroyed; -- } -- -- final boolean checkSniHostnameMatch(byte[] hostname) { -- return Java8SslUtils.checkSniHostnameMatch(matchers, hostname); -- } -- -- @Override -- public String getNegotiatedApplicationProtocol() { -- return applicationProtocol; -- } -- -- private static long bufferAddress(ByteBuffer b) { -- assert b.isDirect(); -- if (PlatformDependent.hasUnsafe()) { -- return PlatformDependent.directBufferAddress(b); -- } -- return Buffer.address(b); -- } -- -- private final class DefaultOpenSslSession implements OpenSslSession { -- private final OpenSslSessionContext sessionContext; -- -- // These are guarded by synchronized(OpenSslEngine.this) as handshakeFinished() may be triggered by any -- // thread. -- private X509Certificate[] x509PeerCerts; -- private Certificate[] peerCerts; -- -- private String protocol; -- private String cipher; -- private byte[] id; -- private long creationTime; -- private volatile int applicationBufferSize = MAX_PLAINTEXT_LENGTH; -- -- // lazy init for memory reasons -- private Map values; -- -- DefaultOpenSslSession(OpenSslSessionContext sessionContext) { -- this.sessionContext = sessionContext; -- } -- -- private SSLSessionBindingEvent newSSLSessionBindingEvent(String name) { -- return new SSLSessionBindingEvent(session, name); -- } -- -- @Override -- public byte[] getId() { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (id == null) { -- return EmptyArrays.EMPTY_BYTES; -- } -- return id.clone(); -- } -- } -- -- @Override -- public SSLSessionContext getSessionContext() { -- return sessionContext; -- } -- -- @Override -- public long getCreationTime() { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (creationTime == 0 && !isDestroyed()) { -- creationTime = SSL.getTime(ssl) * 1000L; -- } -- } -- return creationTime; -- } -- -- @Override -- public long getLastAccessedTime() { -- long lastAccessed = ReferenceCountedOpenSslEngine.this.lastAccessed; -- // if lastAccessed is -1 we will just return the creation time as the handshake was not started yet. -- return lastAccessed == -1 ? getCreationTime() : lastAccessed; -- } -- -- @Override -- public void invalidate() { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (!isDestroyed()) { -- SSL.setTimeout(ssl, 0); -- } -- } -- } -- -- @Override -- public boolean isValid() { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (!isDestroyed()) { -- return System.currentTimeMillis() - (SSL.getTimeout(ssl) * 1000L) < (SSL.getTime(ssl) * 1000L); -- } -- } -- return false; -- } -- -- @Override -- public void putValue(String name, Object value) { -- ObjectUtil.checkNotNull(name, "name"); -- ObjectUtil.checkNotNull(value, "value"); -- -- final Object old; -- synchronized (this) { -- Map values = this.values; -- if (values == null) { -- // Use size of 2 to keep the memory overhead small -- values = this.values = new HashMap(2); -- } -- old = values.put(name, value); -- } -- -- if (value instanceof SSLSessionBindingListener) { -- // Use newSSLSessionBindingEvent so we alway use the wrapper if needed. -- ((SSLSessionBindingListener) value).valueBound(newSSLSessionBindingEvent(name)); -- } -- notifyUnbound(old, name); -- } -- -- @Override -- public Object getValue(String name) { -- ObjectUtil.checkNotNull(name, "name"); -- synchronized (this) { -- if (values == null) { -- return null; -- } -- return values.get(name); -- } -- } -- -- @Override -- public void removeValue(String name) { -- ObjectUtil.checkNotNull(name, "name"); -- -- final Object old; -- synchronized (this) { -- Map values = this.values; -- if (values == null) { -- return; -- } -- old = values.remove(name); -- } -- -- notifyUnbound(old, name); -- } -- -- @Override -- public String[] getValueNames() { -- synchronized (this) { -- Map values = this.values; -- if (values == null || values.isEmpty()) { -- return EmptyArrays.EMPTY_STRINGS; -- } -- return values.keySet().toArray(new String[0]); -- } -- } -- -- private void notifyUnbound(Object value, String name) { -- if (value instanceof SSLSessionBindingListener) { -- // Use newSSLSessionBindingEvent so we alway use the wrapper if needed. -- ((SSLSessionBindingListener) value).valueUnbound(newSSLSessionBindingEvent(name)); -- } -- } -- -- /** -- * Finish the handshake and so init everything in the {@link OpenSslSession} that should be accessible by -- * the user. -- */ -- @Override -- public void handshakeFinished() throws SSLException { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (!isDestroyed()) { -- id = SSL.getSessionId(ssl); -- cipher = toJavaCipherSuite(SSL.getCipherForSSL(ssl)); -- protocol = SSL.getVersion(ssl); -- -- initPeerCerts(); -- selectApplicationProtocol(); -- calculateMaxWrapOverhead(); -- -- handshakeState = HandshakeState.FINISHED; -- } else { -- throw new SSLException("Already closed"); -- } -- } -- } -- -- /** -- * Init peer certificates that can be obtained via {@link #getPeerCertificateChain()} -- * and {@link #getPeerCertificates()}. -- */ -- private void initPeerCerts() { -- // Return the full chain from the JNI layer. -- byte[][] chain = SSL.getPeerCertChain(ssl); -- if (clientMode) { -- if (isEmpty(chain)) { -- peerCerts = EmptyArrays.EMPTY_CERTIFICATES; -- x509PeerCerts = EmptyArrays.EMPTY_JAVAX_X509_CERTIFICATES; -- } else { -- peerCerts = new Certificate[chain.length]; -- x509PeerCerts = new X509Certificate[chain.length]; -- initCerts(chain, 0); -- } -- } else { -- // if used on the server side SSL_get_peer_cert_chain(...) will not include the remote peer -- // certificate. We use SSL_get_peer_certificate to get it in this case and add it to our -- // array later. -- // -- // See https://www.openssl.org/docs/ssl/SSL_get_peer_cert_chain.html -- byte[] clientCert = SSL.getPeerCertificate(ssl); -- if (isEmpty(clientCert)) { -- peerCerts = EmptyArrays.EMPTY_CERTIFICATES; -- x509PeerCerts = EmptyArrays.EMPTY_JAVAX_X509_CERTIFICATES; -- } else { -- if (isEmpty(chain)) { -- peerCerts = new Certificate[] {new OpenSslX509Certificate(clientCert)}; -- x509PeerCerts = new X509Certificate[] {new OpenSslJavaxX509Certificate(clientCert)}; -- } else { -- peerCerts = new Certificate[chain.length + 1]; -- x509PeerCerts = new X509Certificate[chain.length + 1]; -- peerCerts[0] = new OpenSslX509Certificate(clientCert); -- x509PeerCerts[0] = new OpenSslJavaxX509Certificate(clientCert); -- initCerts(chain, 1); -- } -- } -- } -- } -- -- private void initCerts(byte[][] chain, int startPos) { -- for (int i = 0; i < chain.length; i++) { -- int certPos = startPos + i; -- peerCerts[certPos] = new OpenSslX509Certificate(chain[i]); -- x509PeerCerts[certPos] = new OpenSslJavaxX509Certificate(chain[i]); -- } -- } -- -- /** -- * Select the application protocol used. -- */ -- private void selectApplicationProtocol() throws SSLException { -- ApplicationProtocolConfig.SelectedListenerFailureBehavior behavior = apn.selectedListenerFailureBehavior(); -- List protocols = apn.protocols(); -- String applicationProtocol; -- switch (apn.protocol()) { -- case NONE: -- break; -- // We always need to check for applicationProtocol == null as the remote peer may not support -- // the TLS extension or may have returned an empty selection. -- case ALPN: -- applicationProtocol = SSL.getAlpnSelected(ssl); -- if (applicationProtocol != null) { -- ReferenceCountedOpenSslEngine.this.applicationProtocol = selectApplicationProtocol( -- protocols, behavior, applicationProtocol); -- } -- break; -- case NPN: -- applicationProtocol = SSL.getNextProtoNegotiated(ssl); -- if (applicationProtocol != null) { -- ReferenceCountedOpenSslEngine.this.applicationProtocol = selectApplicationProtocol( -- protocols, behavior, applicationProtocol); -- } -- break; -- case NPN_AND_ALPN: -- applicationProtocol = SSL.getAlpnSelected(ssl); -- if (applicationProtocol == null) { -- applicationProtocol = SSL.getNextProtoNegotiated(ssl); -- } -- if (applicationProtocol != null) { -- ReferenceCountedOpenSslEngine.this.applicationProtocol = selectApplicationProtocol( -- protocols, behavior, applicationProtocol); -- } -- break; -- default: -- throw new Error(); -- } -- } -- -- private String selectApplicationProtocol(List protocols, -- ApplicationProtocolConfig.SelectedListenerFailureBehavior behavior, -- String applicationProtocol) throws SSLException { -- if (behavior == ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT) { -- return applicationProtocol; -- } else { -- int size = protocols.size(); -- assert size > 0; -- if (protocols.contains(applicationProtocol)) { -- return applicationProtocol; -- } else { -- if (behavior == ApplicationProtocolConfig.SelectedListenerFailureBehavior.CHOOSE_MY_LAST_PROTOCOL) { -- return protocols.get(size - 1); -- } else { -- throw new SSLException("unknown protocol " + applicationProtocol); -- } -- } -- } -- } -- -- @Override -- public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (isEmpty(peerCerts)) { -- throw new SSLPeerUnverifiedException("peer not verified"); -- } -- return peerCerts.clone(); -- } -- } -- -- @Override -- public Certificate[] getLocalCertificates() { -- Certificate[] localCerts = ReferenceCountedOpenSslEngine.this.localCertificateChain; -- if (localCerts == null) { -- return null; -- } -- return localCerts.clone(); -- } -- -- @Override -- public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (isEmpty(x509PeerCerts)) { -- throw new SSLPeerUnverifiedException("peer not verified"); -- } -- return x509PeerCerts.clone(); -- } -- } -- -- @Override -- public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { -- Certificate[] peer = getPeerCertificates(); -- // No need for null or length > 0 is needed as this is done in getPeerCertificates() -- // already. -- return ((java.security.cert.X509Certificate) peer[0]).getSubjectX500Principal(); -- } -- -- @Override -- public Principal getLocalPrincipal() { -- Certificate[] local = ReferenceCountedOpenSslEngine.this.localCertificateChain; -- if (local == null || local.length == 0) { -- return null; -- } -- return ((java.security.cert.X509Certificate) local[0]).getIssuerX500Principal(); -- } -- -- @Override -- public String getCipherSuite() { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (cipher == null) { -- return SslUtils.INVALID_CIPHER; -- } -- return cipher; -- } -- } -- -- @Override -- public String getProtocol() { -- String protocol = this.protocol; -- if (protocol == null) { -- synchronized (ReferenceCountedOpenSslEngine.this) { -- if (!isDestroyed()) { -- protocol = SSL.getVersion(ssl); -- } else { -- protocol = StringUtil.EMPTY_STRING; -- } -- } -- } -- return protocol; -- } -- -- @Override -- public String getPeerHost() { -- return ReferenceCountedOpenSslEngine.this.getPeerHost(); -- } -- -- @Override -- public int getPeerPort() { -- return ReferenceCountedOpenSslEngine.this.getPeerPort(); -- } -- -- @Override -- public int getPacketBufferSize() { -- return maxEncryptedPacketLength(); -- } -- -- @Override -- public int getApplicationBufferSize() { -- return applicationBufferSize; -- } -- -- @Override -- public void tryExpandApplicationBufferSize(int packetLengthDataOnly) { -- if (packetLengthDataOnly > MAX_PLAINTEXT_LENGTH && applicationBufferSize != MAX_RECORD_SIZE) { -- applicationBufferSize = MAX_RECORD_SIZE; -- } -- } -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java -deleted file mode 100644 -index bac027a3b4..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java -+++ /dev/null -@@ -1,286 +0,0 @@ --/* -- * Copyright 2016 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.buffer.ByteBufAllocator; --import io.netty.internal.tcnative.CertificateCallback; --import io.netty.internal.tcnative.SSL; --import io.netty.internal.tcnative.SSLContext; --import io.netty.internal.tcnative.SniHostNameMatcher; --import io.netty.util.CharsetUtil; --import io.netty.util.internal.PlatformDependent; --import io.netty.util.internal.SuppressJava6Requirement; --import io.netty.util.internal.SystemPropertyUtil; --import io.netty.util.internal.logging.InternalLogger; --import io.netty.util.internal.logging.InternalLoggerFactory; -- --import java.security.KeyStore; --import java.security.PrivateKey; --import java.security.cert.X509Certificate; --import javax.net.ssl.KeyManagerFactory; --import javax.net.ssl.SSLException; --import javax.net.ssl.TrustManagerFactory; --import javax.net.ssl.X509ExtendedTrustManager; --import javax.net.ssl.X509TrustManager; -- --import static io.netty.util.internal.ObjectUtil.checkNotNull; -- --/** -- * A server-side {@link SslContext} which uses OpenSSL's SSL/TLS implementation. -- *

Instances of this class must be {@link #release() released} or else native memory will leak! -- * -- *

Instances of this class must not be released before any {@link ReferenceCountedOpenSslEngine} -- * which depends upon the instance of this class is released. Otherwise if any method of -- * {@link ReferenceCountedOpenSslEngine} is called which uses this class's JNI resources the JVM may crash. -- */ --public final class ReferenceCountedOpenSslServerContext extends ReferenceCountedOpenSslContext { -- private static final InternalLogger logger = -- InternalLoggerFactory.getInstance(ReferenceCountedOpenSslServerContext.class); -- private static final byte[] ID = {'n', 'e', 't', 't', 'y'}; -- private final OpenSslServerSessionContext sessionContext; -- -- private static final boolean ENABLE_SESSION_TICKET = -- SystemPropertyUtil.getBoolean("jdk.tls.server.enableSessionTicketExtension", false); -- -- ReferenceCountedOpenSslServerContext( -- X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, -- X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, -- Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, -- long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls, -- boolean enableOcsp, String keyStore) throws SSLException { -- this(trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory, ciphers, -- cipherFilter, toNegotiator(apn), sessionCacheSize, sessionTimeout, clientAuth, protocols, startTls, -- enableOcsp, keyStore); -- } -- -- ReferenceCountedOpenSslServerContext( -- X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, -- X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, -- Iterable ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn, -- long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls, -- boolean enableOcsp, String keyStore) throws SSLException { -- super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_SERVER, keyCertChain, -- clientAuth, protocols, startTls, enableOcsp, true); -- // Create a new SSL_CTX and configure it. -- boolean success = false; -- try { -- sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory, -- keyCertChain, key, keyPassword, keyManagerFactory, keyStore); -- if (ENABLE_SESSION_TICKET) { -- sessionContext.setTicketKeys(); -- } -- success = true; -- } finally { -- if (!success) { -- release(); -- } -- } -- } -- -- @Override -- public OpenSslServerSessionContext sessionContext() { -- return sessionContext; -- } -- -- static OpenSslServerSessionContext newSessionContext(ReferenceCountedOpenSslContext thiz, long ctx, -- OpenSslEngineMap engineMap, -- X509Certificate[] trustCertCollection, -- TrustManagerFactory trustManagerFactory, -- X509Certificate[] keyCertChain, PrivateKey key, -- String keyPassword, KeyManagerFactory keyManagerFactory, -- String keyStore) -- throws SSLException { -- OpenSslKeyMaterialProvider keyMaterialProvider = null; -- try { -- try { -- SSLContext.setVerify(ctx, SSL.SSL_CVERIFY_NONE, VERIFY_DEPTH); -- if (!OpenSsl.useKeyManagerFactory()) { -- if (keyManagerFactory != null) { -- throw new IllegalArgumentException( -- "KeyManagerFactory not supported"); -- } -- checkNotNull(keyCertChain, "keyCertChain"); -- -- setKeyMaterial(ctx, keyCertChain, key, keyPassword); -- } else { -- // javadocs state that keyManagerFactory has precedent over keyCertChain, and we must have a -- // keyManagerFactory for the server so build one if it is not specified. -- if (keyManagerFactory == null) { -- char[] keyPasswordChars = keyStorePassword(keyPassword); -- KeyStore ks = buildKeyStore(keyCertChain, key, keyPasswordChars, keyStore); -- if (ks.aliases().hasMoreElements()) { -- keyManagerFactory = new OpenSslX509KeyManagerFactory(); -- } else { -- keyManagerFactory = new OpenSslCachingX509KeyManagerFactory( -- KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())); -- } -- keyManagerFactory.init(ks, keyPasswordChars); -- } -- keyMaterialProvider = providerFor(keyManagerFactory, keyPassword); -- -- SSLContext.setCertificateCallback(ctx, new OpenSslServerCertificateCallback( -- engineMap, new OpenSslKeyMaterialManager(keyMaterialProvider))); -- } -- } catch (Exception e) { -- throw new SSLException("failed to set certificate and key", e); -- } -- try { -- if (trustCertCollection != null) { -- trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore); -- } else if (trustManagerFactory == null) { -- // Mimic the way SSLContext.getInstance(KeyManager[], null, null) works -- trustManagerFactory = TrustManagerFactory.getInstance( -- TrustManagerFactory.getDefaultAlgorithm()); -- trustManagerFactory.init((KeyStore) null); -- } -- -- final X509TrustManager manager = chooseTrustManager(trustManagerFactory.getTrustManagers()); -- -- // IMPORTANT: The callbacks set for verification must be static to prevent memory leak as -- // otherwise the context can never be collected. This is because the JNI code holds -- // a global reference to the callbacks. -- // -- // See https://github.com/netty/netty/issues/5372 -- -- setVerifyCallback(ctx, engineMap, manager); -- -- X509Certificate[] issuers = manager.getAcceptedIssuers(); -- if (issuers != null && issuers.length > 0) { -- long bio = 0; -- try { -- bio = toBIO(ByteBufAllocator.DEFAULT, issuers); -- if (!SSLContext.setCACertificateBio(ctx, bio)) { -- throw new SSLException("unable to setup accepted issuers for trustmanager " + manager); -- } -- } finally { -- freeBio(bio); -- } -- } -- -- if (PlatformDependent.javaVersion() >= 8) { -- // Only do on Java8+ as SNIMatcher is not supported in earlier releases. -- // IMPORTANT: The callbacks set for hostname matching must be static to prevent memory leak as -- // otherwise the context can never be collected. This is because the JNI code holds -- // a global reference to the matcher. -- SSLContext.setSniHostnameMatcher(ctx, new OpenSslSniHostnameMatcher(engineMap)); -- } -- } catch (SSLException e) { -- throw e; -- } catch (Exception e) { -- throw new SSLException("unable to setup trustmanager", e); -- } -- -- OpenSslServerSessionContext sessionContext = new OpenSslServerSessionContext(thiz, keyMaterialProvider); -- sessionContext.setSessionIdContext(ID); -- -- keyMaterialProvider = null; -- -- return sessionContext; -- } finally { -- if (keyMaterialProvider != null) { -- keyMaterialProvider.destroy(); -- } -- } -- } -- -- @SuppressJava6Requirement(reason = "Guarded by java version check") -- private static void setVerifyCallback(long ctx, OpenSslEngineMap engineMap, X509TrustManager manager) { -- // Use this to prevent an error when running on java < 7 -- if (useExtendedTrustManager(manager)) { -- SSLContext.setCertVerifyCallback(ctx, new ExtendedTrustManagerVerifyCallback( -- engineMap, (X509ExtendedTrustManager) manager)); -- } else { -- SSLContext.setCertVerifyCallback(ctx, new TrustManagerVerifyCallback(engineMap, manager)); -- } -- } -- -- private static final class OpenSslServerCertificateCallback implements CertificateCallback { -- private final OpenSslEngineMap engineMap; -- private final OpenSslKeyMaterialManager keyManagerHolder; -- -- OpenSslServerCertificateCallback(OpenSslEngineMap engineMap, OpenSslKeyMaterialManager keyManagerHolder) { -- this.engineMap = engineMap; -- this.keyManagerHolder = keyManagerHolder; -- } -- -- @Override -- public void handle(long ssl, byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals) throws Exception { -- final ReferenceCountedOpenSslEngine engine = engineMap.get(ssl); -- if (engine == null) { -- // Maybe null if destroyed in the meantime. -- return; -- } -- try { -- // For now we just ignore the asn1DerEncodedPrincipals as this is kind of inline with what the -- // OpenJDK SSLEngineImpl does. -- keyManagerHolder.setKeyMaterialServerSide(engine); -- } catch (Throwable cause) { -- logger.debug("Failed to set the server-side key material", cause); -- engine.initHandshakeException(cause); -- } -- } -- } -- -- private static final class TrustManagerVerifyCallback extends AbstractCertificateVerifier { -- private final X509TrustManager manager; -- -- TrustManagerVerifyCallback(OpenSslEngineMap engineMap, X509TrustManager manager) { -- super(engineMap); -- this.manager = manager; -- } -- -- @Override -- void verify(ReferenceCountedOpenSslEngine engine, X509Certificate[] peerCerts, String auth) -- throws Exception { -- manager.checkClientTrusted(peerCerts, auth); -- } -- } -- -- @SuppressJava6Requirement(reason = "Usage guarded by java version check") -- private static final class ExtendedTrustManagerVerifyCallback extends AbstractCertificateVerifier { -- private final X509ExtendedTrustManager manager; -- -- ExtendedTrustManagerVerifyCallback(OpenSslEngineMap engineMap, X509ExtendedTrustManager manager) { -- super(engineMap); -- this.manager = OpenSslTlsv13X509ExtendedTrustManager.wrap(manager); -- } -- -- @Override -- void verify(ReferenceCountedOpenSslEngine engine, X509Certificate[] peerCerts, String auth) -- throws Exception { -- manager.checkClientTrusted(peerCerts, auth, engine); -- } -- } -- -- private static final class OpenSslSniHostnameMatcher implements SniHostNameMatcher { -- private final OpenSslEngineMap engineMap; -- -- OpenSslSniHostnameMatcher(OpenSslEngineMap engineMap) { -- this.engineMap = engineMap; -- } -- -- @Override -- public boolean match(long ssl, String hostname) { -- ReferenceCountedOpenSslEngine engine = engineMap.get(ssl); -- if (engine != null) { -- // TODO: In the next release of tcnative we should pass the byte[] directly in and not use a String. -- return engine.checkSniHostnameMatch(hostname.getBytes(CharsetUtil.UTF_8)); -- } -- logger.warn("No ReferenceCountedOpenSslEngine found for SSL pointer: {}", ssl); -- return false; -- } -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/SslContext.java b/handler/src/main/java/io/netty/handler/ssl/SslContext.java -index fef2702cfb..eb5110d145 100644 ---- a/handler/src/main/java/io/netty/handler/ssl/SslContext.java -+++ b/handler/src/main/java/io/netty/handler/ssl/SslContext.java -@@ -120,11 +120,7 @@ public abstract class SslContext { - } - - private static SslProvider defaultProvider() { -- if (OpenSsl.isAvailable()) { -- return SslProvider.OPENSSL; -- } else { -- return SslProvider.JDK; -- } -+ return SslProvider.JDK; - } - - /** -@@ -466,18 +462,6 @@ public abstract class SslContext { - trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, - keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, - clientAuth, protocols, startTls, keyStoreType); -- case OPENSSL: -- verifyNullSslContextProvider(provider, sslContextProvider); -- return new OpenSslServerContext( -- trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, -- keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, -- clientAuth, protocols, startTls, enableOcsp, keyStoreType); -- case OPENSSL_REFCNT: -- verifyNullSslContextProvider(provider, sslContextProvider); -- return new ReferenceCountedOpenSslServerContext( -- trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, -- keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, -- clientAuth, protocols, startTls, enableOcsp, keyStoreType); - default: - throw new Error(provider.toString()); - } -@@ -822,18 +806,6 @@ public abstract class SslContext { - trustCert, trustManagerFactory, keyCertChain, key, keyPassword, - keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, - sessionTimeout, keyStoreType); -- case OPENSSL: -- verifyNullSslContextProvider(provider, sslContextProvider); -- return new OpenSslClientContext( -- trustCert, trustManagerFactory, keyCertChain, key, keyPassword, -- keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout, -- enableOcsp, keyStoreType); -- case OPENSSL_REFCNT: -- verifyNullSslContextProvider(provider, sslContextProvider); -- return new ReferenceCountedOpenSslClientContext( -- trustCert, trustManagerFactory, keyCertChain, key, keyPassword, -- keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout, -- enableOcsp, keyStoreType); - default: - throw new Error(provider.toString()); - } -diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java -index 8e11bbf4cc..56be212b09 100644 ---- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java -+++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java -@@ -181,53 +181,6 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH - private static final int MAX_PLAINTEXT_LENGTH = 16 * 1024; - - private enum SslEngineType { -- TCNATIVE(true, COMPOSITE_CUMULATOR) { -- @Override -- SSLEngineResult unwrap(SslHandler handler, ByteBuf in, int readerIndex, int len, ByteBuf out) -- throws SSLException { -- int nioBufferCount = in.nioBufferCount(); -- int writerIndex = out.writerIndex(); -- final SSLEngineResult result; -- if (nioBufferCount > 1) { -- /* -- * If {@link OpenSslEngine} is in use, -- * we can use a special {@link OpenSslEngine#unwrap(ByteBuffer[], ByteBuffer[])} method -- * that accepts multiple {@link ByteBuffer}s without additional memory copies. -- */ -- ReferenceCountedOpenSslEngine opensslEngine = (ReferenceCountedOpenSslEngine) handler.engine; -- try { -- handler.singleBuffer[0] = toByteBuffer(out, writerIndex, -- out.writableBytes()); -- result = opensslEngine.unwrap(in.nioBuffers(readerIndex, len), handler.singleBuffer); -- } finally { -- handler.singleBuffer[0] = null; -- } -- } else { -- result = handler.engine.unwrap(toByteBuffer(in, readerIndex, len), -- toByteBuffer(out, writerIndex, out.writableBytes())); -- } -- out.writerIndex(writerIndex + result.bytesProduced()); -- return result; -- } -- -- @Override -- ByteBuf allocateWrapBuffer(SslHandler handler, ByteBufAllocator allocator, -- int pendingBytes, int numComponents) { -- return allocator.directBuffer(((ReferenceCountedOpenSslEngine) handler.engine) -- .calculateMaxLengthForWrap(pendingBytes, numComponents)); -- } -- -- @Override -- int calculatePendingData(SslHandler handler, int guess) { -- int sslPending = ((ReferenceCountedOpenSslEngine) handler.engine).sslPending(); -- return sslPending > 0 ? sslPending : guess; -- } -- -- @Override -- boolean jdkCompatibilityMode(SSLEngine engine) { -- return ((ReferenceCountedOpenSslEngine) engine).jdkCompatibilityMode; -- } -- }, - JDK(false, MERGE_CUMULATOR) { - @Override - SSLEngineResult unwrap(SslHandler handler, ByteBuf in, int readerIndex, int len, ByteBuf out) -@@ -280,7 +233,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH - }; - - static SslEngineType forEngine(SSLEngine engine) { -- return engine instanceof ReferenceCountedOpenSslEngine ? TCNATIVE : JDK; -+ return JDK; - } - - SslEngineType(boolean wantsDirectBuffer, Cumulator cumulator) { -diff --git a/handler/src/main/java/io/netty/handler/ssl/SslMasterKeyHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslMasterKeyHandler.java -index b1c710c841..44ef0456ed 100644 ---- a/handler/src/main/java/io/netty/handler/ssl/SslMasterKeyHandler.java -+++ b/handler/src/main/java/io/netty/handler/ssl/SslMasterKeyHandler.java -@@ -138,9 +138,6 @@ public abstract class SslMasterKeyHandler extends ChannelInboundHandlerAdapter { - "via reflection.", e); - } - accept(secretKey, sslSession); -- } else if (OpenSsl.isAvailable() && engine instanceof ReferenceCountedOpenSslEngine) { -- SecretKeySpec secretKey = ((ReferenceCountedOpenSslEngine) engine).masterKey(); -- accept(secretKey, sslSession); - } - } - } -diff --git a/handler/src/main/java/io/netty/handler/ssl/SslProvider.java b/handler/src/main/java/io/netty/handler/ssl/SslProvider.java -index e72cfed8d9..5263314e7c 100644 ---- a/handler/src/main/java/io/netty/handler/ssl/SslProvider.java -+++ b/handler/src/main/java/io/netty/handler/ssl/SslProvider.java -@@ -26,16 +26,7 @@ public enum SslProvider { - /** - * JDK's default implementation. - */ -- JDK, -- /** -- * OpenSSL-based implementation. -- */ -- OPENSSL, -- /** -- * OpenSSL-based implementation which does not have finalizers and instead implements {@link ReferenceCounted}. -- */ -- @UnstableApi -- OPENSSL_REFCNT; -+ JDK; - - /** - * Returns {@code true} if the specified {@link SslProvider} supports -@@ -45,9 +36,6 @@ public enum SslProvider { - switch (provider) { - case JDK: - return JdkAlpnApplicationProtocolNegotiator.isAlpnSupported(); -- case OPENSSL: -- case OPENSSL_REFCNT: -- return OpenSsl.isAlpnSupported(); - default: - throw new Error("Unknown SslProvider: " + provider); - } -diff --git a/handler/src/main/java/io/netty/handler/ssl/ocsp/OcspClientHandler.java b/handler/src/main/java/io/netty/handler/ssl/ocsp/OcspClientHandler.java -deleted file mode 100644 -index c45c50e1e3..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/ocsp/OcspClientHandler.java -+++ /dev/null -@@ -1,61 +0,0 @@ --/* -- * 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.ocsp; -- --import io.netty.channel.ChannelHandlerContext; --import io.netty.channel.ChannelInboundHandlerAdapter; --import io.netty.handler.ssl.ReferenceCountedOpenSslContext; --import io.netty.handler.ssl.ReferenceCountedOpenSslEngine; --import io.netty.handler.ssl.SslHandshakeCompletionEvent; --import io.netty.util.internal.ObjectUtil; --import io.netty.util.internal.UnstableApi; -- --import javax.net.ssl.SSLHandshakeException; -- --/** -- * A handler for SSL clients to handle and act upon stapled OCSP responses. -- * -- * @see ReferenceCountedOpenSslContext#enableOcsp() -- * @see ReferenceCountedOpenSslEngine#getOcspResponse() -- */ --@UnstableApi --public abstract class OcspClientHandler extends ChannelInboundHandlerAdapter { -- -- private final ReferenceCountedOpenSslEngine engine; -- -- protected OcspClientHandler(ReferenceCountedOpenSslEngine engine) { -- this.engine = ObjectUtil.checkNotNull(engine, "engine"); -- } -- -- /** -- * @see ReferenceCountedOpenSslEngine#getOcspResponse() -- */ -- protected abstract boolean verify(ChannelHandlerContext ctx, ReferenceCountedOpenSslEngine engine) throws Exception; -- -- @Override -- public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { -- if (evt instanceof SslHandshakeCompletionEvent) { -- ctx.pipeline().remove(this); -- -- SslHandshakeCompletionEvent event = (SslHandshakeCompletionEvent) evt; -- if (event.isSuccess() && !verify(ctx, engine)) { -- throw new SSLHandshakeException("Bad OCSP response"); -- } -- } -- -- ctx.fireUserEventTriggered(evt); -- } --} -diff --git a/handler/src/main/java/io/netty/handler/ssl/ocsp/package-info.java b/handler/src/main/java/io/netty/handler/ssl/ocsp/package-info.java -deleted file mode 100644 -index 2883ff48cf..0000000000 ---- a/handler/src/main/java/io/netty/handler/ssl/ocsp/package-info.java -+++ /dev/null -@@ -1,23 +0,0 @@ --/* -- * 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. -- */ -- --/** -- * OCSP stapling, -- * formally known as the TLS Certificate Status Request extension, is an -- * alternative approach to the Online Certificate Status Protocol (OCSP) -- * for checking the revocation status of X.509 digital certificates. -- */ --package io.netty.handler.ssl.ocsp; -diff --git a/pom.xml b/pom.xml -index bedd6d6903..75a2da328a 100644 ---- a/pom.xml -+++ b/pom.xml -@@ -465,16 +465,6 @@ - 3.0.0-alpha-5 - - -- -- -- ${project.groupId} -- ${tcnative.artifactId} -- ${tcnative.version} -- ${tcnative.classifier} -- compile -- true -- -- -