From 90457b4af6104b62a08a9e09fcc77360dc0c6f5c Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Thu, 19 Sep 2013 10:32:50 +0000
Subject: [PATCH] Fix OPENDJ-734 - NPE when attempting SSL connect with client certs Review CR-1243

---
 opendj-sdk/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java |   65 ++++++++++++++++++++++++++++++++
 opendj-sdk/opendj3/opendj-ldap-toolkit/src/test/resources/dummy-truststore                                              |    0 
 opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProvider.java     |   23 +++++------
 3 files changed, 75 insertions(+), 13 deletions(-)

diff --git a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProvider.java b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProvider.java
index aef0aa7..a2b4841 100644
--- a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProvider.java
+++ b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProvider.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
- *      Portions copyright 2011-2012 ForgeRock AS
+ *      Portions copyright 2011-2013 ForgeRock AS
  */
 
 package com.forgerock.opendj.ldap.tools;
@@ -387,7 +387,7 @@
             if (keyStorePathArg.isPresent()) {
                 // Check that the path exists and is readable
                 final String value = keyStorePathArg.getValue();
-                if (!canRead(trustStorePathArg.getValue())) {
+                if (!canRead(keyStorePathArg.getValue())) {
                     final LocalizableMessage message = ERR_CANNOT_READ_KEYSTORE.get(value);
                     throw new ArgumentException(message);
                 }
@@ -594,6 +594,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public String toString() {
         return connFactory.toString();
     }
@@ -728,15 +729,11 @@
 
         X509TrustManager tm = null;
         if (trustStorePathArg.isPresent() && trustStorePathArg.getValue().length() > 0) {
-            tm =
-                    TrustManagers.checkValidityDates(TrustManagers.checkHostName(hostNameArg
-                            .getValue(), TrustManagers.checkUsingTrustStore(trustStorePathArg
-                            .getValue(), getTrustStorePIN().toCharArray(), null)));
+            tm = TrustManagers.checkValidityDates(TrustManagers.checkHostName(hostNameArg.getValue(),
+                    TrustManagers.checkUsingTrustStore(trustStorePathArg.getValue(), getTrustStorePIN(), null)));
         } else if (getTrustStore() != null) {
-            tm =
-                    TrustManagers.checkValidityDates(TrustManagers.checkHostName(hostNameArg
-                            .getValue(), TrustManagers.checkUsingTrustStore(getTrustStore(),
-                            getTrustStorePIN().toCharArray(), null)));
+            tm = TrustManagers.checkValidityDates(TrustManagers.checkHostName(hostNameArg.getValue(),
+                    TrustManagers.checkUsingTrustStore(getTrustStore(), getTrustStorePIN(), null)));
         }
 
         if (app != null && !app.isQuiet()) {
@@ -759,10 +756,10 @@
     /**
      * Read the TrustStore PIN from the JSSE system property.
      *
-     * @return The PIN that should be used to access the trust store.
+     * @return The PIN that should be used to access the trust store, can be null.
      */
 
-    private String getTrustStorePIN() {
+    private char[] getTrustStorePIN() {
         String pwd;
         if (trustStorePasswordArg.isPresent()) {
             pwd = trustStorePasswordArg.getValue();
@@ -771,7 +768,7 @@
         } else {
             pwd = System.getProperty("javax.net.ssl.trustStorePassword");
         }
-        return pwd;
+        return pwd == null ? null : pwd.toCharArray();
     }
 
     private String parseSASLOptionValue(final String option) throws ArgumentException {
diff --git a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java
new file mode 100644
index 0000000..c1fd243
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ConnectionFactoryProviderTest.java
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2013 ForgeRock AS.
+ */
+package com.forgerock.opendj.ldap.tools;
+
+import static org.fest.assertions.Assertions.*;
+
+import org.forgerock.i18n.LocalizableMessageBuilder;
+import org.forgerock.opendj.ldap.ConnectionFactory;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ConnectionFactoryProviderTest extends ToolsTestCase {
+
+    @Mock
+    private ConsoleApplication app;
+
+    private ArgumentParser argParser;
+
+    private ConnectionFactoryProvider connectionFactoryProvider;
+
+    @BeforeMethod
+    public void init() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        argParser = new ArgumentParser("unused", new LocalizableMessageBuilder().toMessage(), false);
+        connectionFactoryProvider = new ConnectionFactoryProvider(argParser, app);
+    }
+
+    @Test
+    /** Issue OPENDJ-734 */
+    public void getConnectionFactoryShouldAllowNullTrustStorePassword() throws Exception {
+        // provide a trustStorePath but no password
+        String trustStorePath = getClass().getClassLoader().getResource("dummy-truststore").getFile();
+        argParser.parseArguments(new String[] { "--useStartTLS", "--trustStorePath", trustStorePath });
+
+        ConnectionFactory factory = connectionFactoryProvider.getConnectionFactory();
+
+        assertThat(factory).isNotNull();
+    }
+
+}
diff --git a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/test/resources/dummy-truststore b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/test/resources/dummy-truststore
new file mode 100644
index 0000000..65c6eed
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/test/resources/dummy-truststore
Binary files differ

--
Gitblit v1.10.0