summaryrefslogtreecommitdiffstats
path: root/athenz-identity-provider-service
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@oath.com>2017-12-04 15:59:06 +0100
committerBjørn Christian Seime <bjorncs@oath.com>2017-12-05 09:38:05 +0100
commit01e753dba200a870dfba495a252fc7b9854f8ec3 (patch)
treeea43c67c76d7b54b791577d4b5e057c4d14158cf /athenz-identity-provider-service
parent69c0128865dac863aba8d1d8ea511eec850e2ade (diff)
Add trust store configurator with config server's CA cert
Diffstat (limited to 'athenz-identity-provider-service')
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslTrustStoreConfigurator.java108
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/KeyProvider.java5
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/SecretStoreKeyProvider.java3
3 files changed, 115 insertions, 1 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslTrustStoreConfigurator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslTrustStoreConfigurator.java
new file mode 100644
index 00000000000..059c91aecd3
--- /dev/null
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslTrustStoreConfigurator.java
@@ -0,0 +1,108 @@
+// 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.athenz.instanceproviderservice;
+
+import com.google.inject.Inject;
+import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.jdisc.http.ssl.SslTrustStoreConfigurator;
+import com.yahoo.jdisc.http.ssl.SslTrustStoreContext;
+import com.yahoo.log.LogLevel;
+import com.yahoo.vespa.hosted.athenz.instanceproviderservice.config.AthenzProviderServiceConfig;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Date;
+import java.util.logging.Logger;
+
+/**
+ * @author bjorncs
+ */
+// TODO Add Athenz CA certificates to trust store
+public class AthenzSslTrustStoreConfigurator implements SslTrustStoreConfigurator {
+
+ private static final Logger log = Logger.getLogger(AthenzSslTrustStoreConfigurator.class.getName());
+
+ private static final Provider provider = new BouncyCastleProvider();
+ private final KeyStore trustStore;
+
+ @Inject
+ public AthenzSslTrustStoreConfigurator(KeyProvider keyProvider,
+ ConfigserverConfig configserverConfig,
+ AthenzProviderServiceConfig athenzProviderServiceConfig) {
+ this.trustStore = createTrustStore(keyProvider, configserverConfig, athenzProviderServiceConfig);
+ }
+
+ @Override
+ public void configure(SslTrustStoreContext sslTrustStoreContext) {
+ sslTrustStoreContext.updateTrustStore(trustStore);
+ log.log(LogLevel.INFO, "Configured JDisc trust store with self-signed certificate");
+ }
+
+ private static KeyStore createTrustStore(KeyProvider keyProvider,
+ ConfigserverConfig configserverConfig,
+ AthenzProviderServiceConfig athenzProviderServiceConfig) {
+ try {
+ KeyPair keyPair = getKeyPair(keyProvider, configserverConfig, athenzProviderServiceConfig);
+ X509Certificate selfSignedCertificate = createSelfSignedCertificate(keyPair, configserverConfig);
+ log.log(LogLevel.FINE, "Generated self-signed certificate: " + selfSignedCertificate);
+ KeyStore trustStore = KeyStore.getInstance("JKS");
+ trustStore.load(null);
+ trustStore.setCertificateEntry("cfgselfsigned", selfSignedCertificate);
+ return trustStore;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static KeyPair getKeyPair(KeyProvider keyProvider,
+ ConfigserverConfig configserverConfig,
+ AthenzProviderServiceConfig athenzProviderServiceConfig) {
+ String key = configserverConfig.environment() + "." + configserverConfig.region();
+ AthenzProviderServiceConfig.Zones zoneConfig = athenzProviderServiceConfig.zones(key);
+ return keyProvider.getKeyPair(zoneConfig.secretVersion());
+ }
+
+ private static X509Certificate createSelfSignedCertificate(KeyPair keyPair, ConfigserverConfig config)
+ throws IOException, CertificateException, OperatorCreationException {
+ ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(keyPair.getPrivate());
+ X500Name x500Name = new X500Name("CN="+ config.loadBalancerAddress());
+ Instant now = Instant.now();
+ Date notBefore = Date.from(now);
+ Date notAfter = Date.from(now.plus(Duration.ofDays(30)));
+
+ GeneralNames generalNames = new GeneralNames(
+ config.zookeeperserver().stream()
+ .map(server -> new GeneralName(GeneralName.dNSName, server.hostname()))
+ .toArray(GeneralName[]::new));
+
+ X509v3CertificateBuilder certificateBuilder =
+ new JcaX509v3CertificateBuilder(
+ x500Name, BigInteger.valueOf(now.toEpochMilli()), notBefore, notAfter, x500Name, keyPair.getPublic()
+ )
+ .addExtension(Extension.basicConstraints, true, new BasicConstraints(true))
+ .addExtension(Extension.subjectAlternativeName, false, generalNames);
+
+ return new JcaX509CertificateConverter()
+ .setProvider(provider)
+ .getCertificate(certificateBuilder.build(contentSigner));
+ }
+
+}
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/KeyProvider.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/KeyProvider.java
index a72a2fcbc6c..1d141099428 100644
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/KeyProvider.java
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/KeyProvider.java
@@ -1,6 +1,7 @@
// 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.athenz.instanceproviderservice;
+import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -11,4 +12,8 @@ public interface KeyProvider {
PrivateKey getPrivateKey(int version);
PublicKey getPublicKey(int version);
+
+ default KeyPair getKeyPair(int version) {
+ return new KeyPair(getPublicKey(version), getPrivateKey(version));
+ }
}
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/SecretStoreKeyProvider.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/SecretStoreKeyProvider.java
index e66131b6cf7..ac8c0eabf31 100644
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/SecretStoreKeyProvider.java
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/SecretStoreKeyProvider.java
@@ -45,7 +45,8 @@ public class SecretStoreKeyProvider implements KeyProvider {
return getKeyPair(version).getPublic();
}
- private KeyPair getKeyPair(int version) {
+ @Override
+ public KeyPair getKeyPair(int version) {
synchronized (secrets) {
KeyPair keyPair = secrets.get(version);
if (keyPair == null) {