diff options
Diffstat (limited to 'vespa-feed-client')
-rw-r--r-- | vespa-feed-client/src/main/java/ai/vespa/feed/client/SslContextBuilder.java | 39 | ||||
-rw-r--r-- | vespa-feed-client/src/test/java/ai/vespa/feed/client/SslContextBuilderTest.java | 24 |
2 files changed, 54 insertions, 9 deletions
diff --git a/vespa-feed-client/src/main/java/ai/vespa/feed/client/SslContextBuilder.java b/vespa-feed-client/src/main/java/ai/vespa/feed/client/SslContextBuilder.java index 9114e22f4a6..9c863c51111 100644 --- a/vespa-feed-client/src/main/java/ai/vespa/feed/client/SslContextBuilder.java +++ b/vespa-feed-client/src/main/java/ai/vespa/feed/client/SslContextBuilder.java @@ -11,8 +11,10 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; +import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import java.io.IOException; import java.nio.file.Files; @@ -29,6 +31,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Optional; /** * BouncyCastle integration for creating a {@link SSLContext} instance from PEM encoded material @@ -72,28 +75,46 @@ class SslContextBuilder { try { KeyStore keystore = KeyStore.getInstance("PKCS12"); keystore.load(null); - if (certificateFile != null && privateKeyFile != null) { + if (hasCertificateFile()) { keystore.setKeyEntry("cert", privateKey(privateKeyFile), new char[0], certificates(certificateFile)); - } else if (certificate != null && privateKey != null) { + } else if (hasCertificateInstance()) { keystore.setKeyEntry("cert", privateKey, new char[0], certificate.toArray(new Certificate[0])); } - if (caCertificatesFile != null) { + if (hasCaCertificateFile()) { addCaCertificates(keystore, Arrays.asList(certificates(caCertificatesFile))); - } else if (caCertificates != null) { + } else if (hasCaCertificateInstance()) { addCaCertificates(keystore, caCertificates); } - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(keystore, new char[0]); - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(keystore); SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + sslContext.init( + createKeyManagers(keystore).orElse(null), + createTrustManagers(keystore).orElse(null), + /*Default secure random algorithm*/null); return sslContext; } catch (GeneralSecurityException e) { throw new IOException(e); } } + private boolean hasCertificateFile() { return certificateFile != null && privateKeyFile != null; } + private boolean hasCertificateInstance() { return certificate != null && privateKey != null; } + private boolean hasCaCertificateFile() { return caCertificatesFile != null; } + private boolean hasCaCertificateInstance() { return caCertificates != null; } + + private Optional<KeyManager[]> createKeyManagers(KeyStore keystore) throws GeneralSecurityException { + if (!hasCertificateInstance() && !hasCertificateFile()) return Optional.empty(); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keystore, new char[0]); + return Optional.of(kmf.getKeyManagers()); + } + + private Optional<TrustManager[]> createTrustManagers(KeyStore keystore) throws GeneralSecurityException { + if (!hasCaCertificateInstance() && !hasCaCertificateFile()) return Optional.empty(); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keystore); + return Optional.of(tmf.getTrustManagers()); + } + private static void addCaCertificates(KeyStore keystore, Collection<? extends Certificate> certificates) throws KeyStoreException { int i = 0; for (Certificate cert : certificates) { diff --git a/vespa-feed-client/src/test/java/ai/vespa/feed/client/SslContextBuilderTest.java b/vespa-feed-client/src/test/java/ai/vespa/feed/client/SslContextBuilderTest.java index e930c602ec7..5d3923d086c 100644 --- a/vespa-feed-client/src/test/java/ai/vespa/feed/client/SslContextBuilderTest.java +++ b/vespa-feed-client/src/test/java/ai/vespa/feed/client/SslContextBuilderTest.java @@ -59,6 +59,30 @@ class SslContextBuilderTest { assertEquals("TLS", sslContext.getProtocol()); } + @Test + void successfully_constructs_sslcontext_when_no_builder_parameter_given() { + SSLContext sslContext = assertDoesNotThrow(() -> new SslContextBuilder().build()); + assertEquals("TLS", sslContext.getProtocol()); + } + + @Test + void successfully_constructs_sslcontext_with_only_certificate_file() { + SSLContext sslContext = assertDoesNotThrow(() -> + new SslContextBuilder() + .withCertificateAndKey(certificateFile, privateKeyFile) + .build()); + assertEquals("TLS", sslContext.getProtocol()); + } + + @Test + void successfully_constructs_sslcontext_with_only_ca_certificate_file() { + SSLContext sslContext = assertDoesNotThrow(() -> + new SslContextBuilder() + .withCaCertificates(certificateFile) + .build()); + assertEquals("TLS", sslContext.getProtocol()); + } + private static void writePem(Path file, String type, byte[] asn1DerEncodedObject) throws IOException { try (BufferedWriter fileWriter = Files.newBufferedWriter(file); JcaPEMWriter pemWriter = new JcaPEMWriter(fileWriter)) { |