Close

Connecting to MongoDB using SSL, but without locally installed server SSL certificate

The problem:

MongoClientOptions options=MongoClientOptions.builder().sslEnabled(true).sslInvalidHostNameAllowed(true).build();
MongoClient mongoClient = new MongoClient("servermongodb.server.tralala:27017",options);
... = mongoClient.getDatabase("lot_of_data_here");

… does this…

INFO: Exception in monitor thread while connecting to servermongodb.server.tralala:27017
com.mongodb.MongoSocketWriteException: Exception sending message
	at com.mongodb.connection.InternalStreamConnection.translateWriteException(InternalStreamConnection.java:462)
	at com.mongodb.connection.InternalStreamConnection.sendMessage(InternalStreamConnection.java:205)
	at com.mongodb.connection.CommandHelper.sendMessage(CommandHelper.java:89)
	at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32)
	at com.mongodb.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:83)
	at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:43)
	at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
	at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:128)
	at java.lang.Thread.run(Thread.java:745)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
	at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
	at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747)
	at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
	at com.mongodb.connection.SocketStream.write(SocketStream.java:75)
	at com.mongodb.connection.InternalStreamConnection.sendMessage(InternalStreamConnection.java:201)
	... 7 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
	at sun.security.validator.Validator.validate(Validator.java:260)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
	... 16 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
	... 22 more

.

If you do not need serious SSL server authentication and use SSL “only” for transfer encryption because you have learned that “Trusted Networks (TM)” do not exist, then you will find this helpful to avoid hacking JVM certificate chains and key bundles. Note that you should use this only if you know what you are doing here, as usual when playing with security things… :)

TrustManager[] trustManagers=new TrustManager[] {
    new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() { return null; }
        public void checkClientTrusted(X509Certificate[] certs, String t) { }
        public void checkServerTrusted(X509Certificate[] certs, String t) { }
    }
};

SSLContext sslContext=SSLContext.getInstance("TLS");
sslContext.init(null,trustManagers,new SecureRandom());

// Note: the order is of importance as "sslEnabled()" (wrongly) sets the 
// socket factory to default
MongoClientOptions options=MongoClientOptions.builder().
                sslEnabled(true).
                sslInvalidHostNameAllowed(true).
                socketFactory(sslContext.getSocketFactory()).
                build();

MongoClient mongoClient = new MongoClient(uri,options);
... = mongoClient.getDatabase("i_see_documents");

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close