diff options
author | Bjørn Christian Seime <bjorncs@oath.com> | 2018-03-08 13:21:06 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@oath.com> | 2018-03-08 13:59:55 +0100 |
commit | a6e47d2fb7162a9337db562bc7d41490823fa640 (patch) | |
tree | 1dbff8f539616b533c1010b40e98a83fe1ac871c /vespa-athenz | |
parent | 1f6f506795c4f05364327ca6a8d1c370ccbbd1e7 (diff) |
Use BouncyCastle to read PKCS12 keystores
Introduce enum for the supported keystore types
Diffstat (limited to 'vespa-athenz')
-rw-r--r-- | vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilder.java | 54 | ||||
-rw-r--r-- | vespa-athenz/src/test/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilderTest.java | 55 |
2 files changed, 90 insertions, 19 deletions
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilder.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilder.java index 0c350356986..fdf58f9e64b 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilder.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilder.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.athenz.tls; import com.yahoo.vespa.athenz.api.AthenzIdentityCertificate; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; @@ -14,20 +15,39 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.security.GeneralSecurityException; import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.PrivateKey; import java.security.cert.Certificate; +import java.security.cert.X509Certificate; /** * @author bjorncs */ public class AthenzSslContextBuilder { + public enum KeyStoreType { + JKS { + KeyStore createKeystore() throws KeyStoreException { + return KeyStore.getInstance("JKS"); + } + }, + PKCS12 { + private final BouncyCastleProvider bouncyCastleProvider = new BouncyCastleProvider(); + + KeyStore createKeystore() throws KeyStoreException { + return KeyStore.getInstance("PKCS12", bouncyCastleProvider); + } + }; + abstract KeyStore createKeystore() throws GeneralSecurityException; + } + private KeyStoreSupplier trustStoreSupplier; private KeyStoreSupplier keyStoreSupplier; private char[] keyStorePassword; public AthenzSslContextBuilder() {} - public AthenzSslContextBuilder withTrustStore(File file, String trustStoreType) { + public AthenzSslContextBuilder withTrustStore(File file, KeyStoreType trustStoreType) { this.trustStoreSupplier = () -> loadKeyStoreFromFile(file, null, trustStoreType); return this; } @@ -38,14 +58,12 @@ public class AthenzSslContextBuilder { } public AthenzSslContextBuilder withIdentityCertificate(AthenzIdentityCertificate certificate) { + return withKeyStore(certificate.getPrivateKey(), certificate.getCertificate()); + } + + public AthenzSslContextBuilder withKeyStore(PrivateKey privateKey, X509Certificate certificate) { char[] pwd = new char[0]; - this.keyStoreSupplier = () -> { - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(null); - keyStore.setKeyEntry( - "athenz-identity", certificate.getPrivateKey(), pwd, new Certificate[]{certificate.getCertificate()}); - return keyStore; - }; + this.keyStoreSupplier = () -> createJksKeyStore(privateKey, certificate, pwd); this.keyStorePassword = pwd; return this; } @@ -56,7 +74,7 @@ public class AthenzSslContextBuilder { return this; } - public AthenzSslContextBuilder withKeyStore(File file, char[] password, String keyStoreType) { + public AthenzSslContextBuilder withKeyStore(File file, char[] password, KeyStoreType keyStoreType) { this.keyStoreSupplier = () -> loadKeyStoreFromFile(file, password, keyStoreType); this.keyStorePassword = password; return this; @@ -80,27 +98,37 @@ public class AthenzSslContextBuilder { private static TrustManager[] createTrustManagers(KeyStoreSupplier trustStoreSupplier) throws GeneralSecurityException, IOException { - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + TrustManagerFactory trustManagerFactory = + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trustStoreSupplier.get()); return trustManagerFactory.getTrustManagers(); } private static KeyManager[] createKeyManagers(KeyStoreSupplier keyStoreSupplier, char[] password) throws GeneralSecurityException, IOException { - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + KeyManagerFactory keyManagerFactory = + KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStoreSupplier.get(), password); return keyManagerFactory.getKeyManagers(); } - private static KeyStore loadKeyStoreFromFile(File file, char[] password, String keyStoreType) + private static KeyStore loadKeyStoreFromFile(File file, char[] password, KeyStoreType keyStoreType) throws IOException, GeneralSecurityException{ - KeyStore keyStore = KeyStore.getInstance(keyStoreType); + KeyStore keyStore = keyStoreType.createKeystore(); try (FileInputStream in = new FileInputStream(file)) { keyStore.load(in, password); } return keyStore; } + private KeyStore createJksKeyStore(PrivateKey privateKey, X509Certificate certificate, char[] password) + throws GeneralSecurityException, IOException{ + KeyStore keyStore = KeyStoreType.JKS.createKeystore(); + keyStore.load(null); + keyStore.setKeyEntry("athenz-identity", privateKey, password, new Certificate[]{certificate}); + return keyStore; + } + private interface KeyStoreSupplier { KeyStore get() throws IOException, GeneralSecurityException; } diff --git a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilderTest.java b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilderTest.java index 5aca1fc3116..38f3b12b16b 100644 --- a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilderTest.java +++ b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilderTest.java @@ -2,12 +2,19 @@ package com.yahoo.vespa.athenz.tls; import com.yahoo.athenz.auth.util.Crypto; +import com.yahoo.vespa.athenz.tls.AthenzSslContextBuilder.KeyStoreType; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; @@ -22,31 +29,67 @@ public class AthenzSslContextBuilderTest { private static final char[] PASSWORD = new char[0]; + @Rule + public TemporaryFolder tempDirectory = new TemporaryFolder(); + @Test public void can_build_sslcontext_with_truststore_only() throws Exception { new AthenzSslContextBuilder() - .withTrustStore(createKeystore()) + .withTrustStore(createKeystore("JKS")) .build(); } @Test public void can_build_sslcontext_with_keystore_only() throws Exception { new AthenzSslContextBuilder() - .withKeyStore(createKeystore(), PASSWORD) + .withKeyStore(createKeystore("JKS"), PASSWORD) .build(); } @Test public void can_build_sslcontext_with_truststore_and_keystore() throws Exception { new AthenzSslContextBuilder() - .withKeyStore(createKeystore(), PASSWORD) - .withTrustStore(createKeystore()) + .withKeyStore(createKeystore("JKS"), PASSWORD) + .withTrustStore(createKeystore("JKS")) + .build(); + } + + @Test + public void can_build_sslcontext_with_keystore_from_private_key_and_certificate() throws Exception { + KeyPair keyPair = createKeyPair(); + X509Certificate certificate = createCertificate(keyPair); + new AthenzSslContextBuilder() + .withKeyStore(keyPair.getPrivate(), certificate) + .build(); + } + + @Test + public void can_build_sslcontext_with_jks_keystore_from_file() throws Exception { + KeyStore keystore = createKeystore("JKS"); + File keystoreFile = tempDirectory.newFile(); + try (OutputStream out = new BufferedOutputStream(new FileOutputStream(keystoreFile))) { + keystore.store(out, PASSWORD); + } + new AthenzSslContextBuilder() + .withKeyStore(keystoreFile, PASSWORD, KeyStoreType.JKS) + .build(); + } + + @Test + public void can_build_sslcontext_with_pcks12_keystore_from_file() throws Exception { + KeyStore keystore = createKeystore("PKCS12"); + File keystoreFile = tempDirectory.newFile(); + try (OutputStream out = new BufferedOutputStream(new FileOutputStream(keystoreFile))) { + keystore.store(out, PASSWORD); + } + new AthenzSslContextBuilder() + .withKeyStore(keystoreFile, PASSWORD, KeyStoreType.PKCS12) .build(); } - private static KeyStore createKeystore() throws Exception { + private static KeyStore createKeystore(String type) throws Exception { KeyPair keyPair = createKeyPair(); - KeyStore keystore = KeyStore.getInstance("JKS"); + KeyStore keystore = KeyStore.getInstance(type); keystore.load(null); keystore.setKeyEntry("entry-name", keyPair.getPrivate(), PASSWORD, new Certificate[]{createCertificate(keyPair)}); return keystore; |