aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--http-utils/src/main/java/ai/vespa/util/http/VespaAsyncHttpClientBuilder.java2
-rw-r--r--http-utils/src/main/java/ai/vespa/util/http/VespaHttpClientBuilder.java2
-rw-r--r--jaxrs_client_utils/src/main/java/ai/vespa/util/http/VespaClientBuilderFactory.java2
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/DefaultSslContextFactoryProvider.java2
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/ConfigFileBasedTlsContext.java24
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityUtils.java25
6 files changed, 36 insertions, 21 deletions
diff --git a/http-utils/src/main/java/ai/vespa/util/http/VespaAsyncHttpClientBuilder.java b/http-utils/src/main/java/ai/vespa/util/http/VespaAsyncHttpClientBuilder.java
index 6c53ea0dc69..f5457e17e96 100644
--- a/http-utils/src/main/java/ai/vespa/util/http/VespaAsyncHttpClientBuilder.java
+++ b/http-utils/src/main/java/ai/vespa/util/http/VespaAsyncHttpClientBuilder.java
@@ -45,7 +45,7 @@ public class VespaAsyncHttpClientBuilder {
public static HttpAsyncClientBuilder create(AsyncConnectionManagerFactory factory) {
HttpAsyncClientBuilder clientBuilder = HttpAsyncClientBuilder.create();
- TlsContext vespaTlsContext = TransportSecurityUtils.createTlsContext().orElse(null);
+ TlsContext vespaTlsContext = TransportSecurityUtils.getSystemTlsContext().orElse(null);
TlsStrategy tlsStrategy;
if (vespaTlsContext != null) {
SSLParameters vespaTlsParameters = vespaTlsContext.parameters();
diff --git a/http-utils/src/main/java/ai/vespa/util/http/VespaHttpClientBuilder.java b/http-utils/src/main/java/ai/vespa/util/http/VespaHttpClientBuilder.java
index a408b0d79ae..741570e950b 100644
--- a/http-utils/src/main/java/ai/vespa/util/http/VespaHttpClientBuilder.java
+++ b/http-utils/src/main/java/ai/vespa/util/http/VespaHttpClientBuilder.java
@@ -78,7 +78,7 @@ public class VespaHttpClientBuilder {
}
private static void addSslSocketFactory(HttpClientBuilder builder, ConnectionManagerFactory connectionManagerFactory) {
- TransportSecurityUtils.createTlsContext()
+ TransportSecurityUtils.getSystemTlsContext()
.ifPresent(tlsContext -> {
log.log(Level.FINE, "Adding ssl socket factory to client");
SSLConnectionSocketFactory socketFactory = createSslSocketFactory(tlsContext);
diff --git a/jaxrs_client_utils/src/main/java/ai/vespa/util/http/VespaClientBuilderFactory.java b/jaxrs_client_utils/src/main/java/ai/vespa/util/http/VespaClientBuilderFactory.java
index c6afa889041..380bdfbf7a3 100644
--- a/jaxrs_client_utils/src/main/java/ai/vespa/util/http/VespaClientBuilderFactory.java
+++ b/jaxrs_client_utils/src/main/java/ai/vespa/util/http/VespaClientBuilderFactory.java
@@ -60,7 +60,7 @@ public class VespaClientBuilderFactory implements AutoCloseable {
}
- private final TlsContext tlsContext = TransportSecurityUtils.createTlsContext().orElse(null);
+ private final TlsContext tlsContext = TransportSecurityUtils.getSystemTlsContext().orElse(null);
private final MixedMode mixedMode = TransportSecurityUtils.getInsecureMixedMode();
private final AtomicBoolean closed = new AtomicBoolean(false);
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/DefaultSslContextFactoryProvider.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/DefaultSslContextFactoryProvider.java
index f753084152e..7395d2307af 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/DefaultSslContextFactoryProvider.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/DefaultSslContextFactoryProvider.java
@@ -73,5 +73,7 @@ public class DefaultSslContextFactoryProvider extends AbstractComponent implemen
protected TlsContext getTlsContext(String containerId, int port) {
return tlsContext;
}
+
+ @Override public void deconstruct() { tlsContext.close(); }
}
} \ No newline at end of file
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/ConfigFileBasedTlsContext.java b/security-utils/src/main/java/com/yahoo/security/tls/ConfigFileBasedTlsContext.java
index 28854c59b2c..b061d2f9165 100644
--- a/security-utils/src/main/java/com/yahoo/security/tls/ConfigFileBasedTlsContext.java
+++ b/security-utils/src/main/java/com/yahoo/security/tls/ConfigFileBasedTlsContext.java
@@ -14,7 +14,6 @@ import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import java.io.IOException;
import java.io.UncheckedIOException;
-import java.lang.ref.WeakReference;
import java.nio.file.Path;
import java.security.KeyStore;
import java.time.Duration;
@@ -140,14 +139,12 @@ public class ConfigFileBasedTlsContext implements TlsContext {
}
}
- // Note: no reference to outer class (directly or indirectly) to ensure trust/key managers are eventually GCed once
- // there are no more use of the outer class and the underlying SSLContext
private static class CryptoMaterialReloader implements Runnable {
final Path tlsOptionsConfigFile;
final ScheduledExecutorService scheduler;
- final WeakReference<MutableX509TrustManager> trustManager;
- final WeakReference<MutableX509KeyManager> keyManager;
+ final MutableX509TrustManager trustManager;
+ final MutableX509KeyManager keyManager;
CryptoMaterialReloader(Path tlsOptionsConfigFile,
ScheduledExecutorService scheduler,
@@ -155,25 +152,23 @@ public class ConfigFileBasedTlsContext implements TlsContext {
MutableX509KeyManager keyManager) {
this.tlsOptionsConfigFile = tlsOptionsConfigFile;
this.scheduler = scheduler;
- this.trustManager = new WeakReference<>(trustManager);
- this.keyManager = new WeakReference<>(keyManager);
+ this.trustManager = trustManager;
+ this.keyManager = keyManager;
}
@Override
public void run() {
try {
- MutableX509TrustManager trustManager = this.trustManager.get();
- MutableX509KeyManager keyManager = this.keyManager.get();
- if (trustManager == null && keyManager == null) {
+ if (this.trustManager == null && this.keyManager == null) {
scheduler.shutdown();
return;
}
TransportSecurityOptions options = TransportSecurityOptions.fromJsonFile(tlsOptionsConfigFile);
- if (trustManager != null) {
- reloadTrustManager(options, trustManager);
+ if (this.trustManager != null) {
+ reloadTrustManager(options, this.trustManager);
}
- if (keyManager != null) {
- reloadKeyManager(options, keyManager);
+ if (this.keyManager != null) {
+ reloadKeyManager(options, this.keyManager);
}
} catch (Throwable t) {
log.log(Level.SEVERE, String.format("Failed to reload crypto material (path='%s'): %s", tlsOptionsConfigFile, t.getMessage()), t);
@@ -181,7 +176,6 @@ public class ConfigFileBasedTlsContext implements TlsContext {
}
}
- // Static class to ensure no reference to outer class is contained
private static class ReloaderThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityUtils.java b/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityUtils.java
index f28cad2a071..af77827ae16 100644
--- a/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityUtils.java
+++ b/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityUtils.java
@@ -13,6 +13,8 @@ import java.util.Optional;
*/
public class TransportSecurityUtils {
+ private static ConfigFileBasedTlsContext systemTlsContext;
+
public static final String CONFIG_FILE_ENVIRONMENT_VARIABLE = "VESPA_TLS_CONFIG_FILE";
public static final String INSECURE_MIXED_MODE_ENVIRONMENT_VARIABLE = "VESPA_TLS_INSECURE_MIXED_MODE";
public static final String INSECURE_AUTHORIZATION_MODE_ENVIRONMENT_VARIABLE = "VESPA_TLS_INSECURE_AUTHORIZATION_MODE";
@@ -64,13 +66,30 @@ public class TransportSecurityUtils {
.map(TransportSecurityOptions::fromJsonFile);
}
- public static Optional<TlsContext> createTlsContext() {
- return getConfigFile()
- .map(configFile -> new ConfigFileBasedTlsContext(configFile, getInsecureAuthorizationMode()));
+ /**
+ * @return The shared {@link TlsContext} for the Vespa system environment
+ */
+ public static Optional<TlsContext> getSystemTlsContext() {
+ synchronized (TransportSecurityUtils.class) {
+ Path configFile = getConfigFile().orElse(null);
+ if (configFile == null) return Optional.empty();
+ if (systemTlsContext == null) {
+ systemTlsContext = new SystemTlsContext(configFile);
+ }
+ return Optional.of(systemTlsContext);
+ }
}
private static Optional<String> getEnvironmentVariable(Map<String, String> environmentVariables, String variableName) {
return Optional.ofNullable(environmentVariables.get(variableName))
.filter(var -> !var.isEmpty());
}
+
+ private static class SystemTlsContext extends ConfigFileBasedTlsContext {
+ SystemTlsContext(Path tlsOptionsConfigFile) {
+ super(tlsOptionsConfigFile, getInsecureAuthorizationMode());
+ }
+
+ @Override public void close() { throw new UnsupportedOperationException("Shared TLS context cannot be closed"); }
+ }
}