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

Valery Kharseko
yesterday 70d9a179cdd8d975b44e1815c249e20d9f91097f
opendj-server-legacy/src/main/java/org/opends/server/util/CertificateManager.java
@@ -13,13 +13,17 @@
 *
 * Copyright 2008-2010 Sun Microsystems, Inc.
 * Portions Copyright 2013-2016 ForgeRock AS.
 * Portions Copyright 2026 3A Systems, LLC.
 */
package org.opends.server.util;
import java.io.File;
import java.io.FileInputStream;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
@@ -81,6 +85,8 @@
  private static final String CERT_ALIAS_MSG = "certificate alias";
  private static final String CERT_REQUEST_FILE_MSG =
                                                    "certificate request file";
  private static final String SOURCE_KEYSTORE_MSG = "source key store";
  private static final String CERT_MSG = "certificate";
  /** The parsed key store backing this certificate manager. */
  private KeyStore keyStore;
@@ -191,6 +197,17 @@
  /**
   * Retrieves the path of the key store this certificate manager works on.
   *
   * @return  The path of the key store.
   */
  public String getKeyStorePath() {
    return keyStorePath;
  }
  /**
   * Indicates whether the provided alias is in use in the key store.
   *
   * @param  alias  The alias for which to make the determination.  It must not
@@ -268,6 +285,113 @@
  /**
   * Retrieves the certificate chain of the key entry with the specified alias from the
   * key store, the certificate the key belongs to first and its issuers next.
   *
   * @param  alias  The alias of the key entry whose chain to retrieve.  It must not be
   *                {@code null} or empty.
   *
   * @return  The certificate chain, or {@code null} if the key store holds no key entry
   *          under the specified alias.
   *
   * @throws  KeyStoreException  If a problem occurs while interacting with the key store,
   *                             or the key store does not exist.
   */
  public Certificate[] getCertificateChain(String alias)
  throws KeyStoreException {
    ensureValid(alias, CERT_ALIAS_MSG);
    KeyStore ks = getKeyStore();
    if (ks == null) {
      LocalizableMessage msg = ERR_CERTMGR_KEYSTORE_NONEXISTANT.get();
      throw new KeyStoreException(msg.toString());
    }
    return ks.getCertificateChain(alias);
  }
  /**
   * Copies the key entry with the specified alias from the provided key store into this
   * one, with its whole certificate chain.  The private key is re-encrypted with the
   * password of this key store: the key managers of the server are initialised with the
   * store password only, so a key which kept the password of the key store it comes from
   * could not be read back.
   * <p>
   * The certificates of the chain are not added as trusted certificates, as only a
   * trusted certificate entry is a trust anchor.  Use {@link #addTrustedCertificate} for
   * the issuers which have to be trusted.
   *
   * @param  alias          The alias to store the key entry under in this key store.  It
   *                        must not be {@code null} or empty.
   * @param  sourceManager  The certificate manager of the key store holding the key entry
   *                        to copy.  It must not be {@code null}.
   * @param  sourceAlias    The alias of the key entry to copy.  It must not be
   *                        {@code null} or empty.
   *
   * @throws  KeyStoreException  If the source key store holds no key entry under the
   *                             provided alias, if its private key is protected by a
   *                             password other than the one of the source key store, if
   *                             the alias is already in use in this key store, or a
   *                             problem occurs while interacting with either key store.
   */
  public void importKeyEntry(String alias, CertificateManager sourceManager, String sourceAlias)
  throws KeyStoreException {
    ensureValid(alias, CERT_ALIAS_MSG);
    ensureValid(sourceAlias, CERT_ALIAS_MSG);
    if (sourceManager == null) {
      LocalizableMessage msg = ERR_CERTMGR_VALUE_INVALID.get(SOURCE_KEYSTORE_MSG);
      throw new NullPointerException(msg.toString());
    }
    final Certificate[] chain = sourceManager.getCertificateChain(sourceAlias);
    final Key privateKey;
    try {
      privateKey = sourceManager.getKeyStore().getKey(sourceAlias, sourceManager.password);
    } catch (UnrecoverableKeyException e) {
      // The key is protected by a password of its own.  The key managers of the server
      // unlock private keys with the store password only, so this is the same limitation
      // the key store already has for LDAPS: say so rather than "Cannot recover key".
      throw new KeyStoreException(
          ERR_CERTMGR_KEY_PASSWORD_DIFFERS.get(sourceAlias, sourceManager.keyStorePath).toString(), e);
    } catch (GeneralSecurityException e) {
      throw new KeyStoreException(
          ERR_CERTMGR_IMPORT_KEY_ENTRY.get(sourceAlias, e.getMessage()).toString(), e);
    }
    if (privateKey == null || chain == null || chain.length == 0) {
      LocalizableMessage msg =
          ERR_CERTMGR_NO_KEY_ENTRY.get(sourceAlias, sourceManager.keyStorePath);
      throw new KeyStoreException(msg.toString());
    }
    keyStore = null;
    Platform.importKeyEntry(getKeyStore(), keyStoreType, keyStorePath, alias, password, privateKey, chain);
  }
  /**
   * Adds the provided certificate to the key store as a trusted certificate entry.  Only
   * such an entry is a trust anchor: of a key entry, the trust managers take the
   * certificate the key belongs to and none of its issuers.
   *
   * @param  alias        The alias to use for the certificate.  It must not be
   *                      {@code null} or empty.
   * @param  certificate  The certificate to trust.  It must not be {@code null}.
   *
   * @throws  KeyStoreException  If the alias is already in use, or a problem occurs while
   *                             interacting with the key store.
   */
  public void addTrustedCertificate(String alias, Certificate certificate)
  throws KeyStoreException {
    ensureValid(alias, CERT_ALIAS_MSG);
    if (certificate == null) {
      LocalizableMessage msg = ERR_CERTMGR_VALUE_INVALID.get(CERT_MSG);
      throw new NullPointerException(msg.toString());
    }
    keyStore = null;
    Platform.addTrustedCertificate(getKeyStore(), keyStoreType, keyStorePath, alias, password, certificate);
  }
  /**
   * Generates a self-signed certificate using the provided information.
   *
   * @param  keyType    Specifies the key size, key and signature algorithms.