summaryrefslogtreecommitdiffstats
path: root/security-utils/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'security-utils/src/main/java/com')
-rw-r--r--security-utils/src/main/java/com/yahoo/security/SslContextBuilder.java15
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/AutoReloadingX509KeyManager.java4
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/ConfigFileBasedTlsContext.java (renamed from security-utils/src/main/java/com/yahoo/security/tls/ReloadingTlsContext.java)17
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/DefaultTlsContext.java47
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/PeerAuthentication.java9
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/TlsContext.java14
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityUtils.java2
7 files changed, 78 insertions, 30 deletions
diff --git a/security-utils/src/main/java/com/yahoo/security/SslContextBuilder.java b/security-utils/src/main/java/com/yahoo/security/SslContextBuilder.java
index 0ef179f775e..4f8919cdd5e 100644
--- a/security-utils/src/main/java/com/yahoo/security/SslContextBuilder.java
+++ b/security-utils/src/main/java/com/yahoo/security/SslContextBuilder.java
@@ -33,6 +33,7 @@ public class SslContextBuilder {
private char[] keyStorePassword;
private TrustManagerFactory trustManagerFactory = TrustManagerUtils::createDefaultX509TrustManager;
private KeyManagerFactory keyManagerFactory = KeyManagerUtils::createDefaultX509KeyManager;
+ private X509ExtendedKeyManager keyManager;
public SslContextBuilder() {}
@@ -110,11 +111,23 @@ public class SslContextBuilder {
return this;
}
+ /**
+ * Note: Callee is responsible for configuring the key manager.
+ * Any keystore configured by {@link #withKeyStore(KeyStore, char[])} or the other overloads will be ignored.
+ */
+ public SslContextBuilder withKeyManager(X509ExtendedKeyManager keyManager) {
+ this.keyManager = keyManager;
+ return this;
+ }
+
public SSLContext build() {
try {
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
TrustManager[] trustManagers = new TrustManager[] { trustManagerFactory.createTrustManager(trustStoreSupplier.get()) };
- KeyManager[] keyManagers = new KeyManager[] { keyManagerFactory.createKeyManager(keyStoreSupplier.get(), keyStorePassword) };
+ X509ExtendedKeyManager keyManager = this.keyManager != null
+ ? this.keyManager
+ : keyManagerFactory.createKeyManager(keyStoreSupplier.get(), keyStorePassword);
+ KeyManager[] keyManagers = new KeyManager[] {keyManager};
sslContext.init(keyManagers, trustManagers, null);
return sslContext;
} catch (GeneralSecurityException e) {
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
index 0dae185995c..faf6ecb4348 100644
--- a/security-utils/src/main/java/com/yahoo/security/tls/AutoReloadingX509KeyManager.java
+++ b/security-utils/src/main/java/com/yahoo/security/tls/AutoReloadingX509KeyManager.java
@@ -31,6 +31,8 @@ import java.util.logging.Logger;
*/
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());
@@ -61,7 +63,7 @@ public class AutoReloadingX509KeyManager extends X509ExtendedKeyManager implemen
try {
return KeyStoreBuilder.withType(KeyStoreType.PKCS12)
.withKeyEntry(
- "default",
+ CERTIFICATE_ALIAS,
KeyUtils.fromPemEncodedPrivateKey(Files.readString(privateKey)),
X509CertificateUtils.certificateListFromPem(Files.readString(certificateChain)))
.build();
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/ReloadingTlsContext.java b/security-utils/src/main/java/com/yahoo/security/tls/ConfigFileBasedTlsContext.java
index 16f66f91da6..3b9158cf9b1 100644
--- a/security-utils/src/main/java/com/yahoo/security/tls/ReloadingTlsContext.java
+++ b/security-utils/src/main/java/com/yahoo/security/tls/ConfigFileBasedTlsContext.java
@@ -20,6 +20,8 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyStore;
import java.time.Duration;
+import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -29,20 +31,21 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
- * A {@link TlsContext} that regularly reloads the credentials referred to from the transport security options file.
+ * A {@link TlsContext} that uses the tls configuration specified in the transport security options file.
+ * The credentials are regularly reloaded to support short-lived certificates.
*
* @author bjorncs
*/
-public class ReloadingTlsContext implements TlsContext {
+public class ConfigFileBasedTlsContext implements TlsContext {
private static final Duration UPDATE_PERIOD = Duration.ofHours(1);
- private static final Logger log = Logger.getLogger(ReloadingTlsContext.class.getName());
+ private static final Logger log = Logger.getLogger(ConfigFileBasedTlsContext.class.getName());
private final TlsContext tlsContext;
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new ReloaderThreadFactory());
- public ReloadingTlsContext(Path tlsOptionsConfigFile, AuthorizationMode mode) {
+ public ConfigFileBasedTlsContext(Path tlsOptionsConfigFile, AuthorizationMode mode) {
TransportSecurityOptions options = TransportSecurityOptions.fromJsonFile(tlsOptionsConfigFile);
MutableX509TrustManager trustManager = new MutableX509TrustManager();
MutableX509KeyManager keyManager = new MutableX509KeyManager();
@@ -99,13 +102,15 @@ public class ReloadingTlsContext implements TlsContext {
MutableX509TrustManager mutableTrustManager,
MutableX509KeyManager mutableKeyManager) {
SSLContext sslContext = new SslContextBuilder()
- .withKeyManagerFactory((ignoredKeystore, ignoredPassword) -> mutableKeyManager)
+ .withKeyManager(mutableKeyManager)
.withTrustManagerFactory(
ignoredTruststore -> options.getAuthorizedPeers()
.map(authorizedPeers -> (X509ExtendedTrustManager) new PeerAuthorizerTrustManager(authorizedPeers, mode, mutableTrustManager))
.orElseGet(() -> new PeerAuthorizerTrustManager(new AuthorizedPeers(Set.of()), AuthorizationMode.DISABLE, mutableTrustManager)))
.build();
- return new DefaultTlsContext(sslContext, options.getAcceptedCiphers());
+ List<String> acceptedCiphers = options.getAcceptedCiphers();
+ Set<String> ciphers = acceptedCiphers.isEmpty() ? TlsContext.ALLOWED_CIPHER_SUITES : new HashSet<>(acceptedCiphers);
+ return new DefaultTlsContext(sslContext, ciphers, PeerAuthentication.NEED);
}
// Wrapped methods from TlsContext
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/DefaultTlsContext.java b/security-utils/src/main/java/com/yahoo/security/tls/DefaultTlsContext.java
index e74ad49b2f5..572461c6cdd 100644
--- a/security-utils/src/main/java/com/yahoo/security/tls/DefaultTlsContext.java
+++ b/security-utils/src/main/java/com/yahoo/security/tls/DefaultTlsContext.java
@@ -23,47 +23,41 @@ import java.util.logging.Logger;
*/
public class DefaultTlsContext implements TlsContext {
- public static final List<String> ALLOWED_CIPHER_SUITES = Arrays.asList(
- "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
- "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
- "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
- "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
- "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
- "TLS_AES_128_GCM_SHA256", // TLSv1.3
- "TLS_AES_256_GCM_SHA384", // TLSv1.3
- "TLS_CHACHA20_POLY1305_SHA256"); // TLSv1.3
-
- public static final List<String> ALLOWED_PROTOCOLS = List.of("TLSv1.2"); // TODO Enable TLSv1.3
-
private static final Logger log = Logger.getLogger(DefaultTlsContext.class.getName());
private final SSLContext sslContext;
private final String[] validCiphers;
private final String[] validProtocols;
+ private final PeerAuthentication peerAuthentication;
public DefaultTlsContext(List<X509Certificate> certificates,
PrivateKey privateKey,
List<X509Certificate> caCertificates,
AuthorizedPeers authorizedPeers,
AuthorizationMode mode,
- List<String> acceptedCiphers) {
- this(createSslContext(certificates, privateKey, caCertificates, authorizedPeers, mode),
- acceptedCiphers);
+ PeerAuthentication peerAuthentication) {
+ this(createSslContext(certificates, privateKey, caCertificates, authorizedPeers, mode), peerAuthentication);
+ }
+
+ public DefaultTlsContext(SSLContext sslContext, PeerAuthentication peerAuthentication) {
+ this(sslContext, TlsContext.ALLOWED_CIPHER_SUITES, peerAuthentication);
}
+ public DefaultTlsContext(SSLContext sslContext) {
+ this(sslContext, TlsContext.ALLOWED_CIPHER_SUITES, PeerAuthentication.NEED);
+ }
- public DefaultTlsContext(SSLContext sslContext, List<String> acceptedCiphers) {
+ DefaultTlsContext(SSLContext sslContext, Set<String> acceptedCiphers, PeerAuthentication peerAuthentication) {
this.sslContext = sslContext;
+ this.peerAuthentication = peerAuthentication;
this.validCiphers = getAllowedCiphers(sslContext, acceptedCiphers);
this.validProtocols = getAllowedProtocols(sslContext);
}
-
- private static String[] getAllowedCiphers(SSLContext sslContext, List<String> acceptedCiphers) {
+ private static String[] getAllowedCiphers(SSLContext sslContext, Set<String> acceptedCiphers) {
String[] supportedCipherSuites = sslContext.getSupportedSSLParameters().getCipherSuites();
String[] validCipherSuites = Arrays.stream(supportedCipherSuites)
- .filter(suite -> ALLOWED_CIPHER_SUITES.contains(suite) && (acceptedCiphers.isEmpty() || acceptedCiphers.contains(suite)))
+ .filter(suite -> ALLOWED_CIPHER_SUITES.contains(suite) && acceptedCiphers.contains(suite))
.toArray(String[]::new);
if (validCipherSuites.length == 0) {
throw new IllegalStateException(
@@ -117,7 +111,18 @@ public class DefaultTlsContext implements TlsContext {
SSLParameters newParameters = sslContext.getDefaultSSLParameters();
newParameters.setCipherSuites(validCiphers);
newParameters.setProtocols(validProtocols);
- newParameters.setNeedClientAuth(true);
+ switch (peerAuthentication) {
+ case WANT:
+ newParameters.setWantClientAuth(true);
+ break;
+ case NEED:
+ newParameters.setNeedClientAuth(true);
+ break;
+ case DISABLED:
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown peer authentication: " + peerAuthentication);
+ }
return newParameters;
}
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthentication.java b/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthentication.java
new file mode 100644
index 00000000000..9aa7b642b4a
--- /dev/null
+++ b/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthentication.java
@@ -0,0 +1,9 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.security.tls;
+
+/**
+ * @author bjorncs
+ */
+public enum PeerAuthentication {
+ WANT, NEED, DISABLED
+}
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/TlsContext.java b/security-utils/src/main/java/com/yahoo/security/tls/TlsContext.java
index b315dd00b31..ea26be0ef4f 100644
--- a/security-utils/src/main/java/com/yahoo/security/tls/TlsContext.java
+++ b/security-utils/src/main/java/com/yahoo/security/tls/TlsContext.java
@@ -4,6 +4,7 @@ package com.yahoo.security.tls;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
+import java.util.Set;
/**
* A simplified version of {@link SSLContext} modelled as an interface.
@@ -12,6 +13,19 @@ import javax.net.ssl.SSLParameters;
*/
public interface TlsContext extends AutoCloseable {
+ Set<String> ALLOWED_CIPHER_SUITES = Set.of(
+ "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+ "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+ "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_AES_128_GCM_SHA256", // TLSv1.3
+ "TLS_AES_256_GCM_SHA384", // TLSv1.3
+ "TLS_CHACHA20_POLY1305_SHA256"); // TLSv1.3
+
+ Set<String> ALLOWED_PROTOCOLS = Set.of("TLSv1.2"); // TODO Enable TLSv1.3
+
SSLContext context();
SSLParameters parameters();
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 a4e508e0d2a..f28cad2a071 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
@@ -66,7 +66,7 @@ public class TransportSecurityUtils {
public static Optional<TlsContext> createTlsContext() {
return getConfigFile()
- .map(configFile -> new ReloadingTlsContext(configFile, getInsecureAuthorizationMode()));
+ .map(configFile -> new ConfigFileBasedTlsContext(configFile, getInsecureAuthorizationMode()));
}
private static Optional<String> getEnvironmentVariable(Map<String, String> environmentVariables, String variableName) {