mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jvergara
25.42.2009 766ba6b28669b54a6a90c539822661690cf5fa2d
Fix for issue 4371 (setup throws NullPointerException when trying to use a PKCS12 certificate)
Handle the case where the user provides a certificate without an alias. The code in CertificateManager has been updated to detect this situation.
The code in ConfigureDS has also been updated to handle the case where the user does not provide a certificate nickname.
7 files modified
292 ■■■■ changed files
opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java 8 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java 119 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java 30 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/ConfigureDS.java 45 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/InstallDS.java 22 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/CertificateManager.java 40 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/SetupUtils.java 28 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/SecurityOptions.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.quicksetup;
@@ -117,7 +117,7 @@
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   * @param aliasToUse the alias of the certificate in the keystore to be used.
   * @param aliasToUse the alias of the certificate in the key store to be used.
   * @return a new instance of a SecurityOptions using a Java Key Store.
   */
  public static SecurityOptions createJKSCertificateOptions(String keystorePath,
@@ -335,8 +335,8 @@
  }
  /**
   * Returns the alias of the certificate in the keystore to be used.
   * @return the alias of the certificate in the keystore to be used.
   * Returns the alias of the certificate in the key store to be used.
   * @return the alias of the certificate in the key store to be used.
   */
  public String getAliasToUse()
  {
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -853,6 +853,17 @@
      argList.add("-q");
    }
    String aliasInKeyStore = sec.getAliasToUse();
    String aliasInTrustStore;
    if (aliasInKeyStore == null)
    {
      aliasInTrustStore = SELF_SIGNED_CERT_ALIAS;
    }
    else
    {
      aliasInTrustStore = aliasInKeyStore;
    }
    switch (sec.getCertificateType())
    {
    case SELF_SIGNED_CERTIFICATE:
@@ -868,8 +879,11 @@
      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
      argList.add("-m");
      argList.add(sec.getKeystorePath());
      argList.add("-a");
      argList.add(sec.getAliasToUse());
      if (aliasInKeyStore != null)
      {
        argList.add("-a");
        argList.add(aliasInKeyStore);
      }
      break;
    case JCEKS:
      argList.add("-k");
@@ -878,28 +892,37 @@
      argList.add("cn=JCEKS,cn=Trust Manager Providers,cn=config");
      argList.add("-m");
      argList.add(sec.getKeystorePath());
      argList.add("-a");
      argList.add(sec.getAliasToUse());
      if (aliasInKeyStore != null)
      {
        argList.add("-a");
        argList.add(aliasInKeyStore);
      }
      break;
    case PKCS12:
      argList.add("-k");
      argList.add("cn=PKCS12,cn=Key Manager Providers,cn=config");
      argList.add("-t");
      // We are going to import the PCKS12 certificate in a JKS truststore
      // We are going to import the PCKS12 certificate in a JKS trust store
      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
      argList.add("-m");
      argList.add(sec.getKeystorePath());
      argList.add("-a");
      argList.add(sec.getAliasToUse());
      if (aliasInKeyStore != null)
      {
        argList.add("-a");
        argList.add(aliasInKeyStore);
      }
      break;
    case PKCS11:
      argList.add("-k");
      argList.add("cn=PKCS11,cn=Key Manager Providers,cn=config");
      argList.add("-t");
      // We are going to import the PCKS11 certificate in a JKS truststore
      // We are going to import the PCKS11 certificate in a JKS trust store
      argList.add("cn=JKS,cn=Trust Manager Providers,cn=config");
      argList.add("-a");
      argList.add(sec.getAliasToUse());
      if (aliasInKeyStore != null)
      {
        argList.add("-a");
        argList.add(aliasInKeyStore);
      }
      break;
    case NO_CERTIFICATE:
      // Nothing to do.
@@ -1048,14 +1071,22 @@
            sec.getKeystorePath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            sec.getKeystorePassword());
        SetupUtils.exportCertificate(certManager, sec.getAliasToUse(),
            getTemporaryCertificatePath());
        if (aliasInKeyStore != null)
        {
          SetupUtils.exportCertificate(certManager, aliasInKeyStore,
              getTemporaryCertificatePath());
        }
        else
        {
          SetupUtils.exportCertificate(certManager,
              getTemporaryCertificatePath());
        }
        trustManager = new CertificateManager(
            getTrustManagerPath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            sec.getKeystorePassword());
        trustManager.addCertificate(sec.getAliasToUse(),
        trustManager.addCertificate(aliasInTrustStore,
            new File(getTemporaryCertificatePath()));
        createProtectedFile(getKeystorePinPath(), sec.getKeystorePassword());
        f = new File(getTemporaryCertificatePath());
@@ -1066,14 +1097,22 @@
            sec.getKeystorePath(),
            CertificateManager.KEY_STORE_TYPE_JCEKS,
            sec.getKeystorePassword());
        SetupUtils.exportCertificate(certManager, sec.getAliasToUse(),
            getTemporaryCertificatePath());
        if (aliasInKeyStore != null)
        {
          SetupUtils.exportCertificate(certManager, aliasInKeyStore,
              getTemporaryCertificatePath());
        }
        else
        {
          SetupUtils.exportCertificate(certManager,
              getTemporaryCertificatePath());
        }
        trustManager = new CertificateManager(
            getTrustManagerPath(),
            CertificateManager.KEY_STORE_TYPE_JCEKS,
            sec.getKeystorePassword());
        trustManager.addCertificate(sec.getAliasToUse(),
        trustManager.addCertificate(aliasInTrustStore,
            new File(getTemporaryCertificatePath()));
        createProtectedFile(getKeystorePinPath(), sec.getKeystorePassword());
        f = new File(getTemporaryCertificatePath());
@@ -1084,14 +1123,22 @@
            sec.getKeystorePath(),
            CertificateManager.KEY_STORE_TYPE_PKCS12,
            sec.getKeystorePassword());
        SetupUtils.exportCertificate(certManager, sec.getAliasToUse(),
            getTemporaryCertificatePath());
        if (aliasInKeyStore != null)
        {
          SetupUtils.exportCertificate(certManager, aliasInKeyStore,
              getTemporaryCertificatePath());
        }
        else
        {
          SetupUtils.exportCertificate(certManager,
              getTemporaryCertificatePath());
        }
        trustManager = new CertificateManager(
            getTrustManagerPath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            sec.getKeystorePassword());
        trustManager.addCertificate(sec.getAliasToUse(),
        trustManager.addCertificate(aliasInTrustStore,
            new File(getTemporaryCertificatePath()));
        createProtectedFile(getKeystorePinPath(), sec.getKeystorePassword());
        f = new File(getTemporaryCertificatePath());
@@ -1102,14 +1149,22 @@
            CertificateManager.KEY_STORE_PATH_PKCS11,
            CertificateManager.KEY_STORE_TYPE_PKCS11,
            sec.getKeystorePassword());
        SetupUtils.exportCertificate(certManager, sec.getAliasToUse(),
            getTemporaryCertificatePath());
        if (aliasInKeyStore != null)
        {
          SetupUtils.exportCertificate(certManager, aliasInKeyStore,
              getTemporaryCertificatePath());
        }
        else
        {
          SetupUtils.exportCertificate(certManager,
              getTemporaryCertificatePath());
        }
        trustManager = new CertificateManager(
            getTrustManagerPath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            sec.getKeystorePassword());
        trustManager.addCertificate(sec.getAliasToUse(),
        trustManager.addCertificate(aliasInTrustStore,
            new File(getTemporaryCertificatePath()));
        createProtectedFile(getKeystorePinPath(), sec.getKeystorePassword());
        break;
@@ -3518,7 +3573,7 @@
      if (adsContext.hasAdminData())
      {
        /* Check if there are already global administrators */
        Set administrators = adsContext.readAdministratorRegistry();
        Set<?> administrators = adsContext.readAdministratorRegistry();
        if (administrators.size() > 0)
        {
          hasGlobalAdministrators[0] = true;
@@ -3774,7 +3829,7 @@
    if (qs.getFieldValue(FieldName.SUFFIXES_TO_REPLICATE_OPTIONS) ==
      SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES)
    {
      Set s = (Set)qs.getFieldValue(FieldName.SUFFIXES_TO_REPLICATE);
      Set<?> s = (Set<?>)qs.getFieldValue(FieldName.SUFFIXES_TO_REPLICATE);
      if (s.size() == 0)
      {
        errorMsgs.add(INFO_NO_SUFFIXES_CHOSEN_TO_REPLICATE.get());
@@ -3835,8 +3890,10 @@
    ArrayList<Message> errorMsgs = new ArrayList<Message>();
    Map<ServerDescriptor, AuthenticationData> servers =
      getUserData().getRemoteWithNoReplicationPort();
    Map hm = (Map) qs.getFieldValue(FieldName.REMOTE_REPLICATION_PORT);
    Map hmSecure = (Map) qs.getFieldValue(FieldName.REMOTE_REPLICATION_SECURE);
    Map<?, ?> hm =
      (Map<?, ?>) qs.getFieldValue(FieldName.REMOTE_REPLICATION_PORT);
    Map<?, ?> hmSecure =
      (Map<?, ?>) qs.getFieldValue(FieldName.REMOTE_REPLICATION_SECURE);
    for (ServerDescriptor server : servers.keySet())
    {
      String hostName = server.getHostName();
@@ -4435,8 +4492,9 @@
      }
      try
      {
        NamingEnumeration res = ctx.search(dn, filter, searchControls);
        SearchResult sr = (SearchResult)res.next();
        NamingEnumeration<SearchResult> res =
          ctx.search(dn, filter, searchControls);
        SearchResult sr = res.next();
        // Get the number of entries that have been handled and
        // a percentage...
@@ -4729,8 +4787,9 @@
      }
      try
      {
        NamingEnumeration res = ctx.search(dn, filter, searchControls);
        SearchResult sr = (SearchResult)res.next();
        NamingEnumeration<SearchResult> res =
          ctx.search(dn, filter, searchControls);
        SearchResult sr = res.next();
        String logMsg = getFirstValue(sr, "ds-task-log-message");
        if (logMsg != null)
        {
opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java
@@ -100,6 +100,7 @@
  private SecurityOptions securityOptions;
  private String[] aliases;
  private boolean certificateHasAlias;
  private String selectedAlias;
  private final int DEFAULT_PORT = 636;
@@ -663,10 +664,11 @@
   */
  private void okClicked()
  {
    BackgroundTask worker = new BackgroundTask()
    BackgroundTask<ArrayList<Message>> worker =
      new BackgroundTask<ArrayList<Message>>()
    {
      @Override
      public Object processBackgroundTask()
      public ArrayList<Message> processBackgroundTask()
      {
        ArrayList<Message> errorMsgs = new ArrayList<Message>();
@@ -678,7 +680,7 @@
      }
      @Override
      public void backgroundTaskCompleted(Object returnValue,
      public void backgroundTaskCompleted(ArrayList<Message> returnValue,
          Throwable throwable)
      {
        if (throwable != null)
@@ -695,16 +697,10 @@
        {
          cancelButton.setEnabled(true);
          okButton.setEnabled(true);
          ArrayList ar = (ArrayList)returnValue;
          if (ar.size() > 0)
          if (returnValue.size() > 0)
          {
            ArrayList<Message> errorMsgs = new ArrayList<Message>();
            for (Object o: ar)
            {
              errorMsgs.add((Message)o);
            }
            displayError(Utils.getMessageFromCollection(errorMsgs, "\n"),
            displayError(Utils.getMessageFromCollection(returnValue, "\n"),
                INFO_ERROR_TITLE.get());
          }
          else
@@ -712,7 +708,13 @@
            if (rbUseExistingCertificate.isSelected() &&
                (cbEnableSSL.isSelected() || cbEnableStartTLS.isSelected()))
            {
              if (aliases.length > 1)
              if (!certificateHasAlias)
              {
                selectedAlias = null;
                isCancelled = false;
                dispose();
              }
              else if (aliases.length > 1)
              {
                if (aliasDlg == null)
                {
@@ -1050,6 +1052,10 @@
              pathValid = false;
            }
          }
          else
          {
            certificateHasAlias = certManager.hasRealAliases();
          }
        }
        catch (KeyStoreException ke)
        {
opends/src/server/org/opends/server/tools/ConfigureDS.java
@@ -1123,6 +1123,51 @@
          return 1;
        }
      }
      else
      {
        try
        {
          if (ldapPort.isPresent())
          {
            // Use the key manager specified for the LDAP connection handler.
            DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
            ConfigEntry configEntry =
              configHandler.getConfigEntry(ldapListenerDN);
            configEntry.removeConfigAttribute(
                ATTR_SSL_CERT_NICKNAME.toLowerCase());
          }
          if (ldapsPort.isPresent())
          {
            // Use the key manager specified for the LDAPS connection handler.
            DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
            ConfigEntry configEntry =
              configHandler.getConfigEntry(ldapsListenerDN);
            configEntry.removeConfigAttribute(
                ATTR_SSL_CERT_NICKNAME.toLowerCase());
          }
          if (jmxPort.isPresent())
          {
            // Use the key manager specified for the JMX connection handler.
            DN jmxListenerDN = DN.decode(DN_JMX_CONNECTION_HANDLER);
            ConfigEntry configEntry =
              configHandler.getConfigEntry(jmxListenerDN);
            configEntry.removeConfigAttribute(
                ATTR_SSL_CERT_NICKNAME.toLowerCase());
          }
        }
        catch (Exception e)
        {
          Message message = ERR_CONFIGDS_CANNOT_UPDATE_CERT_NICKNAME.get(
                  String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }
      // If a root user DN and password were specified, then update the config
      // accordingly.
opends/src/server/org/opends/server/tools/InstallDS.java
@@ -1961,18 +1961,18 @@
  /**
   * Checks that the provided parameters are valid to access an existing
   * keystore.  This method adds the encountered errors to the provided
   * key store.  This method adds the encountered errors to the provided
   * list of Message.  It also adds the alias (nicknames) found to the provided
   * list of String.
   * @param type the type of keystore.
   * @param path the path of the keystore.
   * @param pwd the password (PIN) to access the keystore.
   * @param type the type of key store.
   * @param path the path of the key store.
   * @param pwd the password (PIN) to access the key store.
   * @param certNickname the certificate nickname that we are looking for (or
   * null if we just one to get the one that is in the keystore).
   * null if we just one to get the one that is in the key store).
   * @param errorMessages the list that will be updated with the errors
   * encountered.
   * @param nicknameList the list that will be updated with the nicknames found
   * in the keystore.
   * in the key store.
   */
  public static void checkCertificateInKeystore(
      SecurityOptions.CertificateType type,
@@ -2065,7 +2065,7 @@
            throw new IllegalArgumentException("Invalid type: "+type);
          }
        }
        else
        else if (certManager.hasRealAliases())
        {
          for (int i=0; i<aliases.length; i++)
          {
@@ -2075,7 +2075,7 @@
              ", ");
          if (certNickname != null)
          {
            // Check if the cert alias is in the list.
            // Check if the certificate alias is in the list.
            boolean found = false;
            for (int i=0; i<aliases.length && !found; i++)
            {
@@ -2096,8 +2096,8 @@
      }
      catch (KeyStoreException ke)
      {
        // Could not access to the keystore: because the password is no good,
        // because the provided file is not a valid keystore, etc.
        // Could not access to the key store: because the password is no good,
        // because the provided file is not a valid key store, etc.
        switch (type)
        {
        case JKS:
@@ -2268,7 +2268,7 @@
          keystoreAliases);
      firstTry = false;
    }
    if (certNickname == null)
    if ((certNickname == null) && !keystoreAliases.isEmpty())
    {
      certNickname = keystoreAliases.getFirst();
    }
opends/src/server/org/opends/server/util/CertificateManager.java
@@ -97,6 +97,8 @@
  private final char[] password;
  private Boolean realAliases;
  /**
   * Always return true.
   *
@@ -439,6 +441,44 @@
      }
  }
  /**
   * Returns whether this certificate manager contains 'real' aliases or not.
   * For instance, the certificate manager can contain a PKCS12 certificate
   * with no alias.
   * @return whether this certificate manager contains 'real' aliases or not.
   * @throws KeyStoreException if there is a problem accessing the key store.
   */
  public boolean hasRealAliases() throws KeyStoreException
  {
    if (realAliases == null)
    {
      String[] aliases = getCertificateAliases();
      if (aliases == null || aliases.length == 0)
      {
        realAliases = Boolean.FALSE;
      }
      else if (aliases.length > 1)
      {
        realAliases = Boolean.TRUE;
      }
      else
      {
        CertificateManager certManager2 = new CertificateManager(keyStorePath,
            keyStoreType, new String(password));
        String[] aliases2 = certManager2.getCertificateAliases();
        if (aliases2 != null && aliases2.length == 1)
        {
          realAliases = aliases[0].equalsIgnoreCase(aliases2[0]);
        }
        else
        {
          realAliases = Boolean.FALSE;
        }
      }
    }
    return realAliases;
  }
  private static void ensureFileValid(File arg, String msgStr) {
    if(arg == null) {
      Message msg = ERR_CERTMGR_FILE_NAME_INVALID.get(msgStr);
opends/src/server/org/opends/server/util/SetupUtils.java
@@ -526,6 +526,34 @@
  /**
   * Export a certificate in a file.  It will export the first certificate
   * defined.  This method is required because of the way.
   *
   * @param certManager Certificate manager to use.
   * @param path Path of the output file.
   *
   * @throws CertificateEncodingException If the certificate manager cannot
   * encode the certificate.
   * @throws IOException If a problem occurs while creating or writing in the
   * output file.
   * @throws KeyStoreException If the certificate manager cannot retrieve the
   * certificate to be exported.
   */
  public static void exportCertificate(
    CertificateManager certManager, String path)
    throws CertificateEncodingException, IOException, KeyStoreException
  {
    String[] aliases = certManager.getCertificateAliases();
    Certificate certificate = certManager.getCertificate(aliases[0]);
    byte[] certificateBytes = certificate.getEncoded();
    FileOutputStream outputStream = new FileOutputStream(path, false);
    outputStream.write(certificateBytes);
    outputStream.close();
  }
  /**
   * Export a certificate in a file.
   *
   * @param certManager Certificate manager to use.