title: Mongo SSL and the Java Driver
body: <p>I'm using Mongo built from source with SSL based on 2.6.5. I set up a 3 node replication set with SSL member communication between nodes. This all works! </p>
  
  <p>The config for the SSL looks like below:</p>
  
  <pre><code># SSL options
  sslMode = requireSSL
  sslPEMKeyFile = /etc/ssl/mongo/serverSSL1.pem
  sslCAFile = /etc/ssl/mongo/rootCA.pem
  clusterAuthMode = x509 
  sslClusterFile = /etc/ssl/mongo/serverInternal1.pem
  </code></pre>
  
  <p>I've set up a CA and used it to sign both the keyfile and cluster file. My understanding is that the <code>sslPEMKeyFile</code> is used to encrypt all traffic traveling over the wire and <code>sslClusterFile</code> is used to authenticate members of the cluster.</p>
  
  <p>As I say, so far, so good. </p>
  
  <p>My problem is with clients connecting using the Java driver. I'm using version 2.12.4 to connect and I'm close... but no cigar. I am generating a keystore on the fly with PEM keys from a database (the keystore generates nicely) and I'm then using that to try and connect to the MongoDB cluster.</p>
  
  <p>I'm using the below code to create the connection and issue a simple command:</p>
  
  <pre><code>try {
      certs c = new certs(s);
  
      MongoCredential credential = MongoCredential.createMongoX509Credential("emailAddress=administrator@local.com,CN=10.27.2.103,OU=Mongo Client,O=local.com,L=Nottingham,ST=Nottinghamshire,C=GB");
  
      //m = new MongoClient(seeds, new MongoClientOptions.Builder().socketFactory(CertificateManager.prepFactory()).build());
      m = new MongoClient(seeds, Arrays.asList(credential), new MongoClientOptions.Builder().socketFactory(c.getSSLSocketFactory()).build());
  
      m.setReadPreference(ReadPreference.primaryPreferred());
      m.setWriteConcern(WriteConcern.ACKNOWLEDGED);
  }
  catch (MongoException ex) {
      System.out.println("a");
  }
  </code></pre>
  
  <p>I have generated a PEM certificate and programmatically added it to the keystore (which is returned from <code>c.getSSLSocketFactory()</code>) in much the same way as I generated the original member certificates. </p>
  
  <pre><code>CERNAME=client
  openssl genrsa -out $CERNAME.key 4096
  openssl req -new -key $CERNAME.key -out $CERNAME.csr -subj "/C=GB/ST=Nottinghamshire/L=Nottingham/O=Local.com/OU=Mongo Clients/CN=10.27.2.103/emailAddress=administrator@local.com"
  openssl x509 -req -in $CERNAME.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out $CERNAME.crt -days 365
  cat $CERNAME.key $CERNAME.crt &gt; $CERNAME.pem
  openssl pkcs8 -topk8 -in $CERNAME.pem -inform pem -out $CERNAME-pk8.key  -outform pem -nocrypt
  cat $CERNAME-pk8.key $CERNAME.crt &gt; $CERNAME-pk8.pem
  </code></pre>
  
  <p>I've added the user to the cluster:</p>
  
  <pre><code>db.getSiblingDB("$external").auth(
    {
      mechanism: "MONGODB-X509",
      user: "emailAddress=administrator@local.com,CN=10.27.2.103,OU=Mongo Clients,O=Local.com,L=Nottingham,ST=Nottinghamshire,C=GB"
    }
  )
  </code></pre>
  
  <p>When I run the Java code and try to connect I get the following error from the client:</p>
  
  <pre><code>Exception in thread "main" com.mongodb.CommandFailureException: { "serverUsed" : "mongo1.local.com:22000" , "ok" : 0.0 , "errmsg" : "auth failed" , "code" : 18}
      at com.mongodb.CommandResult.getException(CommandResult.java:76)
      at com.mongodb.CommandResult.throwOnError(CommandResult.java:131)
      at com.mongodb.DBPort$X509Authenticator.authenticate(DBPort.java:624)
      at com.mongodb.DBPort.authenticate(DBPort.java:364)
      at com.mongodb.DBPort.checkAuth(DBPort.java:375)
      at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:291)
      at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:271)
      at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:84)
      at com.mongodb.DB.command(DB.java:317)
      at com.mongodb.DB.command(DB.java:296)
      at com.mongodb.DBCollection.getStats(DBCollection.java:1742)
      at test.Test.mongoConnection(Test.java:105)
      at test.Test.main(Test.java:67) 
  </code></pre>
  
  <p>And in the server logs I get:</p>
  
  <pre><code>2014-11-21T21:48:17.810+0000 [conn23719]  authenticate db: $external { authenticate: 1, user: "emailAddress=administrator@local.com,CN=10.27.2.103,OU=Mongo Client,O=Local.com,L=Nottingham,ST=Nottinghamshire,C=GB", mechanism: "MONGODB-X509" }
  2014-11-21T21:48:17.810+0000 [conn23719] Failed to authenticate emailAddress=administrator@local.com,CN=10.27.2.103,OU=Mongo Client,O=Local.com,L=Nottingham,ST=Nottinghamshire,C=GB@$external with mechanism MONGODB-X509: AuthenticationFailed There is no x.509 client certificate matching the user.    
  </code></pre>
  
  <p>I've enabled Java Debugging and this is about as far as my knowledge takes me - It seems that it's only referencing the above certificates once or twice - and that's at the beginning of the code execution when it is being added to the keystore. There is no mention of it further down the line when the Mongo connection is being made. There is however, plenty of mention of the other certificates being used in the SSL handshake around the time of the connection being made. </p>
  
  <p>I've tried to give as much relevant information as possible but please ask if I can provide anything else. </p>
  
  <p>Any help in getting the client to connect and authenticate with the database would be hugely appreciated. </p>