Skip to content

Commit 4975873

Browse files
committed
Builder now inits SSL context when protocol and trust manager exist
Ran into this while testing, where I was providing both a protocol and a "trust all" trust manager, but the builder failed to create a client. In this scenario, the builder is able to initialize the SSLContext itself since it has a trust manager from the user, so it now does so.
1 parent ad80b6b commit 4975873

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

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

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import javax.net.ssl.SSLContext;
2323
import javax.net.ssl.X509TrustManager;
24+
import java.security.KeyManagementException;
2425
import java.security.NoSuchAlgorithmException;
2526
import java.util.LinkedHashMap;
2627
import java.util.Map;
@@ -109,10 +110,12 @@ private DatabaseClientFactory.SecurityContext newSecurityContext() {
109110
}
110111
securityContext = newSecurityContext(type);
111112

112-
SSLContext sslContext = determineSSLContext();
113+
X509TrustManager trustManager = determineTrustManager();
114+
SSLContext sslContext = determineSSLContext(trustManager);
113115
if (sslContext != null) {
114-
securityContext.withSSLContext(sslContext, determineTrustManager());
116+
securityContext.withSSLContext(sslContext, trustManager);
115117
}
118+
116119
securityContext.withSSLHostnameVerifier(determineHostnameVerifier());
117120
return securityContext;
118121
}
@@ -180,10 +183,10 @@ private DatabaseClientFactory.SecurityContext newSAMLAuthContext() {
180183
);
181184
}
182185

183-
private SSLContext determineSSLContext() {
184-
Object sslContext = propertySource.apply(PREFIX + "sslContext");
185-
if (sslContext instanceof SSLContext) {
186-
return (SSLContext) sslContext;
186+
private SSLContext determineSSLContext(X509TrustManager trustManager) {
187+
SSLContext sslContext = (SSLContext) propertySource.apply(PREFIX + "sslContext");
188+
if (sslContext != null) {
189+
return sslContext;
187190
}
188191
String protocol = (String) propertySource.apply(PREFIX + "sslProtocol");
189192
if (protocol != null) {
@@ -195,13 +198,21 @@ private SSLContext determineSSLContext() {
195198
}
196199
}
197200
try {
198-
// Note that if only a protocol is specified, and not a TrustManager, an attempt will later be made
199-
// to use the JVM's default TrustManager
200-
return SSLContext.getInstance(protocol);
201+
sslContext = SSLContext.getInstance(protocol);
201202
} catch (NoSuchAlgorithmException e) {
202203
throw new RuntimeException("Unable to get SSLContext instance with protocol: " + protocol
203204
+ "; cause: " + e.getMessage(), e);
204205
}
206+
// Note that if only a protocol is specified, and not a TrustManager, an attempt will later be made
207+
// to use the JVM's default TrustManager
208+
if (trustManager != null) {
209+
try {
210+
sslContext.init(null, new X509TrustManager[]{trustManager}, null);
211+
} catch (KeyManagementException e) {
212+
throw new RuntimeException("Unable to initialize SSLContext; protocol: " + protocol + "; cause: " + e.getMessage(), e);
213+
}
214+
}
215+
return sslContext;
205216
}
206217
return null;
207218
}

marklogic-client-api/src/test/java/com/marklogic/client/test/DatabaseClientBuilderTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ void sslProtocol() {
167167
assertNotNull(bean.getSecurityContext().getSSLContext());
168168
assertNull(bean.getSecurityContext().getTrustManager());
169169
assertNull(bean.getSecurityContext().getSSLHostnameVerifier());
170+
171+
assertThrows(IllegalStateException.class, () -> bean.getSecurityContext().getSSLContext().getSocketFactory(),
172+
"If an SSL protocol is provided with no trust manager, the builder is expected to create an instance of " +
173+
"SSLContext but not to initialize it. Later on - via OkHttpUtil - the Java Client will attempt to " +
174+
"initialize the SSLContext before using it by using the JVM's default trust manager.");
170175
}
171176

172177
@Test
@@ -190,6 +195,12 @@ void sslProtocolAndTrustManager() {
190195
assertNotNull(bean.getSecurityContext().getTrustManager());
191196
assertEquals(Common.TRUST_ALL_MANAGER, bean.getSecurityContext().getTrustManager());
192197
assertNull(bean.getSecurityContext().getSSLHostnameVerifier());
198+
199+
assertNotNull(bean.getSecurityContext().getSSLContext().getSocketFactory(),
200+
"Since a protocol was provided with a trust manager, the builder is expected to initialize the " +
201+
"SSLContext created via the protocol using the given trust manager. This is primarily intended to " +
202+
"support a use case of providing a custom trust manager (often a 'trust all' one in a development or " +
203+
"test environment) without forcing the user to initialize an SSLContext themselves.");
193204
}
194205

195206
@Test

0 commit comments

Comments
 (0)