summaryrefslogtreecommitdiffstats
path: root/athenz-identity-provider-service
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@oath.com>2018-06-13 16:28:13 +0200
committerBjørn Christian Seime <bjorncs@oath.com>2018-06-13 16:28:20 +0200
commitffe8ed4966e26fd5cc0e5944900f2ac457c542bf (patch)
treef708d0eae612f293fda13bb792e7295b156d1eb2 /athenz-identity-provider-service
parent1003fa297992ca412bff990df1def643b3c132fd (diff)
Store configserver certificate to VESPA_HOME/var/vespa/sia
Diffstat (limited to 'athenz-identity-provider-service')
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslKeyStoreConfigurator.java97
1 files changed, 39 insertions, 58 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslKeyStoreConfigurator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslKeyStoreConfigurator.java
index 2a517e06ae2..3437dea9ece 100644
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslKeyStoreConfigurator.java
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslKeyStoreConfigurator.java
@@ -8,18 +8,17 @@ import com.yahoo.config.provision.Zone;
import com.yahoo.jdisc.http.ssl.SslKeyStoreConfigurator;
import com.yahoo.jdisc.http.ssl.SslKeyStoreContext;
import com.yahoo.log.LogLevel;
+import com.yahoo.vespa.athenz.api.AthenzService;
import com.yahoo.vespa.athenz.identity.ServiceIdentityProvider;
import com.yahoo.vespa.athenz.tls.KeyStoreBuilder;
import com.yahoo.vespa.athenz.tls.KeyStoreType;
+import com.yahoo.vespa.athenz.utils.SiaUtils;
import com.yahoo.vespa.defaults.Defaults;
import com.yahoo.vespa.hosted.athenz.instanceproviderservice.config.AthenzProviderServiceConfig;
import com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl.AthenzCertificateClient;
-import java.io.IOException;
-import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.PrivateKey;
@@ -33,7 +32,6 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
-import static com.yahoo.vespa.athenz.tls.KeyStoreUtils.writeKeyStoreToFile;
import static com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl.Utils.getZoneConfig;
/**
@@ -47,13 +45,14 @@ public class AthenzSslKeyStoreConfigurator extends AbstractComponent implements
private static final Logger log = Logger.getLogger(AthenzSslKeyStoreConfigurator.class.getName());
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 final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private final AthenzCertificateClient certificateClient;
private final KeyProvider keyProvider;
private final AthenzProviderServiceConfig.Zones zoneConfig;
private final Duration updatePeriod;
- private final Path keystoreDirectory;
+ private final AthenzService configserverIdentity;
private volatile KeyStoreAndPassword currentKeyStore;
@Inject
@@ -63,55 +62,40 @@ public class AthenzSslKeyStoreConfigurator extends AbstractComponent implements
Zone zone,
ConfigserverConfig configserverConfig) {
AthenzProviderServiceConfig.Zones zoneConfig = getZoneConfig(config, zone);
- Path keystoreDirectory = createKeystoreCacheDirectory(configserverConfig);
+ AthenzService configserverIdentity = new AthenzService(zoneConfig.domain(), zoneConfig.serviceName());
AthenzCertificateClient certificateClient = new AthenzCertificateClient(bootstrapIdentity, zoneConfig);
Duration updatePeriod = Duration.ofDays(config.updatePeriodDays());
this.certificateClient = certificateClient;
this.keyProvider = keyProvider;
this.zoneConfig = zoneConfig;
- this.currentKeyStore = initializeKeystore(keyProvider, certificateClient, zoneConfig, keystoreDirectory, updatePeriod);
+ this.currentKeyStore = initializeKeystore(configserverIdentity, keyProvider, certificateClient, zoneConfig, updatePeriod);
this.updatePeriod = updatePeriod;
- this.keystoreDirectory = keystoreDirectory;
+ this.configserverIdentity = configserverIdentity;
}
- private static KeyStoreAndPassword initializeKeystore(KeyProvider keyProvider,
- AthenzCertificateClient certificateClient,
- AthenzProviderServiceConfig.Zones zoneConfig,
- Path keystoreCacheDirectory,
- Duration updatePeriod) {
- return tryReadKeystoreFile(keystoreCacheDirectory, updatePeriod)
- .orElseGet(() -> downloadCertificate(keyProvider, certificateClient, zoneConfig, keystoreCacheDirectory));
+ private static KeyStoreAndPassword initializeKeystore(AthenzService configserverIdentity,
+ KeyProvider keyProvider,
+ AthenzCertificateClient zoneConfig,
+ AthenzProviderServiceConfig.Zones keystoreCacheDirectory,
+ Duration updatePeriod) {
+ return tryReadKeystoreFile(configserverIdentity, updatePeriod)
+ .orElseGet(() -> downloadCertificate(configserverIdentity, keyProvider, zoneConfig, keystoreCacheDirectory));
}
- private static Optional<KeyStoreAndPassword> tryReadKeystoreFile(Path keystoreDirectory, Duration updatePeriod) {
- try {
- Path keystoreFile = keystoreFile(keystoreDirectory);
- Path keystoreSecretFile = keystoreSecretFile(keystoreDirectory);
- if (!Files.exists(keystoreFile) || !Files.exists(keystoreSecretFile)) return Optional.empty();
- KeyStore keyStore = KeyStoreBuilder.withType(KeyStoreType.JKS)
- .fromFile(keystoreFile.toFile())
- .build();
- Instant minimumExpiration = Instant.now().plus(updatePeriod).plus(EXPIRATION_MARGIN);
- boolean isExpired = getCertificateExpiry(keyStore).isBefore(minimumExpiration);
- if (isExpired) return Optional.empty();
- char[] pwd = new String(Files.readAllBytes(keystoreSecretFile)).toCharArray();
- return Optional.of(new KeyStoreAndPassword(keyStore, pwd));
- } catch (GeneralSecurityException | IOException e) {
- log.log(LogLevel.ERROR, "Failed to read keystore from disk: " + e.getMessage(), e);
- return Optional.empty();
- }
- }
-
- private static Path createKeystoreCacheDirectory(ConfigserverConfig configserverConfig) {
- return Paths.get(Defaults.getDefaults().underVespaHome(configserverConfig.configServerDBDir()));
- }
+ private static Optional<KeyStoreAndPassword> tryReadKeystoreFile(AthenzService configserverIdentity,
+ Duration updatePeriod) {
+ Optional<X509Certificate> certificate = SiaUtils.readCertificateFile(VESPA_SIA_DIRECTORY, configserverIdentity);
+ if (!certificate.isPresent()) return Optional.empty();
+ Optional<PrivateKey> privateKey = SiaUtils.readPrivateKeyFile(VESPA_SIA_DIRECTORY, configserverIdentity);
+ if (!privateKey.isPresent()) return Optional.empty();
+ Instant minimumExpiration = Instant.now().plus(updatePeriod).plus(EXPIRATION_MARGIN);
+ boolean isExpired = certificate.get().getNotAfter().toInstant().isBefore(minimumExpiration);
+ if (isExpired) return Optional.empty();
- private static Path keystoreFile(Path keystoreDirectory) {
- return keystoreDirectory.resolve("server-x509-athenz-cert.jks");
- }
-
- private static Path keystoreSecretFile(Path keystoreDirectory) {
- return keystoreDirectory.resolve("keystore-secret");
+ KeyStore keyStore = KeyStoreBuilder.withType(KeyStoreType.JKS)
+ .withKeyEntry(CERTIFICATE_ALIAS, privateKey.get(), certificate.get())
+ .build();
+ return Optional.of(new KeyStoreAndPassword(keyStore, generateKeystorePassword()));
}
@Override
@@ -142,12 +126,13 @@ public class AthenzSslKeyStoreConfigurator extends AbstractComponent implements
return certificate.getNotAfter().toInstant();
}
- private static KeyStoreAndPassword downloadCertificate(KeyProvider keyProvider,
- AthenzCertificateClient certificateClient,
- AthenzProviderServiceConfig.Zones zoneConfig,
- Path keystoreDirectory) {
+ private static KeyStoreAndPassword downloadCertificate(AthenzService configserverIdentity,
+ KeyProvider keyProvider,
+ AthenzCertificateClient certificateClient,
+ AthenzProviderServiceConfig.Zones zoneConfig) {
PrivateKey privateKey = keyProvider.getPrivateKey(zoneConfig.secretVersion());
X509Certificate certificate = certificateClient.updateCertificate(privateKey);
+ writeCredentials(configserverIdentity, certificate, privateKey);
Instant expirationTime = certificate.getNotAfter().toInstant();
Duration expiry = Duration.between(certificate.getNotBefore().toInstant(), expirationTime);
log.log(LogLevel.INFO, String.format("Got Athenz x509 certificate with expiry %s (expires %s)", expiry, expirationTime));
@@ -156,18 +141,14 @@ public class AthenzSslKeyStoreConfigurator extends AbstractComponent implements
KeyStore keyStore = KeyStoreBuilder.withType(KeyStoreType.JKS)
.withKeyEntry(CERTIFICATE_ALIAS, privateKey, keystorePassword, certificate)
.build();
- KeyStoreAndPassword keyStoreAndPassword = new KeyStoreAndPassword(keyStore, keystorePassword);
- tryWriteKeystore(keyStoreAndPassword, keystoreDirectory);
- return keyStoreAndPassword;
+ return new KeyStoreAndPassword(keyStore, keystorePassword);
}
- private static void tryWriteKeystore(KeyStoreAndPassword keyStore, Path keystoreDirectory) {
- try {
- writeKeyStoreToFile(keyStore.keyStore, keystoreFile(keystoreDirectory).toFile());
- Files.write(keystoreSecretFile(keystoreDirectory), new String(keyStore.password).getBytes());
- } catch (Exception e) {
- log.log(LogLevel.ERROR, "Failed to write keystore to disk: " + e.getMessage(), e);
- }
+ private static void writeCredentials(AthenzService configserverIdentity,
+ X509Certificate certificate,
+ PrivateKey privateKey) {
+ SiaUtils.writeCertificateFile(VESPA_SIA_DIRECTORY, configserverIdentity, certificate);
+ SiaUtils.writePrivateKeyFile(VESPA_SIA_DIRECTORY, configserverIdentity, privateKey);
}
private static char[] generateKeystorePassword() {
@@ -186,7 +167,7 @@ public class AthenzSslKeyStoreConfigurator extends AbstractComponent implements
public void run() {
try {
log.log(LogLevel.INFO, "Updating Athenz certificate from ZTS");
- currentKeyStore = downloadCertificate(keyProvider, certificateClient, zoneConfig, keystoreDirectory);
+ currentKeyStore = downloadCertificate(configserverIdentity, keyProvider, certificateClient, zoneConfig);
sslKeyStoreContext.updateKeyStore(currentKeyStore.keyStore, new String(currentKeyStore.password));
log.log(LogLevel.INFO, "Athenz certificate reload successfully completed");
} catch (Throwable e) {