aboutsummaryrefslogtreecommitdiffstats
path: root/security-utils/src/main/java/com/yahoo/security/tls
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@yahooinc.com>2022-07-19 17:35:12 +0200
committerBjørn Christian Seime <bjorncs@yahooinc.com>2022-07-20 13:56:33 +0200
commit6276364ef4e626d8eb65ddb0d9e39c7bb114cc0c (patch)
tree6efb48632c7f8786c7ca71727ffef18f5b8eb2ea /security-utils/src/main/java/com/yahoo/security/tls
parent91b46555d137dcdf73a534ba5fa10e07510eb0f9 (diff)
Move generic crypto helpers from 'c.y.s.tls' to 'c.y.s'
Diffstat (limited to 'security-utils/src/main/java/com/yahoo/security/tls')
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/AutoReloadingX509KeyManager.java162
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/ConfigFileBasedTlsContext.java2
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/KeyManagerUtils.java49
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/MutableX509KeyManager.java126
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/MutableX509TrustManager.java70
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java1
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/TrustAllX509TrustManager.java27
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/TrustManagerUtils.java48
8 files changed, 3 insertions, 482 deletions
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/AutoReloadingX509KeyManager.java b/security-utils/src/main/java/com/yahoo/security/tls/AutoReloadingX509KeyManager.java
deleted file mode 100644
index 259d4b50d3f..00000000000
--- a/security-utils/src/main/java/com/yahoo/security/tls/AutoReloadingX509KeyManager.java
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.security.tls;
-
-import com.yahoo.security.KeyStoreBuilder;
-import com.yahoo.security.KeyStoreType;
-import com.yahoo.security.KeyUtils;
-import com.yahoo.security.X509CertificateUtils;
-import com.yahoo.security.X509CertificateWithKey;
-
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.X509ExtendedKeyManager;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.net.Socket;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.KeyStore;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.time.Duration;
-import java.util.Arrays;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * A {@link X509ExtendedKeyManager} that reloads the certificate and private key from file regularly.
- *
- * @author bjorncs
- */
-public class AutoReloadingX509KeyManager extends X509ExtendedKeyManager implements AutoCloseable {
-
- public static final String CERTIFICATE_ALIAS = "default";
-
- private static final Duration UPDATE_PERIOD = Duration.ofHours(1);
-
- private static final Logger log = Logger.getLogger(AutoReloadingX509KeyManager.class.getName());
-
- private final MutableX509KeyManager mutableX509KeyManager;
- private final ScheduledExecutorService scheduler;
- private final Path privateKeyFile;
- private final Path certificatesFile;
-
- private AutoReloadingX509KeyManager(Path privateKeyFile, Path certificatesFile) {
- this(privateKeyFile, certificatesFile, createDefaultScheduler());
- }
-
- AutoReloadingX509KeyManager(Path privateKeyFile, Path certificatesFile, ScheduledExecutorService scheduler) {
- this.privateKeyFile = privateKeyFile;
- this.certificatesFile = certificatesFile;
- this.scheduler = scheduler;
- this.mutableX509KeyManager = new MutableX509KeyManager(createKeystore(privateKeyFile, certificatesFile), new char[0]);
- scheduler.scheduleAtFixedRate(
- new KeyManagerReloader(), UPDATE_PERIOD.getSeconds()/*initial delay*/, UPDATE_PERIOD.getSeconds(), TimeUnit.SECONDS);
- }
-
- public static AutoReloadingX509KeyManager fromPemFiles(Path privateKeyFile, Path certificatesFile) {
- return new AutoReloadingX509KeyManager(privateKeyFile, certificatesFile);
- }
-
- public X509CertificateWithKey getCurrentCertificateWithKey() {
- X509ExtendedKeyManager manager = mutableX509KeyManager.currentManager();
- X509Certificate[] certificateChain = manager.getCertificateChain(CERTIFICATE_ALIAS);
- PrivateKey privateKey = manager.getPrivateKey(CERTIFICATE_ALIAS);
- return new X509CertificateWithKey(Arrays.asList(certificateChain), privateKey);
- }
-
- private static KeyStore createKeystore(Path privateKey, Path certificateChain) {
- try {
- return KeyStoreBuilder.withType(KeyStoreType.PKCS12)
- .withKeyEntry(
- CERTIFICATE_ALIAS,
- KeyUtils.fromPemEncodedPrivateKey(new String(Files.readAllBytes(privateKey), StandardCharsets.UTF_8)),
- X509CertificateUtils.certificateListFromPem(new String(Files.readAllBytes(certificateChain), StandardCharsets.UTF_8)))
- .build();
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
-
- private static ScheduledExecutorService createDefaultScheduler() {
- return Executors.newSingleThreadScheduledExecutor(runnable -> {
- Thread thread = new Thread(runnable, "auto-reloading-x509-key-manager");
- thread.setDaemon(true);
- return thread;
- });
- }
-
- private class KeyManagerReloader implements Runnable {
- @Override
- public void run() {
- try {
- log.log(Level.FINE, () -> String.format("Reloading key and certificate chain (private-key='%s', certificates='%s')", privateKeyFile, certificatesFile));
- mutableX509KeyManager.updateKeystore(createKeystore(privateKeyFile, certificatesFile), new char[0]);
- } catch (Throwable t) {
- log.log(Level.SEVERE,
- String.format("Failed to load X509 key manager (private-key='%s', certificates='%s'): %s",
- privateKeyFile, certificatesFile, t.getMessage()),
- t);
- }
- }
- }
-
- @Override
- public void close() {
- try {
- scheduler.shutdownNow();
- scheduler.awaitTermination(5, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
-
- //
- // Methods from X509ExtendedKeyManager
- //
-
- @Override
- public String[] getServerAliases(String keyType, Principal[] issuers) {
- return mutableX509KeyManager.getServerAliases(keyType, issuers);
- }
-
- @Override
- public String[] getClientAliases(String keyType, Principal[] issuers) {
- return mutableX509KeyManager.getClientAliases(keyType, issuers);
- }
-
- @Override
- public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
- return mutableX509KeyManager.chooseServerAlias(keyType, issuers, socket);
- }
-
- @Override
- public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
- return mutableX509KeyManager.chooseClientAlias(keyType, issuers, socket);
- }
-
- @Override
- public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
- return mutableX509KeyManager.chooseEngineServerAlias(keyType, issuers, engine);
- }
-
- @Override
- public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
- return mutableX509KeyManager.chooseEngineClientAlias(keyType, issuers, engine);
- }
-
- @Override
- public X509Certificate[] getCertificateChain(String alias) {
- return mutableX509KeyManager.getCertificateChain(alias);
- }
-
- @Override
- public PrivateKey getPrivateKey(String alias) {
- return mutableX509KeyManager.getPrivateKey(alias);
- }
-
-}
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 d89e4631103..69635b92e74 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
@@ -4,6 +4,8 @@ package com.yahoo.security.tls;
import com.yahoo.security.KeyStoreBuilder;
import com.yahoo.security.KeyStoreType;
import com.yahoo.security.KeyUtils;
+import com.yahoo.security.MutableX509KeyManager;
+import com.yahoo.security.MutableX509TrustManager;
import com.yahoo.security.SslContextBuilder;
import com.yahoo.security.X509CertificateUtils;
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/KeyManagerUtils.java b/security-utils/src/main/java/com/yahoo/security/tls/KeyManagerUtils.java
deleted file mode 100644
index c9216d7273c..00000000000
--- a/security-utils/src/main/java/com/yahoo/security/tls/KeyManagerUtils.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.security.tls;
-
-import com.yahoo.security.KeyStoreBuilder;
-import com.yahoo.security.KeyStoreType;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.X509ExtendedKeyManager;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Utility methods for constructing {@link X509ExtendedKeyManager}.
- *
- * @author bjorncs
- */
-public class KeyManagerUtils {
-
- public static X509ExtendedKeyManager createDefaultX509KeyManager(KeyStore keystore, char[] password) {
- try {
- KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- keyManagerFactory.init(keystore, password);
- KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
- return Arrays.stream(keyManagers)
- .filter(manager -> manager instanceof X509ExtendedKeyManager)
- .map(X509ExtendedKeyManager.class::cast)
- .findFirst()
- .orElseThrow(() -> new RuntimeException("No X509ExtendedKeyManager in " + Arrays.asList(keyManagers)));
- } catch (GeneralSecurityException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static X509ExtendedKeyManager createDefaultX509KeyManager(PrivateKey privateKey, List<X509Certificate> certificateChain) {
- KeyStore keystore = KeyStoreBuilder.withType(KeyStoreType.PKCS12)
- .withKeyEntry("default", privateKey, certificateChain)
- .build();
- return createDefaultX509KeyManager(keystore, new char[0]);
- }
-
- public static X509ExtendedKeyManager createDefaultX509KeyManager() {
- return createDefaultX509KeyManager(null, new char[0]);
- }
-}
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/MutableX509KeyManager.java b/security-utils/src/main/java/com/yahoo/security/tls/MutableX509KeyManager.java
deleted file mode 100644
index 6d784efc3e8..00000000000
--- a/security-utils/src/main/java/com/yahoo/security/tls/MutableX509KeyManager.java
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.security.tls;
-
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.X509ExtendedKeyManager;
-import java.net.Socket;
-import java.security.KeyStore;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.WeakHashMap;
-
-/**
- * A {@link X509ExtendedKeyManager} which can be updated with new certificate chain and private key while in use.
- *
- * The implementations assumes that aliases are retrieved from the same thread as the certificate chain and private key.
- * This is case for OpenJDK 11.
- *
- * @author bjorncs
- */
-public class MutableX509KeyManager extends X509ExtendedKeyManager {
-
- private final Object monitor = new Object();
- // Not using ThreadLocal as we want the thread local x509 key manager instances to be garbage collected
- // when either the thread dies or the MutableX509KeyManager instance is collected (latter not the case for ThreadLocal).
- private final WeakHashMap<Thread, X509ExtendedKeyManager> threadLocalManager = new WeakHashMap<>();
- private X509ExtendedKeyManager currentManager;
-
- public MutableX509KeyManager(KeyStore keystore, char[] password) {
- synchronized (monitor) {
- this.currentManager = KeyManagerUtils.createDefaultX509KeyManager(keystore, password);
- }
- }
-
- public MutableX509KeyManager() {
- synchronized (monitor) {
- this.currentManager = KeyManagerUtils.createDefaultX509KeyManager();
- }
- }
-
- public void updateKeystore(KeyStore keystore, char[] password) {
- synchronized (monitor) {
- this.currentManager = KeyManagerUtils.createDefaultX509KeyManager(keystore, password);
- }
- }
-
- public void useDefaultKeystore() {
- synchronized (monitor) {
- this.currentManager = KeyManagerUtils.createDefaultX509KeyManager();
- }
- }
-
- public X509ExtendedKeyManager currentManager() {
- synchronized (monitor) {
- return currentManager;
- }
- }
-
- @Override
- public String[] getServerAliases(String keyType, Principal[] issuers) {
- return updateAndGetThreadLocalManager()
- .getServerAliases(keyType, issuers);
- }
-
- @Override
- public String[] getClientAliases(String keyType, Principal[] issuers) {
- return updateAndGetThreadLocalManager()
- .getClientAliases(keyType, issuers);
- }
-
- @Override
- public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
- return updateAndGetThreadLocalManager()
- .chooseServerAlias(keyType, issuers, socket);
- }
-
- @Override
- public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
- return updateAndGetThreadLocalManager()
- .chooseClientAlias(keyType, issuers, socket);
- }
-
- @Override
- public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
- return updateAndGetThreadLocalManager()
- .chooseEngineServerAlias(keyType, issuers, engine);
- }
-
- @Override
- public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
- return updateAndGetThreadLocalManager()
- .chooseEngineClientAlias(keyType, issuers, engine);
- }
-
- private X509ExtendedKeyManager updateAndGetThreadLocalManager() {
- synchronized (monitor) {
- X509ExtendedKeyManager currentManager = this.currentManager;
- threadLocalManager.put(Thread.currentThread(), currentManager);
- return currentManager;
- }
- }
-
- @Override
- public X509Certificate[] getCertificateChain(String alias) {
- if (alias == null) return null; // this method can be called with 'null' alias prior to any alias getter methods.
- return getThreadLocalManager()
- .getCertificateChain(alias);
- }
-
- @Override
- public PrivateKey getPrivateKey(String alias) {
- if (alias == null) return null; // this method can be called with 'null' alias prior to any alias getter methods.
- return getThreadLocalManager()
- .getPrivateKey(alias);
- }
-
- private X509ExtendedKeyManager getThreadLocalManager() {
- synchronized (monitor) {
- X509ExtendedKeyManager manager = threadLocalManager.get(Thread.currentThread());
- if (manager == null) {
- throw new IllegalStateException("Methods to retrieve valid aliases has not been called previously from this thread");
- }
- return manager;
- }
- }
-}
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/MutableX509TrustManager.java b/security-utils/src/main/java/com/yahoo/security/tls/MutableX509TrustManager.java
deleted file mode 100644
index 6db43ef94a9..00000000000
--- a/security-utils/src/main/java/com/yahoo/security/tls/MutableX509TrustManager.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.security.tls;
-
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.X509ExtendedTrustManager;
-import java.net.Socket;
-import java.security.KeyStore;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-
-/**
- * A {@link X509ExtendedTrustManager} which can be updated with new CA certificates while in use.
- *
- * @author bjorncs
- */
-public class MutableX509TrustManager extends X509ExtendedTrustManager {
-
- private volatile X509ExtendedTrustManager currentManager;
-
- public MutableX509TrustManager(KeyStore truststore) {
- this.currentManager = TrustManagerUtils.createDefaultX509TrustManager(truststore);
- }
-
- public MutableX509TrustManager() {
- this.currentManager = TrustManagerUtils.createDefaultX509TrustManager();
- }
-
- public void updateTruststore(KeyStore truststore) {
- this.currentManager = TrustManagerUtils.createDefaultX509TrustManager(truststore);
- }
-
- public void useDefaultTruststore() {
- this.currentManager = TrustManagerUtils.createDefaultX509TrustManager();
- }
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- currentManager.checkClientTrusted(chain, authType);
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- currentManager.checkServerTrusted(chain, authType);
- }
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
- currentManager.checkClientTrusted(chain, authType, socket);
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
- currentManager.checkServerTrusted(chain, authType, socket);
- }
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine sslEngine) throws CertificateException {
- currentManager.checkClientTrusted(chain, authType, sslEngine);
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine sslEngine) throws CertificateException {
- currentManager.checkServerTrusted(chain, authType, sslEngine);
- }
-
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return currentManager.getAcceptedIssuers();
- }
-}
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java b/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java
index 8e7dd039081..089023e55f1 100644
--- a/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java
+++ b/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java
@@ -1,6 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.security.tls;
+import com.yahoo.security.TrustManagerUtils;
import com.yahoo.security.X509CertificateUtils;
import javax.net.ssl.SSLEngine;
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/TrustAllX509TrustManager.java b/security-utils/src/main/java/com/yahoo/security/tls/TrustAllX509TrustManager.java
deleted file mode 100644
index b0303620cf7..00000000000
--- a/security-utils/src/main/java/com/yahoo/security/tls/TrustAllX509TrustManager.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.security.tls;
-
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.X509ExtendedTrustManager;
-import java.net.Socket;
-import java.security.cert.X509Certificate;
-
-/**
- * A {@link X509ExtendedTrustManager} that accepts all server certificates.
- *
- * @author bjorncs
- */
-public class TrustAllX509TrustManager extends X509ExtendedTrustManager {
- @Override public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) { failWhenUsedOnServer(); }
- @Override public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) { failWhenUsedOnServer(); }
- @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { failWhenUsedOnServer(); }
-
- @Override public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) {}
- @Override public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {}
- @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {}
- @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
-
- private static void failWhenUsedOnServer() {
- throw new IllegalStateException("TrustAllX509TrustManager cannot be used on server, only client");
- }
-}
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/TrustManagerUtils.java b/security-utils/src/main/java/com/yahoo/security/tls/TrustManagerUtils.java
deleted file mode 100644
index 4172e337789..00000000000
--- a/security-utils/src/main/java/com/yahoo/security/tls/TrustManagerUtils.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.security.tls;
-
-import com.yahoo.security.KeyStoreBuilder;
-import com.yahoo.security.KeyStoreType;
-
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509ExtendedTrustManager;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Utility methods for constructing {@link X509ExtendedTrustManager}.
- *
- * @author bjorncs
- */
-public class TrustManagerUtils {
-
- public static X509ExtendedTrustManager createDefaultX509TrustManager(KeyStore truststore) {
- try {
- TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- trustManagerFactory.init(truststore);
- TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
- return Arrays.stream(trustManagers)
- .filter(manager -> manager instanceof X509ExtendedTrustManager)
- .map(X509ExtendedTrustManager.class::cast)
- .findFirst()
- .orElseThrow(() -> new RuntimeException("No X509ExtendedTrustManager in " + Arrays.asList(trustManagers)));
- } catch (GeneralSecurityException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static X509ExtendedTrustManager createDefaultX509TrustManager(List<X509Certificate> certificates) {
- return createDefaultX509TrustManager(
- KeyStoreBuilder.withType(KeyStoreType.PKCS12)
- .withCertificateEntries("cert", certificates)
- .build());
- }
-
- public static X509ExtendedTrustManager createDefaultX509TrustManager() {
- return createDefaultX509TrustManager((KeyStore) null);
- }
-}