summaryrefslogtreecommitdiffstats
path: root/vespa-athenz
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@oath.com>2018-03-08 13:21:06 +0100
committerBjørn Christian Seime <bjorncs@oath.com>2018-03-08 13:59:55 +0100
commita6e47d2fb7162a9337db562bc7d41490823fa640 (patch)
tree1dbff8f539616b533c1010b40e98a83fe1ac871c /vespa-athenz
parent1f6f506795c4f05364327ca6a8d1c370ccbbd1e7 (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.java54
-rw-r--r--vespa-athenz/src/test/java/com/yahoo/vespa/athenz/tls/AthenzSslContextBuilderTest.java55
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;