From d1011759d75243d1c7c4bdc15e36fe2518e20267 Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Thu, 15 Aug 2019 15:10:50 -0700 Subject: [PATCH] Enable client TLS auth for Netty This commit enables customers to configure a TlsKeyManagersProvider on the Netty client which will be used to authenticate the client during client TLS authentication. --- .../amazon/awssdk/spotbugs-suppressions.xml | 7 + .../http/SdkHttpConfigurationOption.java | 10 + .../awssdk/http/TlsKeyManagersProvider.java | 8 + .../http/NoneTlsKeyManagersProvider.java | 42 ++++ .../http/TlsKeyManagersProviderTest.java | 27 +++ .../http/NoneTlsKeyManagersProviderTest.java | 39 ++++ .../awssdk/http/apache/ApacheHttpClient.java | 18 +- .../http/apache/ApacheClientTlsAuthTest.java | 36 +++- .../nio/netty/NettyNioAsyncHttpClient.java | 22 +- .../internal/AwaitCloseChannelPoolMap.java | 13 ++ .../netty/internal/NettyConfiguration.java | 5 + .../internal/StaticKeyManagerFactory.java | 34 ++++ .../internal/StaticKeyManagerFactorySpi.java | 53 +++++ .../http/nio/netty/ClientTlsAuthTestBase.java | 64 ++++++ .../nio/netty/NettyClientTlsAuthTest.java | 190 ++++++++++++++++++ .../AwaitCloseChannelPoolMapTest.java | 25 +++ .../StaticKeyManagerFactorySpiTest.java | 72 +++++++ .../internal/StaticKeyManagerFactoryTest.java | 41 ++++ .../amazon/awssdk/http/netty/client1.p12 | Bin 0 -> 1714 bytes .../amazon/awssdk/http/netty/server-keystore | Bin 0 -> 2696 bytes 20 files changed, 689 insertions(+), 17 deletions(-) create mode 100644 http-client-spi/src/main/java/software/amazon/awssdk/internal/http/NoneTlsKeyManagersProvider.java create mode 100644 http-client-spi/src/test/java/software/amazon/awssdk/http/TlsKeyManagersProviderTest.java create mode 100644 http-client-spi/src/test/java/software/amazon/awssdk/http/software/amazon/awssdk/internal/http/NoneTlsKeyManagersProviderTest.java create mode 100644 http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/StaticKeyManagerFactory.java create mode 100644 http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/StaticKeyManagerFactorySpi.java create mode 100644 http-clients/netty-nio-client/src/test/java/software/amazon/awssdk/http/nio/netty/ClientTlsAuthTestBase.java create mode 100644 http-clients/netty-nio-client/src/test/java/software/amazon/awssdk/http/nio/netty/NettyClientTlsAuthTest.java create mode 100644 http-clients/netty-nio-client/src/test/java/software/amazon/awssdk/http/nio/netty/internal/StaticKeyManagerFactorySpiTest.java create mode 100644 http-clients/netty-nio-client/src/test/java/software/amazon/awssdk/http/nio/netty/internal/StaticKeyManagerFactoryTest.java create mode 100644 http-clients/netty-nio-client/src/test/resources/software/amazon/awssdk/http/netty/client1.p12 create mode 100644 http-clients/netty-nio-client/src/test/resources/software/amazon/awssdk/http/netty/server-keystore diff --git a/build-tools/src/main/resources/software/amazon/awssdk/spotbugs-suppressions.xml b/build-tools/src/main/resources/software/amazon/awssdk/spotbugs-suppressions.xml index 821b7255619f..69f864b741af 100644 --- a/build-tools/src/main/resources/software/amazon/awssdk/spotbugs-suppressions.xml +++ b/build-tools/src/main/resources/software/amazon/awssdk/spotbugs-suppressions.xml @@ -143,4 +143,11 @@ + + + + + + + diff --git a/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java b/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java index 52e91eaaa3c7..ac90fd0ba72f 100644 --- a/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java +++ b/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java @@ -97,6 +97,13 @@ public final class SdkHttpConfigurationOption extends AttributeMap.Key { public static final SdkHttpConfigurationOption REAP_IDLE_CONNECTIONS = new SdkHttpConfigurationOption<>("ReapIdleConnections", Boolean.class); + /** + * The {@link TlsKeyManagersProvider} that will be used by the HTTP client when authenticating with a + * TLS host. + */ + public static final SdkHttpConfigurationOption TLS_KEY_MANAGERS_PROVIDER = + new SdkHttpConfigurationOption<>("TlsKeyManagersProvider", TlsKeyManagersProvider.class); + private static final Duration DEFAULT_SOCKET_READ_TIMEOUT = Duration.ofSeconds(30); private static final Duration DEFAULT_SOCKET_WRITE_TIMEOUT = Duration.ofSeconds(30); private static final Duration DEFAULT_CONNECTION_TIMEOUT = Duration.ofSeconds(2); @@ -110,6 +117,8 @@ public final class SdkHttpConfigurationOption extends AttributeMap.Key { private static final Protocol DEFAULT_PROTOCOL = Protocol.HTTP1_1; + private static final TlsKeyManagersProvider DEFAULT_TLS_KEY_MANAGERS_PROVIDER = SystemPropertyTlsKeyManagersProvider.create(); + public static final AttributeMap GLOBAL_HTTP_DEFAULTS = AttributeMap .builder() .put(READ_TIMEOUT, DEFAULT_SOCKET_READ_TIMEOUT) @@ -123,6 +132,7 @@ public final class SdkHttpConfigurationOption extends AttributeMap.Key { .put(PROTOCOL, DEFAULT_PROTOCOL) .put(TRUST_ALL_CERTIFICATES, DEFAULT_TRUST_ALL_CERTIFICATES) .put(REAP_IDLE_CONNECTIONS, DEFAULT_REAP_IDLE_CONNECTIONS) + .put(TLS_KEY_MANAGERS_PROVIDER, DEFAULT_TLS_KEY_MANAGERS_PROVIDER) .build(); private final String name; diff --git a/http-client-spi/src/main/java/software/amazon/awssdk/http/TlsKeyManagersProvider.java b/http-client-spi/src/main/java/software/amazon/awssdk/http/TlsKeyManagersProvider.java index ed4e41f00576..1571814e8c69 100644 --- a/http-client-spi/src/main/java/software/amazon/awssdk/http/TlsKeyManagersProvider.java +++ b/http-client-spi/src/main/java/software/amazon/awssdk/http/TlsKeyManagersProvider.java @@ -17,6 +17,7 @@ import javax.net.ssl.KeyManager; import software.amazon.awssdk.annotations.SdkPublicApi; +import software.amazon.awssdk.internal.http.NoneTlsKeyManagersProvider; /** * Provider for the {@link KeyManager key managers} to be used by the SDK when @@ -31,4 +32,11 @@ public interface TlsKeyManagersProvider { * @return The {@link KeyManager}s, or {@code null}. */ KeyManager[] keyManagers(); + + /** + * @return A provider that returns a {@code null} array of {@link KeyManager}s. + */ + static TlsKeyManagersProvider noneProvider() { + return NoneTlsKeyManagersProvider.getInstance(); + } } diff --git a/http-client-spi/src/main/java/software/amazon/awssdk/internal/http/NoneTlsKeyManagersProvider.java b/http-client-spi/src/main/java/software/amazon/awssdk/internal/http/NoneTlsKeyManagersProvider.java new file mode 100644 index 000000000000..9e5d165ef708 --- /dev/null +++ b/http-client-spi/src/main/java/software/amazon/awssdk/internal/http/NoneTlsKeyManagersProvider.java @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.internal.http; + +import javax.net.ssl.KeyManager; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.http.TlsKeyManagersProvider; + +/** + * Simple implementation of {@link TlsKeyManagersProvider} that return a null array. + *

+ * Use this provider if you don't want the client to present any certificates to the remote TLS host. + */ +@SdkInternalApi +public final class NoneTlsKeyManagersProvider implements TlsKeyManagersProvider { + private static final NoneTlsKeyManagersProvider INSTANCE = new NoneTlsKeyManagersProvider(); + + private NoneTlsKeyManagersProvider() { + } + + @Override + public KeyManager[] keyManagers() { + return null; + } + + public static NoneTlsKeyManagersProvider getInstance() { + return INSTANCE; + } +} diff --git a/http-client-spi/src/test/java/software/amazon/awssdk/http/TlsKeyManagersProviderTest.java b/http-client-spi/src/test/java/software/amazon/awssdk/http/TlsKeyManagersProviderTest.java new file mode 100644 index 000000000000..79412f79c334 --- /dev/null +++ b/http-client-spi/src/test/java/software/amazon/awssdk/http/TlsKeyManagersProviderTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.http; + +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class TlsKeyManagersProviderTest { + + @Test + public void noneProvider_returnsProviderThatReturnsNull() { + assertThat(TlsKeyManagersProvider.noneProvider().keyManagers()).isNull(); + } +} diff --git a/http-client-spi/src/test/java/software/amazon/awssdk/http/software/amazon/awssdk/internal/http/NoneTlsKeyManagersProviderTest.java b/http-client-spi/src/test/java/software/amazon/awssdk/http/software/amazon/awssdk/internal/http/NoneTlsKeyManagersProviderTest.java new file mode 100644 index 000000000000..2e3098e62de4 --- /dev/null +++ b/http-client-spi/src/test/java/software/amazon/awssdk/http/software/amazon/awssdk/internal/http/NoneTlsKeyManagersProviderTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.http.software.amazon.awssdk.internal.http; + +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; +import software.amazon.awssdk.internal.http.NoneTlsKeyManagersProvider; + +public class NoneTlsKeyManagersProviderTest { + @Test + public void getInstance_returnsNonNull() { + assertThat(NoneTlsKeyManagersProvider.getInstance()).isNotNull(); + } + + @Test + public void keyManagers_returnsNull() { + assertThat(NoneTlsKeyManagersProvider.getInstance().keyManagers()).isNull(); + } + + @Test + public void getInstance_returnsSingletonInstance() { + NoneTlsKeyManagersProvider provider1 = NoneTlsKeyManagersProvider.getInstance(); + NoneTlsKeyManagersProvider provider2 = NoneTlsKeyManagersProvider.getInstance(); + assertThat(provider1 == provider2).isTrue(); + } +} diff --git a/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ApacheHttpClient.java b/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ApacheHttpClient.java index e4c6c9fe10da..b86a74a78604 100644 --- a/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ApacheHttpClient.java +++ b/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ApacheHttpClient.java @@ -26,6 +26,7 @@ import static software.amazon.awssdk.http.SdkHttpConfigurationOption.MAX_CONNECTIONS; import static software.amazon.awssdk.http.SdkHttpConfigurationOption.READ_TIMEOUT; import static software.amazon.awssdk.http.SdkHttpConfigurationOption.REAP_IDLE_CONNECTIONS; +import static software.amazon.awssdk.http.SdkHttpConfigurationOption.TLS_KEY_MANAGERS_PROVIDER; import static software.amazon.awssdk.utils.NumericUtils.saturatedCast; import java.io.IOException; @@ -381,6 +382,10 @@ public interface Builder extends SdkHttpClient.Builder /** * Configure the {@link TlsKeyManagersProvider} that will provide the {@link javax.net.ssl.KeyManager}s to use * when constructing the SSL context. + *

+ * The default used by the client will be {@link SystemPropertyTlsKeyManagersProvider}. Configure an instance of + * {@link software.amazon.awssdk.internal.http.NoneTlsKeyManagersProvider} or another implementation of + * {@link TlsKeyManagersProvider} to override it. */ Builder tlsKeyManagersProvider(TlsKeyManagersProvider tlsKeyManagersProvider); } @@ -392,7 +397,6 @@ private static final class DefaultBuilder implements Builder { private Boolean expectContinueEnabled; private HttpRoutePlanner httpRoutePlanner; private CredentialsProvider credentialsProvider; - private TlsKeyManagersProvider tlsKeyManagersProvider = SystemPropertyTlsKeyManagersProvider.create(); private DefaultBuilder() { } @@ -521,7 +525,7 @@ public Builder credentialsProvider(CredentialsProvider credentialsProvider) { @Override public Builder tlsKeyManagersProvider(TlsKeyManagersProvider tlsKeyManagersProvider) { - this.tlsKeyManagersProvider = tlsKeyManagersProvider; + standardOptions.put(TLS_KEY_MANAGERS_PROVIDER, tlsKeyManagersProvider); return this; } @@ -565,7 +569,7 @@ public HttpClientConnectionManager create(ApacheHttpClient.DefaultBuilder config private ConnectionSocketFactory getPreferredSocketFactory(ApacheHttpClient.DefaultBuilder configuration, AttributeMap standardOptions) { // TODO v2 custom socket factory - return new SdkTlsSocketFactory(getSslContext(configuration.tlsKeyManagersProvider, standardOptions), + return new SdkTlsSocketFactory(getSslContext(standardOptions), getHostNameVerifier(standardOptions)); } @@ -575,7 +579,7 @@ private HostnameVerifier getHostNameVerifier(AttributeMap standardOptions) { : SSLConnectionSocketFactory.getDefaultHostnameVerifier(); } - private SSLContext getSslContext(TlsKeyManagersProvider keyManagersProvider, AttributeMap standardOptions) { + private SSLContext getSslContext(AttributeMap standardOptions) { TrustManager[] trustManagers = null; if (standardOptions.get(SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES)) { log.warn(() -> "SSL Certificate verification is disabled. This is not a safe setting and should only be " @@ -583,10 +587,8 @@ private SSLContext getSslContext(TlsKeyManagersProvider keyManagersProvider, Att trustManagers = trustAllTrustManager(); } - KeyManager[] keyManagers = null; - if (keyManagersProvider != null) { - keyManagers = keyManagersProvider.keyManagers(); - } + TlsKeyManagersProvider provider = standardOptions.get(TLS_KEY_MANAGERS_PROVIDER); + KeyManager[] keyManagers = provider.keyManagers(); try { SSLContext sslcontext = SSLContext.getInstance("TLS"); diff --git a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientTlsAuthTest.java b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientTlsAuthTest.java index cb00b6e96bfb..314049947c96 100644 --- a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientTlsAuthTest.java +++ b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientTlsAuthTest.java @@ -21,6 +21,8 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; +import static org.hamcrest.Matchers.anyOf; +import static org.hamcrest.Matchers.instanceOf; import static software.amazon.awssdk.utils.JavaSystemSetting.SSL_KEY_STORE; import static software.amazon.awssdk.utils.JavaSystemSetting.SSL_KEY_STORE_PASSWORD; import static software.amazon.awssdk.utils.JavaSystemSetting.SSL_KEY_STORE_TYPE; @@ -30,11 +32,14 @@ import java.net.URI; import javax.net.ssl.SSLException; import org.apache.http.NoHttpResponseException; +import org.hamcrest.Matchers; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import software.amazon.awssdk.http.FileStoreTlsKeyManagersProvider; import software.amazon.awssdk.http.HttpExecuteRequest; import software.amazon.awssdk.http.HttpExecuteResponse; @@ -43,6 +48,7 @@ import software.amazon.awssdk.http.SdkHttpMethod; import software.amazon.awssdk.http.SdkHttpRequest; import software.amazon.awssdk.http.TlsKeyManagersProvider; +import software.amazon.awssdk.internal.http.NoneTlsKeyManagersProvider; /** * Tests to ensure that {@link ApacheHttpClient} can properly support TLS @@ -53,6 +59,9 @@ public class ApacheClientTlsAuthTest extends ClientTlsAuthTestBase { private static TlsKeyManagersProvider keyManagersProvider; private SdkHttpClient client; + @Rule + public ExpectedException thrown = ExpectedException.none(); + @BeforeClass public static void setUp() throws IOException { ClientTlsAuthTestBase.setUp(); @@ -108,14 +117,9 @@ public void canMakeHttpsRequestWhenKeyProviderConfigured() throws IOException { @Test public void requestFailsWhenKeyProviderNotConfigured() throws IOException { - client = ApacheHttpClient.builder().build(); - try { - makeRequestWithHttpClient(client); - fail("HTTP request should have failed"); - } catch (NoHttpResponseException | SSLException | SocketException expected) { - // The client doesn't seem to consistently throw a single error, - // and can also vary depending on actual JVM used. - } + thrown.expect(anyOf(instanceOf(NoHttpResponseException.class), instanceOf(SSLException.class))); + client = ApacheHttpClient.builder().tlsKeyManagersProvider(NoneTlsKeyManagersProvider.getInstance()).build(); + makeRequestWithHttpClient(client); } @Test @@ -151,6 +155,22 @@ public void defaultTlsKeyManagersProviderIsSystemPropertyProvider() throws IOExc } } + @Test + public void defaultTlsKeyManagersProviderIsSystemPropertyProvider_explicitlySetToNull() throws IOException { + System.setProperty(SSL_KEY_STORE.property(), clientKeyStore.toAbsolutePath().toString()); + System.setProperty(SSL_KEY_STORE_TYPE.property(), CLIENT_STORE_TYPE); + System.setProperty(SSL_KEY_STORE_PASSWORD.property(), STORE_PASSWORD); + + client = ApacheHttpClient.builder().tlsKeyManagersProvider(null).build(); + try { + makeRequestWithHttpClient(client); + } finally { + System.clearProperty(SSL_KEY_STORE.property()); + System.clearProperty(SSL_KEY_STORE_TYPE.property()); + System.clearProperty(SSL_KEY_STORE_PASSWORD.property()); + } + } + private HttpExecuteResponse makeRequestWithHttpClient(SdkHttpClient httpClient) throws IOException { SdkHttpRequest httpRequest = SdkHttpFullRequest.builder() .method(SdkHttpMethod.GET) diff --git a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.java b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.java index ff76b6720657..751c3d77937e 100644 --- a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.java +++ b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.java @@ -23,6 +23,7 @@ import static software.amazon.awssdk.http.SdkHttpConfigurationOption.MAX_PENDING_CONNECTION_ACQUIRES; import static software.amazon.awssdk.http.SdkHttpConfigurationOption.READ_TIMEOUT; import static software.amazon.awssdk.http.SdkHttpConfigurationOption.REAP_IDLE_CONNECTIONS; +import static software.amazon.awssdk.http.SdkHttpConfigurationOption.TLS_KEY_MANAGERS_PROVIDER; import static software.amazon.awssdk.http.SdkHttpConfigurationOption.WRITE_TIMEOUT; import static software.amazon.awssdk.http.nio.netty.internal.NettyConfiguration.EVENTLOOP_SHUTDOWN_FUTURE_TIMEOUT_SECONDS; import static software.amazon.awssdk.http.nio.netty.internal.NettyConfiguration.EVENTLOOP_SHUTDOWN_QUIET_PERIOD_SECONDS; @@ -48,6 +49,8 @@ import software.amazon.awssdk.http.Protocol; import software.amazon.awssdk.http.SdkHttpConfigurationOption; import software.amazon.awssdk.http.SdkHttpRequest; +import software.amazon.awssdk.http.SystemPropertyTlsKeyManagersProvider; +import software.amazon.awssdk.http.TlsKeyManagersProvider; import software.amazon.awssdk.http.async.AsyncExecuteRequest; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; import software.amazon.awssdk.http.nio.netty.internal.AwaitCloseChannelPoolMap; @@ -354,6 +357,18 @@ public interface Builder extends SdkAsyncHttpClient.Builder + * If no provider is configured, the client will default to {@link SystemPropertyTlsKeyManagersProvider}. To + * disable any automatic resolution via the system properties, use {@link TlsKeyManagersProvider#noneProvider()}. + * + * @param keyManagersProvider The {@code TlsKeyManagersProvider}. + * @return The builder for method chaining. + */ + Builder tlsKeyManagersProvider(TlsKeyManagersProvider keyManagersProvider); } /** @@ -361,7 +376,6 @@ public interface Builder extends SdkAsyncHttpClient.Builder mock(KeyManager.class)) + .toArray(KeyManager[]::new); + + KeyManager[] arg = Arrays.copyOf(keyManagers, keyManagers.length); + StaticKeyManagerFactorySpi spi = new StaticKeyManagerFactorySpi(arg); + for (int i = 0; i < keyManagers.length; ++i) { + arg[i] = null; + } + + assertThat(spi.engineGetKeyManagers()).containsExactly(keyManagers); + } + + @Test + public void engineGetKeyManagers_returnsProvidedList() { + KeyManager[] keyManagers = IntStream.range(0,8) + .mapToObj(i -> mock(KeyManager.class)) + .toArray(KeyManager[]::new); + + StaticKeyManagerFactorySpi spi = new StaticKeyManagerFactorySpi(keyManagers); + + assertThat(spi.engineGetKeyManagers()).containsExactly(keyManagers); + } + + @Test(expected = UnsupportedOperationException.class) + public void engineInit_storeAndPasswords_throws() { + StaticKeyManagerFactorySpi staticKeyManagerFactorySpi = new StaticKeyManagerFactorySpi(new KeyManager[0]); + staticKeyManagerFactorySpi.engineInit(null, null); + } + + @Test(expected = UnsupportedOperationException.class) + public void engineInit_spec_throws() { + StaticKeyManagerFactorySpi staticKeyManagerFactorySpi = new StaticKeyManagerFactorySpi(new KeyManager[0]); + staticKeyManagerFactorySpi.engineInit(null); + } +} diff --git a/http-clients/netty-nio-client/src/test/java/software/amazon/awssdk/http/nio/netty/internal/StaticKeyManagerFactoryTest.java b/http-clients/netty-nio-client/src/test/java/software/amazon/awssdk/http/nio/netty/internal/StaticKeyManagerFactoryTest.java new file mode 100644 index 000000000000..1f5c8713e769 --- /dev/null +++ b/http-clients/netty-nio-client/src/test/java/software/amazon/awssdk/http/nio/netty/internal/StaticKeyManagerFactoryTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.http.nio.netty.internal; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import java.util.stream.IntStream; +import javax.net.ssl.KeyManager; +import org.junit.Test; + +/** + * Tests for {@link StaticKeyManagerFactory}. + */ +public class StaticKeyManagerFactoryTest { + + @Test + public void createReturnFactoryWithCorrectKeyManagers() { + KeyManager[] keyManagers = IntStream.range(0,8) + .mapToObj(i -> mock(KeyManager.class)) + .toArray(KeyManager[]::new); + + StaticKeyManagerFactory staticKeyManagerFactory = StaticKeyManagerFactory.create(keyManagers); + + assertThat(staticKeyManagerFactory.getKeyManagers()) + .containsExactly(keyManagers); + } + +} diff --git a/http-clients/netty-nio-client/src/test/resources/software/amazon/awssdk/http/netty/client1.p12 b/http-clients/netty-nio-client/src/test/resources/software/amazon/awssdk/http/netty/client1.p12 new file mode 100644 index 0000000000000000000000000000000000000000..a56e38c196b50324d5cb17ba7d6d5e2987e0a679 GIT binary patch literal 1714 zcmY+DXIRsR7RIxg$u$}SVT36%tONtqN~^KkP9*s!X8SaOev$W&%M`sKb+@1=Y7v}KAj%{K=2`8C;>o3BIFE{ z?UUD#U>Pt6Ku}=-f+DrO2>^8e*9gG@pvqDU0|A4ig8Z6*32F%We_v1pBM2y%Y{Kq& zTHxIQ9|%Miln6k^0w4+C6+J&5 zK`>f3N15|x{quFp-41YsEVDN64`ZQaYB+3uG|*SWAznL{^*pC@c!6O+aM;(s`_K1b zF2d^8Li_P7by9aqU&!L&>G$Bkv&zh{_#*bb2BlC@u6PKN5o=#x%xQG(-g8GQ(cBbR zvk5pil6V;unpA~d+a~(q_hIqho#1--bkJ9{V=aAaUU5hK<#)QOyXW&h_upz)*Xz`x ziRc(@vle>5uBDPc!A}joV;KgfQ= zuwRTAax5|a)>`mn5^obHb5mEo=uLw6axHpWzwy?$&BldE4~9Pm@Lp&uEPLE5h&+Uw zYQw6cc{Qe8w`pm}qEe=eYo0GmBWvZhn(xGW6U8#7Q(n50&{Wh}wQ#e=bcQ~TYvW@I z0Q*}XMoqC0Z8^&(WXBNo<<&;)jWl%6({_mkJa+J468W?fcH12>)vlYX7yCQR!WZU+zV+B7%1G0t40v?oda<#Rffe;5hZfY-4^){O5@)Ci7<%;FtW z(-5T2FwpWIn_sR48bo(re95ll)@74ZGCwlAP&HNwS1wXRxGq$LH$P(W-P6j2;8k(i zHz_Z4sDadI?MyDLIrkyxQwEOWv7;P0hV+KLxr#((kvwN^L@aK+{xq4?&lR**+SC`z2-A^ zx|5>|4p;#w z*u;&HO*=&NuVj_`L~~-*!ais6;4r(rYT`obAiGf2PbEA}_jhV&cUA1BPVb7GS4etX zeO*}3iWldG2IQnmbsk$7X**b6*MrvQ2ZirS1P-W)lWS&6OIL`uycr&t&apY7Rmy|j zt0k?XF6(?>ztrCL(g*1kj__%sY)nPV-I=4jwge|8a;f39x?!uumU)Mk=RynjkNDiq z$(=IVbwB2@IX}H*Ia^jlP%|~(Ih?(>c6Oro$;JC5K1+F>?4CD2F$;(tt-XUO>FH+T zH$VHm{sv_cSGLtiQK+yy>%qEM`*RKlbzz9@bpvhb3>+sDxNMk)jRO-FUWcta~aB^JxyxI{a6)2`VF3>yENr{MBTk zcQUZ4@6dW#mamrp_kwVqz2$|%zE4n66d}UG#Dk#o->;V2Yl4MgPQ70}Q@Q?&d}22A z^f6QeIc2g?jzIjngfY>>>w?aJD4;M9+U#Yfr|!(?w`#Ayo2mylnO_zSN{1E~N2 literal 0 HcmV?d00001 diff --git a/http-clients/netty-nio-client/src/test/resources/software/amazon/awssdk/http/netty/server-keystore b/http-clients/netty-nio-client/src/test/resources/software/amazon/awssdk/http/netty/server-keystore new file mode 100644 index 0000000000000000000000000000000000000000..55e8a7998c2d06e0c1cf945ab6e51eed2f51107b GIT binary patch literal 2696 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 I{HWpo0R0ktZU6uP literal 0 HcmV?d00001