aboutsummaryrefslogtreecommitdiffstats
path: root/athenz-identity-provider-service
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2019-07-03 14:01:05 +0200
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2019-07-05 11:07:35 +0200
commit303dbfddb8d2e44cf16a2847fa5983aa1dbd4154 (patch)
tree106d931480236e2bf9f566bfc6f4f45ab8fe1dcc /athenz-identity-provider-service
parent99c794f11d90b9d928be05196d244c500298a495 (diff)
Use TlsContextBasedProvider in ConfigserverSslContextFactoryProvider
Diffstat (limited to 'athenz-identity-provider-service')
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/ConfigserverSslContextFactoryProvider.java80
1 files changed, 33 insertions, 47 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/ConfigserverSslContextFactoryProvider.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/ConfigserverSslContextFactoryProvider.java
index 0eeeae457b6..7c25e906b6f 100644
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/ConfigserverSslContextFactoryProvider.java
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/ConfigserverSslContextFactoryProvider.java
@@ -2,13 +2,17 @@
package com.yahoo.vespa.hosted.athenz.instanceproviderservice;
import com.google.inject.Inject;
-import com.yahoo.component.AbstractComponent;
import com.yahoo.config.provision.Zone;
-import com.yahoo.jdisc.http.ssl.SslContextFactoryProvider;
+import com.yahoo.jdisc.http.ssl.impl.TlsContextBasedProvider;
import com.yahoo.log.LogLevel;
import com.yahoo.security.KeyStoreBuilder;
import com.yahoo.security.KeyStoreType;
import com.yahoo.security.KeyUtils;
+import com.yahoo.security.SslContextBuilder;
+import com.yahoo.security.tls.DefaultTlsContext;
+import com.yahoo.security.tls.MutableX509KeyManager;
+import com.yahoo.security.tls.PeerAuthentication;
+import com.yahoo.security.tls.TlsContext;
import com.yahoo.vespa.athenz.api.AthenzService;
import com.yahoo.vespa.athenz.client.zts.DefaultZtsClient;
import com.yahoo.vespa.athenz.client.zts.Identity;
@@ -17,12 +21,11 @@ import com.yahoo.vespa.athenz.identity.ServiceIdentityProvider;
import com.yahoo.vespa.athenz.utils.SiaUtils;
import com.yahoo.vespa.defaults.Defaults;
import com.yahoo.vespa.hosted.athenz.instanceproviderservice.config.AthenzProviderServiceConfig;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
+import javax.net.ssl.SSLContext;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivateKey;
@@ -42,14 +45,15 @@ import java.util.logging.Logger;
*
* @author bjorncs
*/
-public class ConfigserverSslContextFactoryProvider extends AbstractComponent implements SslContextFactoryProvider {
+public class ConfigserverSslContextFactoryProvider extends TlsContextBasedProvider {
private static final String CERTIFICATE_ALIAS = "athenz";
private static final Duration EXPIRATION_MARGIN = Duration.ofHours(6);
private static final Path VESPA_SIA_DIRECTORY = Paths.get(Defaults.getDefaults().underVespaHome("var/vespa/sia"));
private static final Logger log = Logger.getLogger(ConfigserverSslContextFactoryProvider.class.getName());
- private final SslContextFactory sslContextFactory;
+ private final TlsContext tlsContext;
+ private final MutableX509KeyManager keyManager = new MutableX509KeyManager();
private final ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor(runnable -> new Thread(runnable, "configserver-ssl-context-factory-provider"));
private final ZtsClient ztsClient;
@@ -69,25 +73,20 @@ public class ConfigserverSslContextFactoryProvider extends AbstractComponent imp
Duration updatePeriod = Duration.ofDays(config.updatePeriodDays());
Path trustStoreFile = Paths.get(config.athenzCaTrustStore());
- this.sslContextFactory = initializeSslContextFactory(keyProvider, trustStoreFile, updatePeriod, configserverIdentity, ztsClient, athenzProviderServiceConfig);
- scheduler.scheduleAtFixedRate(new KeystoreUpdater(sslContextFactory),
+ this.tlsContext = createTlsContext(keyProvider, keyManager, trustStoreFile, updatePeriod, configserverIdentity, ztsClient, athenzProviderServiceConfig);
+ scheduler.scheduleAtFixedRate(new KeystoreUpdater(keyManager),
updatePeriod.toDays()/*initial delay*/,
updatePeriod.toDays(),
TimeUnit.DAYS);
}
@Override
- public SslContextFactory getInstance(String containerId, int port) {
- return sslContextFactory;
+ protected TlsContext getTlsContext(String containerId, int port) {
+ return tlsContext;
}
Instant getCertificateNotAfter() {
- try {
- X509Certificate certificate = (X509Certificate) sslContextFactory.getKeyStore().getCertificate(CERTIFICATE_ALIAS);
- return certificate.getNotAfter().toInstant();
- } catch (GeneralSecurityException e) {
- throw new IllegalStateException("Unable to find configserver certificate from keystore: " + e.getMessage(), e);
- }
+ return keyManager.getCertificateChain(CERTIFICATE_ALIAS)[0].getNotAfter().toInstant();
}
@Override
@@ -96,38 +95,28 @@ public class ConfigserverSslContextFactoryProvider extends AbstractComponent imp
scheduler.shutdownNow();
scheduler.awaitTermination(30, TimeUnit.SECONDS);
ztsClient.close();
+ super.deconstruct();
} catch (InterruptedException e) {
throw new RuntimeException("Failed to shutdown Athenz certificate updater on time", e);
}
}
- private static SslContextFactory initializeSslContextFactory(KeyProvider keyProvider,
- Path trustStoreFile,
- Duration updatePeriod,
- AthenzService configserverIdentity,
- ZtsClient ztsClient,
- AthenzProviderServiceConfig zoneConfig) {
-
- // TODO Use DefaultTlsContext to configure SslContextFactory (ensure that cipher/protocol configuration is same across all TLS endpoints)
-
- SslContextFactory.Server factory = new SslContextFactory.Server();
-
- factory.setWantClientAuth(true);
-
- KeyStore trustStore =
- KeyStoreBuilder.withType(KeyStoreType.JKS)
- .fromFile(trustStoreFile)
- .build();
- factory.setTrustStore(trustStore);
-
+ private static TlsContext createTlsContext(KeyProvider keyProvider,
+ MutableX509KeyManager keyManager,
+ Path trustStoreFile,
+ Duration updatePeriod,
+ AthenzService configserverIdentity,
+ ZtsClient ztsClient,
+ AthenzProviderServiceConfig zoneConfig) {
KeyStore keyStore =
tryReadKeystoreFile(configserverIdentity, updatePeriod)
.orElseGet(() -> updateKeystore(configserverIdentity, generateKeystorePassword(), keyProvider, ztsClient, zoneConfig));
- factory.setKeyStore(keyStore);
- factory.setKeyStorePassword("");
- factory.setExcludeProtocols("TLSv1.3"); // TLSv1.3 is broken is multiple OpenJDK 11 versions
- factory.setEndpointIdentificationAlgorithm(null); // disable https hostname verification of clients (must be disabled when using Athenz x509 certificates)
- return factory;
+ keyManager.updateKeystore(keyStore, new char[0]);
+ SSLContext sslContext = new SslContextBuilder()
+ .withTrustStore(trustStoreFile)
+ .withKeyManager(keyManager)
+ .build();
+ return new DefaultTlsContext(sslContext, PeerAuthentication.WANT);
}
private static Optional<KeyStore> tryReadKeystoreFile(AthenzService configserverIdentity, Duration updatePeriod) {
@@ -171,10 +160,10 @@ public class ConfigserverSslContextFactoryProvider extends AbstractComponent imp
}
private class KeystoreUpdater implements Runnable {
- final SslContextFactory sslContextFactory;
+ final MutableX509KeyManager keyManager;
- KeystoreUpdater(SslContextFactory sslContextFactory) {
- this.sslContextFactory = sslContextFactory;
+ KeystoreUpdater(MutableX509KeyManager keyManager) {
+ this.keyManager = keyManager;
}
@Override
@@ -183,10 +172,7 @@ public class ConfigserverSslContextFactoryProvider extends AbstractComponent imp
log.log(LogLevel.INFO, "Updating configserver provider certificate from ZTS");
char[] keystorePwd = generateKeystorePassword();
KeyStore keyStore = updateKeystore(configserverIdentity, keystorePwd, keyProvider, ztsClient, athenzProviderServiceConfig);
- sslContextFactory.reload(scf -> {
- scf.setKeyStore(keyStore);
- scf.setKeyStorePassword(new String(keystorePwd));
- });
+ keyManager.updateKeystore(keyStore, keystorePwd);
log.log(LogLevel.INFO, "Certificate successfully updated");
} catch (Throwable t) {
log.log(LogLevel.ERROR, "Failed to update certificate from ZTS: " + t.getMessage(), t);