Skip to content

Commit

Permalink
Add support for creating SSLContext for trustStore file path (#4264)
Browse files Browse the repository at this point in the history
* Add support for creating SSLContext for trustStore file path

Signed-off-by: Dinu John <86094133+dinujoh@users.noreply.github.com>

* Add support for creating SSLContext for trustStore file path

Signed-off-by: Dinu John <86094133+dinujoh@users.noreply.github.com>

---------

Signed-off-by: Dinu John <86094133+dinujoh@users.noreply.github.com>
  • Loading branch information
dinujoh authored Mar 11, 2024
1 parent bb99be7 commit 20b0dd9
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 22 deletions.
1 change: 1 addition & 0 deletions data-prepper-plugins/http-common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
dependencies {
implementation 'org.apache.httpcomponents:httpcore:4.4.16'
testImplementation testLibs.bundles.junit
testImplementation testLibs.mockito.inline
}

jacocoTestCoverageVerification {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

package org.opensearch.dataprepper.plugins.truststore;

import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.slf4j.Logger;
Expand Down Expand Up @@ -63,6 +62,12 @@ private static KeyStore createKeyStore(final Path certificatePath) throws Except
}
}

private static KeyStore createKeyStore(final InputStream trustStoreInputStream, final String password) throws Exception {
final KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(trustStoreInputStream, password.toCharArray());
return trustStore;
}

private static KeyStore createKeyStore(final InputStream certificateInputStream) throws Exception {
final CertificateFactory factory = CertificateFactory.getInstance("X.509");
final Certificate trustedCa = factory.generateCertificate(certificateInputStream);
Expand All @@ -81,6 +86,15 @@ public static SSLContext createSSLContext(final Path certificatePath) {
}
}

public static SSLContext createSSLContext(final Path trustStorePath, final String password) {
LOG.info("Using the truststore path and password to create SSL context.");
try (InputStream is = Files.newInputStream(trustStorePath)) {
return createSSLContext(is, password);
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage(), ex);
}
}

