diff --git a/benchmarks/src/main/java/io/grpc/benchmarks/qps/AsyncClient.java b/benchmarks/src/main/java/io/grpc/benchmarks/qps/AsyncClient.java index 8e8456fbb4..fcad5b89df 100644 --- a/benchmarks/src/main/java/io/grpc/benchmarks/qps/AsyncClient.java +++ b/benchmarks/src/main/java/io/grpc/benchmarks/qps/AsyncClient.java @@ -65,6 +65,7 @@ import io.grpc.Channel; import io.grpc.ChannelImpl; import io.grpc.Status; import io.grpc.stub.StreamObserver; +import io.grpc.transport.netty.GrpcSslContexts; import io.grpc.transport.netty.NegotiationType; import io.grpc.transport.netty.NettyChannelBuilder; import io.grpc.transport.okhttp.OkHttpChannelBuilder; @@ -184,7 +185,7 @@ public class AsyncClient { // Force the hostname to match the cert the server uses. address = InetAddress.getByAddress("foo.test.google.fr", address.getAddress()); File cert = loadCert("ca.pem"); - context = SslContext.newClientContext(cert); + context = GrpcSslContexts.forClient().trustManager(cert).build(); } return NettyChannelBuilder .forAddress(new InetSocketAddress(address, config.port)) diff --git a/benchmarks/src/main/java/io/grpc/benchmarks/qps/AsyncServer.java b/benchmarks/src/main/java/io/grpc/benchmarks/qps/AsyncServer.java index d617687c04..fdcba3184a 100644 --- a/benchmarks/src/main/java/io/grpc/benchmarks/qps/AsyncServer.java +++ b/benchmarks/src/main/java/io/grpc/benchmarks/qps/AsyncServer.java @@ -45,6 +45,7 @@ import grpc.testing.TestServiceGrpc; import io.grpc.ServerImpl; import io.grpc.Status; import io.grpc.stub.StreamObserver; +import io.grpc.transport.netty.GrpcSslContexts; import io.grpc.transport.netty.NettyServerBuilder; import io.netty.handler.ssl.SslContext; @@ -82,7 +83,7 @@ public class AsyncServer { File cert = loadCert("server1.pem"); File key = loadCert("server1.key"); - sslContext = SslContext.newServerContext(cert, key); + sslContext = GrpcSslContexts.forServer(cert, key).build(); } if (port == 0) { diff --git a/benchmarks/src/main/java/io/grpc/benchmarks/qps/ClientUtil.java b/benchmarks/src/main/java/io/grpc/benchmarks/qps/ClientUtil.java index ebb89b2310..68771e98d5 100644 --- a/benchmarks/src/main/java/io/grpc/benchmarks/qps/ClientUtil.java +++ b/benchmarks/src/main/java/io/grpc/benchmarks/qps/ClientUtil.java @@ -39,6 +39,7 @@ import com.google.protobuf.ByteString; import grpc.testing.Qpstest; import grpc.testing.Qpstest.SimpleRequest; import io.grpc.Channel; +import io.grpc.transport.netty.GrpcSslContexts; import io.grpc.transport.netty.NegotiationType; import io.grpc.transport.netty.NettyChannelBuilder; import io.grpc.transport.okhttp.OkHttpChannelBuilder; @@ -91,7 +92,7 @@ final class ClientUtil { // Force the hostname to match the cert the server uses. address = InetAddress.getByAddress("foo.test.google.fr", address.getAddress()); File cert = loadCert("ca.pem"); - context = SslContext.newClientContext(cert); + context = GrpcSslContexts.forClient().trustManager(cert).build(); } return NettyChannelBuilder .forAddress(new InetSocketAddress(address, config.port)) diff --git a/integration-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java b/integration-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java index 19e1a63d2f..9fd0ce745e 100644 --- a/integration-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java +++ b/integration-testing/src/main/java/io/grpc/testing/integration/TestServiceClient.java @@ -32,6 +32,7 @@ package io.grpc.testing.integration; import io.grpc.ChannelImpl; +import io.grpc.transport.netty.GrpcSslContexts; import io.grpc.transport.netty.NegotiationType; import io.grpc.transport.netty.NettyChannelBuilder; import io.grpc.transport.okhttp.OkHttpChannelBuilder; @@ -224,7 +225,7 @@ public class TestServiceClient { SslContext sslContext = null; if (useTestCa) { try { - sslContext = SslContext.newClientContext(Util.loadCert("ca.pem")); + sslContext = GrpcSslContexts.forClient().trustManager(Util.loadCert("ca.pem")).build(); } catch (Exception ex) { throw new RuntimeException(ex); } diff --git a/integration-testing/src/main/java/io/grpc/testing/integration/TestServiceServer.java b/integration-testing/src/main/java/io/grpc/testing/integration/TestServiceServer.java index 8e4713ea5f..47597902c2 100644 --- a/integration-testing/src/main/java/io/grpc/testing/integration/TestServiceServer.java +++ b/integration-testing/src/main/java/io/grpc/testing/integration/TestServiceServer.java @@ -36,6 +36,7 @@ import com.google.common.util.concurrent.MoreExecutors; import io.grpc.ServerImpl; import io.grpc.ServerInterceptors; import io.grpc.testing.TestUtils; +import io.grpc.transport.netty.GrpcSslContexts; import io.grpc.transport.netty.NettyServerBuilder; import io.netty.handler.ssl.SslContext; @@ -133,8 +134,8 @@ public class TestServiceServer { executor = Executors.newSingleThreadScheduledExecutor(); SslContext sslContext = null; if (useTls) { - sslContext = SslContext.newServerContext(Util.loadCert("server1.pem"), - Util.loadCert("server1.key")); + sslContext = GrpcSslContexts.forServer( + Util.loadCert("server1.pem"), Util.loadCert("server1.key")).build(); } server = NettyServerBuilder.forPort(port) .sslContext(sslContext) diff --git a/integration-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java b/integration-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java index d864ad0101..49b027fa7b 100644 --- a/integration-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java +++ b/integration-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java @@ -32,9 +32,9 @@ package io.grpc.testing.integration; import io.grpc.ChannelImpl; +import io.grpc.transport.netty.GrpcSslContexts; import io.grpc.transport.netty.NettyChannelBuilder; import io.grpc.transport.netty.NettyServerBuilder; -import io.netty.handler.ssl.SslContext; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -57,8 +57,8 @@ public class Http2NettyTest extends AbstractTransportTest { public static void startServer() { try { startStaticServer(NettyServerBuilder.forPort(serverPort) - .sslContext(SslContext.newServerContext( - Util.loadCert("server1.pem"), Util.loadCert("server1.key")))); + .sslContext(GrpcSslContexts.forServer( + Util.loadCert("server1.pem"), Util.loadCert("server1.key")).build())); } catch (IOException ex) { throw new RuntimeException(ex); } @@ -76,7 +76,7 @@ public class Http2NettyTest extends AbstractTransportTest { = InetAddress.getByAddress("foo.test.google.fr", new byte[] {127, 0, 0, 1}); return NettyChannelBuilder .forAddress(new InetSocketAddress(address, serverPort)) - .sslContext(SslContext.newClientContext(Util.loadCert("ca.pem"))) + .sslContext(GrpcSslContexts.forClient().trustManager(Util.loadCert("ca.pem")).build()) .build(); } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/netty/src/main/java/io/grpc/transport/netty/GrpcSslContexts.java b/netty/src/main/java/io/grpc/transport/netty/GrpcSslContexts.java new file mode 100644 index 0000000000..874c6526f5 --- /dev/null +++ b/netty/src/main/java/io/grpc/transport/netty/GrpcSslContexts.java @@ -0,0 +1,86 @@ +/* + * Copyright 2015, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.grpc.transport.netty; + +import io.netty.handler.codec.http2.Http2SecurityUtil; +import io.netty.handler.ssl.SslContextBuilder; +import io.netty.handler.ssl.SupportedCipherSuiteFilter; + +import java.io.File; + +/** + * Utility for configuring SslContext for gRPC. + */ +public class GrpcSslContexts { + private GrpcSslContexts() {} + + /** + * Creates a SslContextBuilder with ciphers and APN appropriate for gRPC. + * + * @see SslContextBuilder#forClient() + * @see #configure(SslContextBuilder) + */ + public static SslContextBuilder forClient() { + return configure(SslContextBuilder.forClient()); + } + + /** + * Creates a SslContextBuilder with ciphers and APN appropriate for gRPC. + * + * @see SslContextBuilder#forServer(File, File) + * @see #configure(SslContextBuilder) + */ + public static SslContextBuilder forServer(File keyCertChainFile, File keyFile) { + return configure(SslContextBuilder.forServer(keyCertChainFile, keyFile)); + } + + /** + * Creates a SslContextBuilder with ciphers and APN appropriate for gRPC. + * + * @see SslContextBuilder#forServer(File, File, String) + * @see #configure(SslContextBuilder) + */ + public static SslContextBuilder forServer( + File keyCertChainFile, File keyFile, String keyPassword) { + return configure(SslContextBuilder.forServer(keyCertChainFile, keyFile, keyPassword)); + } + + /** + * Set ciphers and APN appropriate for gRPC. Precisely what is set is permitted to change, so if + * an application requires particular settings it should override the options set here. + */ + public static SslContextBuilder configure(SslContextBuilder builder) { + return builder.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE) + // We currently handle ALPN ourselves, so we require ALPN in Netty disabled. + .applicationProtocolConfig(null); + } +} diff --git a/netty/src/main/java/io/grpc/transport/netty/NettyChannelBuilder.java b/netty/src/main/java/io/grpc/transport/netty/NettyChannelBuilder.java index 24fe4e10c3..b8c0eb23b9 100644 --- a/netty/src/main/java/io/grpc/transport/netty/NettyChannelBuilder.java +++ b/netty/src/main/java/io/grpc/transport/netty/NettyChannelBuilder.java @@ -111,7 +111,10 @@ public final class NettyChannelBuilder extends AbstractChannelBuilder