MLE-30239 Use secure trust store#1945
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the MarkLogic Java Client SSL examples/tests to avoid “trust-all” trust managers and instead rely on certificate validation via a configured truststore (or the JVM default trust managers where applicable).
Changes:
- Replaces a trust-all
TrustManagerin the SSL cookbook example with a truststore-backedTrustManagerFactoryapproach and switches to STRICT hostname verification. - Updates functional test SSLContext creation to use a truststore (classpath resource) when configured, falling back to JVM default trust managers otherwise.
- Adds/updates properties and a new test asserting handshake failure when the server CA is not trusted.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| marklogic-client-api/src/test/java/com/marklogic/client/test/ssl/OneWaySSLTest.java | Adds a test validating TLS handshake fails when using default JVM trust managers that don’t trust the test CA. |
| marklogic-client-api-functionaltests/src/test/resources/test.properties | Documents optional truststore properties for SSL-enabled functional test runs. |
| marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/functionaltest/ConnectedRESTQA.java | Replaces trust-all trust manager with truststore/JVM-default trust managers for SSLContext initialization. |
| examples/src/main/resources/Example.properties | Documents truststore configuration for the SSL cookbook example. |
| examples/src/main/java/com/marklogic/client/example/cookbook/Util.java | Adds truststore fields to example configuration parsing. |
| examples/src/main/java/com/marklogic/client/example/cookbook/SSLClientCreator.java | Loads truststore and uses a real trust manager + STRICT hostname verification for the SSL example. |
| */ | ||
| public class SSLClientCreator { | ||
| public static void main(String[] args) throws IOException, KeyManagementException, NoSuchAlgorithmException { | ||
| public static void main(String[] args) throws IOException, KeyManagementException, NoSuchAlgorithmException, |
There was a problem hiding this comment.
I think this should instead use the support in DatabaseClientFactory to configure trusted SSL via properties so that the user doesn't have to deal with all this boilerplate. Check out the public static DatabaseClient newClient(Function<String, Object> propertySource) { method. It handles all of this plumbing.
| // When ml_truststore_file is configured, a TrustManagerFactory is initialised | ||
| // from that truststore (which must contain the MarkLogic server's CA certificate). | ||
| // Otherwise the JVM's default trust managers are used as a safe fallback. | ||
| final TrustManager[] trustManagers; |
There was a problem hiding this comment.
Same thing here - try reworking this to use the support in DatabaseClientFactory for doing all of this for the user.
b9b5310 to
c0d2511
Compare
| // server certificate | ||
| // CN/SANs are checked against the connected host. | ||
| try (DatabaseClient client = DatabaseClientFactory.newClient(propertyName -> switch (propertyName) { | ||
| case "marklogic.client.host" -> props.host; |
There was a problem hiding this comment.
This works, but I would just update the example properties file to use these "marklogic.client." properties instead so that no translation is needed.
|
Got one failed test OneWaySSLTest > tLS12ClientWithTLS13ServerShouldFail() FAILED Copilot root cause analysis: newer JDKs prefix the SSLHandshakeException message with the alert type in parentheses — (protocol_version) Received fatal alert: protocol_version — while older JDKs emit just Received fatal alert: protocol_version. The hardcoded assertEquals against the old format fails on your JDK 17+ |
|
Got an error when I enabled the trust store (still keep restSSLset=false) and created a self-signed java-client-api\marklogic-client-api-functionaltests\src\test\resources\truststore.jks ml_truststore_file=/truststore.jks ./gradlew :marklogic-client-api-functionaltests:test --tests "com.marklogic.client.fastfunctest.TestDatabaseClientConnection.testDatabaseClientGetters" TestDatabaseClientConnection > testDatabaseClientGetters() FAILED Copilot suggested to fix ConnectedRESTQA.java Line 811: |
0c879d0 to
01eedc7
Compare
|
@RitaChen609 I updated I wasn't able to reproduce the other failure for assertTrue(ex.getCause() instanceof SSLHandshakeException, |


Replace trust-all TrustManager in SSL cookbook example with a trust-store-based approach