This is an automated email from the ASF dual-hosted git repository.
krisden pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new d96128d KNOX-1111 - 2-way SSL Truststore and Keystore Improvements
(#74)
d96128d is described below
commit d96128dfa3d8c8a656a94d97719fb28737fae925
Author: Robert Levas <[email protected]>
AuthorDate: Fri Mar 15 13:28:24 2019 -0400
KNOX-1111 - 2-way SSL Truststore and Keystore Improvements (#74)
---
.../security/impl/DefaultKeystoreService.java | 3 +-
.../security/impl/DefaultKeystoreServiceTest.java | 14 +-
.../gateway/dispatch/DefaultHttpClientFactory.java | 101 ++++++++--
.../gateway/services/security/KeystoreService.java | 4 +-
.../dispatch/DefaultHttpClientFactoryTest.java | 212 +++++++++++++++++++++
.../src/test/resources/keystores/readme.txt | 40 ++++
.../test/resources/keystores/server-keystore.jks | Bin 0 -> 1387 bytes
.../test/resources/keystores/server-truststore.jks | Bin 0 -> 680 bytes
.../resources/keystores/testSigningKeyName.jks | Bin 0 -> 2238 bytes
9 files changed, 337 insertions(+), 37 deletions(-)
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
index 97889fc..9a0b95a 100644
---
a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
+++
b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
@@ -133,8 +133,7 @@ public class DefaultKeystoreService implements
KeystoreService, Service {
public KeyStore getTruststoreForHttpClient() throws KeystoreServiceException
{
String trustStorePath = config.getHttpClientTruststorePath();
if (trustStorePath == null) {
- // If the trustStorePath is null, fallback to behavior before KNOX-1812
- return getKeystoreForGateway();
+ return null;
} else {
return getKeystore(Paths.get(trustStorePath),
config.getHttpClientTruststoreType(),
config.getHttpClientTruststorePasswordAlias(), true);
}
diff --git
a/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java
b/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java
index ebfdc57..04431b2 100644
---
a/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java
+++
b/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java
@@ -83,20 +83,10 @@ public class DefaultKeystoreServiceTest {
GatewayConfigImpl config = new GatewayConfigImpl();
config.set("gateway.data.dir", dataDir.toString());
- KeyStore keystore = createNiceMock(KeyStore.class);
-
- DefaultKeystoreService keystoreService =
createMockBuilder(DefaultKeystoreService.class)
- .addMockedMethod("getKeystoreForGateway")
- .createMock();
- expect(keystoreService.getKeystoreForGateway()).andReturn(keystore).once();
-
- replay(keystore, keystoreService);
-
+ DefaultKeystoreService keystoreService = new DefaultKeystoreService();
keystoreService.init(config, Collections.emptyMap());
- assertEquals(keystore, keystoreService.getTruststoreForHttpClient());
-
- verify(keystore, keystoreService);
+ assertNull(keystoreService.getTruststoreForHttpClient());
}
@Test
diff --git
a/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
b/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
index 0ea3f9c..e53d28b 100644
---
a/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
+++
b/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
@@ -27,6 +27,7 @@ import java.util.List;
import javax.net.ssl.SSLContext;
import javax.servlet.FilterConfig;
+import org.apache.http.ssl.SSLContextBuilder;
import org.apache.knox.gateway.services.security.AliasService;
import org.apache.knox.gateway.services.security.KeystoreService;
import org.apache.knox.gateway.config.GatewayConfig;
@@ -63,6 +64,7 @@ import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
public class DefaultHttpClientFactory implements HttpClientFactory {
+ static final String PARAMETER_USE_TWO_WAY_SSL = "useTwoWaySsl";
@Override
public HttpClient createHttpClient(FilterConfig filterConfig) {
@@ -76,28 +78,13 @@ public class DefaultHttpClientFactory implements
HttpClientFactory {
} else {
builder = HttpClients.custom();
}
- if (Boolean.parseBoolean(filterConfig.getInitParameter("useTwoWaySsl"))) {
- AliasService as = services.getService(GatewayServices.ALIAS_SERVICE);
- KeystoreService ks =
services.getService(GatewayServices.KEYSTORE_SERVICE);
- final SSLContext sslcontext;
- try {
- KeyStore identityKeystore = ks.getKeystoreForGateway();
- char[] identityKeyPassphrase = as.getGatewayIdentityPassphrase();
- // The trustKeystore will be the same as the identityKeystore if a
truststore was not explicitly
- // configured in gateway-site (gateway.truststore.password.alias,
gateway.truststore.path, gateway.truststore.type)
- // This was the behavior before KNOX-1812
- KeyStore trustKeystore = ks.getTruststoreForHttpClient();
-
- sslcontext = SSLContexts.custom()
- .loadTrustMaterial(trustKeystore, new TrustSelfSignedStrategy())
- .loadKeyMaterial(identityKeystore, identityKeyPassphrase)
- .build();
- } catch (Exception e) {
- throw new IllegalArgumentException("Unable to create SSLContext", e);
- }
- builder.setSSLSocketFactory(new SSLConnectionSocketFactory(sslcontext));
+ // Conditionally set a custom SSLContext
+ SSLContext sslContext = createSSLContext(services, filterConfig);
+ if(sslContext != null) {
+ builder.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext));
}
+
if
(Boolean.parseBoolean(System.getProperty(GatewayConfig.HADOOP_KERBEROS_SECURED)))
{
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new
UseJaasCredentials());
@@ -130,6 +117,80 @@ public class DefaultHttpClientFactory implements
HttpClientFactory {
return builder.build();
}
+ /**
+ * Conditionally creates a custom {@link SSLContext} based on the Gateway's
configuration and whether
+ * two-way SSL is enabled or not.
+ * <p>
+ * If two-way SSL is enabled, then a context with the Gateway's identity and
a configured trust store
+ * is created. The trust store is forced to be the same as the identity's
keystore if an explicit
+ * trust store is not configured.
+ * <p>
+ * If two-way SSL is not enabled and an explict trust store is configured,
then a context with the
+ * configured trust store is created.
+ * <p>
+ * Else, a custom context is not crated and <code>null</code> is returned.
+ * <p>
+ * This method is package private to allow access to unit tests
+ *
+ * @param services the {@link GatewayServices}
+ * @param filterConfig a {@link FilterConfig} used to query for parameters
for this operation
+ * @return a {@link SSLContext} or <code>null</code> if a custom {@link
SSLContext} is not needed.
+ */
+ SSLContext createSSLContext(GatewayServices services, FilterConfig
filterConfig) {
+ KeyStore identityKeystore;
+ char[] identityKeyPassphrase;
+ KeyStore trustKeystore;
+
+ KeystoreService ks = services.getService(GatewayServices.KEYSTORE_SERVICE);
+ try {
+ if
(Boolean.parseBoolean(filterConfig.getInitParameter(PARAMETER_USE_TWO_WAY_SSL)))
{
+ AliasService as = services.getService(GatewayServices.ALIAS_SERVICE);
+
+ // Get the Gateway's configured identity keystore and key passphrase
+ identityKeystore = ks.getKeystoreForGateway();
+ identityKeyPassphrase = as.getGatewayIdentityPassphrase();
+
+ // The trustKeystore will be the same as the identityKeystore if a
truststore was not explicitly
+ // configured in gateway-site (gateway.truststore.password.alias,
gateway.truststore.path, gateway.truststore.type)
+ // This was the behavior before KNOX-1812
+ trustKeystore = ks.getTruststoreForHttpClient();
+ if (trustKeystore == null) {
+ trustKeystore = identityKeystore;
+ }
+ } else {
+ // If not using twoWaySsl, there is no need to calculate the Gateway's
identity keystore or
+ // identity key.
+ identityKeystore = null;
+ identityKeyPassphrase = null;
+
+ // The the behavior before KNOX-1812 was to use the HttpClients
default SslContext. However,
+ // if a truststore was explicitly configured in gateway-site
(gateway.truststore.password.alias,
+ // gateway.truststore.path, gateway.truststore.type) create a custom
SslContext and use it.
+ trustKeystore = ks.getTruststoreForHttpClient();
+ }
+
+ // If an identity keystore or a trust store needs to be set, create and
return a custom
+ // SSLContext; else return null.
+ if ((identityKeystore != null) || (trustKeystore != null)) {
+ SSLContextBuilder sslContextBuilder = SSLContexts.custom();
+
+ if (identityKeystore != null) {
+ sslContextBuilder.loadKeyMaterial(identityKeystore,
identityKeyPassphrase);
+ }
+
+ if (trustKeystore != null) {
+ sslContextBuilder.loadTrustMaterial(trustKeystore, new
TrustSelfSignedStrategy());
+ }
+
+ return sslContextBuilder.build();
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Unable to create SSLContext", e);
+ }
+ }
+
private static RequestConfig getRequestConfig( FilterConfig config ) {
RequestConfig.Builder builder = RequestConfig.custom();
int connectionTimeout = getConnectionTimeout( config );
diff --git
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
index d4dcd4d..d16766d 100644
---
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
+++
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
@@ -34,11 +34,9 @@ public interface KeystoreService {
/**
* Gets the configured keystore instance that contains trust data.
- * <p>
- * If not configured, the Gateway's identity keystore should be returned.
See {@link #getKeystoreForGateway()}
*
* @throws KeystoreServiceException Exception when unable to get truststore
- * @return a {@link KeyStore}
+ * @return a {@link KeyStore}; or <code>null</code> if not configured
*/
KeyStore getTruststoreForHttpClient() throws KeystoreServiceException;
diff --git
a/gateway-spi/src/test/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactoryTest.java
b/gateway-spi/src/test/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactoryTest.java
new file mode 100644
index 0000000..28d4a50
--- /dev/null
+++
b/gateway-spi/src/test/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactoryTest.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 org.apache.knox.gateway.dispatch;
+
+import static
org.apache.knox.gateway.dispatch.DefaultHttpClientFactory.PARAMETER_USE_TWO_WAY_SSL;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.apache.http.client.HttpClient;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.KeystoreService;
+import org.junit.Test;
+
+import javax.net.ssl.SSLContext;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+
+public class DefaultHttpClientFactoryTest {
+
+ @Test
+ public void testCreateHttpClientSSLContextDefaults() throws Exception {
+ KeystoreService keystoreService = createMock(KeystoreService.class);
+
expect(keystoreService.getTruststoreForHttpClient()).andReturn(null).once();
+
+ GatewayConfig gatewayConfig = createMock(GatewayConfig.class);
+ expect(gatewayConfig.isMetricsEnabled()).andReturn(false).once();
+ expect(gatewayConfig.getHttpClientMaxConnections()).andReturn(32).once();
+
expect(gatewayConfig.getHttpClientConnectionTimeout()).andReturn(20000).once();
+ expect(gatewayConfig.getHttpClientSocketTimeout()).andReturn(20000).once();
+
+ GatewayServices gatewayServices = createMock(GatewayServices.class);
+
expect(gatewayServices.getService(GatewayServices.KEYSTORE_SERVICE)).andReturn(keystoreService).once();
+
+ ServletContext servletContext = createMock(ServletContext.class);
+
expect(servletContext.getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE)).andReturn(gatewayConfig).atLeastOnce();
+
expect(servletContext.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE)).andReturn(gatewayServices).atLeastOnce();
+
+ FilterConfig filterConfig = createMock(FilterConfig.class);
+
expect(filterConfig.getServletContext()).andReturn(servletContext).atLeastOnce();
+
expect(filterConfig.getInitParameter("useTwoWaySsl")).andReturn("false").once();
+
expect(filterConfig.getInitParameter("httpclient.maxConnections")).andReturn(null).once();
+
expect(filterConfig.getInitParameter("httpclient.connectionTimeout")).andReturn(null).once();
+
expect(filterConfig.getInitParameter("httpclient.socketTimeout")).andReturn(null).once();
+
+ replay(keystoreService, gatewayConfig, gatewayServices, servletContext,
filterConfig);
+
+ DefaultHttpClientFactory factory = new DefaultHttpClientFactory();
+ HttpClient client = factory.createHttpClient(filterConfig);
+ assertNotNull(client);
+
+ verify(keystoreService, gatewayConfig, gatewayServices, servletContext,
filterConfig);
+ }
+
+ @Test
+ public void testCreateSSLContextDefaults() throws Exception {
+ KeystoreService keystoreService = createMock(KeystoreService.class);
+
expect(keystoreService.getTruststoreForHttpClient()).andReturn(null).once();
+
+ GatewayServices gatewayServices = createMock(GatewayServices.class);
+
expect(gatewayServices.getService(GatewayServices.KEYSTORE_SERVICE)).andReturn(keystoreService).once();
+
+ FilterConfig filterConfig = createMock(FilterConfig.class);
+
expect(filterConfig.getInitParameter(PARAMETER_USE_TWO_WAY_SSL)).andReturn("false").once();
+
+ replay(keystoreService, gatewayServices, filterConfig);
+
+ DefaultHttpClientFactory factory = new DefaultHttpClientFactory();
+ SSLContext context = factory.createSSLContext(gatewayServices,
filterConfig);
+ assertNull(context);
+
+ verify(keystoreService, gatewayServices, filterConfig);
+ }
+
+ @Test
+ public void testCreateSSLContextTwoWaySslNoCustomTrustStore() throws
Exception {
+ KeyStore gatewayIdentityKeyStore =
loadKeyStore("target/test-classes/keystores/server-keystore.jks", "horton",
"JKS");
+
+ KeystoreService keystoreService = createMock(KeystoreService.class);
+
expect(keystoreService.getTruststoreForHttpClient()).andReturn(null).once();
+
expect(keystoreService.getKeystoreForGateway()).andReturn(gatewayIdentityKeyStore).once();
+
+ AliasService aliasService = createMock(AliasService.class);
+
expect(aliasService.getGatewayIdentityPassphrase()).andReturn("horton".toCharArray()).once();
+
+ GatewayServices gatewayServices = createMock(GatewayServices.class);
+
expect(gatewayServices.getService(GatewayServices.KEYSTORE_SERVICE)).andReturn(keystoreService).once();
+
expect(gatewayServices.getService(GatewayServices.ALIAS_SERVICE)).andReturn(aliasService).once();
+
+ FilterConfig filterConfig = createMock(FilterConfig.class);
+
expect(filterConfig.getInitParameter(PARAMETER_USE_TWO_WAY_SSL)).andReturn("true").once();
+
+ replay(keystoreService, aliasService, gatewayServices, filterConfig);
+
+ DefaultHttpClientFactory factory = new DefaultHttpClientFactory();
+ SSLContext context = factory.createSSLContext(gatewayServices,
filterConfig);
+ assertNotNull(context);
+
+ verify(keystoreService, aliasService, gatewayServices, filterConfig);
+ }
+
+ @Test
+ public void testCreateSSLContextTwoWaySslWithCustomTrustStore() throws
Exception {
+ KeyStore gatewayIdentityKeyStore =
loadKeyStore("target/test-classes/keystores/server-keystore.jks", "horton",
"JKS");
+ KeyStore trustStore =
loadKeyStore("target/test-classes/keystores/server-truststore.jks", "horton",
"JKS");
+
+ KeystoreService keystoreService = createMock(KeystoreService.class);
+
expect(keystoreService.getTruststoreForHttpClient()).andReturn(trustStore).once();
+
expect(keystoreService.getKeystoreForGateway()).andReturn(gatewayIdentityKeyStore).once();
+
+ AliasService aliasService = createMock(AliasService.class);
+
expect(aliasService.getGatewayIdentityPassphrase()).andReturn("horton".toCharArray()).once();
+
+ GatewayServices gatewayServices = createMock(GatewayServices.class);
+
expect(gatewayServices.getService(GatewayServices.KEYSTORE_SERVICE)).andReturn(keystoreService).once();
+
expect(gatewayServices.getService(GatewayServices.ALIAS_SERVICE)).andReturn(aliasService).once();
+
+ FilterConfig filterConfig = createMock(FilterConfig.class);
+
expect(filterConfig.getInitParameter(PARAMETER_USE_TWO_WAY_SSL)).andReturn("true").once();
+
+ replay(keystoreService, aliasService, gatewayServices, filterConfig);
+
+ DefaultHttpClientFactory factory = new DefaultHttpClientFactory();
+ SSLContext context = factory.createSSLContext(gatewayServices,
filterConfig);
+ assertNotNull(context);
+
+ verify(keystoreService, aliasService, gatewayServices, filterConfig);
+ }
+
+ @Test
+ public void testCreateSSLContextOneWaySslNoCustomTrustStore() throws
Exception {
+ KeystoreService keystoreService = createMock(KeystoreService.class);
+
expect(keystoreService.getTruststoreForHttpClient()).andReturn(null).once();
+
+ GatewayServices gatewayServices = createMock(GatewayServices.class);
+
expect(gatewayServices.getService(GatewayServices.KEYSTORE_SERVICE)).andReturn(keystoreService).once();
+
+ FilterConfig filterConfig = createMock(FilterConfig.class);
+
expect(filterConfig.getInitParameter(PARAMETER_USE_TWO_WAY_SSL)).andReturn("false").once();
+
+ replay(keystoreService, gatewayServices, filterConfig);
+
+ DefaultHttpClientFactory factory = new DefaultHttpClientFactory();
+ SSLContext context = factory.createSSLContext(gatewayServices,
filterConfig);
+ assertNull(context);
+
+ verify(keystoreService, gatewayServices, filterConfig);
+ }
+
+ @Test
+ public void testCreateSSLContextOneWaySslWithCustomTrustStore() throws
Exception {
+ KeyStore trustStore =
loadKeyStore("target/test-classes/keystores/server-truststore.jks", "horton",
"JKS");
+
+ KeystoreService keystoreService = createMock(KeystoreService.class);
+
expect(keystoreService.getTruststoreForHttpClient()).andReturn(trustStore).once();
+
+ GatewayServices gatewayServices = createMock(GatewayServices.class);
+
expect(gatewayServices.getService(GatewayServices.KEYSTORE_SERVICE)).andReturn(keystoreService).once();
+
+ FilterConfig filterConfig = createMock(FilterConfig.class);
+
expect(filterConfig.getInitParameter(PARAMETER_USE_TWO_WAY_SSL)).andReturn("false").once();
+
+ replay(keystoreService, gatewayServices, filterConfig);
+
+ DefaultHttpClientFactory factory = new DefaultHttpClientFactory();
+ SSLContext context = factory.createSSLContext(gatewayServices,
filterConfig);
+ assertNotNull(context);
+
+ verify(keystoreService, gatewayServices, filterConfig);
+ }
+
+ private KeyStore loadKeyStore(String keyStoreFile, String password, String
storeType)
+ throws CertificateException, IOException, KeyStoreException,
NoSuchAlgorithmException {
+ KeyStore keyStore = KeyStore.getInstance(storeType);
+ try (InputStream input = Files.newInputStream(Paths.get(keyStoreFile))) {
+ keyStore.load(input, password.toCharArray());
+ }
+ return keyStore;
+ }
+}
\ No newline at end of file
diff --git a/gateway-spi/src/test/resources/keystores/readme.txt
b/gateway-spi/src/test/resources/keystores/readme.txt
new file mode 100644
index 0000000..865c0fb
--- /dev/null
+++ b/gateway-spi/src/test/resources/keystores/readme.txt
@@ -0,0 +1,40 @@
+##########################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License 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.
+##########################################################################
+
+server-keystore.jks
+ Keystore password: horton
+ identity key alias: server
+ identity key password: horton
+
+----
+
+server-truststore.jks
+ Keystore password: horton
+ trusted cert alias: client
+
+----
+
+testSigningKeyName.jks
+ Keystore password: testSigningKeyPassphrase
+ Signing key alias: testSigningKeyAlias
+ Signing key password: testSigningKeyPassphrase
+
+ keytool -genkey -alias testSigningKeyAlias -keyalg RSA -keystore
testSigningKeyName.jks \
+ -storepass testSigningKeyPassphrase -keypass testSigningKeyPassphrase
-keysize 2048 \
+ -dname 'CN=testSigningKey,OU=example,O=Apache,L=US,ST=CA,C=US' -noprompt
+
diff --git a/gateway-spi/src/test/resources/keystores/server-keystore.jks
b/gateway-spi/src/test/resources/keystores/server-keystore.jks
new file mode 100644
index 0000000..570c92c
Binary files /dev/null and
b/gateway-spi/src/test/resources/keystores/server-keystore.jks differ
diff --git a/gateway-spi/src/test/resources/keystores/server-truststore.jks
b/gateway-spi/src/test/resources/keystores/server-truststore.jks
new file mode 100644
index 0000000..0e9f6ab
Binary files /dev/null and
b/gateway-spi/src/test/resources/keystores/server-truststore.jks differ
diff --git a/gateway-spi/src/test/resources/keystores/testSigningKeyName.jks
b/gateway-spi/src/test/resources/keystores/testSigningKeyName.jks
new file mode 100644
index 0000000..d5e984a
Binary files /dev/null and
b/gateway-spi/src/test/resources/keystores/testSigningKeyName.jks differ