/* * JobServerAuthenticationTest * * v1.0 * * May 21, 2019 */ package JobServ; import static org.junit.Assert.assertEquals; import static org.mockito.AdditionalAnswers.delegatesTo; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import io.grpc.ManagedChannel; import io.grpc.inprocess.InProcessChannelBuilder; import io.grpc.inprocess.InProcessServerBuilder; import io.grpc.stub.StreamObserver; import io.grpc.testing.GrpcCleanupRule; import io.grpc.netty.GrpcSslContexts; import io.netty.handler.ssl.ClientAuth; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslProvider; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; /* * JobServerAuthenticationTest * Creates a client using authorized certs and another one using unauthorized certs * Ensures only the client with authorized certs can connect to the server. * For more information on the hardcoded paths check buildwrapper.sh */ @RunWith(JUnit4.class) public class JobServerAuthorizationTest { // Authorized client key/cert/ca private final String clientCa = "resources/client/ca.crt"; private final String clientKey = "resources/client/private.pem"; private final String clientCert = "resources/client/client.crt"; // Authorized server key/cert/ca private final String serverCa = "resources/server/ca.crt"; private final String serverKey = "resources/server/private.pem"; private final String serverCert = "resources/server/server.crt"; // controlled failure key/cert/ca private final String badCa = "resources/test/ca.crt"; private final String badKey = "resources/test/private.pem"; private final String badCert = "resources/test/test.crt"; // Automates (graceful) shutdown at end of tests @Rule public final GrpcCleanupRule grpcCleanup = newCleanupRule(); private final ShellServerGrpc.ShellServerImplBase = mock(ShellServerGrpc.ShellServerImplBase.class, delegatesTo(new ShellServerGrpc.ShellServerImplBase() {})); // badClient uses unauthorized certs private JobServClient goodClient; private JobServClient badClient; // was setUp able to use SSL Certs private Boolean serverSslInitialized; private Boolean clientSslInitialized; /* * setUp() * generates both clients and the server */ @Before public void setUp() throws Exception { String serverName = InProcessServerBuilder.generateName(); try { // generate SSL contexts SslContextBuilder serverContextBuilder = SslContextBuilder.forServer(new File(serverCert), new File(serverKey)); serverContextBuilder.trustManager(new File(clientCa)); serverContextBuilder.clientAuth(ClientAuth.REQUIRE); grpcCleanup.register(InProcessServerBuilder.forName(serverName) .sslContext(serverContextBuilder.build()) .directExecutor() .addService(this.serviceImpl); .build().start()); this.serverSslInitialized = true; } catch (SSLException e) { // One of the certs or keys was bad, ssl cannot be used this.serverSslInitialized = false; grpcCleanup.register(InProcessServerBuilder.forName(serverName) .directExecutor() .addService(this.serviceImpl).build().start()); } // generate ssl for clients if (this.serverSslInitialized) { try { SslContextBuilder goodClientBuilder = SslContextBuilder.forClient(); goodClientBuilder.trustManager(new File(serverCa)); goodClientBuilder.keyManager(new File(clientCert), new File(clientKey)); SslContextBuilder badClientBuilder = SslContextBuilder.forClient(); badClientBuilder.trustManager(new File(serverCa)); badClientBuilder.keyManager(new File(badCert), new File(badKey)); ManagedChannel goodChannel = grpcCleanup.register(InProcessChannelBuilder.forName(serverName) .sslContext(goodClientBuilder.build()) .directExecutor() .build()); ManagedChannel badChannel = grpcCleanup.register(InProcessChannelBuilder.forName(serverName) .sslContext(badClientBuilder.build()) .directExecutor() .build()); goodClient = new JobServClient(goodChannel); badClient = new JobServClient(badChannel); this.clientSslInitialized = true; } catch (SSLException e) { this.clientSslInitialized = false; ManagedChannel nonSslChannel = grpcCleanup.register(InProcessChannelBuilder.forName(serverName) .directExecutor() .build()); goodClient = new JobServClient(nonSslChannel); badClient = null; // } } } /* * Server TLS Test * fails if server SslContext generation threw an SSLException */ @Test public void serverTlsTest() { assertEquals(this.serverSslInitialized, true); } /* * Client TLS Test * fails if client SslContext generation threw an SSL Exception */ @Test public void clientTlsTest() { assertEquals(this.clientSslInitialized, true); } /* * TLS Cert Auth Negative Test * fails if badClient can successfully make requests of the server */ @Test public void certAuthNegTest() { assertEquals(clientSslInitialized, true); int result = badClient.sendNewJobMessage("test command"); assertEquals(result, -2); } /* * TLS Cert Auth Positive Test * fails if goodClient cannot make requests of the server */ @Test public void certAuthPosTest() { assertEquals(clientSslInitialized, true); int result = goodClient.sendNewJobMessage("test command"); assertNotEquals(result, -2); } }