From bd224286f5a9fa00432ecfd2291801b417fd4eb4 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Thu, 26 Mar 2015 14:06:11 -0700 Subject: [PATCH] [#3531] Create SslContext.Builder Motivation: SslContext factory methods have gotten out of control; it's past time to swap to a builder. Modifications: New Builder class. The existing factory methods must be left as-is for backward compatibility. Result: Fixes #3531 --- .../netty/example/discard/DiscardClient.java | 4 +- .../netty/example/discard/DiscardServer.java | 3 +- .../io/netty/example/echo/EchoClient.java | 4 +- .../io/netty/example/echo/EchoServer.java | 3 +- .../example/factorial/FactorialClient.java | 4 +- .../example/factorial/FactorialServer.java | 3 +- .../io/netty/example/file/FileServer.java | 3 +- .../example/http/cors/HttpCorsServer.java | 3 +- .../http/file/HttpStaticFileServer.java | 4 +- .../http/helloworld/HttpHelloWorldServer.java | 3 +- .../example/http/snoop/HttpSnoopClient.java | 4 +- .../example/http/snoop/HttpSnoopServer.java | 3 +- .../example/http/upload/HttpUploadClient.java | 4 +- .../example/http/upload/HttpUploadServer.java | 3 +- .../benchmarkserver/WebSocketServer.java | 3 +- .../websocketx/client/WebSocketClient.java | 4 +- .../websocketx/server/WebSocketServer.java | 3 +- .../example/objectecho/ObjectEchoClient.java | 4 +- .../example/objectecho/ObjectEchoServer.java | 3 +- .../PortUnificationServer.java | 4 +- .../example/securechat/SecureChatClient.java | 4 +- .../example/securechat/SecureChatServer.java | 4 +- .../netty/example/spdy/client/SpdyClient.java | 11 +- .../netty/example/spdy/server/SpdyServer.java | 10 +- .../io/netty/example/telnet/TelnetClient.java | 4 +- .../io/netty/example/telnet/TelnetServer.java | 3 +- .../example/worldclock/WorldClockClient.java | 4 +- .../example/worldclock/WorldClockServer.java | 3 +- .../java/io/netty/handler/ssl/SslContext.java | 68 +++++- .../netty/handler/ssl/SslContextBuilder.java | 216 ++++++++++++++++++ 30 files changed, 358 insertions(+), 38 deletions(-) create mode 100644 handler/src/main/java/io/netty/handler/ssl/SslContextBuilder.java diff --git a/example/src/main/java/io/netty/example/discard/DiscardClient.java b/example/src/main/java/io/netty/example/discard/DiscardClient.java index 1f3d57b4cb..3e89342700 100644 --- a/example/src/main/java/io/netty/example/discard/DiscardClient.java +++ b/example/src/main/java/io/netty/example/discard/DiscardClient.java @@ -24,6 +24,7 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; /** @@ -40,7 +41,8 @@ public final class DiscardClient { // Configure SSL. final SslContext sslCtx; if (SSL) { - sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); + sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/discard/DiscardServer.java b/example/src/main/java/io/netty/example/discard/DiscardServer.java index 81dd9e2217..e3071d32cc 100644 --- a/example/src/main/java/io/netty/example/discard/DiscardServer.java +++ b/example/src/main/java/io/netty/example/discard/DiscardServer.java @@ -26,6 +26,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -41,7 +42,7 @@ public final class DiscardServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/echo/EchoClient.java b/example/src/main/java/io/netty/example/echo/EchoClient.java index f0023e8975..1789201600 100644 --- a/example/src/main/java/io/netty/example/echo/EchoClient.java +++ b/example/src/main/java/io/netty/example/echo/EchoClient.java @@ -25,6 +25,7 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; /** @@ -44,7 +45,8 @@ public final class EchoClient { // Configure SSL.git final SslContext sslCtx; if (SSL) { - sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); + sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/echo/EchoServer.java b/example/src/main/java/io/netty/example/echo/EchoServer.java index b4e4029bbb..ddc43fe042 100644 --- a/example/src/main/java/io/netty/example/echo/EchoServer.java +++ b/example/src/main/java/io/netty/example/echo/EchoServer.java @@ -27,6 +27,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -42,7 +43,7 @@ public final class EchoServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/factorial/FactorialClient.java b/example/src/main/java/io/netty/example/factorial/FactorialClient.java index 38c8855066..5d30bf296a 100644 --- a/example/src/main/java/io/netty/example/factorial/FactorialClient.java +++ b/example/src/main/java/io/netty/example/factorial/FactorialClient.java @@ -21,6 +21,7 @@ import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; /** @@ -38,7 +39,8 @@ public final class FactorialClient { // Configure SSL. final SslContext sslCtx; if (SSL) { - sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); + sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/factorial/FactorialServer.java b/example/src/main/java/io/netty/example/factorial/FactorialServer.java index 73f2c72644..f2ba410226 100644 --- a/example/src/main/java/io/netty/example/factorial/FactorialServer.java +++ b/example/src/main/java/io/netty/example/factorial/FactorialServer.java @@ -22,6 +22,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -38,7 +39,7 @@ public final class FactorialServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/file/FileServer.java b/example/src/main/java/io/netty/example/file/FileServer.java index f03f42aa7d..a1e710e2e1 100644 --- a/example/src/main/java/io/netty/example/file/FileServer.java +++ b/example/src/main/java/io/netty/example/file/FileServer.java @@ -30,6 +30,7 @@ import io.netty.handler.codec.string.StringEncoder; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; import io.netty.handler.stream.ChunkedWriteHandler; import io.netty.util.CharsetUtil; @@ -48,7 +49,7 @@ public final class FileServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/http/cors/HttpCorsServer.java b/example/src/main/java/io/netty/example/http/cors/HttpCorsServer.java index 203893611f..da50138cc8 100644 --- a/example/src/main/java/io/netty/example/http/cors/HttpCorsServer.java +++ b/example/src/main/java/io/netty/example/http/cors/HttpCorsServer.java @@ -22,6 +22,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -80,7 +81,7 @@ public final class HttpCorsServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/http/file/HttpStaticFileServer.java b/example/src/main/java/io/netty/example/http/file/HttpStaticFileServer.java index 3acb697086..3f54f830c5 100644 --- a/example/src/main/java/io/netty/example/http/file/HttpStaticFileServer.java +++ b/example/src/main/java/io/netty/example/http/file/HttpStaticFileServer.java @@ -23,6 +23,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslProvider; import io.netty.handler.ssl.util.SelfSignedCertificate; @@ -36,7 +37,8 @@ public final class HttpStaticFileServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(SslProvider.JDK, ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()) + .sslProvider(SslProvider.JDK).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/http/helloworld/HttpHelloWorldServer.java b/example/src/main/java/io/netty/example/http/helloworld/HttpHelloWorldServer.java index 3fc34bba86..849183ee13 100644 --- a/example/src/main/java/io/netty/example/http/helloworld/HttpHelloWorldServer.java +++ b/example/src/main/java/io/netty/example/http/helloworld/HttpHelloWorldServer.java @@ -24,6 +24,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -40,7 +41,7 @@ public final class HttpHelloWorldServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java index b7c14d4cc8..8737c82782 100644 --- a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java +++ b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java @@ -29,6 +29,7 @@ import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import java.net.URI; @@ -63,7 +64,8 @@ public final class HttpSnoopClient { final boolean ssl = "https".equalsIgnoreCase(scheme); final SslContext sslCtx; if (ssl) { - sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); + sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServer.java b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServer.java index 3628d3c2ef..e720da087f 100644 --- a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServer.java +++ b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServer.java @@ -23,6 +23,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -39,7 +40,7 @@ public final class HttpSnoopServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/http/upload/HttpUploadClient.java b/example/src/main/java/io/netty/example/http/upload/HttpUploadClient.java index 3ee0ae43b2..2c2c51e65e 100644 --- a/example/src/main/java/io/netty/example/http/upload/HttpUploadClient.java +++ b/example/src/main/java/io/netty/example/http/upload/HttpUploadClient.java @@ -38,6 +38,7 @@ import io.netty.handler.codec.http.multipart.HttpDataFactory; import io.netty.handler.codec.http.multipart.HttpPostRequestEncoder; import io.netty.handler.codec.http.multipart.InterfaceHttpData; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import java.io.File; @@ -87,7 +88,8 @@ public final class HttpUploadClient { final boolean ssl = "https".equalsIgnoreCase(scheme); final SslContext sslCtx; if (ssl) { - sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); + sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/http/upload/HttpUploadServer.java b/example/src/main/java/io/netty/example/http/upload/HttpUploadServer.java index 5e5d3cbf8e..a004f759e3 100644 --- a/example/src/main/java/io/netty/example/http/upload/HttpUploadServer.java +++ b/example/src/main/java/io/netty/example/http/upload/HttpUploadServer.java @@ -23,6 +23,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -38,7 +39,7 @@ public final class HttpUploadServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/http/websocketx/benchmarkserver/WebSocketServer.java b/example/src/main/java/io/netty/example/http/websocketx/benchmarkserver/WebSocketServer.java index 73fee73497..96b08807d9 100644 --- a/example/src/main/java/io/netty/example/http/websocketx/benchmarkserver/WebSocketServer.java +++ b/example/src/main/java/io/netty/example/http/websocketx/benchmarkserver/WebSocketServer.java @@ -23,6 +23,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -43,7 +44,7 @@ public final class WebSocketServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/http/websocketx/client/WebSocketClient.java b/example/src/main/java/io/netty/example/http/websocketx/client/WebSocketClient.java index 2c44af2932..8b06516c36 100644 --- a/example/src/main/java/io/netty/example/http/websocketx/client/WebSocketClient.java +++ b/example/src/main/java/io/netty/example/http/websocketx/client/WebSocketClient.java @@ -34,6 +34,7 @@ import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory; import io.netty.handler.codec.http.websocketx.WebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketVersion; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import io.netty.handler.ssl.util.SelfSignedCertificate; @@ -83,7 +84,8 @@ public final class WebSocketClient { final boolean ssl = "wss".equalsIgnoreCase(scheme); final SslContext sslCtx; if (ssl) { - sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); + sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/http/websocketx/server/WebSocketServer.java b/example/src/main/java/io/netty/example/http/websocketx/server/WebSocketServer.java index 199a08149a..3d18f138fe 100644 --- a/example/src/main/java/io/netty/example/http/websocketx/server/WebSocketServer.java +++ b/example/src/main/java/io/netty/example/http/websocketx/server/WebSocketServer.java @@ -23,6 +23,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -54,7 +55,7 @@ public final class WebSocketServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/objectecho/ObjectEchoClient.java b/example/src/main/java/io/netty/example/objectecho/ObjectEchoClient.java index ce2f49ea28..a6deec57a8 100644 --- a/example/src/main/java/io/netty/example/objectecho/ObjectEchoClient.java +++ b/example/src/main/java/io/netty/example/objectecho/ObjectEchoClient.java @@ -27,6 +27,7 @@ import io.netty.handler.codec.serialization.ClassResolvers; import io.netty.handler.codec.serialization.ObjectDecoder; import io.netty.handler.codec.serialization.ObjectEncoder; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; /** @@ -43,7 +44,8 @@ public final class ObjectEchoClient { // Configure SSL. final SslContext sslCtx; if (SSL) { - sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); + sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/objectecho/ObjectEchoServer.java b/example/src/main/java/io/netty/example/objectecho/ObjectEchoServer.java index 9b277ea7ca..2c11324667 100644 --- a/example/src/main/java/io/netty/example/objectecho/ObjectEchoServer.java +++ b/example/src/main/java/io/netty/example/objectecho/ObjectEchoServer.java @@ -29,6 +29,7 @@ import io.netty.handler.codec.serialization.ObjectEncoder; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -44,7 +45,7 @@ public final class ObjectEchoServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/portunification/PortUnificationServer.java b/example/src/main/java/io/netty/example/portunification/PortUnificationServer.java index 68f70f978e..bff59f285b 100644 --- a/example/src/main/java/io/netty/example/portunification/PortUnificationServer.java +++ b/example/src/main/java/io/netty/example/portunification/PortUnificationServer.java @@ -24,6 +24,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -40,7 +41,8 @@ public final class PortUnificationServer { public static void main(String[] args) throws Exception { // Configure SSL context SelfSignedCertificate ssc = new SelfSignedCertificate(); - final SslContext sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + final SslContext sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()) + .build(); EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); diff --git a/example/src/main/java/io/netty/example/securechat/SecureChatClient.java b/example/src/main/java/io/netty/example/securechat/SecureChatClient.java index 390775e2cd..3305b6af9e 100644 --- a/example/src/main/java/io/netty/example/securechat/SecureChatClient.java +++ b/example/src/main/java/io/netty/example/securechat/SecureChatClient.java @@ -23,6 +23,7 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.example.telnet.TelnetClient; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import java.io.BufferedReader; @@ -38,7 +39,8 @@ public final class SecureChatClient { public static void main(String[] args) throws Exception { // Configure SSL. - final SslContext sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); + final SslContext sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); EventLoopGroup group = new NioEventLoopGroup(); try { diff --git a/example/src/main/java/io/netty/example/securechat/SecureChatServer.java b/example/src/main/java/io/netty/example/securechat/SecureChatServer.java index 0726246098..e72f835643 100644 --- a/example/src/main/java/io/netty/example/securechat/SecureChatServer.java +++ b/example/src/main/java/io/netty/example/securechat/SecureChatServer.java @@ -23,6 +23,7 @@ import io.netty.example.telnet.TelnetServer; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -34,7 +35,8 @@ public final class SecureChatServer { public static void main(String[] args) throws Exception { SelfSignedCertificate ssc = new SelfSignedCertificate(); - SslContext sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + SslContext sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()) + .build(); EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); diff --git a/example/src/main/java/io/netty/example/spdy/client/SpdyClient.java b/example/src/main/java/io/netty/example/spdy/client/SpdyClient.java index 74bbb2dabb..9ceef9f2ec 100644 --- a/example/src/main/java/io/netty/example/spdy/client/SpdyClient.java +++ b/example/src/main/java/io/netty/example/spdy/client/SpdyClient.java @@ -34,6 +34,7 @@ import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBeh import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior; import io.netty.handler.ssl.IdentityCipherSuiteFilter; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; /** @@ -57,15 +58,15 @@ public final class SpdyClient { public static void main(String[] args) throws Exception { // Configure SSL. - final SslContext sslCtx = SslContext.newClientContext( - null, InsecureTrustManagerFactory.INSTANCE, null, IdentityCipherSuiteFilter.INSTANCE, - new ApplicationProtocolConfig( + final SslContext sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE) + .applicationProtocolConfig(new ApplicationProtocolConfig( Protocol.NPN, SelectorFailureBehavior.CHOOSE_MY_LAST_PROTOCOL, SelectedListenerFailureBehavior.CHOOSE_MY_LAST_PROTOCOL, SelectedProtocol.SPDY_3_1.protocolName(), - SelectedProtocol.HTTP_1_1.protocolName()), - 0, 0); + SelectedProtocol.HTTP_1_1.protocolName())) + .build(); HttpResponseClientHandler httpResponseHandler = new HttpResponseClientHandler(); EventLoopGroup workerGroup = new NioEventLoopGroup(); diff --git a/example/src/main/java/io/netty/example/spdy/server/SpdyServer.java b/example/src/main/java/io/netty/example/spdy/server/SpdyServer.java index ff1a6b7d1e..0f5e0ca25c 100644 --- a/example/src/main/java/io/netty/example/spdy/server/SpdyServer.java +++ b/example/src/main/java/io/netty/example/spdy/server/SpdyServer.java @@ -30,6 +30,7 @@ import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBeh import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior; import io.netty.handler.ssl.IdentityCipherSuiteFilter; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -57,15 +58,14 @@ public final class SpdyServer { public static void main(String[] args) throws Exception { // Configure SSL. SelfSignedCertificate ssc = new SelfSignedCertificate(); - SslContext sslCtx = SslContext.newServerContext( - ssc.certificate(), ssc.privateKey(), null, null, IdentityCipherSuiteFilter.INSTANCE, - new ApplicationProtocolConfig( + SslContext sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()) + .applicationProtocolConfig(new ApplicationProtocolConfig( Protocol.NPN, SelectorFailureBehavior.CHOOSE_MY_LAST_PROTOCOL, SelectedListenerFailureBehavior.CHOOSE_MY_LAST_PROTOCOL, SelectedProtocol.SPDY_3_1.protocolName(), - SelectedProtocol.HTTP_1_1.protocolName()), - 0, 0); + SelectedProtocol.HTTP_1_1.protocolName())) + .build(); // Configure the server. EventLoopGroup bossGroup = new NioEventLoopGroup(1); diff --git a/example/src/main/java/io/netty/example/telnet/TelnetClient.java b/example/src/main/java/io/netty/example/telnet/TelnetClient.java index 87923419c6..c2be136163 100644 --- a/example/src/main/java/io/netty/example/telnet/TelnetClient.java +++ b/example/src/main/java/io/netty/example/telnet/TelnetClient.java @@ -22,6 +22,7 @@ import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import java.io.BufferedReader; @@ -40,7 +41,8 @@ public final class TelnetClient { // Configure SSL. final SslContext sslCtx; if (SSL) { - sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); + sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/telnet/TelnetServer.java b/example/src/main/java/io/netty/example/telnet/TelnetServer.java index 751add8794..acdf8d3a3d 100644 --- a/example/src/main/java/io/netty/example/telnet/TelnetServer.java +++ b/example/src/main/java/io/netty/example/telnet/TelnetServer.java @@ -22,6 +22,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -37,7 +38,7 @@ public final class TelnetServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/worldclock/WorldClockClient.java b/example/src/main/java/io/netty/example/worldclock/WorldClockClient.java index 4b2ca5424f..c5863d4e9c 100644 --- a/example/src/main/java/io/netty/example/worldclock/WorldClockClient.java +++ b/example/src/main/java/io/netty/example/worldclock/WorldClockClient.java @@ -21,6 +21,7 @@ import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import java.util.Arrays; @@ -42,7 +43,8 @@ public final class WorldClockClient { // Configure SSL. final SslContext sslCtx; if (SSL) { - sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); + sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); } else { sslCtx = null; } diff --git a/example/src/main/java/io/netty/example/worldclock/WorldClockServer.java b/example/src/main/java/io/netty/example/worldclock/WorldClockServer.java index 1900f3c37c..cabea2aef9 100644 --- a/example/src/main/java/io/netty/example/worldclock/WorldClockServer.java +++ b/example/src/main/java/io/netty/example/worldclock/WorldClockServer.java @@ -22,6 +22,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; /** @@ -38,7 +39,7 @@ public final class WorldClockServer { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); - sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey()); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } 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 669ea7516b..ebb735d5c0 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SslContext.java +++ b/handler/src/main/java/io/netty/handler/ssl/SslContext.java @@ -56,7 +56,7 @@ import java.util.List; *
  * // In your {@link ChannelInitializer}:
  * {@link ChannelPipeline} p = channel.pipeline();
- * {@link SslContext} sslCtx = {@link #newServerContext(File, File) SslContext.newServerContext(...)};
+ * {@link SslContext} sslCtx = {@link SslContextBuilder#forServer(File, File) SslContextBuilder.forServer(...)}.build();
  * p.addLast("ssl", {@link #newEngine(ByteBufAllocator) sslCtx.newEngine(channel.alloc())});
  * ...
  * 
@@ -65,7 +65,7 @@ import java.util.List; *
  * // In your {@link ChannelInitializer}:
  * {@link ChannelPipeline} p = channel.pipeline();
- * {@link SslContext} sslCtx = {@link #newClientContext(File) SslContext.newClientContext(...)};
+ * {@link SslContext} sslCtx = {@link #newBuilderForClient() SslContext.newBuilderForClient()}.build();
  * p.addLast("ssl", {@link #newEngine(ByteBufAllocator, String, int) sslCtx.newEngine(channel.alloc(), host, port)});
  * ...
  * 
@@ -112,7 +112,9 @@ public abstract class SslContext { * @param certChainFile an X.509 certificate chain file in PEM format * @param keyFile a PKCS#8 private key file in PEM format * @return a new server-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newServerContext(File certChainFile, File keyFile) throws SSLException { return newServerContext(certChainFile, keyFile, null); } @@ -125,7 +127,9 @@ public abstract class SslContext { * @param keyPassword the password of the {@code keyFile}. * {@code null} if it's not password-protected. * @return a new server-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newServerContext( File certChainFile, File keyFile, String keyPassword) throws SSLException { return newServerContext(null, certChainFile, keyFile, keyPassword); @@ -149,6 +153,7 @@ public abstract class SslContext { * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. * {@code 0} to use the default value. * @return a new server-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ @Deprecated public static SslContext newServerContext( @@ -177,7 +182,9 @@ public abstract class SslContext { * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. * {@code 0} to use the default value. * @return a new server-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newServerContext( File certChainFile, File keyFile, String keyPassword, Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, @@ -195,7 +202,9 @@ public abstract class SslContext { * @param certChainFile an X.509 certificate chain file in PEM format * @param keyFile a PKCS#8 private key file in PEM format * @return a new server-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newServerContext( SslProvider provider, File certChainFile, File keyFile) throws SSLException { return newServerContext(provider, certChainFile, keyFile, null); @@ -211,7 +220,9 @@ public abstract class SslContext { * @param keyPassword the password of the {@code keyFile}. * {@code null} if it's not password-protected. * @return a new server-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newServerContext( SslProvider provider, File certChainFile, File keyFile, String keyPassword) throws SSLException { return newServerContext(provider, certChainFile, keyFile, keyPassword, null, IdentityCipherSuiteFilter.INSTANCE, @@ -238,6 +249,7 @@ public abstract class SslContext { * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. * {@code 0} to use the default value. * @return a new server-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ @Deprecated public static SslContext newServerContext( @@ -271,7 +283,9 @@ public abstract class SslContext { * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. * {@code 0} to use the default value. * @return a new server-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newServerContext( SslProvider provider, File certChainFile, File keyFile, String keyPassword, TrustManagerFactory trustManagerFactory, @@ -303,7 +317,9 @@ public abstract class SslContext { * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. * {@code 0} to use the default value. * @return a new server-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newServerContext(SslProvider provider, File certChainFile, File keyFile, String keyPassword, Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, @@ -342,13 +358,26 @@ public abstract class SslContext { * @param sessionTimeout the timeout for the cached SSL session objects, in seconds. * {@code 0} to use the default value. * @return a new server-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newServerContext( SslProvider provider, File trustCertChainFile, TrustManagerFactory trustManagerFactory, File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout) throws SSLException { + return newServerContext(provider, trustCertChainFile, trustManagerFactory, keyCertChainFile, + keyFile, keyPassword, keyManagerFactory, ciphers, cipherFilter, apn, + sessionCacheSize, sessionTimeout); + } + + static SslContext newServerContextInternal( + SslProvider provider, + File trustCertChainFile, TrustManagerFactory trustManagerFactory, + File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory, + Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, + long sessionCacheSize, long sessionTimeout) throws SSLException { if (provider == null) { provider = defaultServerProvider(); @@ -372,7 +401,9 @@ public abstract class SslContext { * Creates a new client-side {@link SslContext}. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext() throws SSLException { return newClientContext(null, null, null); } @@ -383,7 +414,9 @@ public abstract class SslContext { * @param certChainFile an X.509 certificate chain file in PEM format * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext(File certChainFile) throws SSLException { return newClientContext(null, certChainFile); } @@ -396,7 +429,9 @@ public abstract class SslContext { * {@code null} to use the default. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext(TrustManagerFactory trustManagerFactory) throws SSLException { return newClientContext(null, null, trustManagerFactory); } @@ -411,7 +446,9 @@ public abstract class SslContext { * {@code null} to use the default. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext( File certChainFile, TrustManagerFactory trustManagerFactory) throws SSLException { return newClientContext(null, certChainFile, trustManagerFactory); @@ -437,6 +474,7 @@ public abstract class SslContext { * {@code 0} to use the default value. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ @Deprecated public static SslContext newClientContext( @@ -466,7 +504,9 @@ public abstract class SslContext { * {@code 0} to use the default value. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext( File certChainFile, TrustManagerFactory trustManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, @@ -483,7 +523,9 @@ public abstract class SslContext { * {@code null} to use the current default one. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext(SslProvider provider) throws SSLException { return newClientContext(provider, null, null); } @@ -497,7 +539,9 @@ public abstract class SslContext { * {@code null} to use the system default * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext(SslProvider provider, File certChainFile) throws SSLException { return newClientContext(provider, certChainFile, null); } @@ -512,7 +556,9 @@ public abstract class SslContext { * {@code null} to use the default. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext( SslProvider provider, TrustManagerFactory trustManagerFactory) throws SSLException { return newClientContext(provider, null, trustManagerFactory); @@ -530,7 +576,9 @@ public abstract class SslContext { * {@code null} to use the default. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext( SslProvider provider, File certChainFile, TrustManagerFactory trustManagerFactory) throws SSLException { return newClientContext(provider, certChainFile, trustManagerFactory, null, IdentityCipherSuiteFilter.INSTANCE, @@ -559,6 +607,7 @@ public abstract class SslContext { * {@code 0} to use the default value. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ @Deprecated public static SslContext newClientContext( @@ -592,7 +641,9 @@ public abstract class SslContext { * {@code 0} to use the default value. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext( SslProvider provider, File certChainFile, TrustManagerFactory trustManagerFactory, @@ -638,13 +689,26 @@ public abstract class SslContext { * {@code 0} to use the default value. * * @return a new client-side {@link SslContext} + * @deprecated Replaced by {@link SslContextBuilder} */ + @Deprecated public static SslContext newClientContext( SslProvider provider, File trustCertChainFile, TrustManagerFactory trustManagerFactory, File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout) throws SSLException { + return newClientContextInternal(provider, trustCertChainFile, trustManagerFactory, + keyCertChainFile, keyFile, keyPassword, keyManagerFactory, ciphers, cipherFilter, apn, + sessionCacheSize, sessionTimeout); + } + + static SslContext newClientContextInternal( + SslProvider provider, + File trustCertChainFile, TrustManagerFactory trustManagerFactory, + File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory, + Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, + long sessionCacheSize, long sessionTimeout) throws SSLException { if (provider == null) { provider = defaultClientProvider(); } diff --git a/handler/src/main/java/io/netty/handler/ssl/SslContextBuilder.java b/handler/src/main/java/io/netty/handler/ssl/SslContextBuilder.java new file mode 100644 index 0000000000..e935e7c8b3 --- /dev/null +++ b/handler/src/main/java/io/netty/handler/ssl/SslContextBuilder.java @@ -0,0 +1,216 @@ +/* + * 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 static io.netty.util.internal.ObjectUtil.checkNotNull; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; + +/** + * Builder for configuring a new SslContext for creation. + */ +public final class SslContextBuilder { + /** + * Creates a builder for new client-side {@link SslContext}. + */ + public static SslContextBuilder forClient() { + return new SslContextBuilder(true); + } + + /** + * Creates a builder for new server-side {@link SslContext}. + * + * @param keyCertChainFile an X.509 certificate chain file in PEM format + * @param keyFile a PKCS#8 private key file in PEM format + */ + public static SslContextBuilder forServer(File keyCertChainFile, File keyFile) { + return new SslContextBuilder(false).keyManager(keyCertChainFile, keyFile); + } + + /** + * Creates a builder for new server-side {@link SslContext}. + * + * @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}, or {@code null} if it's not + * password-protected + */ + public static SslContextBuilder forServer( + File keyCertChainFile, File keyFile, String keyPassword) { + return new SslContextBuilder(false).keyManager(keyCertChainFile, keyFile, keyPassword); + } + + private final boolean forServer; + private SslProvider provider; + private File trustCertChainFile; + private TrustManagerFactory trustManagerFactory; + private File keyCertChainFile; + private File keyFile; + private String keyPassword; + private KeyManagerFactory keyManagerFactory; + private Iterable ciphers; + private CipherSuiteFilter cipherFilter = IdentityCipherSuiteFilter.INSTANCE; + private ApplicationProtocolConfig apn; + private long sessionCacheSize; + private long sessionTimeout; + + private SslContextBuilder(boolean forServer) { + this.forServer = forServer; + } + + /** + * The {@link SslContext} implementation to use. {@code null} uses the default one. + */ + public SslContextBuilder sslProvider(SslProvider provider) { + this.provider = provider; + return this; + } + + /** + * Trusted certificates for verifying the remote endpoint's certificate. The file should + * contain an X.509 certificate chain in PEM format. {@code null} uses the system default. + */ + public SslContextBuilder trustManager(File trustCertChainFile) { + this.trustCertChainFile = trustCertChainFile; + this.trustManagerFactory = null; + return this; + } + + /** + * Trusted manager for verifying the remote endpoint's certificate. Using a {@link + * TrustManagerFactory} is only supported for {@link SslProvider#JDK}; for other providers, + * you must use {@link #trustManager(File)}. {@code null} uses the system default. + */ + public SslContextBuilder trustManager(TrustManagerFactory trustManagerFactory) { + this.trustCertChainFile = null; + this.trustManagerFactory = trustManagerFactory; + return this; + } + + /** + * Identifying certificate for this host. {@code keyCertChainFile} and {@code keyFile} may + * be {@code null} for client contexts, which disables mutual authentication. + * + * @param keyCertChainFile an X.509 certificate chain file in PEM format + * @param keyFile a PKCS#8 private key file in PEM format + */ + public SslContextBuilder keyManager(File keyCertChainFile, File keyFile) { + return keyManager(keyCertChainFile, keyFile, null); + } + + /** + * Identifying certificate for this host. {@code keyCertChainFile} and {@code keyFile} may + * be {@code null} for client contexts, which disables mutual authentication. + * + * @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}, or {@code null} if it's not + * password-protected + */ + public SslContextBuilder keyManager(File keyCertChainFile, File keyFile, String keyPassword) { + if (forServer) { + checkNotNull(keyCertChainFile, "keyCertChainFile required for servers"); + checkNotNull(keyFile, "keyFile required for servers"); + } + this.keyCertChainFile = keyCertChainFile; + this.keyFile = keyFile; + this.keyPassword = keyPassword; + this.keyManagerFactory = null; + return this; + } + + /** + * Identifying manager for this host. {@code keyManagerFactory} may be {@code null} for + * client contexts, which disables mutual authentication. Using a {@code KeyManagerFactory} + * is only supported for {@link SslProvider#JDK}; for other providers, you must use {@link + * #keyManager(File, File)} or {@link #keyManager(File, File, String)}. + */ + public SslContextBuilder keyManager(KeyManagerFactory keyManagerFactory) { + if (forServer) { + checkNotNull(keyManagerFactory, "keyManagerFactory required for servers"); + } + this.keyCertChainFile = null; + this.keyFile = null; + this.keyPassword = null; + this.keyManagerFactory = keyManagerFactory; + return this; + } + + /** + * The cipher suites to enable, in the order of preference. {@code null} to use default + * cipher suites. + */ + public SslContextBuilder ciphers(Iterable ciphers) { + return ciphers(ciphers, IdentityCipherSuiteFilter.INSTANCE); + } + + /** + * The cipher suites to enable, in the order of preference. {@code cipherFilter} will be + * applied to the ciphers before use if provider is {@link SslProvider#JDK}. If {@code + * ciphers} is {@code null}, then the default cipher suites will be used. + */ + public SslContextBuilder ciphers(Iterable ciphers, CipherSuiteFilter cipherFilter) { + checkNotNull(cipherFilter, "cipherFilter"); + this.ciphers = ciphers; + this.cipherFilter = cipherFilter; + return this; + } + + /** + * Application protocol negotiation configuration. {@code null} disables support. + */ + public SslContextBuilder applicationProtocolConfig(ApplicationProtocolConfig apn) { + this.apn = apn; + return this; + } + + /** + * Set the size of the cache used for storing SSL session objects. {@code 0} to use the + * default value. + */ + public SslContextBuilder sessionCacheSize(long sessionCacheSize) { + this.sessionCacheSize = sessionCacheSize; + return this; + } + + /** + * Set the timeout for the cached SSL session objects, in seconds. {@code 0} to use the + * default value. + */ + public SslContextBuilder sessionTimeout(long sessionTimeout) { + this.sessionTimeout = sessionTimeout; + return this; + } + + /** + * Create new {@code SslContext} instance with configured settings. + */ + public SslContext build() throws SSLException { + if (forServer) { + return SslContext.newServerContextInternal(provider, trustCertChainFile, + trustManagerFactory, keyCertChainFile, keyFile, keyPassword, keyManagerFactory, + ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout); + } else { + return SslContext.newClientContextInternal(provider, trustCertChainFile, + trustManagerFactory, keyCertChainFile, keyFile, keyPassword, keyManagerFactory, + ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout); + } + } +}