Skip to content

Added test for certificate auth with file and password #1608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,9 @@ private SSLInputs buildSSLInputs(String authType) {
useNewSSLContext(sslProtocol, userTrustManager);
}

// Approach 4 - no SSL connection is needed.
return new SSLInputs(null, null);
// Approach 4 - still return the user-defined TrustManager as that may be needed for certificate authentication,
// which has its own way of constructing an SSLContext from a PKCS12 file.
return new SSLInputs(null, userTrustManager);
}

private X509TrustManager getTrustManager() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
public class TwoWaySSLTest {

private final static String TEST_DOCUMENT_URI = "/optic/test/musician1.json";
private final static String KEYSTORE_PASSWORD = "password";

// Used for creating a temporary JKS (Java KeyStore) file.
@TempDir
Expand All @@ -52,6 +53,7 @@ public class TwoWaySSLTest {
private static DatabaseClient securityClient;
private static ManageClient manageClient;
private static File keyStoreFile;
private static File p12File;


@BeforeAll
Expand All @@ -77,6 +79,7 @@ public static void setup() throws Exception {
createPkcs12File(tempDir);
createKeystoreFile(tempDir);
keyStoreFile = new File(tempDir.toFile(), "client.jks");
p12File = new File(tempDir.toFile(), "client.p12");
}

@AfterAll
Expand Down Expand Up @@ -126,16 +129,17 @@ void digestAuthentication() throws Exception {
"Unexpected exception: " + userException.getMessage());
}

/**
* Verifies certificate authentication when a user provides their own SSLContext.
*/
@Test
void certificateAuthentication() throws Exception {
void certificateAuthenticationWithSSLContext() throws Exception {
if (Common.USE_REVERSE_PROXY_SERVER) {
return;
}

setAuthenticationToCertificate();
try {
new ServerManager(manageClient)
.save(Common.newServerPayload().put("authentication", "certificate").toString());

SSLContext sslContext = createSSLContextWithClientCertificate(keyStoreFile);
DatabaseClient client = Common.newClientBuilder()
.withCertificateAuth(sslContext, RequireSSLExtension.newTrustManager())
Expand All @@ -144,11 +148,44 @@ void certificateAuthentication() throws Exception {

verifyTestDocumentCanBeRead(client);
} finally {
new ServerManager(manageClient)
.save(Common.newServerPayload().put("authentication", "digestbasic").toString());
setAuthenticationToDigestbasic();
}
}

/**
* Verifies certificate authentication when a user provides a file and password, which must point to a PKC12
* keystore.
*/
@Test
void certificateAuthenticationWithCertificateFileAndPassword() {
if (Common.USE_REVERSE_PROXY_SERVER) {
return;
}

setAuthenticationToCertificate();
try {
DatabaseClient client = Common.newClientBuilder()
.withCertificateAuth(p12File.getAbsolutePath(), KEYSTORE_PASSWORD)
.withTrustManager(RequireSSLExtension.newTrustManager())
.withSSLHostnameVerifier(DatabaseClientFactory.SSLHostnameVerifier.ANY)
.build();

verifyTestDocumentCanBeRead(client);
} finally {
setAuthenticationToDigestbasic();
}
}

private void setAuthenticationToCertificate() {
new ServerManager(manageClient)
.save(Common.newServerPayload().put("authentication", "certificate").toString());
}

private void setAuthenticationToDigestbasic() {
new ServerManager(manageClient)
.save(Common.newServerPayload().put("authentication", "digestbasic").toString());
}

private void verifyTestDocumentCanBeRead(DatabaseClient client) {
DocumentDescriptor descriptor = client.newJSONDocumentManager().exists(TEST_DOCUMENT_URI);
assertNotNull(descriptor);
Expand All @@ -157,9 +194,9 @@ private void verifyTestDocumentCanBeRead(DatabaseClient client) {

private SSLContext createSSLContextWithClientCertificate(File keystoreFile) throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(keystoreFile), "password".toCharArray());
keyStore.load(new FileInputStream(keystoreFile), KEYSTORE_PASSWORD.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, "password".toCharArray());
keyManagerFactory.init(keyStore, KEYSTORE_PASSWORD.toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(
keyManagerFactory.getKeyManagers(),
Expand Down Expand Up @@ -316,7 +353,7 @@ private static void createPkcs12File(Path tempDir) throws Exception {
"-in", "cert.pem", "-inkey", "client.key",
"-out", "client.p12",
"-name", "my-client",
"-passout", "pass:password");
"-passout", "pass:" + KEYSTORE_PASSWORD);

ExecutorService executorService = Executors.newSingleThreadExecutor();
Process process = builder.start();
Expand All @@ -330,12 +367,12 @@ private static void createKeystoreFile(Path tempDir) throws Exception {
ProcessBuilder builder = new ProcessBuilder();
builder.directory(tempDir.toFile());
builder.command("keytool", "-importkeystore",
"-deststorepass", "password",
"-destkeypass", "password",
"-deststorepass", KEYSTORE_PASSWORD,
"-destkeypass", KEYSTORE_PASSWORD,
"-destkeystore", "client.jks",
"-srckeystore", "client.p12",
"-srcstoretype", "PKCS12",
"-srcstorepass", "password",
"-srcstorepass", KEYSTORE_PASSWORD,
"-alias", "my-client");

Process process = builder.start();
Expand Down