下面列出了io.grpc.internal.testing.TestUtils#loadCert ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Creates and starts a new {@link TestServiceImpl} server.
*/
private Server newServer() throws CertificateException, IOException {
File serverCertChainFile = TestUtils.loadCert("server1.pem");
File serverPrivateKeyFile = TestUtils.loadCert("server1.key");
X509Certificate[] serverTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
SslContext sslContext =
GrpcSslContexts.forServer(serverCertChainFile, serverPrivateKeyFile)
.trustManager(serverTrustedCaCerts)
.clientAuth(ClientAuth.REQUIRE)
.build();
return NettyServerBuilder.forPort(0)
.sslContext(sslContext)
.addService(new TestServiceImpl(serverExecutor))
.build()
.start();
}
private ManagedChannel newClientChannel() throws CertificateException, IOException {
File clientCertChainFile = TestUtils.loadCert("client.pem");
File clientPrivateKeyFile = TestUtils.loadCert("client.key");
X509Certificate[] clientTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
SslContext sslContext =
GrpcSslContexts.forClient()
.keyManager(clientCertChainFile, clientPrivateKeyFile)
.trustManager(clientTrustedCaCerts)
.build();
return NettyChannelBuilder.forAddress("localhost", server.getPort())
.overrideAuthority(TestUtils.TEST_SERVER_HOST)
.negotiationType(NegotiationType.TLS)
.sslContext(sslContext)
.build();
}
/**
* Tests that a client and a server configured using GrpcSslContexts can successfully
* communicate with each other.
*/
@Test
public void basicClientServerIntegrationTest() throws Exception {
// Create & start a server.
File serverCertFile = TestUtils.loadCert("server1.pem");
File serverPrivateKeyFile = TestUtils.loadCert("server1.key");
X509Certificate[] serverTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
server = serverBuilder(0, serverCertFile, serverPrivateKeyFile, serverTrustedCaCerts)
.addService(new SimpleServiceImpl())
.build()
.start();
// Create a client.
File clientCertChainFile = TestUtils.loadCert("client.pem");
File clientPrivateKeyFile = TestUtils.loadCert("client.key");
X509Certificate[] clientTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
channel = clientChannel(server.getPort(), clientContextBuilder
.keyManager(clientCertChainFile, clientPrivateKeyFile)
.trustManager(clientTrustedCaCerts)
.build());
SimpleServiceGrpc.SimpleServiceBlockingStub client = SimpleServiceGrpc.newBlockingStub(channel);
// Send an actual request, via the full GRPC & network stack, and check that a proper
// response comes back.
client.unaryRpc(SimpleRequest.getDefaultInstance());
}
@Test
public void clientTlsHandler_userEventTriggeredSslEvent_supportedProtocolCustom()
throws Exception {
SslHandler goodSslHandler = new SslHandler(engine, false) {
@Override
public String applicationProtocol() {
return "managed_mtls";
}
};
DefaultEventLoopGroup elg = new DefaultEventLoopGroup(1);
File clientCert = TestUtils.loadCert("client.pem");
File key = TestUtils.loadCert("client.key");
List<String> alpnList = Arrays.asList("managed_mtls", "h2");
ApplicationProtocolConfig apn = new ApplicationProtocolConfig(
ApplicationProtocolConfig.Protocol.ALPN,
ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
alpnList);
sslContext = GrpcSslContexts.forClient()
.keyManager(clientCert, key)
.ciphers(TestUtils.preferredTestCiphers(), SupportedCipherSuiteFilter.INSTANCE)
.applicationProtocolConfig(apn).build();
ClientTlsHandler handler = new ClientTlsHandler(grpcHandler, sslContext, "authority", elg);
pipeline.addLast(handler);
pipeline.replace(SslHandler.class, null, goodSslHandler);
pipeline.fireUserEventTriggered(ProtocolNegotiationEvent.DEFAULT);
channelHandlerCtx = pipeline.context(handler);
Object sslEvent = SslHandshakeCompletionEvent.SUCCESS;
pipeline.fireUserEventTriggered(sslEvent);
ChannelHandlerContext grpcHandlerCtx = pipeline.context(grpcHandler);
assertNotNull(grpcHandlerCtx);
}
/**
* Tests that a client configured using GrpcSslContexts refuses to talk to a server that has an
* an untrusted certificate.
*/
@Test
public void clientRejectsUntrustedServerCert() throws Exception {
// Create & start a server.
File serverCertFile = TestUtils.loadCert("badserver.pem");
File serverPrivateKeyFile = TestUtils.loadCert("badserver.key");
X509Certificate[] serverTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
server = serverBuilder(0, serverCertFile, serverPrivateKeyFile, serverTrustedCaCerts)
.addService(new SimpleServiceImpl())
.build()
.start();
// Create a client.
File clientCertChainFile = TestUtils.loadCert("client.pem");
File clientPrivateKeyFile = TestUtils.loadCert("client.key");
X509Certificate[] clientTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
channel = clientChannel(server.getPort(), clientContextBuilder
.keyManager(clientCertChainFile, clientPrivateKeyFile)
.trustManager(clientTrustedCaCerts)
.build());
SimpleServiceGrpc.SimpleServiceBlockingStub client = SimpleServiceGrpc.newBlockingStub(channel);
// Check that the TLS handshake fails.
try {
client.unaryRpc(SimpleRequest.getDefaultInstance());
fail("TLS handshake should have failed, but didn't; received RPC response");
} catch (StatusRuntimeException e) {
// GRPC reports this situation by throwing a StatusRuntimeException that wraps either a
// javax.net.ssl.SSLHandshakeException or a java.nio.channels.ClosedChannelException.
// Thus, reliably detecting the underlying cause is not feasible.
// TODO(carl-mastrangelo): eventually replace this with a hamcrest matcher.
assertEquals(
Throwables.getStackTraceAsString(e),
Status.Code.UNAVAILABLE, e.getStatus().getCode());
}
}
private static SslContext createSslContext() {
try {
File serverCert = TestUtils.loadCert("server1.pem");
File key = TestUtils.loadCert("server1.key");
return GrpcSslContexts.forServer(serverCert, key)
.ciphers(TestUtils.preferredTestCiphers(), SupportedCipherSuiteFilter.INSTANCE).build();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
@Before
public void setUp() throws Exception {
File serverCert = TestUtils.loadCert("server1.pem");
File key = TestUtils.loadCert("server1.key");
sslContext = GrpcSslContexts.forServer(serverCert, key)
.ciphers(TestUtils.preferredTestCiphers(), SupportedCipherSuiteFilter.INSTANCE).build();
engine = SSLContext.getDefault().createSSLEngine();
engine.setUseClientMode(true);
}
private static NettyChannelBuilder newNettyClientChannel(Transport transport,
SocketAddress address, boolean tls, boolean testca, int flowControlWindow)
throws IOException {
NettyChannelBuilder builder =
NettyChannelBuilder.forAddress(address).flowControlWindow(flowControlWindow);
if (!tls) {
builder.usePlaintext();
} else if (testca) {
File cert = TestUtils.loadCert("ca.pem");
builder.sslContext(GrpcSslContexts.forClient().trustManager(cert).build());
}
DefaultThreadFactory tf = new DefaultThreadFactory("client-elg-", true /*daemon */);
switch (transport) {
case NETTY_NIO:
builder
.eventLoopGroup(new NioEventLoopGroup(0, tf))
.channelType(NioSocketChannel.class);
break;
case NETTY_EPOLL:
// These classes only work on Linux.
builder
.eventLoopGroup(new EpollEventLoopGroup(0, tf))
.channelType(EpollSocketChannel.class);
break;
case NETTY_UNIX_DOMAIN_SOCKET:
// These classes only work on Linux.
builder
.eventLoopGroup(new EpollEventLoopGroup(0, tf))
.channelType(EpollDomainSocketChannel.class);
break;
default:
// Should never get here.
throw new IllegalArgumentException("Unsupported transport: " + transport);
}
return builder;
}
private static NettyChannelBuilder newNettyClientChannel(Transport transport,
SocketAddress address, boolean tls, boolean testca, int flowControlWindow)
throws IOException {
NettyChannelBuilder builder =
NettyChannelBuilder.forAddress(address).flowControlWindow(flowControlWindow);
if (!tls) {
builder.usePlaintext();
} else if (testca) {
File cert = TestUtils.loadCert("ca.pem");
builder.sslContext(GrpcSslContexts.forClient().trustManager(cert).build());
}
DefaultThreadFactory tf = new DefaultThreadFactory("client-elg-", true /*daemon */);
switch (transport) {
case NETTY_NIO:
builder
.eventLoopGroup(new NioEventLoopGroup(0, tf))
.channelType(NioSocketChannel.class);
break;
case NETTY_EPOLL:
// These classes only work on Linux.
builder
.eventLoopGroup(new EpollEventLoopGroup(0, tf))
.channelType(EpollSocketChannel.class);
break;
case NETTY_UNIX_DOMAIN_SOCKET:
// These classes only work on Linux.
builder
.eventLoopGroup(new EpollEventLoopGroup(0, tf))
.channelType(EpollDomainSocketChannel.class);
break;
default:
// Should never get here.
throw new IllegalArgumentException("Unsupported transport: " + transport);
}
return builder;
}
/**
* Tests that a client and a server configured using GrpcSslContexts can successfully
* communicate with each other.
*/
@Test
public void basicClientServerIntegrationTest() throws Exception {
// Create & start a server.
File serverCertFile = TestUtils.loadCert("server1.pem");
File serverPrivateKeyFile = TestUtils.loadCert("server1.key");
X509Certificate[] serverTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
server = serverBuilder(0, serverCertFile, serverPrivateKeyFile, serverTrustedCaCerts)
.addService(new SimpleServiceImpl())
.build()
.start();
// Create a client.
File clientCertChainFile = TestUtils.loadCert("client.pem");
File clientPrivateKeyFile = TestUtils.loadCert("client.key");
X509Certificate[] clientTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
channel = clientChannel(server.getPort(), clientContextBuilder
.keyManager(clientCertChainFile, clientPrivateKeyFile)
.trustManager(clientTrustedCaCerts)
.build());
SimpleServiceGrpc.SimpleServiceBlockingStub client = SimpleServiceGrpc.newBlockingStub(channel);
// Send an actual request, via the full GRPC & network stack, and check that a proper
// response comes back.
client.unaryRpc(SimpleRequest.getDefaultInstance());
}
/**
* Tests that a server configured to require client authentication actually does require client
* authentication.
*/
@Test
public void noClientAuthFailure() throws Exception {
// Create & start a server.
File serverCertFile = TestUtils.loadCert("server1.pem");
File serverPrivateKeyFile = TestUtils.loadCert("server1.key");
X509Certificate[] serverTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
server = serverBuilder(0, serverCertFile, serverPrivateKeyFile, serverTrustedCaCerts)
.addService(new SimpleServiceImpl())
.build()
.start();
// Create a client. It has no credentials.
X509Certificate[] clientTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
channel = clientChannel(server.getPort(), clientContextBuilder
.trustManager(clientTrustedCaCerts)
.build());
SimpleServiceGrpc.SimpleServiceBlockingStub client = SimpleServiceGrpc.newBlockingStub(channel);
// Check that the TLS handshake fails.
try {
client.unaryRpc(SimpleRequest.getDefaultInstance());
fail("TLS handshake should have failed, but didn't; received RPC response");
} catch (StatusRuntimeException e) {
// GRPC reports this situation by throwing a StatusRuntimeException that wraps either a
// javax.net.ssl.SSLHandshakeException or a java.nio.channels.ClosedChannelException.
// Thus, reliably detecting the underlying cause is not feasible.
assertEquals(
Throwables.getStackTraceAsString(e),
Status.Code.UNAVAILABLE, e.getStatus().getCode());
}
}
/**
* Tests that a client configured using GrpcSslContexts refuses to talk to a server that has an
* an untrusted certificate.
*/
@Test
public void clientRejectsUntrustedServerCert() throws Exception {
// Create & start a server.
File serverCertFile = TestUtils.loadCert("badserver.pem");
File serverPrivateKeyFile = TestUtils.loadCert("badserver.key");
X509Certificate[] serverTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
server = serverBuilder(0, serverCertFile, serverPrivateKeyFile, serverTrustedCaCerts)
.addService(new SimpleServiceImpl())
.build()
.start();
// Create a client.
File clientCertChainFile = TestUtils.loadCert("client.pem");
File clientPrivateKeyFile = TestUtils.loadCert("client.key");
X509Certificate[] clientTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
channel = clientChannel(server.getPort(), clientContextBuilder
.keyManager(clientCertChainFile, clientPrivateKeyFile)
.trustManager(clientTrustedCaCerts)
.build());
SimpleServiceGrpc.SimpleServiceBlockingStub client = SimpleServiceGrpc.newBlockingStub(channel);
// Check that the TLS handshake fails.
try {
client.unaryRpc(SimpleRequest.getDefaultInstance());
fail("TLS handshake should have failed, but didn't; received RPC response");
} catch (StatusRuntimeException e) {
// GRPC reports this situation by throwing a StatusRuntimeException that wraps either a
// javax.net.ssl.SSLHandshakeException or a java.nio.channels.ClosedChannelException.
// Thus, reliably detecting the underlying cause is not feasible.
// TODO(carl-mastrangelo): eventually replace this with a hamcrest matcher.
assertEquals(
Throwables.getStackTraceAsString(e),
Status.Code.UNAVAILABLE, e.getStatus().getCode());
}
}
private static SslContext createSslContext() {
try {
File serverCert = TestUtils.loadCert("server1.pem");
File key = TestUtils.loadCert("server1.key");
return GrpcSslContexts.forServer(serverCert, key)
.ciphers(TestUtils.preferredTestCiphers(), SupportedCipherSuiteFilter.INSTANCE).build();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
@Before
public void setUp() throws Exception {
File serverCert = TestUtils.loadCert("server1.pem");
File key = TestUtils.loadCert("server1.key");
sslContext = GrpcSslContexts.forServer(serverCert, key)
.ciphers(TestUtils.preferredTestCiphers(), SupportedCipherSuiteFilter.INSTANCE).build();
engine = SSLContext.getDefault().createSSLEngine();
engine.setUseClientMode(true);
}
/**
* Tests that a server configured to require client authentication refuses to accept connections
* from a client that has an untrusted certificate.
*/
@Test
public void serverRejectsUntrustedClientCert() throws Exception {
// Create & start a server. It requires client authentication and trusts only the test CA.
File serverCertFile = TestUtils.loadCert("server1.pem");
File serverPrivateKeyFile = TestUtils.loadCert("server1.key");
X509Certificate[] serverTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
server = serverBuilder(0, serverCertFile, serverPrivateKeyFile, serverTrustedCaCerts)
.addService(new SimpleServiceImpl())
.build()
.start();
// Create a client. Its credentials come from a CA that the server does not trust. The client
// trusts both test CAs, so we can be sure that the handshake failure is due to the server
// rejecting the client's cert, not the client rejecting the server's cert.
File clientCertChainFile = TestUtils.loadCert("badclient.pem");
File clientPrivateKeyFile = TestUtils.loadCert("badclient.key");
X509Certificate[] clientTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
channel = clientChannel(server.getPort(), clientContextBuilder
.keyManager(clientCertChainFile, clientPrivateKeyFile)
.trustManager(clientTrustedCaCerts)
.build());
SimpleServiceGrpc.SimpleServiceBlockingStub client = SimpleServiceGrpc.newBlockingStub(channel);
// Check that the TLS handshake fails.
try {
client.unaryRpc(SimpleRequest.getDefaultInstance());
fail("TLS handshake should have failed, but didn't; received RPC response");
} catch (StatusRuntimeException e) {
// GRPC reports this situation by throwing a StatusRuntimeException that wraps either a
// javax.net.ssl.SSLHandshakeException or a java.nio.channels.ClosedChannelException.
// Thus, reliably detecting the underlying cause is not feasible.
assertEquals(
Throwables.getStackTraceAsString(e),
Status.Code.UNAVAILABLE, e.getStatus().getCode());
}
}
private ProtocolNegotiator newNegotiator() throws IOException {
File caCert = TestUtils.loadCert("ca.pem");
SslContext clientContext = GrpcSslContexts.forClient().trustManager(caCert)
.ciphers(TestUtils.preferredTestCiphers(), SupportedCipherSuiteFilter.INSTANCE).build();
return ProtocolNegotiators.tls(clientContext);
}
LoadServer(Control.ServerConfig config) throws Exception {
log.log(Level.INFO, "Server Config \n" + config.toString());
port = config.getPort() == 0 ? Utils.pickUnusedPort() : config.getPort();
ServerBuilder<?> serverBuilder = ServerBuilder.forPort(port);
int asyncThreads = config.getAsyncServerThreads() == 0
? Runtime.getRuntime().availableProcessors()
: config.getAsyncServerThreads();
// The concepts of sync & async server are quite different in the C impl and the names
// chosen for the enum are based on that implementation. We use 'sync' to mean
// the direct executor case in Java even though the service implementations are always
// fully async.
switch (config.getServerType()) {
case ASYNC_SERVER: {
serverBuilder.executor(getExecutor(asyncThreads));
break;
}
case SYNC_SERVER: {
serverBuilder.directExecutor();
break;
}
case ASYNC_GENERIC_SERVER: {
serverBuilder.executor(getExecutor(asyncThreads));
// Create buffers for the generic service
PooledByteBufAllocator alloc = PooledByteBufAllocator.DEFAULT;
genericResponse = alloc.buffer(config.getPayloadConfig().getBytebufParams().getRespSize());
if (genericResponse.capacity() > 0) {
genericResponse.writerIndex(genericResponse.capacity() - 1);
}
break;
}
default: {
throw new IllegalArgumentException();
}
}
if (config.hasSecurityParams()) {
File cert = TestUtils.loadCert("server1.pem");
File key = TestUtils.loadCert("server1.key");
serverBuilder.useTransportSecurity(cert, key);
}
benchmarkService = new AsyncServer.BenchmarkServiceImpl();
if (config.getServerType() == Control.ServerType.ASYNC_GENERIC_SERVER) {
serverBuilder.addService(
ServerServiceDefinition
.builder(new ServiceDescriptor(BenchmarkServiceGrpc.SERVICE_NAME,
GENERIC_STREAMING_PING_PONG_METHOD))
.addMethod(GENERIC_STREAMING_PING_PONG_METHOD, new GenericServiceCallHandler())
.build());
} else {
serverBuilder.addService(benchmarkService);
}
server = serverBuilder.build();
List<OperatingSystemMXBean> beans =
ManagementFactory.getPlatformMXBeans(OperatingSystemMXBean.class);
if (!beans.isEmpty()) {
osBean = beans.get(0);
} else {
osBean = null;
}
}
@Test
public void serverTlsHandler_userEventTriggeredSslEvent_unsupportedProtocolCustom()
throws Exception {
SslHandler badSslHandler = new SslHandler(engine, false) {
@Override
public String applicationProtocol() {
return "badprotocol";
}
};
File serverCert = TestUtils.loadCert("server1.pem");
File key = TestUtils.loadCert("server1.key");
List<String> alpnList = Arrays.asList("managed_mtls", "h2");
ApplicationProtocolConfig apn = new ApplicationProtocolConfig(
ApplicationProtocolConfig.Protocol.ALPN,
ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
alpnList);
sslContext = GrpcSslContexts.forServer(serverCert, key)
.ciphers(TestUtils.preferredTestCiphers(), SupportedCipherSuiteFilter.INSTANCE)
.applicationProtocolConfig(apn).build();
ChannelHandler handler = new ServerTlsHandler(grpcHandler, sslContext, null);
pipeline.addLast(handler);
final AtomicReference<Throwable> error = new AtomicReference<>();
ChannelHandler errorCapture = new ChannelInboundHandlerAdapter() {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
error.set(cause);
}
};
pipeline.addLast(errorCapture);
pipeline.replace(SslHandler.class, null, badSslHandler);
channelHandlerCtx = pipeline.context(handler);
Object sslEvent = SslHandshakeCompletionEvent.SUCCESS;
pipeline.fireUserEventTriggered(sslEvent);
// No h2 protocol was specified, so there should be an error, (normally handled by WBAEH)
assertThat(error.get()).hasMessageThat().contains("Unable to find compatible protocol");
ChannelHandlerContext grpcHandlerCtx = pipeline.context(grpcHandler);
assertNull(grpcHandlerCtx);
}
/**
* Tests that a server configured to require client authentication refuses to accept connections
* from a client that has an untrusted certificate.
*/
@Test
public void serverRejectsUntrustedClientCert() throws Exception {
// Create & start a server. It requires client authentication and trusts only the test CA.
File serverCertFile = TestUtils.loadCert("server1.pem");
File serverPrivateKeyFile = TestUtils.loadCert("server1.key");
X509Certificate[] serverTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
server = serverBuilder(0, serverCertFile, serverPrivateKeyFile, serverTrustedCaCerts)
.addService(new SimpleServiceImpl())
.build()
.start();
// Create a client. Its credentials come from a CA that the server does not trust. The client
// trusts both test CAs, so we can be sure that the handshake failure is due to the server
// rejecting the client's cert, not the client rejecting the server's cert.
File clientCertChainFile = TestUtils.loadCert("badclient.pem");
File clientPrivateKeyFile = TestUtils.loadCert("badclient.key");
X509Certificate[] clientTrustedCaCerts = {
TestUtils.loadX509Cert("ca.pem")
};
channel = clientChannel(server.getPort(), clientContextBuilder
.keyManager(clientCertChainFile, clientPrivateKeyFile)
.trustManager(clientTrustedCaCerts)
.build());
SimpleServiceGrpc.SimpleServiceBlockingStub client = SimpleServiceGrpc.newBlockingStub(channel);
// Check that the TLS handshake fails.
try {
client.unaryRpc(SimpleRequest.getDefaultInstance());
fail("TLS handshake should have failed, but didn't; received RPC response");
} catch (StatusRuntimeException e) {
// GRPC reports this situation by throwing a StatusRuntimeException that wraps either a
// javax.net.ssl.SSLHandshakeException or a java.nio.channels.ClosedChannelException.
// Thus, reliably detecting the underlying cause is not feasible.
assertEquals(
Throwables.getStackTraceAsString(e),
Status.Code.UNAVAILABLE, e.getStatus().getCode());
}
}
private ProtocolNegotiator newNegotiator() throws IOException {
File caCert = TestUtils.loadCert("ca.pem");
SslContext clientContext = GrpcSslContexts.forClient().trustManager(caCert)
.ciphers(TestUtils.preferredTestCiphers(), SupportedCipherSuiteFilter.INSTANCE).build();
return ProtocolNegotiators.tls(clientContext);
}