diff options
author | Valerij Fredriksen <valerijf@oath.com> | 2018-05-04 16:22:21 +0200 |
---|---|---|
committer | Valerij Fredriksen <valerijf@oath.com> | 2018-05-04 16:22:21 +0200 |
commit | ea03a45011628970ffdc14de01e3b4f45849d91f (patch) | |
tree | 5a49e7f7744ddadc4c74952df3c4d8216f0b118e /node-admin/src/main | |
parent | 536ecf86f85e1ca415e8de22cb38f95dd2b50cd4 (diff) |
Remove old certificate refresher
Diffstat (limited to 'node-admin/src/main')
4 files changed, 0 insertions, 314 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/CertificateSerializedPayload.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/CertificateSerializedPayload.java deleted file mode 100644 index 94bff3c9633..00000000000 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/CertificateSerializedPayload.java +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.node.admin.configserver.certificate; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.yahoo.vespa.athenz.tls.X509CertificateUtils; - -import java.io.IOException; -import java.security.cert.X509Certificate; - -/** - * Contains PEM formatted signed certificate - * TODO: Combine with its counterpart in athenz-identity-provider-service? - * - * @author freva - */ -public class CertificateSerializedPayload { - - @JsonProperty("certificate") public final X509Certificate certificate; - - @JsonCreator - public CertificateSerializedPayload(@JsonProperty("certificate") @JsonDeserialize(using = CertificateDeserializer.class) - X509Certificate certificate) { - this.certificate = certificate; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CertificateSerializedPayload that = (CertificateSerializedPayload) o; - - return certificate.equals(that.certificate); - } - - @Override - public int hashCode() { - return certificate.hashCode(); - } - - @Override - public String toString() { - return "CertificateSerializedPayload{" + - "certificate='" + certificate + '\'' + - '}'; - } - - public static class CertificateDeserializer extends JsonDeserializer<X509Certificate> { - @Override - public X509Certificate deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { - return X509CertificateUtils.fromPem(jsonParser.getValueAsString()); - } - } -} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/ConfigServerKeyStoreRefresher.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/ConfigServerKeyStoreRefresher.java deleted file mode 100644 index 24e0f995584..00000000000 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/ConfigServerKeyStoreRefresher.java +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.node.admin.configserver.certificate; - -import com.yahoo.log.LogLevel; -import com.yahoo.vespa.athenz.tls.KeyAlgorithm; -import com.yahoo.vespa.athenz.tls.KeyStoreBuilder; -import com.yahoo.vespa.athenz.tls.KeyUtils; -import com.yahoo.vespa.athenz.tls.Pkcs10Csr; -import com.yahoo.vespa.athenz.tls.Pkcs10CsrBuilder; -import com.yahoo.vespa.athenz.tls.SignatureAlgorithm; -import com.yahoo.vespa.hosted.node.admin.configserver.ConfigServerApi; -import com.yahoo.vespa.hosted.node.admin.util.KeyStoreOptions; - -import javax.security.auth.x500.X500Principal; -import java.security.KeyPair; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.cert.X509Certificate; -import java.time.Clock; -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; - -/** - * Automatically refreshes the KeyStore used to authenticate this node to the configserver. - * The keystore contains a single certificate signed by one of the configservers. - * - * @author freva - */ -public class ConfigServerKeyStoreRefresher { - - private static final Logger logger = Logger.getLogger(ConfigServerKeyStoreRefresher.class.getName()); - private static final String KEY_STORE_ALIAS = "alias"; - static final long MINIMUM_SECONDS_BETWEEN_REFRESH_RETRY = 3600; - static final SignatureAlgorithm SIGNER_ALGORITHM = SignatureAlgorithm.SHA256_WITH_RSA; - static final String CONFIG_SERVER_CERTIFICATE_SIGNING_PATH = "/athenz/v1/provider/sign"; - - private final ScheduledExecutorService executor; - private final KeyStoreOptions keyStoreOptions; - private final Runnable keyStoreUpdatedCallback; - private final ConfigServerApi configServerApi; - private final Clock clock; - private final String hostname; - - public ConfigServerKeyStoreRefresher( - KeyStoreOptions keyStoreOptions, Runnable keyStoreUpdatedCallback, ConfigServerApi configServerApi, String hostname) { - this(keyStoreOptions, keyStoreUpdatedCallback, configServerApi, Executors.newScheduledThreadPool(1), - Clock.systemUTC(), hostname); - } - - ConfigServerKeyStoreRefresher(KeyStoreOptions keyStoreOptions, - Runnable keyStoreUpdatedCallback, - ConfigServerApi configServerApi, - ScheduledExecutorService executor, - Clock clock, - String hostname) { - this.keyStoreOptions = keyStoreOptions; - this.keyStoreUpdatedCallback = keyStoreUpdatedCallback; - this.configServerApi = configServerApi; - this.executor = executor; - this.clock = clock; - this.hostname = hostname; - } - - public void start() { - executor.schedule(this::refresh, getSecondsUntilNextRefresh(), TimeUnit.SECONDS); - } - - void refresh() { - try { - if (refreshKeyStoreIfNeeded()) { - keyStoreUpdatedCallback.run(); - } - final long secondsUntilNextRefresh = getSecondsUntilNextRefresh(); - executor.schedule(this::refresh, secondsUntilNextRefresh, TimeUnit.SECONDS); - logger.log(Level.INFO, "Successfully updated keystore, scheduled next refresh in " + - secondsUntilNextRefresh + "sec"); - } catch (Exception e) { - logger.log(Level.WARNING, "Failed to update keystore on schedule, will try again in " + - MINIMUM_SECONDS_BETWEEN_REFRESH_RETRY + "sec", e); - executor.schedule(this::refresh, MINIMUM_SECONDS_BETWEEN_REFRESH_RETRY, TimeUnit.SECONDS); - } - } - - public void stop() { - executor.shutdownNow(); - do { - try { - executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); - } catch (InterruptedException e1) { - logger.info("Interrupted while waiting for ConfigServerKeyStoreRefresher thread to shutdown"); - } - } while (!executor.isTerminated()); - } - - public boolean refreshKeyStoreIfNeeded() { - if (!shouldRefreshCertificate()) return false; - - KeyPair keyPair = generateKeyPair(); - Pkcs10Csr csr = generateCsr(keyPair, hostname); - X509Certificate certificate = sendCsr(csr); - - storeCertificate(keyPair, certificate); - - logger.log(LogLevel.INFO, "Key store certificate refreshed, expires " + - certificate.getNotAfter().toInstant()); - - return true; - } - - private long getSecondsUntilNextRefresh() { - long secondsUntilNextCheck = 0; - try { - secondsUntilNextCheck = getSecondsUntilCertificateShouldBeRefreshed(); - } catch (Exception e) { - logger.log(Level.WARNING, "Failed to get remaining certificate lifetime", e); - } - - return Math.max(MINIMUM_SECONDS_BETWEEN_REFRESH_RETRY, secondsUntilNextCheck); - } - - private boolean shouldRefreshCertificate() { - try { - return getSecondsUntilCertificateShouldBeRefreshed() <= 0; - } catch (Exception e) { // We can't read the key store for whatever reason, let's just try to refresh it - return true; - } - } - - /** - * Returns number of seconds until we should start trying to refresh the certificate, this should be - * well before the certificate actually expires so that we have enough time to retry without - * overloading config server. - */ - private long getSecondsUntilCertificateShouldBeRefreshed() throws KeyStoreException{ - X509Certificate cert = getConfigServerCertificate(); - long notBefore = cert.getNotBefore().getTime() / 1000; - long notAfter = cert.getNotAfter().getTime() / 1000; - long now = clock.millis() / 1000; - long thirdOfLifetime = (notAfter - notBefore) / 3; - - return Math.max(0, notBefore + thirdOfLifetime - now); - } - - X509Certificate getConfigServerCertificate() throws KeyStoreException { - return (X509Certificate) keyStoreOptions.loadKeyStore().getCertificate(KEY_STORE_ALIAS); - } - - private void storeCertificate(KeyPair keyPair, X509Certificate certificate) { - keyStoreOptions.path.getParent().toFile().mkdirs(); - - KeyStore keyStore = KeyStoreBuilder.withType(keyStoreOptions.keyStoreType) - .withKeyEntry(KEY_STORE_ALIAS, keyPair.getPrivate(), keyStoreOptions.password, certificate) - .build(); - - keyStoreOptions.storeKeyStore(keyStore); - } - - private X509Certificate sendCsr(Pkcs10Csr csr) { - CertificateSerializedPayload certificateSerializedPayload = configServerApi.post( - CONFIG_SERVER_CERTIFICATE_SIGNING_PATH, - new CsrSerializedPayload(csr), - CertificateSerializedPayload.class); - - return certificateSerializedPayload.certificate; - } - - static KeyPair generateKeyPair() { - return KeyUtils.generateKeypair(KeyAlgorithm.RSA, 2048); - } - - private static Pkcs10Csr generateCsr(KeyPair keyPair, String commonName) { - return Pkcs10CsrBuilder.fromKeypair(new X500Principal("CN=" + commonName), keyPair, SIGNER_ALGORITHM) - .build(); - } -} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/ConfigServerKeyStoreRefresherFactory.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/ConfigServerKeyStoreRefresherFactory.java deleted file mode 100644 index d7685e737f5..00000000000 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/ConfigServerKeyStoreRefresherFactory.java +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.node.admin.configserver.certificate; - -import com.yahoo.vespa.hosted.node.admin.configserver.ConfigServerApi; -import com.yahoo.vespa.hosted.node.admin.util.KeyStoreOptions; - -/** - * @author hakon - */ -@FunctionalInterface -public interface ConfigServerKeyStoreRefresherFactory { - ConfigServerKeyStoreRefresher create( - KeyStoreOptions keyStoreOptions, - Runnable keyStoreUpdatedCallback, - ConfigServerApi configServerApi, - String hostname); -} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/CsrSerializedPayload.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/CsrSerializedPayload.java deleted file mode 100644 index 34b190b546c..00000000000 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/CsrSerializedPayload.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.node.admin.configserver.certificate; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.yahoo.vespa.athenz.tls.Pkcs10Csr; -import com.yahoo.vespa.athenz.tls.Pkcs10CsrUtils; - -import java.io.IOException; - -/** - * Contains PEM formatted Certificate Signing Request (CSR) - * TODO: Combine with its counterpart in athenz-identity-provider-service? - * - * @author freva - */ -public class CsrSerializedPayload { - - @JsonProperty("csr") @JsonSerialize(using = CertificateRequestSerializer.class) - public final Pkcs10Csr csr; - - @JsonCreator - public CsrSerializedPayload(@JsonProperty("csr") Pkcs10Csr csr) { - this.csr = csr; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CsrSerializedPayload that = (CsrSerializedPayload) o; - - return csr.equals(that.csr); - } - - @Override - public int hashCode() { - return csr.hashCode(); - } - - @Override - public String toString() { - return "CsrSerializedPayload{" + - "csr='" + csr + '\'' + - '}'; - } - - public static class CertificateRequestSerializer extends JsonSerializer<Pkcs10Csr> { - @Override - public void serialize(Pkcs10Csr csr, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeString(Pkcs10CsrUtils.toPem(csr)); - } - } -} |