public static SSLContext createSSLContext(final String certificateContent) {
LOG.info("Using the certificate content to create SSL context.");
try (InputStream certificateInputStream = new ByteArrayInputStream(certificateContent.getBytes())) {
Expand All @@ -91,10 +105,20 @@ public static SSLContext createSSLContext(final String certificateContent) {
}

private static SSLContext createSSLContext(final InputStream certificateInputStream) throws Exception {
KeyStore trustStore = createKeyStore(certificateInputStream);
SSLContextBuilder sslContextBuilder = SSLContexts.custom()
.loadTrustMaterial(trustStore, null);
return sslContextBuilder.build();
final KeyStore trustStore = createKeyStore(certificateInputStream);
return SSLContexts.custom()
.loadTrustMaterial(trustStore, null).build();
}

private static SSLContext createSSLContext(final InputStream certificateInputStream, final String password) throws Exception {
final KeyStore trustStore = createKeyStore(certificateInputStream, password);
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
// Create an SSLContext that uses the truststore
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
SSLContext.setDefault(sslContext);
return sslContext;
}

public static SSLContext createSSLContextWithTrustAllStrategy() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,62 +1,60 @@
package org.opensearch.dataprepper.plugins.truststore;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyStore;
import java.util.UUID;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;

@ExtendWith(MockitoExtension.class)
class TrustStoreProviderTest {

private TrustStoreProvider trustStoreProvider;

@BeforeEach
void setUp() {
trustStoreProvider = new TrustStoreProvider();
}

@Test
void createTrustManagerWithCertificatePath() {
final Path certFilePath = Path.of("data/certificate/test_cert.crt");
final TrustManager[] trustManagers = trustStoreProvider.createTrustManager(certFilePath);
final TrustManager[] trustManagers = TrustStoreProvider.createTrustManager(certFilePath);
assertThat(trustManagers, is(notNullValue()));
}

@Test
void createTrustManagerWithInvalidCertificatePath() {
final Path certFilePath = Path.of("data/certificate/cert_doesnt_exist.crt");
assertThrows(RuntimeException.class, () -> trustStoreProvider.createTrustManager(certFilePath));
assertThrows(RuntimeException.class, () -> TrustStoreProvider.createTrustManager(certFilePath));
}

@Test
void createTrustManagerWithCertificateContent() throws IOException {
final Path certFilePath = Path.of("data/certificate/test_cert.crt");
final String certificateContent = Files.readString(certFilePath);
final TrustManager[] trustManagers = trustStoreProvider.createTrustManager(certificateContent);
final TrustManager[] trustManagers = TrustStoreProvider.createTrustManager(certificateContent);
assertThat(trustManagers, is(notNullValue()));
}

@Test
void createTrustManagerWithInvalidCertificateContent() {
assertThrows(RuntimeException.class, () -> trustStoreProvider.createTrustManager("invalid certificate content"));
assertThrows(RuntimeException.class, () -> TrustStoreProvider.createTrustManager("invalid certificate content"));
}

@Test
void createTrustAllManager() {
final TrustManager[] trustManagers = trustStoreProvider.createTrustAllManager();
final TrustManager[] trustManagers = TrustStoreProvider.createTrustAllManager();
assertThat(trustManagers, is(notNullValue()));
assertThat(trustManagers, is(arrayWithSize(1)));
assertThat(trustManagers[0], is(instanceOf(X509TrustAllManager.class)));
Expand All @@ -65,21 +63,36 @@ void createTrustAllManager() {
@Test
void createSSLContextWithCertificatePath() {
final Path certFilePath = Path.of("data/certificate/test_cert.crt");
final SSLContext sslContext = trustStoreProvider.createSSLContext(certFilePath);
final SSLContext sslContext = TrustStoreProvider.createSSLContext(certFilePath);
assertThat(sslContext, is(notNullValue()));
}

@Test
void createSSLContextWithTrustStorePathAndPassword() throws Exception {
final Path certFilePath = Path.of("data/certificate/test_cert.crt");
final KeyStore trustStore = mock(KeyStore.class);
final TrustManagerFactory trustManagerFactory = mock(TrustManagerFactory.class);
try (MockedStatic<KeyStore> keyStoreMockedStatic = mockStatic(KeyStore.class);
MockedStatic<TrustManagerFactory> trustManagerFactoryMockedStatic = mockStatic(TrustManagerFactory.class)) {
keyStoreMockedStatic.when(() -> KeyStore.getInstance("JKS")).thenReturn(trustStore);
trustManagerFactoryMockedStatic.when(() ->
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())).thenReturn(trustManagerFactory);
final SSLContext sslContext = TrustStoreProvider.createSSLContext(certFilePath, UUID.randomUUID().toString());
assertThat(sslContext, is(notNullValue()));
}
}

@Test
void createSSLContextWithCertificateContent() throws IOException {
final Path certFilePath = Path.of("data/certificate/test_cert.crt");
final String certificateContent = Files.readString(certFilePath);
final SSLContext sslContext = trustStoreProvider.createSSLContext(certificateContent);
final SSLContext sslContext = TrustStoreProvider.createSSLContext(certificateContent);
assertThat(sslContext, is(notNullValue()));
}

@Test
void createSSLContextWithTrustAllStrategy() {
final SSLContext sslContext = trustStoreProvider.createSSLContextWithTrustAllStrategy();
final SSLContext sslContext = TrustStoreProvider.createSSLContextWithTrustAllStrategy();
assertThat(sslContext, is(notNullValue()));
}
}
1 change: 0 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,3 @@ include 'data-prepper-plugins:decompress-processor'
include 'data-prepper-plugins:split-event-processor'
include 'data-prepper-plugins:http-common'
include 'data-prepper-plugins:flatten-processor'

0 comments on commit 20b0dd9

Please sign in to comment.