From e3f3413dae7f676d326d03e9a351d70cf2777f57 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Thu, 19 Sep 2024 09:46:11 -0700 Subject: [PATCH 1/9] Use StandardCharsets in FakeS2AServerTest. --- .../test/java/io/grpc/s2a/handshaker/FakeS2AServerTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServerTest.java b/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServerTest.java index e200d119867..7f1a55c385f 100644 --- a/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServerTest.java +++ b/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServerTest.java @@ -29,6 +29,7 @@ import io.grpc.benchmarks.Utils; import io.grpc.s2a.handshaker.ValidatePeerCertificateChainReq.VerificationMode; import io.grpc.stub.StreamObserver; +import java.nio.charset.StandardCharsets; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -45,9 +46,7 @@ public final class FakeS2AServerTest { private static final Logger logger = Logger.getLogger(FakeS2AServerTest.class.getName()); private static final ImmutableList FAKE_CERT_DER_CHAIN = - ImmutableList.of( - ByteString.copyFrom( - new byte[] {'f', 'a', 'k', 'e', '-', 'd', 'e', 'r', '-', 'c', 'h', 'a', 'i', 'n'})); + ImmutableList.of(ByteString.copyFrom("fake-der-chain".getBytes(StandardCharsets.US_ASCII))); private int port; private String serverAddress; private SessionResp response = null; From d13bd88b66d4bb24d1879b3afe1e961bf212fb96 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Thu, 19 Sep 2024 09:50:56 -0700 Subject: [PATCH 2/9] Use add instead of offer in S2AStub. --- s2a/src/main/java/io/grpc/s2a/handshaker/S2AStub.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/s2a/src/main/java/io/grpc/s2a/handshaker/S2AStub.java b/s2a/src/main/java/io/grpc/s2a/handshaker/S2AStub.java index 8249ca59d09..d85ec37ca7f 100644 --- a/s2a/src/main/java/io/grpc/s2a/handshaker/S2AStub.java +++ b/s2a/src/main/java/io/grpc/s2a/handshaker/S2AStub.java @@ -111,7 +111,7 @@ public SessionResp send(SessionReq req) throws IOException, InterruptedException writer.onNext(req); } catch (RuntimeException e) { writer.onError(e); - responses.offer(Result.createWithThrowable(e)); + responses.add(Result.createWithThrowable(e)); } try { return responses.take().getResultOrThrow(); @@ -159,7 +159,7 @@ private class Reader implements StreamObserver { @Override public void onNext(SessionResp resp) { verify(!doneReading); - responses.offer(Result.createWithResponse(resp)); + responses.add(Result.createWithResponse(resp)); } /** @@ -169,7 +169,7 @@ public void onNext(SessionResp resp) { */ @Override public void onError(Throwable t) { - responses.offer(Result.createWithThrowable(t)); + responses.add(Result.createWithThrowable(t)); } /** @@ -180,7 +180,7 @@ public void onError(Throwable t) { public void onCompleted() { logger.log(Level.INFO, "Reading from the S2A is complete."); doneReading = true; - responses.offer( + responses.add( Result.createWithThrowable( new ConnectionClosedException("Reading from the S2A is complete."))); } From 577b4e513050dcea72643407d967050e2846638d Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Thu, 19 Sep 2024 09:58:27 -0700 Subject: [PATCH 3/9] remove dead code in ProtoUtil.java. --- .../io/grpc/s2a/handshaker/ProtoUtil.java | 26 ------------ .../io/grpc/s2a/handshaker/ProtoUtilTest.java | 41 ------------------- 2 files changed, 67 deletions(-) diff --git a/s2a/src/main/java/io/grpc/s2a/handshaker/ProtoUtil.java b/s2a/src/main/java/io/grpc/s2a/handshaker/ProtoUtil.java index 59e3931d9e6..442c21bf330 100644 --- a/s2a/src/main/java/io/grpc/s2a/handshaker/ProtoUtil.java +++ b/s2a/src/main/java/io/grpc/s2a/handshaker/ProtoUtil.java @@ -20,32 +20,6 @@ /** Converts proto messages to Netty strings. */ final class ProtoUtil { - /** - * Converts {@link Ciphersuite} to its {@link String} representation. - * - * @param ciphersuite the {@link Ciphersuite} to be converted. - * @return a {@link String} representing the ciphersuite. - * @throws AssertionError if the {@link Ciphersuite} is not one of the supported ciphersuites. - */ - static String convertCiphersuite(Ciphersuite ciphersuite) { - switch (ciphersuite) { - case CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; - case CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; - case CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"; - case CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; - case CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; - case CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"; - default: - throw new AssertionError( - String.format("Ciphersuite %d is not supported.", ciphersuite.getNumber())); - } - } /** * Converts a {@link TLSVersion} object to its {@link String} representation. diff --git a/s2a/src/test/java/io/grpc/s2a/handshaker/ProtoUtilTest.java b/s2a/src/test/java/io/grpc/s2a/handshaker/ProtoUtilTest.java index 6d134b43f7a..f54063b9e04 100644 --- a/s2a/src/test/java/io/grpc/s2a/handshaker/ProtoUtilTest.java +++ b/s2a/src/test/java/io/grpc/s2a/handshaker/ProtoUtilTest.java @@ -30,47 +30,6 @@ public final class ProtoUtilTest { @Rule public final Expect expect = Expect.create(); - @Test - public void convertCiphersuite_success() { - expect - .that( - ProtoUtil.convertCiphersuite( - Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)) - .isEqualTo("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); - expect - .that( - ProtoUtil.convertCiphersuite( - Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)) - .isEqualTo("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"); - expect - .that( - ProtoUtil.convertCiphersuite( - Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)) - .isEqualTo("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"); - expect - .that( - ProtoUtil.convertCiphersuite(Ciphersuite.CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256)) - .isEqualTo("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); - expect - .that( - ProtoUtil.convertCiphersuite(Ciphersuite.CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384)) - .isEqualTo("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"); - expect - .that( - ProtoUtil.convertCiphersuite( - Ciphersuite.CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)) - .isEqualTo("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"); - } - - @Test - public void convertCiphersuite_withUnspecifiedCiphersuite_fails() { - AssertionError expected = - assertThrows( - AssertionError.class, - () -> ProtoUtil.convertCiphersuite(Ciphersuite.CIPHERSUITE_UNSPECIFIED)); - expect.that(expected).hasMessageThat().isEqualTo("Ciphersuite 0 is not supported."); - } - @Test public void convertTlsProtocolVersion_success() { expect From 59573ec590815a207489d2bd0228e4a35eac39b8 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Thu, 19 Sep 2024 10:01:06 -0700 Subject: [PATCH 4/9] Mark convertTlsProtocolVersion as VisibleForTesting. --- s2a/src/main/java/io/grpc/s2a/handshaker/ProtoUtil.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/s2a/src/main/java/io/grpc/s2a/handshaker/ProtoUtil.java b/s2a/src/main/java/io/grpc/s2a/handshaker/ProtoUtil.java index 442c21bf330..129cc2d60f1 100644 --- a/s2a/src/main/java/io/grpc/s2a/handshaker/ProtoUtil.java +++ b/s2a/src/main/java/io/grpc/s2a/handshaker/ProtoUtil.java @@ -16,6 +16,7 @@ package io.grpc.s2a.handshaker; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSet; /** Converts proto messages to Netty strings. */ @@ -28,6 +29,7 @@ final class ProtoUtil { * @return a {@link String} representation of the TLS version. * @throws AssertionError if the {@code tlsVersion} is not one of the supported TLS versions. */ + @VisibleForTesting static String convertTlsProtocolVersion(TLSVersion tlsVersion) { switch (tlsVersion) { case TLS_VERSION_1_3: From 9efaa6a1fa1c3de02267f373950698a6621562d1 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Thu, 19 Sep 2024 11:21:03 -0700 Subject: [PATCH 5/9] S2AStub doesn't return responses at front of queue. --- .../java/io/grpc/s2a/handshaker/S2AStub.java | 7 ++--- .../io/grpc/s2a/handshaker/S2AStubTest.java | 27 +++++-------------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/s2a/src/main/java/io/grpc/s2a/handshaker/S2AStub.java b/s2a/src/main/java/io/grpc/s2a/handshaker/S2AStub.java index d85ec37ca7f..bf9b866ef93 100644 --- a/s2a/src/main/java/io/grpc/s2a/handshaker/S2AStub.java +++ b/s2a/src/main/java/io/grpc/s2a/handshaker/S2AStub.java @@ -84,6 +84,7 @@ BlockingQueue getResponses() { * @throws IOException if an unexpected response is received, or if the {@code reader} or {@code * writer} calls their {@code onError} method. */ + @SuppressWarnings("CheckReturnValue") public SessionResp send(SessionReq req) throws IOException, InterruptedException { if (doneWriting && doneReading) { logger.log(Level.INFO, "Stream to the S2A is closed."); @@ -92,9 +93,8 @@ public SessionResp send(SessionReq req) throws IOException, InterruptedException createWriterIfNull(); if (!responses.isEmpty()) { IOException exception = null; - SessionResp resp = null; try { - resp = responses.take().getResultOrThrow(); + responses.take().getResultOrThrow(); } catch (IOException e) { exception = e; } @@ -104,8 +104,9 @@ public SessionResp send(SessionReq req) throws IOException, InterruptedException "Received an unexpected response from a host at the S2A's address. The S2A might be" + " unavailable." + exception.getMessage()); + } else { + throw new IOException("Received an unexpected response from a host at the S2A's address."); } - return resp; } try { writer.onNext(req); diff --git a/s2a/src/test/java/io/grpc/s2a/handshaker/S2AStubTest.java b/s2a/src/test/java/io/grpc/s2a/handshaker/S2AStubTest.java index bb90be12b6a..0348fb97e56 100644 --- a/s2a/src/test/java/io/grpc/s2a/handshaker/S2AStubTest.java +++ b/s2a/src/test/java/io/grpc/s2a/handshaker/S2AStubTest.java @@ -189,26 +189,13 @@ public void send_receiveManyUnexpectedResponse_expectResponsesEmpty() throws Exc @Test public void send_receiveDelayedResponse() throws Exception { writer.sendGetTlsConfigResp(); - SessionResp resp = stub.send(SessionReq.getDefaultInstance()); - SessionResp expected = - SessionResp.newBuilder() - .setGetTlsConfigurationResp( - GetTlsConfigurationResp.newBuilder() - .setClientTlsConfiguration( - GetTlsConfigurationResp.ClientTlsConfiguration.newBuilder() - .addCertificateChain(FakeWriter.LEAF_CERT) - .addCertificateChain(FakeWriter.INTERMEDIATE_CERT_2) - .addCertificateChain(FakeWriter.INTERMEDIATE_CERT_1) - .setMinTlsVersion(TLSVersion.TLS_VERSION_1_3) - .setMaxTlsVersion(TLSVersion.TLS_VERSION_1_3) - .addCiphersuites( - Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - .addCiphersuites( - Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - .addCiphersuites( - Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256))) - .build(); - assertThat(resp).ignoringRepeatedFieldOrder().isEqualTo(expected); + IOException expectedException = + assertThrows(IOException.class, () -> stub.send(SessionReq.getDefaultInstance())); + assertThat(expectedException) + .hasMessageThat() + .contains("Received an unexpected response from a host at the S2A's address."); + + assertThat(stub.getResponses()).isEmpty(); } @Test From df413b116fa896f99f678e619a16760c962c50d6 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Thu, 19 Sep 2024 14:09:03 -0700 Subject: [PATCH 6/9] Remove global SHARED_RESOURCE_CHANNELS. --- .../s2a/channel/S2AHandshakerServiceChannel.java | 13 ++++--------- .../channel/S2AHandshakerServiceChannelTest.java | 10 +++++----- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/s2a/src/main/java/io/grpc/s2a/channel/S2AHandshakerServiceChannel.java b/s2a/src/main/java/io/grpc/s2a/channel/S2AHandshakerServiceChannel.java index 75ec7347bb5..9968d9cbdf7 100644 --- a/s2a/src/main/java/io/grpc/s2a/channel/S2AHandshakerServiceChannel.java +++ b/s2a/src/main/java/io/grpc/s2a/channel/S2AHandshakerServiceChannel.java @@ -20,7 +20,6 @@ import static java.util.concurrent.TimeUnit.SECONDS; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.Maps; import io.grpc.CallOptions; import io.grpc.Channel; import io.grpc.ChannelCredentials; @@ -35,14 +34,13 @@ import io.netty.util.concurrent.DefaultThreadFactory; import java.time.Duration; import java.util.Optional; -import java.util.concurrent.ConcurrentMap; import javax.annotation.concurrent.ThreadSafe; /** - * Provides APIs for managing gRPC channels to S2A servers. Each channel is local and plaintext. If - * credentials are provided, they are used to secure the channel. + * Provides APIs for managing gRPC channels to an S2A server. Each channel is local and plaintext. + * If credentials are provided, they are used to secure the channel. * - *

This is done as follows: for each S2A server, provides an implementation of gRPC's {@link + *

This is done as follows: for an S2A server, provides an implementation of gRPC's {@link * SharedResourceHolder.Resource} interface called a {@code Resource}. A {@code * Resource} is a factory for creating gRPC channels to the S2A server at a given address, * and a channel must be returned to the {@code Resource} when it is no longer needed. @@ -59,8 +57,6 @@ */ @ThreadSafe public final class S2AHandshakerServiceChannel { - private static final ConcurrentMap> SHARED_RESOURCE_CHANNELS = - Maps.newConcurrentMap(); private static final Duration DELEGATE_TERMINATION_TIMEOUT = Duration.ofSeconds(2); private static final Duration CHANNEL_SHUTDOWN_TIMEOUT = Duration.ofSeconds(10); @@ -76,8 +72,7 @@ public final class S2AHandshakerServiceChannel { public static Resource getChannelResource( String s2aAddress, Optional s2aChannelCredentials) { checkNotNull(s2aAddress); - return SHARED_RESOURCE_CHANNELS.computeIfAbsent( - s2aAddress, channelResource -> new ChannelResource(s2aAddress, s2aChannelCredentials)); + return new ChannelResource(s2aAddress, s2aChannelCredentials); } /** diff --git a/s2a/src/test/java/io/grpc/s2a/channel/S2AHandshakerServiceChannelTest.java b/s2a/src/test/java/io/grpc/s2a/channel/S2AHandshakerServiceChannelTest.java index 57288be1b6f..b9d93e7665a 100644 --- a/s2a/src/test/java/io/grpc/s2a/channel/S2AHandshakerServiceChannelTest.java +++ b/s2a/src/test/java/io/grpc/s2a/channel/S2AHandshakerServiceChannelTest.java @@ -97,10 +97,10 @@ public void getChannelResource_mtlsSuccess() throws Exception { /** * Creates two {@code Resoure}s for the same target address and verifies that they are - * equal. + * distinct. */ @Test - public void getChannelResource_twoEqualChannels() { + public void getChannelResource_twoUnEqualChannels() { Resource resource = S2AHandshakerServiceChannel.getChannelResource( "localhost:" + plaintextServer.getPort(), @@ -109,19 +109,19 @@ public void getChannelResource_twoEqualChannels() { S2AHandshakerServiceChannel.getChannelResource( "localhost:" + plaintextServer.getPort(), /* s2aChannelCredentials= */ Optional.empty()); - assertThat(resource).isEqualTo(resourceTwo); + assertThat(resource).isNotEqualTo(resourceTwo); } /** Same as getChannelResource_twoEqualChannels, but use mTLS. */ @Test - public void getChannelResource_mtlsTwoEqualChannels() throws Exception { + public void getChannelResource_mtlsTwoUnEqualChannels() throws Exception { Resource resource = S2AHandshakerServiceChannel.getChannelResource( "localhost:" + mtlsServer.getPort(), getTlsChannelCredentials()); Resource resourceTwo = S2AHandshakerServiceChannel.getChannelResource( "localhost:" + mtlsServer.getPort(), getTlsChannelCredentials()); - assertThat(resource).isEqualTo(resourceTwo); + assertThat(resource).isNotEqualTo(resourceTwo); } /** From 81ea900590c13ce38e2212c089f9428444b89b35 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Thu, 19 Sep 2024 14:14:02 -0700 Subject: [PATCH 7/9] Don't suppress RethrowReflectiveOperationExceptionAsLinkageError. --- .../grpc/s2a/handshaker/tokenmanager/AccessTokenManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/s2a/src/main/java/io/grpc/s2a/handshaker/tokenmanager/AccessTokenManager.java b/s2a/src/main/java/io/grpc/s2a/handshaker/tokenmanager/AccessTokenManager.java index 94549d11c87..da75cf0d4dd 100644 --- a/s2a/src/main/java/io/grpc/s2a/handshaker/tokenmanager/AccessTokenManager.java +++ b/s2a/src/main/java/io/grpc/s2a/handshaker/tokenmanager/AccessTokenManager.java @@ -27,7 +27,6 @@ public final class AccessTokenManager { private final TokenFetcher tokenFetcher; /** Creates an {@code AccessTokenManager} based on the environment where the application runs. */ - @SuppressWarnings("RethrowReflectiveOperationExceptionAsLinkageError") public static Optional create() { Optional tokenFetcher; try { @@ -38,7 +37,7 @@ public static Optional create() { } catch (ClassNotFoundException e) { tokenFetcher = Optional.empty(); } catch (ReflectiveOperationException e) { - throw new AssertionError(e); + throw new LinkageError(e.getMessage(), e); } return tokenFetcher.isPresent() ? Optional.of(new AccessTokenManager((TokenFetcher) tokenFetcher.get())) From d46e56d21d0271e81c1ef3426b016534c4ee2076 Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Thu, 19 Sep 2024 16:39:17 -0700 Subject: [PATCH 8/9] Update javadoc. --- .../io/grpc/s2a/channel/S2AHandshakerServiceChannelTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s2a/src/test/java/io/grpc/s2a/channel/S2AHandshakerServiceChannelTest.java b/s2a/src/test/java/io/grpc/s2a/channel/S2AHandshakerServiceChannelTest.java index b9d93e7665a..6ce5bcc3708 100644 --- a/s2a/src/test/java/io/grpc/s2a/channel/S2AHandshakerServiceChannelTest.java +++ b/s2a/src/test/java/io/grpc/s2a/channel/S2AHandshakerServiceChannelTest.java @@ -112,7 +112,7 @@ public void getChannelResource_twoUnEqualChannels() { assertThat(resource).isNotEqualTo(resourceTwo); } - /** Same as getChannelResource_twoEqualChannels, but use mTLS. */ + /** Same as getChannelResource_twoUnEqualChannels, but use mTLS. */ @Test public void getChannelResource_mtlsTwoUnEqualChannels() throws Exception { Resource resource = From 19b8f2176abf5f433ccc27d7c79e96260f0e43fb Mon Sep 17 00:00:00 2001 From: Riya Mehta Date: Fri, 20 Sep 2024 07:29:57 -0700 Subject: [PATCH 9/9] Make clear which certs are used in tests + add how to regenerate. --- .../io/grpc/s2a/handshaker/FakeS2AServer.java | 7 +- .../s2a/handshaker/FakeS2AServerTest.java | 13 +- .../io/grpc/s2a/handshaker/FakeWriter.java | 165 ++++++++---------- .../grpc/s2a/handshaker/IntegrationTest.java | 80 +-------- .../handshaker/S2APrivateKeyMethodTest.java | 5 +- .../S2AProtocolNegotiatorFactoryTest.java | 7 +- .../io/grpc/s2a/handshaker/S2AStubTest.java | 11 +- s2a/src/test/resources/README.md | 37 ++++ s2a/src/test/resources/cert_chain_ec.pem | 36 ++++ s2a/src/test/resources/int_cert1_.cnf | 14 ++ s2a/src/test/resources/int_cert1_ec.pem | 12 ++ s2a/src/test/resources/int_cert2.cnf | 14 ++ s2a/src/test/resources/int_cert2_ec.pem | 12 ++ s2a/src/test/resources/int_key1_ec.pem | 5 + s2a/src/test/resources/int_key2_ec.pem | 5 + s2a/src/test/resources/leaf.cnf | 14 ++ s2a/src/test/resources/leaf_cert_ec.pem | 12 ++ s2a/src/test/resources/leaf_key_ec.pem | 5 + s2a/src/test/resources/root_cert_ec.pem | 12 ++ s2a/src/test/resources/root_ec.cnf | 14 ++ s2a/src/test/resources/root_key_ec.pem | 5 + 21 files changed, 315 insertions(+), 170 deletions(-) create mode 100644 s2a/src/test/resources/cert_chain_ec.pem create mode 100644 s2a/src/test/resources/int_cert1_.cnf create mode 100644 s2a/src/test/resources/int_cert1_ec.pem create mode 100644 s2a/src/test/resources/int_cert2.cnf create mode 100644 s2a/src/test/resources/int_cert2_ec.pem create mode 100644 s2a/src/test/resources/int_key1_ec.pem create mode 100644 s2a/src/test/resources/int_key2_ec.pem create mode 100644 s2a/src/test/resources/leaf.cnf create mode 100644 s2a/src/test/resources/leaf_cert_ec.pem create mode 100644 s2a/src/test/resources/leaf_key_ec.pem create mode 100644 s2a/src/test/resources/root_cert_ec.pem create mode 100644 s2a/src/test/resources/root_ec.cnf create mode 100644 s2a/src/test/resources/root_key_ec.pem diff --git a/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServer.java b/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServer.java index 66f636ada22..d630f57d90d 100644 --- a/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServer.java +++ b/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServer.java @@ -17,6 +17,7 @@ package io.grpc.s2a.handshaker; import io.grpc.stub.StreamObserver; +import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import java.util.logging.Logger; @@ -38,7 +39,11 @@ public StreamObserver setUpSession(StreamObserver respo @Override public void onNext(SessionReq req) { logger.info("Received a request from client."); - responseObserver.onNext(writer.handleResponse(req)); + try { + responseObserver.onNext(writer.handleResponse(req)); + } catch (IOException e) { + responseObserver.onError(e); + } } @Override diff --git a/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServerTest.java b/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServerTest.java index 7f1a55c385f..a8868744f80 100644 --- a/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServerTest.java +++ b/s2a/src/test/java/io/grpc/s2a/handshaker/FakeS2AServerTest.java @@ -29,7 +29,9 @@ import io.grpc.benchmarks.Utils; import io.grpc.s2a.handshaker.ValidatePeerCertificateChainReq.VerificationMode; import io.grpc.stub.StreamObserver; +import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -67,7 +69,7 @@ public void tearDown() { @Test public void callS2AServerOnce_getTlsConfiguration_returnsValidResult() - throws InterruptedException { + throws InterruptedException, IOException { ExecutorService executor = Executors.newSingleThreadExecutor(); logger.info("Client connecting to: " + serverAddress); ManagedChannel channel = @@ -121,9 +123,12 @@ public void onCompleted() {} GetTlsConfigurationResp.newBuilder() .setClientTlsConfiguration( GetTlsConfigurationResp.ClientTlsConfiguration.newBuilder() - .addCertificateChain(FakeWriter.LEAF_CERT) - .addCertificateChain(FakeWriter.INTERMEDIATE_CERT_2) - .addCertificateChain(FakeWriter.INTERMEDIATE_CERT_1) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.leafCertFile.toPath()), StandardCharsets.UTF_8)) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.cert1File.toPath()), StandardCharsets.UTF_8)) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.cert2File.toPath()), StandardCharsets.UTF_8)) .setMinTlsVersion(TLSVersion.TLS_VERSION_1_3) .setMaxTlsVersion(TLSVersion.TLS_VERSION_1_3) .addCiphersuites( diff --git a/s2a/src/test/java/io/grpc/s2a/handshaker/FakeWriter.java b/s2a/src/test/java/io/grpc/s2a/handshaker/FakeWriter.java index 45961b81b7b..b0e84fdf962 100644 --- a/s2a/src/test/java/io/grpc/s2a/handshaker/FakeWriter.java +++ b/s2a/src/test/java/io/grpc/s2a/handshaker/FakeWriter.java @@ -23,7 +23,10 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.protobuf.ByteString; import io.grpc.stub.StreamObserver; +import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; @@ -50,59 +53,18 @@ enum VerificationResult { FAILURE } - public static final String LEAF_CERT = - "-----BEGIN CERTIFICATE-----\n" - + "MIICkDCCAjagAwIBAgIUSAtcrPhNNs1zxv51lIfGOVtkw6QwCgYIKoZIzj0EAwIw\n" - + "QTEXMBUGA1UECgwOc2VjdXJpdHktcmVhbG0xEDAOBgNVBAsMB2NvbnRleHQxFDAS\n" - + "BgorBgEEAdZ5AggBDAQyMDIyMCAXDTIzMDcxNDIyMzYwNFoYDzIwNTAxMTI5MjIz\n" - + "NjA0WjARMQ8wDQYDVQQDDAZ1bnVzZWQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC\n" - + "AAQGFlJpLxJMh4HuUm0DKjnUF7larH3tJvroQ12xpk+pPKQepn4ILoq9lZ8Xd3jz\n" - + "U98eDRXG5f4VjnX98DDHE4Ido4IBODCCATQwDgYDVR0PAQH/BAQDAgeAMCAGA1Ud\n" - + "JQEB/wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMIGxBgNV\n" - + "HREBAf8EgaYwgaOGSnNwaWZmZTovL3NpZ25lci1yb2xlLmNvbnRleHQuc2VjdXJp\n" - + "dHktcmVhbG0ucHJvZC5nb29nbGUuY29tL3JvbGUvbGVhZi1yb2xlgjNzaWduZXIt\n" - + "cm9sZS5jb250ZXh0LnNlY3VyaXR5LXJlYWxtLnByb2Quc3BpZmZlLmdvb2eCIGZx\n" - + "ZG4tb2YtdGhlLW5vZGUucHJvZC5nb29nbGUuY29tMB0GA1UdDgQWBBSWSd5Fw6dI\n" - + "TGpt0m1Uxwf0iKqebzAfBgNVHSMEGDAWgBRm5agVVdpWfRZKM7u6OMuzHhqPcDAK\n" - + "BggqhkjOPQQDAgNIADBFAiB0sjRPSYy2eFq8Y0vQ8QN4AZ2NMajskvxnlifu7O4U\n" - + "RwIhANTh5Fkyx2nMYFfyl+W45dY8ODTw3HnlZ4b51hTAdkWl\n" - + "-----END CERTIFICATE-----"; - public static final String INTERMEDIATE_CERT_2 = - "-----BEGIN CERTIFICATE-----\n" - + "MIICQjCCAeigAwIBAgIUKxXRDlnWXefNV5lj5CwhDuXEq7MwCgYIKoZIzj0EAwIw\n" - + "OzEXMBUGA1UECgwOc2VjdXJpdHktcmVhbG0xEDAOBgNVBAsMB2NvbnRleHQxDjAM\n" - + "BgNVBAMMBTEyMzQ1MCAXDTIzMDcxNDIyMzYwNFoYDzIwNTAxMTI5MjIzNjA0WjBB\n" - + "MRcwFQYDVQQKDA5zZWN1cml0eS1yZWFsbTEQMA4GA1UECwwHY29udGV4dDEUMBIG\n" - + "CisGAQQB1nkCCAEMBDIwMjIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT/Zu7x\n" - + "UYVyg+T/vg2H+y4I6t36Kc4qxD0eqqZjRLYBVKkUQHxBqc14t0DpoROMYQCNd4DF\n" - + "pcxv/9m6DaJbRk6Ao4HBMIG+MA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\n" - + "AQH/AgEBMFgGA1UdHgEB/wROMEygSjA1gjNzaWduZXItcm9sZS5jb250ZXh0LnNl\n" - + "Y3VyaXR5LXJlYWxtLnByb2Quc3BpZmZlLmdvb2cwEYIPcHJvZC5nb29nbGUuY29t\n" - + "MB0GA1UdDgQWBBRm5agVVdpWfRZKM7u6OMuzHhqPcDAfBgNVHSMEGDAWgBQcjNAh\n" - + "SCHTj+BW8KrzSSLo2ASEgjAKBggqhkjOPQQDAgNIADBFAiEA6KyGd9VxXDZceMZG\n" - + "IsbC40rtunFjLYI0mjZw9RcRWx8CIHCIiIHxafnDaCi+VB99NZfzAdu37g6pJptB\n" - + "gjIY71MO\n" - + "-----END CERTIFICATE-----"; - public static final String INTERMEDIATE_CERT_1 = - "-----BEGIN CERTIFICATE-----\n" - + "MIICODCCAd6gAwIBAgIUXtZECORWRSKnS9rRTJYkiALUXswwCgYIKoZIzj0EAwIw\n" - + "NzEXMBUGA1UECgwOc2VjdXJpdHktcmVhbG0xDTALBgNVBAsMBHJvb3QxDTALBgNV\n" - + "BAMMBDEyMzQwIBcNMjMwNzE0MjIzNjA0WhgPMjA1MDExMjkyMjM2MDRaMDsxFzAV\n" - + "BgNVBAoMDnNlY3VyaXR5LXJlYWxtMRAwDgYDVQQLDAdjb250ZXh0MQ4wDAYDVQQD\n" - + "DAUxMjM0NTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAycVTZrjockbpD59f1a\n" - + "4l1SNL7nSyXz66Guz4eDveQqLmaMBg7vpACfO4CtiAGnolHEffuRtSkdM434m5En\n" - + "bXCjgcEwgb4wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQIwWAYD\n" - + "VR0eAQH/BE4wTKBKMDWCM3NpZ25lci1yb2xlLmNvbnRleHQuc2VjdXJpdHktcmVh\n" - + "bG0ucHJvZC5zcGlmZmUuZ29vZzARgg9wcm9kLmdvb2dsZS5jb20wHQYDVR0OBBYE\n" - + "FByM0CFIIdOP4FbwqvNJIujYBISCMB8GA1UdIwQYMBaAFMX+vebuj/lYfYEC23IA\n" - + "8HoIW0HsMAoGCCqGSM49BAMCA0gAMEUCIQCfxeXEBd7UPmeImT16SseCRu/6cHxl\n" - + "kTDsq9sKZ+eXBAIgA+oViAVOUhUQO1/6Mjlczg8NmMy2vNtG4V/7g9dMMVU=\n" - + "-----END CERTIFICATE-----"; + public static final File leafCertFile = + new File("src/test/resources/leaf_cert_ec.pem"); + public static final File cert2File = + new File("src/test/resources/int_cert2_ec.pem"); + public static final File cert1File = + new File("src/test/resources/int_cert1_ec.pem"); + // src/test/resources/leaf_key_ec.pem private static final String PRIVATE_KEY = - "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgqA2U0ld1OOHLMXWf" - + "uyN4GSaqhhudEIaKkll3rdIq0M+hRANCAAQGFlJpLxJMh4HuUm0DKjnUF7larH3t" - + "JvroQ12xpk+pPKQepn4ILoq9lZ8Xd3jzU98eDRXG5f4VjnX98DDHE4Id"; + "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgR2HBqtWTWu4NLiow" + + "ar8vh+9vAmCONE59C+jXNAb9r8ehRANCAATRM8ozcr8PTOVsZNWh+rTmJ6t+rODu" + + "g3LwWpUQq9h7AddjGlLrrTNrceOyO7nh9aEk5plKhs/h7PO8+vkEFsEx"; private static final ImmutableMap ALGORITHM_TO_SIGNATURE_INSTANCE_IDENTIFIER = ImmutableMap.of( @@ -167,24 +129,32 @@ void sendIoError() { } void sendGetTlsConfigResp() { - reader.onNext( - SessionResp.newBuilder() - .setGetTlsConfigurationResp( - GetTlsConfigurationResp.newBuilder() - .setClientTlsConfiguration( - GetTlsConfigurationResp.ClientTlsConfiguration.newBuilder() - .addCertificateChain(LEAF_CERT) - .addCertificateChain(INTERMEDIATE_CERT_2) - .addCertificateChain(INTERMEDIATE_CERT_1) - .setMinTlsVersion(TLS_VERSION_1_3) - .setMaxTlsVersion(TLS_VERSION_1_3) - .addCiphersuites( - Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - .addCiphersuites( - Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - .addCiphersuites( - Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256))) - .build()); + try { + reader.onNext( + SessionResp.newBuilder() + .setGetTlsConfigurationResp( + GetTlsConfigurationResp.newBuilder() + .setClientTlsConfiguration( + GetTlsConfigurationResp.ClientTlsConfiguration.newBuilder() + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.leafCertFile.toPath()), StandardCharsets.UTF_8)) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.cert1File.toPath()), StandardCharsets.UTF_8)) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.cert2File.toPath()), StandardCharsets.UTF_8)) + .setMinTlsVersion(TLS_VERSION_1_3) + .setMaxTlsVersion(TLS_VERSION_1_3) + .addCiphersuites( + Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) + .addCiphersuites( + Ciphersuite.CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) + .addCiphersuites( + Ciphersuite + .CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256))) + .build()); + } catch (IOException e) { + reader.onError(e); + } } boolean isFakeWriterClosed() { @@ -195,7 +165,11 @@ boolean isFakeWriterClosed() { public void onNext(SessionReq sessionReq) { switch (behavior) { case OK_STATUS: - reader.onNext(handleResponse(sessionReq)); + try { + reader.onNext(handleResponse(sessionReq)); + } catch (IOException e) { + reader.onError(e); + } break; case EMPTY_RESPONSE: reader.onNext(SessionResp.getDefaultInstance()); @@ -216,25 +190,36 @@ public void onNext(SessionReq sessionReq) { reader.onCompleted(); break; case BAD_TLS_VERSION_RESPONSE: - reader.onNext( - SessionResp.newBuilder() - .setGetTlsConfigurationResp( - GetTlsConfigurationResp.newBuilder() - .setClientTlsConfiguration( - GetTlsConfigurationResp.ClientTlsConfiguration.newBuilder() - .addCertificateChain(LEAF_CERT) - .addCertificateChain(INTERMEDIATE_CERT_2) - .addCertificateChain(INTERMEDIATE_CERT_1) - .setMinTlsVersion(TLS_VERSION_1_3) - .setMaxTlsVersion(TLS_VERSION_1_2))) - .build()); + try { + reader.onNext( + SessionResp.newBuilder() + .setGetTlsConfigurationResp( + GetTlsConfigurationResp.newBuilder() + .setClientTlsConfiguration( + GetTlsConfigurationResp.ClientTlsConfiguration.newBuilder() + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.leafCertFile.toPath()), StandardCharsets.UTF_8)) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.cert1File.toPath()), StandardCharsets.UTF_8)) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.cert2File.toPath()), StandardCharsets.UTF_8)) + .setMinTlsVersion(TLS_VERSION_1_3) + .setMaxTlsVersion(TLS_VERSION_1_2))) + .build()); + } catch (IOException e) { + reader.onError(e); + } break; default: - reader.onNext(handleResponse(sessionReq)); + try { + reader.onNext(handleResponse(sessionReq)); + } catch (IOException e) { + reader.onError(e); + } } } - SessionResp handleResponse(SessionReq sessionReq) { + SessionResp handleResponse(SessionReq sessionReq) throws IOException { if (sessionReq.hasGetTlsConfigurationReq()) { return handleGetTlsConfigurationReq(sessionReq.getGetTlsConfigurationReq()); } @@ -253,7 +238,8 @@ SessionResp handleResponse(SessionReq sessionReq) { .build(); } - private SessionResp handleGetTlsConfigurationReq(GetTlsConfigurationReq req) { + private SessionResp handleGetTlsConfigurationReq(GetTlsConfigurationReq req) + throws IOException { if (!req.getConnectionSide().equals(ConnectionSide.CONNECTION_SIDE_CLIENT)) { return SessionResp.newBuilder() .setStatus( @@ -267,9 +253,12 @@ private SessionResp handleGetTlsConfigurationReq(GetTlsConfigurationReq req) { GetTlsConfigurationResp.newBuilder() .setClientTlsConfiguration( GetTlsConfigurationResp.ClientTlsConfiguration.newBuilder() - .addCertificateChain(LEAF_CERT) - .addCertificateChain(INTERMEDIATE_CERT_2) - .addCertificateChain(INTERMEDIATE_CERT_1) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.leafCertFile.toPath()), StandardCharsets.UTF_8)) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.cert1File.toPath()), StandardCharsets.UTF_8)) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.cert2File.toPath()), StandardCharsets.UTF_8)) .setMinTlsVersion(TLS_VERSION_1_3) .setMaxTlsVersion(TLS_VERSION_1_3) .addCiphersuites( diff --git a/s2a/src/test/java/io/grpc/s2a/handshaker/IntegrationTest.java b/s2a/src/test/java/io/grpc/s2a/handshaker/IntegrationTest.java index 19dda7a19e4..7de16020b55 100644 --- a/s2a/src/test/java/io/grpc/s2a/handshaker/IntegrationTest.java +++ b/s2a/src/test/java/io/grpc/s2a/handshaker/IntegrationTest.java @@ -17,7 +17,6 @@ package io.grpc.s2a.handshaker; import static com.google.common.truth.Truth.assertThat; -import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.concurrent.TimeUnit.SECONDS; import io.grpc.ChannelCredentials; @@ -42,7 +41,6 @@ import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslProvider; -import java.io.ByteArrayInputStream; import java.io.File; import java.util.concurrent.FutureTask; import java.util.logging.Logger; @@ -58,72 +56,12 @@ public final class IntegrationTest { private static final Logger logger = Logger.getLogger(FakeS2AServer.class.getName()); - private static final String CERT_CHAIN = - "-----BEGIN CERTIFICATE-----\n" - + "MIICkDCCAjagAwIBAgIUSAtcrPhNNs1zxv51lIfGOVtkw6QwCgYIKoZIzj0EAwIw\n" - + "QTEXMBUGA1UECgwOc2VjdXJpdHktcmVhbG0xEDAOBgNVBAsMB2NvbnRleHQxFDAS\n" - + "BgorBgEEAdZ5AggBDAQyMDIyMCAXDTIzMDcxNDIyMzYwNFoYDzIwNTAxMTI5MjIz\n" - + "NjA0WjARMQ8wDQYDVQQDDAZ1bnVzZWQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC\n" - + "AAQGFlJpLxJMh4HuUm0DKjnUF7larH3tJvroQ12xpk+pPKQepn4ILoq9lZ8Xd3jz\n" - + "U98eDRXG5f4VjnX98DDHE4Ido4IBODCCATQwDgYDVR0PAQH/BAQDAgeAMCAGA1Ud\n" - + "JQEB/wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMIGxBgNV\n" - + "HREBAf8EgaYwgaOGSnNwaWZmZTovL3NpZ25lci1yb2xlLmNvbnRleHQuc2VjdXJp\n" - + "dHktcmVhbG0ucHJvZC5nb29nbGUuY29tL3JvbGUvbGVhZi1yb2xlgjNzaWduZXIt\n" - + "cm9sZS5jb250ZXh0LnNlY3VyaXR5LXJlYWxtLnByb2Quc3BpZmZlLmdvb2eCIGZx\n" - + "ZG4tb2YtdGhlLW5vZGUucHJvZC5nb29nbGUuY29tMB0GA1UdDgQWBBSWSd5Fw6dI\n" - + "TGpt0m1Uxwf0iKqebzAfBgNVHSMEGDAWgBRm5agVVdpWfRZKM7u6OMuzHhqPcDAK\n" - + "BggqhkjOPQQDAgNIADBFAiB0sjRPSYy2eFq8Y0vQ8QN4AZ2NMajskvxnlifu7O4U\n" - + "RwIhANTh5Fkyx2nMYFfyl+W45dY8ODTw3HnlZ4b51hTAdkWl\n" - + "-----END CERTIFICATE-----\n" - + "-----BEGIN CERTIFICATE-----\n" - + "MIICQjCCAeigAwIBAgIUKxXRDlnWXefNV5lj5CwhDuXEq7MwCgYIKoZIzj0EAwIw\n" - + "OzEXMBUGA1UECgwOc2VjdXJpdHktcmVhbG0xEDAOBgNVBAsMB2NvbnRleHQxDjAM\n" - + "BgNVBAMMBTEyMzQ1MCAXDTIzMDcxNDIyMzYwNFoYDzIwNTAxMTI5MjIzNjA0WjBB\n" - + "MRcwFQYDVQQKDA5zZWN1cml0eS1yZWFsbTEQMA4GA1UECwwHY29udGV4dDEUMBIG\n" - + "CisGAQQB1nkCCAEMBDIwMjIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT/Zu7x\n" - + "UYVyg+T/vg2H+y4I6t36Kc4qxD0eqqZjRLYBVKkUQHxBqc14t0DpoROMYQCNd4DF\n" - + "pcxv/9m6DaJbRk6Ao4HBMIG+MA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\n" - + "AQH/AgEBMFgGA1UdHgEB/wROMEygSjA1gjNzaWduZXItcm9sZS5jb250ZXh0LnNl\n" - + "Y3VyaXR5LXJlYWxtLnByb2Quc3BpZmZlLmdvb2cwEYIPcHJvZC5nb29nbGUuY29t\n" - + "MB0GA1UdDgQWBBRm5agVVdpWfRZKM7u6OMuzHhqPcDAfBgNVHSMEGDAWgBQcjNAh\n" - + "SCHTj+BW8KrzSSLo2ASEgjAKBggqhkjOPQQDAgNIADBFAiEA6KyGd9VxXDZceMZG\n" - + "IsbC40rtunFjLYI0mjZw9RcRWx8CIHCIiIHxafnDaCi+VB99NZfzAdu37g6pJptB\n" - + "gjIY71MO\n" - + "-----END CERTIFICATE-----\n" - + "-----BEGIN CERTIFICATE-----\n" - + "MIICODCCAd6gAwIBAgIUXtZECORWRSKnS9rRTJYkiALUXswwCgYIKoZIzj0EAwIw\n" - + "NzEXMBUGA1UECgwOc2VjdXJpdHktcmVhbG0xDTALBgNVBAsMBHJvb3QxDTALBgNV\n" - + "BAMMBDEyMzQwIBcNMjMwNzE0MjIzNjA0WhgPMjA1MDExMjkyMjM2MDRaMDsxFzAV\n" - + "BgNVBAoMDnNlY3VyaXR5LXJlYWxtMRAwDgYDVQQLDAdjb250ZXh0MQ4wDAYDVQQD\n" - + "DAUxMjM0NTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAycVTZrjockbpD59f1a\n" - + "4l1SNL7nSyXz66Guz4eDveQqLmaMBg7vpACfO4CtiAGnolHEffuRtSkdM434m5En\n" - + "bXCjgcEwgb4wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQIwWAYD\n" - + "VR0eAQH/BE4wTKBKMDWCM3NpZ25lci1yb2xlLmNvbnRleHQuc2VjdXJpdHktcmVh\n" - + "bG0ucHJvZC5zcGlmZmUuZ29vZzARgg9wcm9kLmdvb2dsZS5jb20wHQYDVR0OBBYE\n" - + "FByM0CFIIdOP4FbwqvNJIujYBISCMB8GA1UdIwQYMBaAFMX+vebuj/lYfYEC23IA\n" - + "8HoIW0HsMAoGCCqGSM49BAMCA0gAMEUCIQCfxeXEBd7UPmeImT16SseCRu/6cHxl\n" - + "kTDsq9sKZ+eXBAIgA+oViAVOUhUQO1/6Mjlczg8NmMy2vNtG4V/7g9dMMVU=\n" - + "-----END CERTIFICATE-----"; - private static final String ROOT_PEM = - "-----BEGIN CERTIFICATE-----\n" - + "MIIBtTCCAVqgAwIBAgIUbAe+8OocndQXRBCElLBxBSdfdV8wCgYIKoZIzj0EAwIw\n" - + "NzEXMBUGA1UECgwOc2VjdXJpdHktcmVhbG0xDTALBgNVBAsMBHJvb3QxDTALBgNV\n" - + "BAMMBDEyMzQwIBcNMjMwNzE0MjIzNjA0WhgPMjA1MDExMjkyMjM2MDRaMDcxFzAV\n" - + "BgNVBAoMDnNlY3VyaXR5LXJlYWxtMQ0wCwYDVQQLDARyb290MQ0wCwYDVQQDDAQx\n" - + "MjM0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaMY2tBW5r1t0+vhayz0ZoGMF\n" - + "boX/ZmmCmIh0iTWg4madvwNOh74CMVVvDUlXZcuVqZ3vVIX/a7PTFVqUwQlKW6NC\n" - + "MEAwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMX+\n" - + "vebuj/lYfYEC23IA8HoIW0HsMAoGCCqGSM49BAMCA0kAMEYCIQDETd27nsUTXKWY\n" - + "CiOno78O09gK95NoTkPU5e2chJYMqAIhALYFAyh7PU5xgFQsN9hiqgsHUc5/pmBG\n" - + "BGjJ1iz8rWGJ\n" - + "-----END CERTIFICATE-----"; - private static final String PRIVATE_KEY = - "-----BEGIN PRIVATE KEY-----\n" - + "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgqA2U0ld1OOHLMXWf\n" - + "uyN4GSaqhhudEIaKkll3rdIq0M+hRANCAAQGFlJpLxJMh4HuUm0DKjnUF7larH3t\n" - + "JvroQ12xpk+pPKQepn4ILoq9lZ8Xd3jzU98eDRXG5f4VjnX98DDHE4Id\n" - + "-----END PRIVATE KEY-----"; - + public static final File privateKeyFile = + new File("src/test/resources/leaf_key_ec.pem"); + public static final File rootCertFile = + new File("src/test/resources/root_cert_ec.pem"); + public static final File certChainFile = + new File("src/test/resources/cert_chain_ec.pem"); private String s2aAddress; private Server s2aServer; private String s2aDelayAddress; @@ -252,13 +190,11 @@ public static boolean doUnaryRpc(ManagedChannel channel) throws InterruptedExcep private static SslContext buildSslContext() throws SSLException { SslContextBuilder sslServerContextBuilder = - SslContextBuilder.forServer( - new ByteArrayInputStream(CERT_CHAIN.getBytes(UTF_8)), - new ByteArrayInputStream(PRIVATE_KEY.getBytes(UTF_8))); + SslContextBuilder.forServer(certChainFile, privateKeyFile); SslContext sslServerContext = GrpcSslContexts.configure(sslServerContextBuilder, SslProvider.OPENSSL) .protocols("TLSv1.3", "TLSv1.2") - .trustManager(new ByteArrayInputStream(ROOT_PEM.getBytes(UTF_8))) + .trustManager(rootCertFile) .clientAuth(ClientAuth.REQUIRE) .build(); diff --git a/s2a/src/test/java/io/grpc/s2a/handshaker/S2APrivateKeyMethodTest.java b/s2a/src/test/java/io/grpc/s2a/handshaker/S2APrivateKeyMethodTest.java index 8252aa245d7..fc8d42d09c0 100644 --- a/s2a/src/test/java/io/grpc/s2a/handshaker/S2APrivateKeyMethodTest.java +++ b/s2a/src/test/java/io/grpc/s2a/handshaker/S2APrivateKeyMethodTest.java @@ -30,6 +30,8 @@ import io.netty.handler.ssl.OpenSslPrivateKeyMethod; import io.netty.handler.ssl.SslContextBuilder; import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.security.PublicKey; import java.security.Signature; import java.security.cert.CertificateFactory; @@ -61,7 +63,8 @@ private static PublicKey extractPublicKeyFromPem(String pem) throws Exception { private static boolean verifySignature( byte[] dataToSign, byte[] signature, String signatureAlgorithm) throws Exception { Signature sig = Signature.getInstance(signatureAlgorithm); - sig.initVerify(extractPublicKeyFromPem(FakeWriter.LEAF_CERT)); + sig.initVerify(extractPublicKeyFromPem(new String( + Files.readAllBytes(FakeWriter.leafCertFile.toPath()), StandardCharsets.UTF_8))); sig.update(dataToSign); return sig.verify(signature); } diff --git a/s2a/src/test/java/io/grpc/s2a/handshaker/S2AProtocolNegotiatorFactoryTest.java b/s2a/src/test/java/io/grpc/s2a/handshaker/S2AProtocolNegotiatorFactoryTest.java index f130e52aac7..67ed42fdc4b 100644 --- a/s2a/src/test/java/io/grpc/s2a/handshaker/S2AProtocolNegotiatorFactoryTest.java +++ b/s2a/src/test/java/io/grpc/s2a/handshaker/S2AProtocolNegotiatorFactoryTest.java @@ -50,6 +50,7 @@ import io.netty.handler.codec.http2.Http2ConnectionEncoder; import io.netty.handler.codec.http2.Http2Settings; import io.netty.util.AsciiString; +import java.io.IOException; import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -246,7 +247,11 @@ public StreamObserver setUpSession(StreamObserver respo return new StreamObserver() { @Override public void onNext(SessionReq req) { - responseObserver.onNext(writer.handleResponse(req)); + try { + responseObserver.onNext(writer.handleResponse(req)); + } catch (IOException e) { + responseObserver.onError(e); + } } @Override diff --git a/s2a/src/test/java/io/grpc/s2a/handshaker/S2AStubTest.java b/s2a/src/test/java/io/grpc/s2a/handshaker/S2AStubTest.java index 0348fb97e56..88eb5ac43cf 100644 --- a/s2a/src/test/java/io/grpc/s2a/handshaker/S2AStubTest.java +++ b/s2a/src/test/java/io/grpc/s2a/handshaker/S2AStubTest.java @@ -27,6 +27,8 @@ import io.grpc.s2a.channel.S2AHandshakerServiceChannel; import io.grpc.stub.StreamObserver; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.Optional; import org.junit.Before; import org.junit.Rule; @@ -82,9 +84,12 @@ public void send_clientTlsConfiguration_receiveOkStatus() throws Exception { GetTlsConfigurationResp.newBuilder() .setClientTlsConfiguration( GetTlsConfigurationResp.ClientTlsConfiguration.newBuilder() - .addCertificateChain(FakeWriter.LEAF_CERT) - .addCertificateChain(FakeWriter.INTERMEDIATE_CERT_2) - .addCertificateChain(FakeWriter.INTERMEDIATE_CERT_1) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.leafCertFile.toPath()), StandardCharsets.UTF_8)) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.cert1File.toPath()), StandardCharsets.UTF_8)) + .addCertificateChain(new String(Files.readAllBytes( + FakeWriter.cert2File.toPath()), StandardCharsets.UTF_8)) .setMinTlsVersion(TLSVersion.TLS_VERSION_1_3) .setMaxTlsVersion(TLSVersion.TLS_VERSION_1_3) .addCiphersuites( diff --git a/s2a/src/test/resources/README.md b/s2a/src/test/resources/README.md index 726b921a615..2250ffb1dec 100644 --- a/s2a/src/test/resources/README.md +++ b/s2a/src/test/resources/README.md @@ -29,4 +29,41 @@ Sign CSRs for server and client ``` openssl x509 -req -CA root_cert.pem -CAkey root_key.pem -in server.csr -out server_cert.pem -days 7305 -extfile config.cnf -extensions req_ext openssl x509 -req -CA root_cert.pem -CAkey root_key.pem -in client.csr -out client_cert.pem -days 7305 +``` + +Generate self-signed ECDSA root cert + +``` +openssl ecparam -name prime256v1 -genkey -noout -out temp.pem +openssl pkcs8 -topk8 -in temp.pem -out root_key_ec.pem -nocrypt +rm temp.pem +openssl req -x509 -days 7305 -new -key root_key_ec.pem -nodes -out root_cert_ec.pem -config root_ec.cnf -extensions 'v3_req' +``` + +Generate a chain of ECDSA certs + +``` +openssl ecparam -name prime256v1 -genkey -noout -out temp.pem +openssl pkcs8 -topk8 -in temp.pem -out int_key2_ec.pem -nocrypt +rm temp.pem +openssl req -key int_key2_ec.pem -new -out temp.csr -config int_cert2.cnf +openssl x509 -req -days 7305 -in temp.csr -CA root_cert_ec.pem -CAkey root_key_ec.pem -CAcreateserial -out int_cert2_ec.pem -extfile int_cert2.cnf -extensions 'v3_req' + + +openssl ecparam -name prime256v1 -genkey -noout -out temp.pem +openssl pkcs8 -topk8 -in temp.pem -out int_key1_ec.pem -nocrypt +rm temp.pem +openssl req -key int_key1_ec.pem -new -out temp.csr -config int_cert1.cnf +openssl x509 -req -days 7305 -in temp.csr -CA int_cert2_ec.pem -CAkey int_key2_ec.pem -CAcreateserial -out int_cert1_ec.pem -extfile int_cert1.cnf -extensions 'v3_req' + + +openssl ecparam -name prime256v1 -genkey -noout -out temp.pem +openssl pkcs8 -topk8 -in temp.pem -out leaf_key_ec.pem -nocrypt +rm temp.pem +openssl req -key leaf_key_ec.pem -new -out temp.csr -config leaf.cnf +openssl x509 -req -days 7305 -in temp.csr -CA int_cert1_ec.pem -CAkey int_key1_ec.pem -CAcreateserial -out leaf_cert_ec.pem -extfile leaf.cnf -extensions 'v3_req' +``` + +``` +cat leaf_cert_ec.pem int_cert1_ec.pem int_cert2_ec.pem > cert_chain_ec.pem ``` \ No newline at end of file diff --git a/s2a/src/test/resources/cert_chain_ec.pem b/s2a/src/test/resources/cert_chain_ec.pem new file mode 100644 index 00000000000..0e097d39bf2 --- /dev/null +++ b/s2a/src/test/resources/cert_chain_ec.pem @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIB0jCCAXigAwIBAgIUBV1dftEhhEMTI83L6jpeJn2tuyQwCgYIKoZIzj0EAwIw +JjEKMAgGA1UECgwBbzELMAkGA1UECwwCb3UxCzAJBgNVBAMMAmNuMB4XDTI0MDkx +OTIzMDQwMFoXDTQ0MDkxOTIzMDQwMFowJjEKMAgGA1UECgwBbzELMAkGA1UECwwC +b3UxCzAJBgNVBAMMAmNuMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0TPKM3K/ +D0zlbGTVofq05ierfqzg7oNy8FqVEKvYewHXYxpS660za3Hjsju54fWhJOaZSobP +4ezzvPr5BBbBMaOBgzCBgDAOBgNVHQ8BAf8EBAMCB4AwIAYDVR0lAQH/BBYwFAYI +KwYBBQUHAwIGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPvP7dnB +dg8ZoLB0w62tbvoIRRHPMB8GA1UdIwQYMBaAFHeH+MNh2fgyjNHYP9hLAv9Sl1yD +MAoGCCqGSM49BAMCA0gAMEUCIBcsImaxeFjxFXCXYNQJnde+rsEOgbeAHrAC0SZQ +NlB2AiEA4epDhw/o+6BfgDbqlZsNEHkScPrwupnBQGLQlmNJe2c= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB1zCCAX6gAwIBAgIUW4GYHncSLeb7Tmw7FMjX/DesReIwCgYIKoZIzj0EAwIw +JjEKMAgGA1UECgwBbzELMAkGA1UECwwCb3UxCzAJBgNVBAMMAmNuMB4XDTI0MDkx +OTIzMDA0MVoXDTQ0MDkxOTIzMDA0MVowJjEKMAgGA1UECgwBbzELMAkGA1UECwwC +b3UxCzAJBgNVBAMMAmNuMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAqtg2E+h +Wfr5dnewqsCLwM0PohkB83Gh7V3i/TPFkNKF/V6pKdz5a3Z8sicG+g7uJX+eyOoD +43Z8woO7MgJl8aOBiTCBhjAOBgNVHQ8BAf8EBAMCAQYwIAYDVR0lAQH/BBYwFAYI +KwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE +FHeH+MNh2fgyjNHYP9hLAv9Sl1yDMB8GA1UdIwQYMBaAFP+PTOryxis9d7HVfqhP +MyMEgMZOMAoGCCqGSM49BAMCA0cAMEQCIHbzJvxHMIDPBRi1e047K0mqKKBSfViS +guiDSoQ5g5OuAiBT5ePqDLs4PyrK6XFkiEWoRX8Z5T9y419Go+fpLM+DaA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB1zCCAX6gAwIBAgIUBBKkTrqFxQUist2pK2uj8/DRnKMwCgYIKoZIzj0EAwIw +JjEKMAgGA1UECgwBbzELMAkGA1UECwwCb3UxCzAJBgNVBAMMAmNuMB4XDTI0MDkx +OTIyNTYwNloXDTQ0MDkxOTIyNTYwNlowJjEKMAgGA1UECgwBbzELMAkGA1UECwwC +b3UxCzAJBgNVBAMMAmNuMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFW7/Te2z +jS8KlpF8RMMYaZtKf6EZlrZIIo5SO9j6baAKXVna9LmDCrzXnOLIeqOuZq0ODizU +i4DFALB2yd5BkaOBiTCBhjAOBgNVHQ8BAf8EBAMCAQYwIAYDVR0lAQH/BBYwFAYI +KwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYBAf8CAQIwHQYDVR0OBBYE +FP+PTOryxis9d7HVfqhPMyMEgMZOMB8GA1UdIwQYMBaAFFITbB0BULPtynN9SMki +lEarWxcKMAoGCCqGSM49BAMCA0cAMEQCIHK4cTTx4Ti7Te9hA9VVtHoMCt5fL4Cl +XnQR6D5xW4pPAiAQ+CilQdZUhVK5bU6wbrwLgcwf+40ETK/KASId5970rQ== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/s2a/src/test/resources/int_cert1_.cnf b/s2a/src/test/resources/int_cert1_.cnf new file mode 100644 index 00000000000..8eaf6570da1 --- /dev/null +++ b/s2a/src/test/resources/int_cert1_.cnf @@ -0,0 +1,14 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req +prompt = no + +[req_distinguished_name] +O = o +OU = ou +CN = cn + +[v3_req] +keyUsage = critical, keyCertSign, cRLSign +extendedKeyUsage = critical, clientAuth, serverAuth +basicConstraints = critical, CA:true, pathlen: 1 \ No newline at end of file diff --git a/s2a/src/test/resources/int_cert1_ec.pem b/s2a/src/test/resources/int_cert1_ec.pem new file mode 100644 index 00000000000..980de5aa900 --- /dev/null +++ b/s2a/src/test/resources/int_cert1_ec.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB1zCCAX6gAwIBAgIUW4GYHncSLeb7Tmw7FMjX/DesReIwCgYIKoZIzj0EAwIw +JjEKMAgGA1UECgwBbzELMAkGA1UECwwCb3UxCzAJBgNVBAMMAmNuMB4XDTI0MDkx +OTIzMDA0MVoXDTQ0MDkxOTIzMDA0MVowJjEKMAgGA1UECgwBbzELMAkGA1UECwwC +b3UxCzAJBgNVBAMMAmNuMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAqtg2E+h +Wfr5dnewqsCLwM0PohkB83Gh7V3i/TPFkNKF/V6pKdz5a3Z8sicG+g7uJX+eyOoD +43Z8woO7MgJl8aOBiTCBhjAOBgNVHQ8BAf8EBAMCAQYwIAYDVR0lAQH/BBYwFAYI +KwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE +FHeH+MNh2fgyjNHYP9hLAv9Sl1yDMB8GA1UdIwQYMBaAFP+PTOryxis9d7HVfqhP +MyMEgMZOMAoGCCqGSM49BAMCA0cAMEQCIHbzJvxHMIDPBRi1e047K0mqKKBSfViS +guiDSoQ5g5OuAiBT5ePqDLs4PyrK6XFkiEWoRX8Z5T9y419Go+fpLM+DaA== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/s2a/src/test/resources/int_cert2.cnf b/s2a/src/test/resources/int_cert2.cnf new file mode 100644 index 00000000000..c6a2559ce10 --- /dev/null +++ b/s2a/src/test/resources/int_cert2.cnf @@ -0,0 +1,14 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req +prompt = no + +[req_distinguished_name] +O = o +OU = ou +CN = cn + +[v3_req] +keyUsage = critical, keyCertSign, cRLSign +extendedKeyUsage = critical, clientAuth, serverAuth +basicConstraints = critical, CA:true, pathlen: 2 \ No newline at end of file diff --git a/s2a/src/test/resources/int_cert2_ec.pem b/s2a/src/test/resources/int_cert2_ec.pem new file mode 100644 index 00000000000..574fa0195de --- /dev/null +++ b/s2a/src/test/resources/int_cert2_ec.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB1zCCAX6gAwIBAgIUBBKkTrqFxQUist2pK2uj8/DRnKMwCgYIKoZIzj0EAwIw +JjEKMAgGA1UECgwBbzELMAkGA1UECwwCb3UxCzAJBgNVBAMMAmNuMB4XDTI0MDkx +OTIyNTYwNloXDTQ0MDkxOTIyNTYwNlowJjEKMAgGA1UECgwBbzELMAkGA1UECwwC +b3UxCzAJBgNVBAMMAmNuMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFW7/Te2z +jS8KlpF8RMMYaZtKf6EZlrZIIo5SO9j6baAKXVna9LmDCrzXnOLIeqOuZq0ODizU +i4DFALB2yd5BkaOBiTCBhjAOBgNVHQ8BAf8EBAMCAQYwIAYDVR0lAQH/BBYwFAYI +KwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYBAf8CAQIwHQYDVR0OBBYE +FP+PTOryxis9d7HVfqhPMyMEgMZOMB8GA1UdIwQYMBaAFFITbB0BULPtynN9SMki +lEarWxcKMAoGCCqGSM49BAMCA0cAMEQCIHK4cTTx4Ti7Te9hA9VVtHoMCt5fL4Cl +XnQR6D5xW4pPAiAQ+CilQdZUhVK5bU6wbrwLgcwf+40ETK/KASId5970rQ== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/s2a/src/test/resources/int_key1_ec.pem b/s2a/src/test/resources/int_key1_ec.pem new file mode 100644 index 00000000000..7ff3864746b --- /dev/null +++ b/s2a/src/test/resources/int_key1_ec.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgLIQUM1HkFM/LWND8 +jCZ4wHXjFZ1ZZmQolahkZB0O1VChRANCAAQCq2DYT6FZ+vl2d7CqwIvAzQ+iGQHz +caHtXeL9M8WQ0oX9Xqkp3PlrdnyyJwb6Du4lf57I6gPjdnzCg7syAmXx +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/s2a/src/test/resources/int_key2_ec.pem b/s2a/src/test/resources/int_key2_ec.pem new file mode 100644 index 00000000000..7f529ae855f --- /dev/null +++ b/s2a/src/test/resources/int_key2_ec.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGfm6kyaAMMrmYGhS +jxprBwtcZdP6qXlU1cVIO5bOT8qhRANCAAQVbv9N7bONLwqWkXxEwxhpm0p/oRmW +tkgijlI72PptoApdWdr0uYMKvNec4sh6o65mrQ4OLNSLgMUAsHbJ3kGR +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/s2a/src/test/resources/leaf.cnf b/s2a/src/test/resources/leaf.cnf new file mode 100644 index 00000000000..d5b373cbc71 --- /dev/null +++ b/s2a/src/test/resources/leaf.cnf @@ -0,0 +1,14 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req +prompt = no + +[req_distinguished_name] +O = o +OU = ou +CN = cn + +[v3_req] +keyUsage = critical, digitalSignature +extendedKeyUsage = critical, clientAuth, serverAuth +basicConstraints = critical, CA:false \ No newline at end of file diff --git a/s2a/src/test/resources/leaf_cert_ec.pem b/s2a/src/test/resources/leaf_cert_ec.pem new file mode 100644 index 00000000000..39692b95fda --- /dev/null +++ b/s2a/src/test/resources/leaf_cert_ec.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB0jCCAXigAwIBAgIUBV1dftEhhEMTI83L6jpeJn2tuyQwCgYIKoZIzj0EAwIw +JjEKMAgGA1UECgwBbzELMAkGA1UECwwCb3UxCzAJBgNVBAMMAmNuMB4XDTI0MDkx +OTIzMDQwMFoXDTQ0MDkxOTIzMDQwMFowJjEKMAgGA1UECgwBbzELMAkGA1UECwwC +b3UxCzAJBgNVBAMMAmNuMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0TPKM3K/ +D0zlbGTVofq05ierfqzg7oNy8FqVEKvYewHXYxpS660za3Hjsju54fWhJOaZSobP +4ezzvPr5BBbBMaOBgzCBgDAOBgNVHQ8BAf8EBAMCB4AwIAYDVR0lAQH/BBYwFAYI +KwYBBQUHAwIGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPvP7dnB +dg8ZoLB0w62tbvoIRRHPMB8GA1UdIwQYMBaAFHeH+MNh2fgyjNHYP9hLAv9Sl1yD +MAoGCCqGSM49BAMCA0gAMEUCIBcsImaxeFjxFXCXYNQJnde+rsEOgbeAHrAC0SZQ +NlB2AiEA4epDhw/o+6BfgDbqlZsNEHkScPrwupnBQGLQlmNJe2c= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/s2a/src/test/resources/leaf_key_ec.pem b/s2a/src/test/resources/leaf_key_ec.pem new file mode 100644 index 00000000000..d90ad8f4db8 --- /dev/null +++ b/s2a/src/test/resources/leaf_key_ec.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgR2HBqtWTWu4NLiow +ar8vh+9vAmCONE59C+jXNAb9r8ehRANCAATRM8ozcr8PTOVsZNWh+rTmJ6t+rODu +g3LwWpUQq9h7AddjGlLrrTNrceOyO7nh9aEk5plKhs/h7PO8+vkEFsEx +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/s2a/src/test/resources/root_cert_ec.pem b/s2a/src/test/resources/root_cert_ec.pem new file mode 100644 index 00000000000..0dd465e8e90 --- /dev/null +++ b/s2a/src/test/resources/root_cert_ec.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBrzCCAVWgAwIBAgIUGV+9j5V61CZaa6mbrchDag5miEQwCgYIKoZIzj0EAwIw +JjEKMAgGA1UECgwBbzELMAkGA1UECwwCb3UxCzAJBgNVBAMMAmNuMB4XDTI0MDkx +OTIyNDMwOFoXDTQ0MDkxOTIyNDMwOFowJjEKMAgGA1UECgwBbzELMAkGA1UECwwC +b3UxCzAJBgNVBAMMAmNuMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDVPIq1ds +/MX52CX9YU1RdEeM89YP4o3BN8OiP2O4qcuc11k4Qu4Mo4RWeN9OJpNElTQJ0K8n +/rIvbmw8AIMquaNhMF8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdJQQWMBQGCCsGAQUF +BwMBBggrBgEFBQcDAjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRSE2wdAVCz +7cpzfUjJIpRGq1sXCjAKBggqhkjOPQQDAgNIADBFAiEA1TEfHWArDnepmtMDQ4wd +Q3uqPrV2Ye2KMO67/BHEGIQCIFu3JutXYYVU/CinwH89AJW+FJ7zokaPjCDkbiOH ++h+H +-----END CERTIFICATE----- \ No newline at end of file diff --git a/s2a/src/test/resources/root_ec.cnf b/s2a/src/test/resources/root_ec.cnf new file mode 100644 index 00000000000..bee0b80a166 --- /dev/null +++ b/s2a/src/test/resources/root_ec.cnf @@ -0,0 +1,14 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req +prompt = no + +[req_distinguished_name] +O = o +OU = ou +CN = cn + +[v3_req] +keyUsage = critical, keyCertSign, cRLSign +extendedKeyUsage = serverAuth, clientAuth +basicConstraints = critical, CA:true \ No newline at end of file diff --git a/s2a/src/test/resources/root_key_ec.pem b/s2a/src/test/resources/root_key_ec.pem new file mode 100644 index 00000000000..ef5ee1445f9 --- /dev/null +++ b/s2a/src/test/resources/root_key_ec.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd5oZmQBOtMF0xfc3 +uRuw5EDhA1thJKKeHfrij9FMkfahRANCAAQNU8irV2z8xfnYJf1hTVF0R4zz1g/i +jcE3w6I/Y7ipy5zXWThC7gyjhFZ4304mk0SVNAnQryf+si9ubDwAgyq5 +-----END PRIVATE KEY----- \ No newline at end of file