summaryrefslogtreecommitdiffstats
path: root/jdisc_http_service
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@oath.com>2017-11-28 17:10:50 +0100
committerBjørn Christian Seime <bjorncs@oath.com>2017-11-28 17:10:50 +0100
commit6364de1e56f476f0f9dda76cdd9bd738febc88e6 (patch)
tree355f7f789c06913658c3b8be29cc46a37a64cd5d /jdisc_http_service
parent20cb715ad6a4f312d021435c5bb9bed2f3af1d37 (diff)
Add SslTrustStoreConfigurator interface to JDisc
Diffstat (limited to 'jdisc_http_service')
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java33
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/DefaultSslTrustStoreConfigurator.java40
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/DefaultSslTrustStoreContext.java54
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/SslTrustStoreConfigurator.java14
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/SslTrustStoreContext.java16
-rw-r--r--jdisc_http_service/src/test/java/com/yahoo/jdisc/http/guiceModules/ConnectorFactoryRegistryModule.java5
-rw-r--r--jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactoryTest.java5
7 files changed, 138 insertions, 29 deletions
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java
index 8255e16e0ee..69999ebc355 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java
@@ -7,7 +7,9 @@ import com.yahoo.jdisc.http.ConnectorConfig;
import com.yahoo.jdisc.http.ConnectorConfig.Ssl;
import com.yahoo.jdisc.http.SecretStore;
import com.yahoo.jdisc.http.ssl.DefaultSslKeyStoreContext;
+import com.yahoo.jdisc.http.ssl.DefaultSslTrustStoreContext;
import com.yahoo.jdisc.http.ssl.SslKeyStoreConfigurator;
+import com.yahoo.jdisc.http.ssl.SslTrustStoreConfigurator;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
@@ -26,27 +28,16 @@ import java.nio.channels.ServerSocketChannel;
public class ConnectorFactory {
private final ConnectorConfig connectorConfig;
- private final SecretStore secretStore;
private final SslKeyStoreConfigurator sslKeyStoreConfigurator;
+ private final SslTrustStoreConfigurator sslTrustStoreConfigurator;
@Inject
public ConnectorFactory(ConnectorConfig connectorConfig,
- SecretStore secretStore,
- SslKeyStoreConfigurator sslKeyStoreConfigurator) {
+ SslKeyStoreConfigurator sslKeyStoreConfigurator,
+ SslTrustStoreConfigurator sslTrustStoreConfigurator) {
this.connectorConfig = connectorConfig;
- this.secretStore = secretStore;
this.sslKeyStoreConfigurator = sslKeyStoreConfigurator;
-
- if (connectorConfig.ssl().enabled())
- validateSslConfig(connectorConfig);
- }
-
- // TODO: can be removed when we have dedicated SSL config in services.xml
- private static void validateSslConfig(ConnectorConfig config) {
- ConnectorConfig.Ssl ssl = config.ssl();
- if (!ssl.trustStorePath().isEmpty() && ssl.useTrustStorePassword() && ssl.keyDbKey().isEmpty()) {
- throw new IllegalArgumentException("Missing password for JKS truststore");
- }
+ this.sslTrustStoreConfigurator = sslTrustStoreConfigurator;
}
public ConnectorConfig getConnectorConfig() {
@@ -93,13 +84,13 @@ public class ConnectorFactory {
return new HttpConnectionFactory(httpConfig);
}
- //TODO: does not support loading non-yahoo readable JKS key stores.
private SslConnectionFactory newSslConnectionFactory() {
Ssl sslConfig = connectorConfig.ssl();
SslContextFactory factory = new SslContextFactory();
sslKeyStoreConfigurator.configure(new DefaultSslKeyStoreContext(factory));
+ sslTrustStoreConfigurator.configure(new DefaultSslTrustStoreContext(factory));
switch (sslConfig.clientAuth()) {
case NEED_AUTH:
@@ -144,16 +135,6 @@ public class ConnectorFactory {
factory.setIncludeCipherSuites(ciphs);
}
- String keyDbPassword = sslConfig.keyDbKey();
-
- if (!sslConfig.trustStorePath().isEmpty()) {
- factory.setTrustStorePath(sslConfig.trustStorePath());
- factory.setTrustStoreType(sslConfig.trustStoreType().toString());
- if (sslConfig.useTrustStorePassword()) {
- factory.setTrustStorePassword(secretStore.getSecret(keyDbPassword));
- }
- }
-
factory.setKeyManagerFactoryAlgorithm(sslConfig.sslKeyManagerFactoryAlgorithm());
factory.setProtocol(sslConfig.protocol());
return new SslConnectionFactory(factory, HttpVersion.HTTP_1_1.asString());
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/DefaultSslTrustStoreConfigurator.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/DefaultSslTrustStoreConfigurator.java
new file mode 100644
index 00000000000..8af21d48e9a
--- /dev/null
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/DefaultSslTrustStoreConfigurator.java
@@ -0,0 +1,40 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jdisc.http.ssl;
+
+import com.google.inject.Inject;
+import com.yahoo.jdisc.http.ConnectorConfig;
+import com.yahoo.jdisc.http.SecretStore;
+
+/**
+ * @author bjorncs
+ */
+public class DefaultSslTrustStoreConfigurator implements SslTrustStoreConfigurator {
+
+ private final SecretStore secretStore;
+ private final ConnectorConfig.Ssl config;
+
+ @Inject
+ public DefaultSslTrustStoreConfigurator(ConnectorConfig config, SecretStore secretStore) {
+ validateConfig(config.ssl());
+ this.secretStore = secretStore;
+ this.config = config.ssl();
+ }
+
+ @Override
+ public void configure(SslTrustStoreContext context) {
+ if (!config.enabled()) return;
+ String keyDbPassword = config.keyDbKey();
+ if (!config.trustStorePath().isEmpty()) {
+ String password = config.useTrustStorePassword() ? secretStore.getSecret(keyDbPassword) : null;
+ context.updateTrustStore(config.trustStorePath(), config.trustStoreType().toString(), password);
+ }
+ }
+
+ private static void validateConfig(ConnectorConfig.Ssl config) {
+ if (!config.enabled()) return;
+ if (!config.trustStorePath().isEmpty() && config.useTrustStorePassword() && config.keyDbKey().isEmpty()) {
+ throw new IllegalArgumentException("Missing password for JKS truststore");
+ }
+ }
+
+}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/DefaultSslTrustStoreContext.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/DefaultSslTrustStoreContext.java
new file mode 100644
index 00000000000..c2d91cca3ea
--- /dev/null
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/DefaultSslTrustStoreContext.java
@@ -0,0 +1,54 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jdisc.http.ssl;
+
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+import java.security.KeyStore;
+import java.util.function.Consumer;
+
+/**
+ * @author bjorncs
+ */
+public class DefaultSslTrustStoreContext implements SslTrustStoreContext {
+
+ private final SslContextFactory sslContextFactory;
+
+ public DefaultSslTrustStoreContext(SslContextFactory sslContextFactory) {
+ this.sslContextFactory = sslContextFactory;
+ }
+
+ @Override
+ public void updateTrustStore(KeyStore trustStore) {
+ updateTrustStore(trustStore, null);
+ }
+
+ @Override
+ public void updateTrustStore(KeyStore trustStore, String password) {
+ updateTrustStore(sslContextFactory -> {
+ sslContextFactory.setTrustStore(trustStore);
+ if (password != null) {
+ sslContextFactory.setTrustStorePassword(password);
+ }
+ });
+ }
+
+ @Override
+ public void updateTrustStore(String trustStorePath, String trustStoreType, String trustStorePassword) {
+ updateTrustStore(sslContextFactory -> {
+ sslContextFactory.setTrustStorePath(trustStorePath);
+ sslContextFactory.setTrustStoreType(trustStoreType);
+ if (trustStorePassword != null) {
+ sslContextFactory.setTrustStorePassword(trustStorePassword);
+ }
+ });
+ }
+
+ private void updateTrustStore(Consumer<SslContextFactory> reloader) {
+ try {
+ sslContextFactory.reload(reloader);
+ } catch (Exception e) {
+ throw new RuntimeException("Could not update truststore: " + e.getMessage(), e);
+ }
+ }
+
+}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/SslTrustStoreConfigurator.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/SslTrustStoreConfigurator.java
new file mode 100644
index 00000000000..de1119a5275
--- /dev/null
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/SslTrustStoreConfigurator.java
@@ -0,0 +1,14 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jdisc.http.ssl;
+
+/**
+ * An interface for an component that can configure an {@link SslTrustStoreContext}. The implementor can assume that
+ * the {@link SslTrustStoreContext} instance is thread-safe and be updated at any time
+ * during and after the call to{@link #configure(SslTrustStoreContext)}.
+ * Modifying the {@link SslKeyStoreContext} instance will trigger a hot reload of the truststore in JDisc.
+ *
+ * @author bjorncs
+ */
+public interface SslTrustStoreConfigurator {
+ void configure(SslTrustStoreContext context);
+}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/SslTrustStoreContext.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/SslTrustStoreContext.java
new file mode 100644
index 00000000000..fc8cf397b24
--- /dev/null
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/SslTrustStoreContext.java
@@ -0,0 +1,16 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jdisc.http.ssl;
+
+import java.security.KeyStore;
+
+/**
+ * An interface to update the truststore in JDisc. Any update will trigger a hot reload and new connections will
+ * authenticated using the update truststore.
+ *
+ * @author bjorncs
+ */
+public interface SslTrustStoreContext {
+ void updateTrustStore(KeyStore trustStore);
+ void updateTrustStore(KeyStore trustStore, String password);
+ void updateTrustStore(String trustStorePath, String trustStoreType, String trustStorePassword);
+}
diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/guiceModules/ConnectorFactoryRegistryModule.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/guiceModules/ConnectorFactoryRegistryModule.java
index 0d8f433cc39..6281907e083 100644
--- a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/guiceModules/ConnectorFactoryRegistryModule.java
+++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/guiceModules/ConnectorFactoryRegistryModule.java
@@ -12,6 +12,7 @@ import com.yahoo.jdisc.http.SecretStore;
import com.yahoo.jdisc.http.server.jetty.ConnectorFactory;
import com.yahoo.jdisc.http.server.jetty.TestDrivers;
import com.yahoo.jdisc.http.ssl.DefaultSslKeyStoreConfigurator;
+import com.yahoo.jdisc.http.ssl.DefaultSslTrustStoreConfigurator;
/**
* Guice module for test ConnectorFactories
@@ -48,8 +49,8 @@ public class ConnectorFactoryRegistryModule implements Module {
public StaticKeyDbConnectorFactory(ConnectorConfig connectorConfig) {
super(connectorConfig,
- new MockSecretStore(),
- new DefaultSslKeyStoreConfigurator(connectorConfig, new MockSecretStore()));
+ new DefaultSslKeyStoreConfigurator(connectorConfig, new MockSecretStore()),
+ new DefaultSslTrustStoreConfigurator(connectorConfig, new MockSecretStore()));
}
}
diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactoryTest.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactoryTest.java
index 781bc6a7b5f..103a317094b 100644
--- a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactoryTest.java
+++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactoryTest.java
@@ -5,6 +5,7 @@ import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.http.ConnectorConfig;
import com.yahoo.jdisc.http.SecretStore;
import com.yahoo.jdisc.http.ssl.DefaultSslKeyStoreConfigurator;
+import com.yahoo.jdisc.http.ssl.DefaultSslTrustStoreConfigurator;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
@@ -107,7 +108,9 @@ public class ConnectorFactoryTest {
private static ConnectorFactory createConnectorFactory(ConnectorConfig config) {
ThrowingSecretStore secretStore = new ThrowingSecretStore();
- return new ConnectorFactory(config, secretStore, new DefaultSslKeyStoreConfigurator(config, secretStore));
+ return new ConnectorFactory(config,
+ new DefaultSslKeyStoreConfigurator(config, secretStore),
+ new DefaultSslTrustStoreConfigurator(config, secretStore));
}
private static class HelloWorldHandler extends AbstractHandler {