Skip to content

Commit 9e47be9

Browse files
committed
Added test for certificate auth with file and password
This catches the bug that I thought might have existed previous to the prior PR - it ensures that a user-defined TrustManager is used when an SSLContext is created based on a user-defined path for a PKCS12 file.
1 parent f849cf4 commit 9e47be9

File tree

2 files changed

+52
-14
lines changed

2 files changed

+52
-14
lines changed

marklogic-client-api/src/main/java/com/marklogic/client/impl/DatabaseClientPropertySource.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,9 @@ private SSLInputs buildSSLInputs(String authType) {
290290
useNewSSLContext(sslProtocol, userTrustManager);
291291
}
292292

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

297298
private X509TrustManager getTrustManager() {

marklogic-client-api/src/test/java/com/marklogic/client/test/ssl/TwoWaySSLTest.java

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
public class TwoWaySSLTest {
4545

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

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

5658

5759
@BeforeAll
@@ -77,6 +79,7 @@ public static void setup() throws Exception {
7779
createPkcs12File(tempDir);
7880
createKeystoreFile(tempDir);
7981
keyStoreFile = new File(tempDir.toFile(), "client.jks");
82+
p12File = new File(tempDir.toFile(), "client.p12");
8083
}
8184

8285
@AfterAll
@@ -126,16 +129,17 @@ void digestAuthentication() throws Exception {
126129
"Unexpected exception: " + userException.getMessage());
127130
}
128131

132+
/**
133+
* Verifies certificate authentication when a user provides their own SSLContext.
134+
*/
129135
@Test
130-
void certificateAuthentication() throws Exception {
136+
void certificateAuthenticationWithSSLContext() throws Exception {
131137
if (Common.USE_REVERSE_PROXY_SERVER) {
132138
return;
133139
}
134140

141+
setAuthenticationToCertificate();
135142
try {
136-
new ServerManager(manageClient)
137-
.save(Common.newServerPayload().put("authentication", "certificate").toString());
138-
139143
SSLContext sslContext = createSSLContextWithClientCertificate(keyStoreFile);
140144
DatabaseClient client = Common.newClientBuilder()
141145
.withCertificateAuth(sslContext, RequireSSLExtension.newTrustManager())
@@ -144,11 +148,44 @@ void certificateAuthentication() throws Exception {
144148

145149
verifyTestDocumentCanBeRead(client);
146150
} finally {
147-
new ServerManager(manageClient)
148-
.save(Common.newServerPayload().put("authentication", "digestbasic").toString());
151+
setAuthenticationToDigestbasic();
152+
}
153+
}
154+
155+
/**
156+
* Verifies certificate authentication when a user provides a file and password, which must point to a PKC12
157+
* keystore.
158+
*/
159+
@Test
160+
void certificateAuthenticationWithCertificateFileAndPassword() {
161+
if (Common.USE_REVERSE_PROXY_SERVER) {
162+
return;
163+
}
164+
165+
setAuthenticationToCertificate();
166+
try {
167+
DatabaseClient client = Common.newClientBuilder()
168+
.withCertificateAuth(p12File.getAbsolutePath(), KEYSTORE_PASSWORD)
169+
.withTrustManager(RequireSSLExtension.newTrustManager())
170+
.withSSLHostnameVerifier(DatabaseClientFactory.SSLHostnameVerifier.ANY)
171+
.build();
172+
173+
verifyTestDocumentCanBeRead(client);
174+
} finally {
175+
setAuthenticationToDigestbasic();
149176
}
150177
}
151178

179+
private void setAuthenticationToCertificate() {
180+
new ServerManager(manageClient)
181+
.save(Common.newServerPayload().put("authentication", "certificate").toString());
182+
}
183+
184+
private void setAuthenticationToDigestbasic() {
185+
new ServerManager(manageClient)
186+
.save(Common.newServerPayload().put("authentication", "digestbasic").toString());
187+
}
188+
152189
private void verifyTestDocumentCanBeRead(DatabaseClient client) {
153190
DocumentDescriptor descriptor = client.newJSONDocumentManager().exists(TEST_DOCUMENT_URI);
154191
assertNotNull(descriptor);
@@ -157,9 +194,9 @@ private void verifyTestDocumentCanBeRead(DatabaseClient client) {
157194

158195
private SSLContext createSSLContextWithClientCertificate(File keystoreFile) throws Exception {
159196
KeyStore keyStore = KeyStore.getInstance("JKS");
160-
keyStore.load(new FileInputStream(keystoreFile), "password".toCharArray());
197+
keyStore.load(new FileInputStream(keystoreFile), KEYSTORE_PASSWORD.toCharArray());
161198
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
162-
keyManagerFactory.init(keyStore, "password".toCharArray());
199+
keyManagerFactory.init(keyStore, KEYSTORE_PASSWORD.toCharArray());
163200
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
164201
sslContext.init(
165202
keyManagerFactory.getKeyManagers(),
@@ -316,7 +353,7 @@ private static void createPkcs12File(Path tempDir) throws Exception {
316353
"-in", "cert.pem", "-inkey", "client.key",
317354
"-out", "client.p12",
318355
"-name", "my-client",
319-
"-passout", "pass:password");
356+
"-passout", "pass:" + KEYSTORE_PASSWORD);
320357

321358
ExecutorService executorService = Executors.newSingleThreadExecutor();
322359
Process process = builder.start();
@@ -330,12 +367,12 @@ private static void createKeystoreFile(Path tempDir) throws Exception {
330367
ProcessBuilder builder = new ProcessBuilder();
331368
builder.directory(tempDir.toFile());
332369
builder.command("keytool", "-importkeystore",
333-
"-deststorepass", "password",
334-
"-destkeypass", "password",
370+
"-deststorepass", KEYSTORE_PASSWORD,
371+
"-destkeypass", KEYSTORE_PASSWORD,
335372
"-destkeystore", "client.jks",
336373
"-srckeystore", "client.p12",
337374
"-srcstoretype", "PKCS12",
338-
"-srcstorepass", "password",
375+
"-srcstorepass", KEYSTORE_PASSWORD,
339376
"-alias", "my-client");
340377

341378
Process process = builder.start();

0 commit comments

Comments
 (0)