Search in sources :

Example 21 with BooleanArgument

use of com.unboundid.util.args.BooleanArgument in project ldapsdk by pingidentity.

the class ManageCertificates method doChangePrivateKeyPassword.

/**
 * Performs the necessary processing for the change-private-key-password
 * subcommand.
 *
 * @return  A result code that indicates whether the processing completed
 *          successfully.
 */
@NotNull()
private ResultCode doChangePrivateKeyPassword() {
    // Get the values of a number of configured arguments.
    final StringArgument aliasArgument = subCommandParser.getStringArgument("alias");
    final String alias = aliasArgument.getValue();
    final String keystoreType;
    final File keystorePath = getKeystorePath();
    try {
        keystoreType = inferKeystoreType(keystorePath);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    final char[] keystorePassword;
    try {
        keystorePassword = getKeystorePassword(keystorePath);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    // Get the keystore.
    final KeyStore keystore;
    try {
        keystore = getKeystore(keystoreType, keystorePath, keystorePassword);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    // Make sure that the keystore has a key entry with the specified alias.
    if (hasCertificateAlias(keystore, alias)) {
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_CHANGE_PK_PW_ALIAS_IS_CERT.get(alias));
        return ResultCode.PARAM_ERROR;
    } else if (!hasKeyAlias(keystore, alias)) {
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_CHANGE_PK_PW_NO_SUCH_ALIAS.get(alias));
        return ResultCode.PARAM_ERROR;
    }
    // Get the current and new private key passwords.
    final char[] currentPrivateKeyPassword;
    try {
        currentPrivateKeyPassword = getPrivateKeyPassword(keystore, alias, "current", keystorePassword);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    final char[] newPrivateKeyPassword;
    try {
        newPrivateKeyPassword = getPrivateKeyPassword(keystore, alias, "new", keystorePassword);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    // Generate the keytool arguments to use to change the private key.
    final BooleanArgument displayKeytoolCommandArgument = subCommandParser.getBooleanArgument("display-keytool-command");
    if ((displayKeytoolCommandArgument != null) && displayKeytoolCommandArgument.isPresent()) {
        final ArrayList<String> keytoolArguments = new ArrayList<>(30);
        keytoolArguments.add("-keypasswd");
        keytoolArguments.add("-keystore");
        keytoolArguments.add(keystorePath.getAbsolutePath());
        keytoolArguments.add("-storetype");
        keytoolArguments.add(keystoreType);
        keytoolArguments.add("-storepass");
        keytoolArguments.add("*****REDACTED*****");
        keytoolArguments.add("-alias");
        keytoolArguments.add(alias);
        keytoolArguments.add("-keypass");
        keytoolArguments.add("*****REDACTED*****");
        keytoolArguments.add("-new");
        keytoolArguments.add("*****REDACTED*****");
        displayKeytoolCommand(keytoolArguments);
    }
    // Get the contents of the private key entry.
    final Certificate[] chain;
    final PrivateKey privateKey;
    try {
        chain = keystore.getCertificateChain(alias);
        privateKey = (PrivateKey) keystore.getKey(alias, currentPrivateKeyPassword);
    } catch (final UnrecoverableKeyException e) {
        Debug.debugException(e);
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_CHANGE_PK_PW_WRONG_PK_PW.get(alias));
        return ResultCode.PARAM_ERROR;
    } catch (final Exception e) {
        Debug.debugException(e);
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_CHANGE_PK_PW_CANNOT_GET_PK.get(alias));
        e.printStackTrace(getErr());
        return ResultCode.LOCAL_ERROR;
    }
    // Remove the existing key entry and re-add it with the new password.
    try {
        keystore.deleteEntry(alias);
        keystore.setKeyEntry(alias, privateKey, newPrivateKeyPassword, chain);
        writeKeystore(keystore, keystorePath, keystorePassword);
    } catch (final Exception e) {
        Debug.debugException(e);
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_CHANGE_PK_PW_CANNOT_UPDATE_KS.get());
        e.printStackTrace(getErr());
        return ResultCode.LOCAL_ERROR;
    }
    wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_CHANGE_PK_PW_SUCCESSFUL.get(alias));
    return ResultCode.SUCCESS;
}
Also used : PrivateKey(java.security.PrivateKey) BooleanArgument(com.unboundid.util.args.BooleanArgument) ArrayList(java.util.ArrayList) ASN1BitString(com.unboundid.asn1.ASN1BitString) KeyStore(java.security.KeyStore) ArgumentException(com.unboundid.util.args.ArgumentException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) LDAPException(com.unboundid.ldap.sdk.LDAPException) IOException(java.io.IOException) StringArgument(com.unboundid.util.args.StringArgument) LDAPException(com.unboundid.ldap.sdk.LDAPException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) File(java.io.File) Certificate(java.security.cert.Certificate) NotNull(com.unboundid.util.NotNull)

Example 22 with BooleanArgument

use of com.unboundid.util.args.BooleanArgument in project ldapsdk by pingidentity.

the class ManageCertificates method doGenerateOrSignCertificateOrCSR.

/**
 * Performs the necessary processing for the generate-self-signed-certificate,
 * generate-certificate-signing-request, and sign-certificate-signing-request
 * subcommands.
 *
 * @return  A result code that indicates whether the processing completed
 *          successfully.
 */
@NotNull()
private ResultCode doGenerateOrSignCertificateOrCSR() {
    // Figure out which subcommand we're processing.
    final boolean isGenerateCertificate;
    final boolean isGenerateCSR;
    final boolean isSignCSR;
    final SubCommand selectedSubCommand = globalParser.getSelectedSubCommand();
    if (selectedSubCommand.hasName("generate-self-signed-certificate")) {
        isGenerateCertificate = true;
        isGenerateCSR = false;
        isSignCSR = false;
    } else if (selectedSubCommand.hasName("generate-certificate-signing-request")) {
        isGenerateCertificate = false;
        isGenerateCSR = true;
        isSignCSR = false;
    } else {
        Validator.ensureTrue(selectedSubCommand.hasName("sign-certificate-signing-request"));
        isGenerateCertificate = false;
        isGenerateCSR = false;
        isSignCSR = true;
    }
    // Get the values of a number of configured arguments.
    final StringArgument aliasArgument = subCommandParser.getStringArgument("alias");
    final String alias = aliasArgument.getValue();
    final File keystorePath = getKeystorePath();
    final boolean isNewKeystore = (!keystorePath.exists());
    DN subjectDN = null;
    final DNArgument subjectDNArgument = subCommandParser.getDNArgument("subject-dn");
    if ((subjectDNArgument != null) && subjectDNArgument.isPresent()) {
        subjectDN = subjectDNArgument.getValue();
    }
    File inputFile = null;
    final FileArgument inputFileArgument = subCommandParser.getFileArgument("input-file");
    if ((inputFileArgument != null) && inputFileArgument.isPresent()) {
        inputFile = inputFileArgument.getValue();
    }
    File outputFile = null;
    final FileArgument outputFileArgument = subCommandParser.getFileArgument("output-file");
    if ((outputFileArgument != null) && outputFileArgument.isPresent()) {
        outputFile = outputFileArgument.getValue();
    }
    boolean outputPEM = true;
    final StringArgument outputFormatArgument = subCommandParser.getStringArgument("output-format");
    if ((outputFormatArgument != null) && outputFormatArgument.isPresent()) {
        final String format = outputFormatArgument.getValue().toLowerCase();
        if (format.equals("der") || format.equals("binary") || format.equals("bin")) {
            outputPEM = false;
        }
    }
    if ((!outputPEM) && (outputFile == null)) {
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_NO_FILE_WITH_DER.get());
        return ResultCode.PARAM_ERROR;
    }
    final BooleanArgument replaceExistingCertificateArgument = subCommandParser.getBooleanArgument("replace-existing-certificate");
    final boolean replaceExistingCertificate = ((replaceExistingCertificateArgument != null) && replaceExistingCertificateArgument.isPresent());
    if (replaceExistingCertificate && (!keystorePath.exists())) {
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_REPLACE_WITHOUT_KS.get());
        return ResultCode.PARAM_ERROR;
    }
    final BooleanArgument inheritExtensionsArgument = subCommandParser.getBooleanArgument("inherit-extensions");
    final boolean inheritExtensions = ((inheritExtensionsArgument != null) && inheritExtensionsArgument.isPresent());
    final BooleanArgument includeRequestedExtensionsArgument = subCommandParser.getBooleanArgument("include-requested-extensions");
    final boolean includeRequestedExtensions = ((includeRequestedExtensionsArgument != null) && includeRequestedExtensionsArgument.isPresent());
    final BooleanArgument noPromptArgument = subCommandParser.getBooleanArgument("no-prompt");
    final boolean noPrompt = ((noPromptArgument != null) && noPromptArgument.isPresent());
    final BooleanArgument displayKeytoolCommandArgument = subCommandParser.getBooleanArgument("display-keytool-command");
    final boolean displayKeytoolCommand = ((displayKeytoolCommandArgument != null) && displayKeytoolCommandArgument.isPresent());
    int daysValid = 365;
    final IntegerArgument daysValidArgument = subCommandParser.getIntegerArgument("days-valid");
    if ((daysValidArgument != null) && daysValidArgument.isPresent()) {
        daysValid = daysValidArgument.getValue();
    }
    Date validityStartTime = null;
    final TimestampArgument validityStartTimeArgument = subCommandParser.getTimestampArgument("validity-start-time");
    if ((validityStartTimeArgument != null) && validityStartTimeArgument.isPresent()) {
        validityStartTime = validityStartTimeArgument.getValue();
    }
    PublicKeyAlgorithmIdentifier keyAlgorithmIdentifier = null;
    String keyAlgorithmName = null;
    final StringArgument keyAlgorithmArgument = subCommandParser.getStringArgument("key-algorithm");
    if ((keyAlgorithmArgument != null) && keyAlgorithmArgument.isPresent()) {
        final String name = keyAlgorithmArgument.getValue();
        keyAlgorithmIdentifier = PublicKeyAlgorithmIdentifier.forName(name);
        if (keyAlgorithmIdentifier == null) {
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_UNKNOWN_KEY_ALG.get(name));
            return ResultCode.PARAM_ERROR;
        } else {
            keyAlgorithmName = keyAlgorithmIdentifier.getName();
        }
    }
    Integer keySizeBits = null;
    final IntegerArgument keySizeBitsArgument = subCommandParser.getIntegerArgument("key-size-bits");
    if ((keySizeBitsArgument != null) && keySizeBitsArgument.isPresent()) {
        keySizeBits = keySizeBitsArgument.getValue();
    }
    if ((keyAlgorithmIdentifier != null) && (keyAlgorithmIdentifier != PublicKeyAlgorithmIdentifier.RSA) && (keySizeBits == null)) {
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_NO_KEY_SIZE_FOR_NON_RSA_KEY.get());
        return ResultCode.PARAM_ERROR;
    }
    String signatureAlgorithmName = null;
    SignatureAlgorithmIdentifier signatureAlgorithmIdentifier = null;
    final StringArgument signatureAlgorithmArgument = subCommandParser.getStringArgument("signature-algorithm");
    if ((signatureAlgorithmArgument != null) && signatureAlgorithmArgument.isPresent()) {
        final String name = signatureAlgorithmArgument.getValue();
        signatureAlgorithmIdentifier = SignatureAlgorithmIdentifier.forName(name);
        if (signatureAlgorithmIdentifier == null) {
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_UNKNOWN_SIG_ALG.get(name));
            return ResultCode.PARAM_ERROR;
        } else {
            signatureAlgorithmName = signatureAlgorithmIdentifier.getJavaName();
        }
    }
    if ((keyAlgorithmIdentifier != null) && (keyAlgorithmIdentifier != PublicKeyAlgorithmIdentifier.RSA) && (signatureAlgorithmIdentifier == null)) {
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_NO_SIG_ALG_FOR_NON_RSA_KEY.get());
        return ResultCode.PARAM_ERROR;
    }
    // Build a subject alternative name extension, if appropriate.
    final ArrayList<X509CertificateExtension> extensionList = new ArrayList<>(10);
    final GeneralNamesBuilder sanBuilder = new GeneralNamesBuilder();
    final LinkedHashSet<String> sanValues = new LinkedHashSet<>(StaticUtils.computeMapCapacity(10));
    final StringArgument sanDNSArgument = subCommandParser.getStringArgument("subject-alternative-name-dns");
    if ((sanDNSArgument != null) && sanDNSArgument.isPresent()) {
        for (final String value : sanDNSArgument.getValues()) {
            sanBuilder.addDNSName(value);
            sanValues.add("DNS:" + value);
        }
    }
    final StringArgument sanIPArgument = subCommandParser.getStringArgument("subject-alternative-name-ip-address");
    if ((sanIPArgument != null) && sanIPArgument.isPresent()) {
        for (final String value : sanIPArgument.getValues()) {
            try {
                sanBuilder.addIPAddress(LDAPConnectionOptions.DEFAULT_NAME_RESOLVER.getByName(value));
                sanValues.add("IP:" + value);
            } catch (final Exception e) {
                // This should never happen.
                Debug.debugException(e);
                throw new RuntimeException(e);
            }
        }
    }
    final StringArgument sanEmailArgument = subCommandParser.getStringArgument("subject-alternative-name-email-address");
    if ((sanEmailArgument != null) && sanEmailArgument.isPresent()) {
        for (final String value : sanEmailArgument.getValues()) {
            sanBuilder.addRFC822Name(value);
            sanValues.add("EMAIL:" + value);
        }
    }
    final StringArgument sanURIArgument = subCommandParser.getStringArgument("subject-alternative-name-uri");
    if ((sanURIArgument != null) && sanURIArgument.isPresent()) {
        for (final String value : sanURIArgument.getValues()) {
            sanBuilder.addUniformResourceIdentifier(value);
            sanValues.add("URI:" + value);
        }
    }
    final StringArgument sanOIDArgument = subCommandParser.getStringArgument("subject-alternative-name-oid");
    if ((sanOIDArgument != null) && sanOIDArgument.isPresent()) {
        for (final String value : sanOIDArgument.getValues()) {
            sanBuilder.addRegisteredID(new OID(value));
            sanValues.add("OID:" + value);
        }
    }
    if (!sanValues.isEmpty()) {
        try {
            extensionList.add(new SubjectAlternativeNameExtension(false, sanBuilder.build()));
        } catch (final Exception e) {
            // This should never happen.
            Debug.debugException(e);
            throw new RuntimeException(e);
        }
    }
    // Build a set of issuer alternative name extension values.
    final GeneralNamesBuilder ianBuilder = new GeneralNamesBuilder();
    final LinkedHashSet<String> ianValues = new LinkedHashSet<>(StaticUtils.computeMapCapacity(10));
    final StringArgument ianDNSArgument = subCommandParser.getStringArgument("issuer-alternative-name-dns");
    if ((ianDNSArgument != null) && ianDNSArgument.isPresent()) {
        for (final String value : ianDNSArgument.getValues()) {
            ianBuilder.addDNSName(value);
            ianValues.add("DNS:" + value);
        }
    }
    final StringArgument ianIPArgument = subCommandParser.getStringArgument("issuer-alternative-name-ip-address");
    if ((ianIPArgument != null) && ianIPArgument.isPresent()) {
        for (final String value : ianIPArgument.getValues()) {
            try {
                ianBuilder.addIPAddress(LDAPConnectionOptions.DEFAULT_NAME_RESOLVER.getByName(value));
                ianValues.add("IP:" + value);
            } catch (final Exception e) {
                // This should never happen.
                Debug.debugException(e);
                throw new RuntimeException(e);
            }
        }
    }
    final StringArgument ianEmailArgument = subCommandParser.getStringArgument("issuer-alternative-name-email-address");
    if ((ianEmailArgument != null) && ianEmailArgument.isPresent()) {
        for (final String value : ianEmailArgument.getValues()) {
            ianBuilder.addRFC822Name(value);
            ianValues.add("EMAIL:" + value);
        }
    }
    final StringArgument ianURIArgument = subCommandParser.getStringArgument("issuer-alternative-name-uri");
    if ((ianURIArgument != null) && ianURIArgument.isPresent()) {
        for (final String value : ianURIArgument.getValues()) {
            ianBuilder.addUniformResourceIdentifier(value);
            ianValues.add("URI:" + value);
        }
    }
    final StringArgument ianOIDArgument = subCommandParser.getStringArgument("issuer-alternative-name-oid");
    if ((ianOIDArgument != null) && ianOIDArgument.isPresent()) {
        for (final String value : ianOIDArgument.getValues()) {
            ianBuilder.addRegisteredID(new OID(value));
            ianValues.add("OID:" + value);
        }
    }
    if (!ianValues.isEmpty()) {
        try {
            extensionList.add(new IssuerAlternativeNameExtension(false, ianBuilder.build()));
        } catch (final Exception e) {
            // This should never happen.
            Debug.debugException(e);
            throw new RuntimeException(e);
        }
    }
    // Build a basic constraints extension, if appropriate.
    BasicConstraintsExtension basicConstraints = null;
    final BooleanValueArgument basicConstraintsIsCAArgument = subCommandParser.getBooleanValueArgument("basic-constraints-is-ca");
    if ((basicConstraintsIsCAArgument != null) && basicConstraintsIsCAArgument.isPresent()) {
        final boolean isCA = basicConstraintsIsCAArgument.getValue();
        Integer pathLength = null;
        final IntegerArgument pathLengthArgument = subCommandParser.getIntegerArgument("basic-constraints-maximum-path-length");
        if ((pathLengthArgument != null) && pathLengthArgument.isPresent()) {
            if (isCA) {
                pathLength = pathLengthArgument.getValue();
            } else {
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_BC_PATH_LENGTH_WITHOUT_CA.get());
                return ResultCode.PARAM_ERROR;
            }
        }
        basicConstraints = new BasicConstraintsExtension(false, isCA, pathLength);
        extensionList.add(basicConstraints);
    }
    // Build a key usage extension, if appropriate.
    KeyUsageExtension keyUsage = null;
    final StringArgument keyUsageArgument = subCommandParser.getStringArgument("key-usage");
    if ((keyUsageArgument != null) && keyUsageArgument.isPresent()) {
        boolean digitalSignature = false;
        boolean nonRepudiation = false;
        boolean keyEncipherment = false;
        boolean dataEncipherment = false;
        boolean keyAgreement = false;
        boolean keyCertSign = false;
        boolean crlSign = false;
        boolean encipherOnly = false;
        boolean decipherOnly = false;
        for (final String value : keyUsageArgument.getValues()) {
            if (value.equalsIgnoreCase("digital-signature") || value.equalsIgnoreCase("digitalSignature")) {
                digitalSignature = true;
            } else if (value.equalsIgnoreCase("non-repudiation") || value.equalsIgnoreCase("nonRepudiation") || value.equalsIgnoreCase("content-commitment") || value.equalsIgnoreCase("contentCommitment")) {
                nonRepudiation = true;
            } else if (value.equalsIgnoreCase("key-encipherment") || value.equalsIgnoreCase("keyEncipherment")) {
                keyEncipherment = true;
            } else if (value.equalsIgnoreCase("data-encipherment") || value.equalsIgnoreCase("dataEncipherment")) {
                dataEncipherment = true;
            } else if (value.equalsIgnoreCase("key-agreement") || value.equalsIgnoreCase("keyAgreement")) {
                keyAgreement = true;
            } else if (value.equalsIgnoreCase("key-cert-sign") || value.equalsIgnoreCase("keyCertSign")) {
                keyCertSign = true;
            } else if (value.equalsIgnoreCase("crl-sign") || value.equalsIgnoreCase("crlSign")) {
                crlSign = true;
            } else if (value.equalsIgnoreCase("encipher-only") || value.equalsIgnoreCase("encipherOnly")) {
                encipherOnly = true;
            } else if (value.equalsIgnoreCase("decipher-only") || value.equalsIgnoreCase("decipherOnly")) {
                decipherOnly = true;
            } else {
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_INVALID_KEY_USAGE.get(value));
                return ResultCode.PARAM_ERROR;
            }
        }
        keyUsage = new KeyUsageExtension(false, digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, crlSign, encipherOnly, decipherOnly);
        extensionList.add(keyUsage);
    }
    // Build an extended key usage extension, if appropriate.
    ExtendedKeyUsageExtension extendedKeyUsage = null;
    final StringArgument extendedKeyUsageArgument = subCommandParser.getStringArgument("extended-key-usage");
    if ((extendedKeyUsageArgument != null) && extendedKeyUsageArgument.isPresent()) {
        final List<String> values = extendedKeyUsageArgument.getValues();
        final ArrayList<OID> keyPurposeIDs = new ArrayList<>(values.size());
        for (final String value : values) {
            if (value.equalsIgnoreCase("server-auth") || value.equalsIgnoreCase("serverAuth") || value.equalsIgnoreCase("server-authentication") || value.equalsIgnoreCase("serverAuthentication") || value.equalsIgnoreCase("tls-server-authentication") || value.equalsIgnoreCase("tlsServerAuthentication")) {
                keyPurposeIDs.add(ExtendedKeyUsageID.TLS_SERVER_AUTHENTICATION.getOID());
            } else if (value.equalsIgnoreCase("client-auth") || value.equalsIgnoreCase("clientAuth") || value.equalsIgnoreCase("client-authentication") || value.equalsIgnoreCase("clientAuthentication") || value.equalsIgnoreCase("tls-client-authentication") || value.equalsIgnoreCase("tlsClientAuthentication")) {
                keyPurposeIDs.add(ExtendedKeyUsageID.TLS_CLIENT_AUTHENTICATION.getOID());
            } else if (value.equalsIgnoreCase("code-signing") || value.equalsIgnoreCase("codeSigning")) {
                keyPurposeIDs.add(ExtendedKeyUsageID.CODE_SIGNING.getOID());
            } else if (value.equalsIgnoreCase("email-protection") || value.equalsIgnoreCase("emailProtection")) {
                keyPurposeIDs.add(ExtendedKeyUsageID.EMAIL_PROTECTION.getOID());
            } else if (value.equalsIgnoreCase("time-stamping") || value.equalsIgnoreCase("timeStamping")) {
                keyPurposeIDs.add(ExtendedKeyUsageID.TIME_STAMPING.getOID());
            } else if (value.equalsIgnoreCase("ocsp-signing") || value.equalsIgnoreCase("ocspSigning")) {
                keyPurposeIDs.add(ExtendedKeyUsageID.OCSP_SIGNING.getOID());
            } else if (OID.isStrictlyValidNumericOID(value)) {
                keyPurposeIDs.add(new OID(value));
            } else {
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_INVALID_EXTENDED_KEY_USAGE.get(value));
                return ResultCode.PARAM_ERROR;
            }
        }
        try {
            extendedKeyUsage = new ExtendedKeyUsageExtension(false, keyPurposeIDs);
        } catch (final Exception e) {
            // This should never happen.
            Debug.debugException(e);
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_EXTENDED_KEY_USAGE_ERROR.get());
            e.printStackTrace(getErr());
            return ResultCode.PARAM_ERROR;
        }
        extensionList.add(extendedKeyUsage);
    }
    // Build a list of generic extensions.
    final ArrayList<X509CertificateExtension> genericExtensions = new ArrayList<>(5);
    final StringArgument extensionArgument = subCommandParser.getStringArgument("extension");
    if ((extensionArgument != null) && extensionArgument.isPresent()) {
        for (final String value : extensionArgument.getValues()) {
            try {
                final int firstColonPos = value.indexOf(':');
                final int secondColonPos = value.indexOf(':', firstColonPos + 1);
                final OID oid = new OID(value.substring(0, firstColonPos));
                if (!oid.isStrictlyValidNumericOID()) {
                    wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_EXT_MALFORMED_OID.get(value, oid.toString()));
                    return ResultCode.PARAM_ERROR;
                }
                final boolean criticality;
                final String criticalityString = value.substring(firstColonPos + 1, secondColonPos);
                if (criticalityString.equalsIgnoreCase("true") || criticalityString.equalsIgnoreCase("t") || criticalityString.equalsIgnoreCase("yes") || criticalityString.equalsIgnoreCase("y") || criticalityString.equalsIgnoreCase("on") || criticalityString.equalsIgnoreCase("1")) {
                    criticality = true;
                } else if (criticalityString.equalsIgnoreCase("false") || criticalityString.equalsIgnoreCase("f") || criticalityString.equalsIgnoreCase("no") || criticalityString.equalsIgnoreCase("n") || criticalityString.equalsIgnoreCase("off") || criticalityString.equalsIgnoreCase("0")) {
                    criticality = false;
                } else {
                    wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_EXT_INVALID_CRITICALITY.get(value, criticalityString));
                    return ResultCode.PARAM_ERROR;
                }
                final byte[] valueBytes;
                try {
                    valueBytes = StaticUtils.fromHex(value.substring(secondColonPos + 1));
                } catch (final Exception e) {
                    Debug.debugException(e);
                    wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_EXT_INVALID_VALUE.get(value));
                    return ResultCode.PARAM_ERROR;
                }
                final X509CertificateExtension extension = new X509CertificateExtension(oid, criticality, valueBytes);
                genericExtensions.add(extension);
                extensionList.add(extension);
            } catch (final Exception e) {
                Debug.debugException(e);
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_EXT_MALFORMED.get(value));
                return ResultCode.PARAM_ERROR;
            }
        }
    }
    final String keystoreType;
    try {
        keystoreType = inferKeystoreType(keystorePath);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    final char[] keystorePassword;
    try {
        keystorePassword = getKeystorePassword(keystorePath);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    // Get the keystore.
    final KeyStore keystore;
    try {
        keystore = getKeystore(keystoreType, keystorePath, keystorePassword);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    // If there is a private key, then see if we need to use a private key
    // password that is different from the keystore password.
    final char[] privateKeyPassword;
    try {
        privateKeyPassword = getPrivateKeyPassword(keystore, alias, keystorePassword);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    // perform the appropriate processing for that.
    if (replaceExistingCertificate) {
        // specified alias.
        if (!hasKeyAlias(keystore, alias)) {
            if (hasCertificateAlias(keystore, alias)) {
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_REPLACE_ALIAS_IS_CERT.get(alias, keystorePath.getAbsolutePath()));
                return ResultCode.PARAM_ERROR;
            } else {
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_REPLACE_NO_SUCH_ALIAS.get(alias, keystorePath.getAbsolutePath()));
                return ResultCode.PARAM_ERROR;
            }
        }
        // Get the certificate to replace, along with its key pair.
        final X509Certificate certToReplace;
        final KeyPair keyPair;
        try {
            final Certificate[] chain = keystore.getCertificateChain(alias);
            certToReplace = new X509Certificate(chain[0].getEncoded());
            final PublicKey publicKey = chain[0].getPublicKey();
            final PrivateKey privateKey = (PrivateKey) keystore.getKey(alias, privateKeyPassword);
            keyPair = new KeyPair(publicKey, privateKey);
        } catch (final Exception e) {
            Debug.debugException(e);
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_REPLACE_COULD_NOT_GET_CERT.get(alias));
            e.printStackTrace(getErr());
            return ResultCode.LOCAL_ERROR;
        }
        // Assign the remaining values using information in the existing
        // certificate.
        signatureAlgorithmIdentifier = SignatureAlgorithmIdentifier.forOID(certToReplace.getSignatureAlgorithmOID());
        if (signatureAlgorithmIdentifier == null) {
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_UNKNOWN_SIG_ALG_IN_CERT.get(certToReplace.getSignatureAlgorithmOID()));
            return ResultCode.PARAM_ERROR;
        } else {
            signatureAlgorithmName = signatureAlgorithmIdentifier.getJavaName();
        }
        if (subjectDN == null) {
            subjectDN = certToReplace.getSubjectDN();
        }
        if (inheritExtensions) {
            for (final X509CertificateExtension extension : certToReplace.getExtensions()) {
                if ((extension instanceof AuthorityKeyIdentifierExtension) || (extension instanceof IssuerAlternativeNameExtension)) {
                // This extension applies to the issuer.  We won't include this in
                // the set of inherited extensions.
                } else if (extension instanceof SubjectKeyIdentifierExtension) {
                // The generated certificate will automatically include a subject
                // key identifier extension, so we don't need to include it.
                } else if (extension instanceof BasicConstraintsExtension) {
                    // Don't override a value already provided on the command line.
                    if (basicConstraints == null) {
                        basicConstraints = (BasicConstraintsExtension) extension;
                        extensionList.add(basicConstraints);
                    }
                } else if (extension instanceof ExtendedKeyUsageExtension) {
                    // Don't override a value already provided on the command line.
                    if (extendedKeyUsage == null) {
                        extendedKeyUsage = (ExtendedKeyUsageExtension) extension;
                        extensionList.add(extendedKeyUsage);
                    }
                } else if (extension instanceof KeyUsageExtension) {
                    // Don't override a value already provided on the command line.
                    if (keyUsage == null) {
                        keyUsage = (KeyUsageExtension) extension;
                        extensionList.add(keyUsage);
                    }
                } else if (extension instanceof SubjectAlternativeNameExtension) {
                    // line.
                    if (sanValues.isEmpty()) {
                        final SubjectAlternativeNameExtension e = (SubjectAlternativeNameExtension) extension;
                        for (final String dnsName : e.getDNSNames()) {
                            sanValues.add("DNS:" + dnsName);
                        }
                        for (final InetAddress ipAddress : e.getIPAddresses()) {
                            sanValues.add("IP:" + ipAddress.getHostAddress());
                        }
                        for (final String emailAddress : e.getRFC822Names()) {
                            sanValues.add("EMAIL:" + emailAddress);
                        }
                        for (final String uri : e.getUniformResourceIdentifiers()) {
                            sanValues.add("URI:" + uri);
                        }
                        for (final OID oid : e.getRegisteredIDs()) {
                            sanValues.add("OID:" + oid.toString());
                        }
                        extensionList.add(extension);
                    }
                } else {
                    genericExtensions.add(extension);
                    extensionList.add(extension);
                }
            }
        }
        // Create an array with the final set of extensions to include in the
        // certificate or certificate signing request.
        final X509CertificateExtension[] extensions = new X509CertificateExtension[extensionList.size()];
        extensionList.toArray(extensions);
        // a keytool command that we could use to accomplish it.
        if (isGenerateCertificate) {
            if (displayKeytoolCommand) {
                final ArrayList<String> keytoolArguments = new ArrayList<>(30);
                keytoolArguments.add("-selfcert");
                keytoolArguments.add("-keystore");
                keytoolArguments.add(keystorePath.getAbsolutePath());
                keytoolArguments.add("-storetype");
                keytoolArguments.add(keystoreType);
                keytoolArguments.add("-storepass");
                keytoolArguments.add("*****REDACTED*****");
                keytoolArguments.add("-keypass");
                keytoolArguments.add("*****REDACTED*****");
                keytoolArguments.add("-alias");
                keytoolArguments.add(alias);
                keytoolArguments.add("-dname");
                keytoolArguments.add(subjectDN.toString());
                keytoolArguments.add("-sigalg");
                keytoolArguments.add(signatureAlgorithmName);
                keytoolArguments.add("-validity");
                keytoolArguments.add(String.valueOf(daysValid));
                if (validityStartTime != null) {
                    keytoolArguments.add("-startdate");
                    keytoolArguments.add(formatValidityStartTime(validityStartTime));
                }
                addExtensionArguments(keytoolArguments, basicConstraints, keyUsage, extendedKeyUsage, sanValues, ianValues, genericExtensions);
                displayKeytoolCommand(keytoolArguments);
            }
            // Generate the self-signed certificate.
            final long notBefore;
            if (validityStartTime == null) {
                notBefore = System.currentTimeMillis();
            } else {
                notBefore = validityStartTime.getTime();
            }
            final long notAfter = notBefore + TimeUnit.DAYS.toMillis(daysValid);
            final X509Certificate certificate;
            final Certificate[] chain;
            try {
                certificate = X509Certificate.generateSelfSignedCertificate(signatureAlgorithmIdentifier, keyPair, subjectDN, notBefore, notAfter, extensions);
                chain = new Certificate[] { certificate.toCertificate() };
            } catch (final Exception e) {
                Debug.debugException(e);
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_GENERATING_CERT.get());
                e.printStackTrace(getErr());
                return ResultCode.LOCAL_ERROR;
            }
            // Update the keystore with the new certificate.
            try {
                keystore.setKeyEntry(alias, keyPair.getPrivate(), privateKeyPassword, chain);
                writeKeystore(keystore, keystorePath, keystorePassword);
            } catch (final Exception e) {
                Debug.debugException(e);
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_UPDATING_KEYSTORE.get());
                e.printStackTrace(getErr());
                return ResultCode.LOCAL_ERROR;
            }
            // Display the certificate we just generated to the end user.
            out();
            wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_GENERATED_SELF_CERT.get());
            printCertificate(certificate, "", false);
            // If we should write an output file, then do that now.
            if (outputFile != null) {
                try (PrintStream ps = new PrintStream(outputFile)) {
                    final byte[] certBytes = certificate.getX509CertificateBytes();
                    if (outputPEM) {
                        writePEMCertificate(ps, certBytes);
                    } else {
                        ps.write(certBytes);
                    }
                    out();
                    wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_GEN_CERT_WROTE_OUTPUT_FILE.get(outputFile.getAbsolutePath()));
                } catch (final Exception e) {
                    Debug.debugException(e);
                    err();
                    wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_WRITING_CERT.get(outputFile.getAbsolutePath()));
                    e.printStackTrace(getErr());
                    return ResultCode.LOCAL_ERROR;
                }
            }
            return ResultCode.SUCCESS;
        } else {
            // Build the keytool command used to generate the certificate signing
            // request.
            Validator.ensureTrue(isGenerateCSR);
            if (displayKeytoolCommand) {
                final ArrayList<String> keytoolArguments = new ArrayList<>(30);
                keytoolArguments.add("-certreq");
                keytoolArguments.add("-keystore");
                keytoolArguments.add(keystorePath.getAbsolutePath());
                keytoolArguments.add("-storetype");
                keytoolArguments.add(keystoreType);
                keytoolArguments.add("-storepass");
                keytoolArguments.add("*****REDACTED*****");
                keytoolArguments.add("-keypass");
                keytoolArguments.add("*****REDACTED*****");
                keytoolArguments.add("-alias");
                keytoolArguments.add(alias);
                keytoolArguments.add("-dname");
                keytoolArguments.add(subjectDN.toString());
                keytoolArguments.add("-sigalg");
                keytoolArguments.add(signatureAlgorithmName);
                addExtensionArguments(keytoolArguments, basicConstraints, keyUsage, extendedKeyUsage, sanValues, ianValues, genericExtensions);
                if (outputFile != null) {
                    keytoolArguments.add("-file");
                    keytoolArguments.add(outputFile.getAbsolutePath());
                }
                displayKeytoolCommand(keytoolArguments);
            }
            // Generate the certificate signing request.
            final PKCS10CertificateSigningRequest certificateSigningRequest;
            try {
                certificateSigningRequest = PKCS10CertificateSigningRequest.generateCertificateSigningRequest(signatureAlgorithmIdentifier, keyPair, subjectDN, extensions);
            } catch (final Exception e) {
                Debug.debugException(e);
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_GENERATING_CSR.get());
                e.printStackTrace(getErr());
                return ResultCode.LOCAL_ERROR;
            }
            // location.
            try {
                final PrintStream ps;
                if (outputFile == null) {
                    ps = getOut();
                } else {
                    ps = new PrintStream(outputFile);
                }
                if (outputPEM) {
                    writePEMCertificateSigningRequest(ps, certificateSigningRequest.getPKCS10CertificateSigningRequestBytes());
                } else {
                    ps.write(certificateSigningRequest.getPKCS10CertificateSigningRequestBytes());
                }
                if (outputFile != null) {
                    ps.close();
                }
            } catch (final Exception e) {
                Debug.debugException(e);
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_WRITING_CSR.get());
                e.printStackTrace(getErr());
                return ResultCode.LOCAL_ERROR;
            }
            // able to see it.
            if (outputFile != null) {
                out();
                wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_GENERATED_CSR.get(outputFile.getAbsolutePath()));
            }
            return ResultCode.SUCCESS;
        }
    }
    // certificate.  Perform any remaining argument assignment and validation.
    if ((subjectDN == null) && (!isSignCSR)) {
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_NO_SUBJECT_DN_WITHOUT_REPLACE.get());
        return ResultCode.PARAM_ERROR;
    }
    if (keyAlgorithmIdentifier == null) {
        keyAlgorithmIdentifier = PublicKeyAlgorithmIdentifier.RSA;
        keyAlgorithmName = keyAlgorithmIdentifier.getName();
    }
    if (keySizeBits == null) {
        keySizeBits = 2048;
    }
    if ((signatureAlgorithmIdentifier == null) && (!isSignCSR)) {
        signatureAlgorithmIdentifier = SignatureAlgorithmIdentifier.SHA_256_WITH_RSA;
        signatureAlgorithmName = signatureAlgorithmIdentifier.getJavaName();
    }
    // certificate.
    if (isGenerateCertificate || isGenerateCSR) {
        // keystore.
        if (hasKeyAlias(keystore, alias) || hasCertificateAlias(keystore, alias)) {
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ALIAS_EXISTS_WITHOUT_REPLACE.get(alias));
            return ResultCode.PARAM_ERROR;
        }
        if (displayKeytoolCommand) {
            final ArrayList<String> keytoolArguments = new ArrayList<>(30);
            keytoolArguments.add("-genkeypair");
            keytoolArguments.add("-keystore");
            keytoolArguments.add(keystorePath.getAbsolutePath());
            keytoolArguments.add("-storetype");
            keytoolArguments.add(keystoreType);
            keytoolArguments.add("-storepass");
            keytoolArguments.add("*****REDACTED*****");
            keytoolArguments.add("-keypass");
            keytoolArguments.add("*****REDACTED*****");
            keytoolArguments.add("-alias");
            keytoolArguments.add(alias);
            keytoolArguments.add("-dname");
            keytoolArguments.add(subjectDN.toString());
            keytoolArguments.add("-keyalg");
            keytoolArguments.add(keyAlgorithmName);
            keytoolArguments.add("-keysize");
            keytoolArguments.add(String.valueOf(keySizeBits));
            keytoolArguments.add("-sigalg");
            keytoolArguments.add(signatureAlgorithmName);
            keytoolArguments.add("-validity");
            keytoolArguments.add(String.valueOf(daysValid));
            if (validityStartTime != null) {
                keytoolArguments.add("-startdate");
                keytoolArguments.add(formatValidityStartTime(validityStartTime));
            }
            addExtensionArguments(keytoolArguments, basicConstraints, keyUsage, extendedKeyUsage, sanValues, ianValues, genericExtensions);
            displayKeytoolCommand(keytoolArguments);
        }
        // Generate the self-signed certificate.
        final long notBefore;
        if (validityStartTime == null) {
            notBefore = System.currentTimeMillis();
        } else {
            notBefore = validityStartTime.getTime();
        }
        final long notAfter = notBefore + TimeUnit.DAYS.toMillis(daysValid);
        final X509CertificateExtension[] extensions = new X509CertificateExtension[extensionList.size()];
        extensionList.toArray(extensions);
        final Certificate[] chain;
        final KeyPair keyPair;
        final X509Certificate certificate;
        try {
            final ObjectPair<X509Certificate, KeyPair> p = X509Certificate.generateSelfSignedCertificate(signatureAlgorithmIdentifier, keyAlgorithmIdentifier, keySizeBits, subjectDN, notBefore, notAfter, extensions);
            certificate = p.getFirst();
            chain = new Certificate[] { certificate.toCertificate() };
            keyPair = p.getSecond();
        } catch (final Exception e) {
            Debug.debugException(e);
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_GENERATING_CERT.get());
            e.printStackTrace(getErr());
            return ResultCode.LOCAL_ERROR;
        }
        // Update the keystore with the new certificate.
        try {
            keystore.setKeyEntry(alias, keyPair.getPrivate(), privateKeyPassword, chain);
            writeKeystore(keystore, keystorePath, keystorePassword);
        } catch (final Exception e) {
            Debug.debugException(e);
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_UPDATING_KEYSTORE.get());
            e.printStackTrace(getErr());
            return ResultCode.LOCAL_ERROR;
        }
        if (isNewKeystore) {
            out();
            wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_GEN_CERT_CERT_CREATED_KEYSTORE.get(getUserFriendlyKeystoreType(keystoreType)));
        }
        // file.
        if (isGenerateCertificate) {
            out();
            wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_GENERATED_SELF_CERT.get());
            printCertificate(certificate, "", false);
            // If we should write an output file, then do that now.
            if (outputFile != null) {
                try (PrintStream ps = new PrintStream(outputFile)) {
                    final byte[] certBytes = certificate.getX509CertificateBytes();
                    if (outputPEM) {
                        writePEMCertificate(ps, certBytes);
                    } else {
                        ps.write(certBytes);
                    }
                    out();
                    wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_GEN_CERT_WROTE_OUTPUT_FILE.get(outputFile.getAbsolutePath()));
                } catch (final Exception e) {
                    Debug.debugException(e);
                    err();
                    wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_WRITING_CERT.get(outputFile.getAbsolutePath()));
                    e.printStackTrace(getErr());
                    return ResultCode.LOCAL_ERROR;
                }
            }
            return ResultCode.SUCCESS;
        }
        // If we're generating a certificate signing request, then put together
        // the appropriate set of arguments for that.
        Validator.ensureTrue(isGenerateCSR);
        out();
        wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_GENERATED_KEYPAIR.get());
        if (displayKeytoolCommand) {
            final ArrayList<String> keytoolArguments = new ArrayList<>(30);
            keytoolArguments.add("-certreq");
            keytoolArguments.add("-keystore");
            keytoolArguments.add(keystorePath.getAbsolutePath());
            keytoolArguments.add("-storetype");
            keytoolArguments.add(keystoreType);
            keytoolArguments.add("-storepass");
            keytoolArguments.add("*****REDACTED*****");
            keytoolArguments.add("-keypass");
            keytoolArguments.add("*****REDACTED*****");
            keytoolArguments.add("-alias");
            keytoolArguments.add(alias);
            keytoolArguments.add("-dname");
            keytoolArguments.add(subjectDN.toString());
            keytoolArguments.add("-sigalg");
            keytoolArguments.add(signatureAlgorithmName);
            addExtensionArguments(keytoolArguments, basicConstraints, keyUsage, extendedKeyUsage, sanValues, ianValues, genericExtensions);
            if (outputFile != null) {
                keytoolArguments.add("-file");
                keytoolArguments.add(outputFile.getAbsolutePath());
            }
            displayKeytoolCommand(keytoolArguments);
        }
        // Generate the certificate signing request.
        final PKCS10CertificateSigningRequest certificateSigningRequest;
        try {
            certificateSigningRequest = PKCS10CertificateSigningRequest.generateCertificateSigningRequest(signatureAlgorithmIdentifier, keyPair, subjectDN, extensions);
        } catch (final Exception e) {
            Debug.debugException(e);
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_GENERATING_CSR.get());
            e.printStackTrace(getErr());
            return ResultCode.LOCAL_ERROR;
        }
        // location.
        try {
            final PrintStream ps;
            if (outputFile == null) {
                ps = getOut();
            } else {
                ps = new PrintStream(outputFile);
            }
            if (outputPEM) {
                writePEMCertificateSigningRequest(ps, certificateSigningRequest.getPKCS10CertificateSigningRequestBytes());
            } else {
                ps.write(certificateSigningRequest.getPKCS10CertificateSigningRequestBytes());
            }
            if (outputFile != null) {
                ps.close();
            }
        } catch (final Exception e) {
            Debug.debugException(e);
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_WRITING_CSR.get());
            e.printStackTrace(getErr());
            return ResultCode.LOCAL_ERROR;
        }
        // able to see it.
        if (outputFile != null) {
            out();
            wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_GENERATED_CSR.get(outputFile.getAbsolutePath()));
        }
        return ResultCode.SUCCESS;
    }
    // If we've gotten here, then we should be signing a certificate signing
    // request.  Make sure that the keystore already has a private key entry
    // with the specified alias.
    Validator.ensureTrue(isSignCSR);
    if (!hasKeyAlias(keystore, alias)) {
        if (hasCertificateAlias(keystore, alias)) {
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_SIGN_ALIAS_IS_CERT.get(alias, keystorePath.getAbsolutePath()));
            return ResultCode.PARAM_ERROR;
        } else {
            wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_SIGN_NO_SUCH_ALIAS.get(alias, keystorePath.getAbsolutePath()));
            return ResultCode.PARAM_ERROR;
        }
    }
    // Get the signing certificate and its key pair.
    final PrivateKey issuerPrivateKey;
    final X509Certificate issuerCertificate;
    try {
        final Certificate[] chain = keystore.getCertificateChain(alias);
        issuerCertificate = new X509Certificate(chain[0].getEncoded());
        issuerPrivateKey = (PrivateKey) keystore.getKey(alias, privateKeyPassword);
    } catch (final Exception e) {
        Debug.debugException(e);
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_SIGN_CANNOT_GET_SIGNING_CERT.get(alias));
        e.printStackTrace(getErr());
        return ResultCode.LOCAL_ERROR;
    }
    // Make sure that we can decode the certificate signing request.
    final PKCS10CertificateSigningRequest csr;
    try {
        csr = readCertificateSigningRequestFromFile(inputFile);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    // Make sure that we can verify the certificate signing request's signature.
    try {
        csr.verifySignature();
    } catch (final CertException ce) {
        Debug.debugException(ce);
        wrapErr(0, WRAP_COLUMN, ce.getMessage());
        return ResultCode.PARAM_ERROR;
    }
    // Prompt about whether to sign the request, if appropriate.
    if (!noPrompt) {
        out();
        wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_GEN_CERT_SIGN_CONFIRM.get());
        out();
        printCertificateSigningRequest(csr, false, "");
        out();
        try {
            if (!promptForYesNo(INFO_MANAGE_CERTS_GEN_CERT_PROMPT_SIGN.get())) {
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_SIGN_CANCELED.get());
                return ResultCode.USER_CANCELED;
            }
        } catch (final LDAPException le) {
            Debug.debugException(le);
            err();
            wrapErr(0, WRAP_COLUMN, le.getMessage());
            return le.getResultCode();
        }
    }
    // from it.
    if ((subjectDN == null) || (signatureAlgorithmIdentifier == null) || includeRequestedExtensions) {
        if (subjectDN == null) {
            subjectDN = csr.getSubjectDN();
        }
        if (signatureAlgorithmIdentifier == null) {
            signatureAlgorithmIdentifier = SignatureAlgorithmIdentifier.forOID(csr.getSignatureAlgorithmOID());
            if (signatureAlgorithmIdentifier == null) {
                wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_UNKNOWN_SIG_ALG_IN_CSR.get(csr.getSignatureAlgorithmOID()));
                return ResultCode.PARAM_ERROR;
            } else {
                signatureAlgorithmName = signatureAlgorithmIdentifier.getJavaName();
            }
        }
        if (includeRequestedExtensions) {
            for (final X509CertificateExtension extension : csr.getExtensions()) {
                if ((extension instanceof AuthorityKeyIdentifierExtension) || (extension instanceof IssuerAlternativeNameExtension)) {
                // This extension applies to the issuer.  We won't include this in
                // the set of inherited extensions.
                } else if (extension instanceof SubjectKeyIdentifierExtension) {
                // The generated certificate will automatically include a subject
                // key identifier extension, so we don't need to include it.
                } else if (extension instanceof BasicConstraintsExtension) {
                    // Don't override a value already provided on the command line.
                    if (basicConstraints == null) {
                        basicConstraints = (BasicConstraintsExtension) extension;
                        extensionList.add(basicConstraints);
                    }
                } else if (extension instanceof ExtendedKeyUsageExtension) {
                    // Don't override a value already provided on the command line.
                    if (extendedKeyUsage == null) {
                        extendedKeyUsage = (ExtendedKeyUsageExtension) extension;
                        extensionList.add(extendedKeyUsage);
                    }
                } else if (extension instanceof KeyUsageExtension) {
                    // Don't override a value already provided on the command line.
                    if (keyUsage == null) {
                        keyUsage = (KeyUsageExtension) extension;
                        extensionList.add(keyUsage);
                    }
                } else if (extension instanceof SubjectAlternativeNameExtension) {
                    // line.
                    if (sanValues.isEmpty()) {
                        final SubjectAlternativeNameExtension e = (SubjectAlternativeNameExtension) extension;
                        for (final String dnsName : e.getDNSNames()) {
                            sanBuilder.addDNSName(dnsName);
                            sanValues.add("DNS:" + dnsName);
                        }
                        for (final InetAddress ipAddress : e.getIPAddresses()) {
                            sanBuilder.addIPAddress(ipAddress);
                            sanValues.add("IP:" + ipAddress.getHostAddress());
                        }
                        for (final String emailAddress : e.getRFC822Names()) {
                            sanBuilder.addRFC822Name(emailAddress);
                            sanValues.add("EMAIL:" + emailAddress);
                        }
                        for (final String uri : e.getUniformResourceIdentifiers()) {
                            sanBuilder.addUniformResourceIdentifier(uri);
                            sanValues.add("URI:" + uri);
                        }
                        for (final OID oid : e.getRegisteredIDs()) {
                            sanBuilder.addRegisteredID(oid);
                            sanValues.add("OID:" + oid.toString());
                        }
                        try {
                            extensionList.add(new SubjectAlternativeNameExtension(false, sanBuilder.build()));
                        } catch (final Exception ex) {
                            // This should never happen.
                            Debug.debugException(ex);
                            throw new RuntimeException(ex);
                        }
                    }
                } else {
                    genericExtensions.add(extension);
                    extensionList.add(extension);
                }
            }
        }
    }
    // Generate the keytool arguments to use to sign the requested certificate.
    final ArrayList<String> keytoolArguments = new ArrayList<>(30);
    keytoolArguments.add("-gencert");
    keytoolArguments.add("-keystore");
    keytoolArguments.add(keystorePath.getAbsolutePath());
    keytoolArguments.add("-storetype");
    keytoolArguments.add(keystoreType);
    keytoolArguments.add("-storepass");
    keytoolArguments.add("*****REDACTED*****");
    keytoolArguments.add("-keypass");
    keytoolArguments.add("*****REDACTED*****");
    keytoolArguments.add("-alias");
    keytoolArguments.add(alias);
    keytoolArguments.add("-dname");
    keytoolArguments.add(subjectDN.toString());
    keytoolArguments.add("-sigalg");
    keytoolArguments.add(signatureAlgorithmName);
    keytoolArguments.add("-validity");
    keytoolArguments.add(String.valueOf(daysValid));
    if (validityStartTime != null) {
        keytoolArguments.add("-startdate");
        keytoolArguments.add(formatValidityStartTime(validityStartTime));
    }
    addExtensionArguments(keytoolArguments, basicConstraints, keyUsage, extendedKeyUsage, sanValues, ianValues, genericExtensions);
    keytoolArguments.add("-infile");
    keytoolArguments.add(inputFile.getAbsolutePath());
    if (outputFile != null) {
        keytoolArguments.add("-outfile");
        keytoolArguments.add(outputFile.getAbsolutePath());
    }
    if (outputPEM) {
        keytoolArguments.add("-rfc");
    }
    if (displayKeytoolCommand) {
        displayKeytoolCommand(keytoolArguments);
    }
    // Generate the signed certificate.
    final long notBefore;
    if (validityStartTime == null) {
        notBefore = System.currentTimeMillis();
    } else {
        notBefore = validityStartTime.getTime();
    }
    final long notAfter = notBefore + TimeUnit.DAYS.toMillis(daysValid);
    final X509CertificateExtension[] extensions = new X509CertificateExtension[extensionList.size()];
    extensionList.toArray(extensions);
    final X509Certificate signedCertificate;
    try {
        signedCertificate = X509Certificate.generateIssuerSignedCertificate(signatureAlgorithmIdentifier, issuerCertificate, issuerPrivateKey, csr.getPublicKeyAlgorithmOID(), csr.getPublicKeyAlgorithmParameters(), csr.getEncodedPublicKey(), csr.getDecodedPublicKey(), subjectDN, notBefore, notAfter, extensions);
    } catch (final Exception e) {
        Debug.debugException(e);
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_SIGNING_CERT.get());
        e.printStackTrace(getErr());
        return ResultCode.LOCAL_ERROR;
    }
    // Write the signed certificate signing request to the appropriate location.
    try {
        final PrintStream ps;
        if (outputFile == null) {
            ps = getOut();
        } else {
            ps = new PrintStream(outputFile);
        }
        if (outputPEM) {
            writePEMCertificate(ps, signedCertificate.getX509CertificateBytes());
        } else {
            ps.write(signedCertificate.getX509CertificateBytes());
        }
        if (outputFile != null) {
            ps.close();
        }
    } catch (final Exception e) {
        Debug.debugException(e);
        wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GEN_CERT_ERROR_WRITING_SIGNED_CERT.get());
        e.printStackTrace(getErr());
        return ResultCode.LOCAL_ERROR;
    }
    // able to see it.
    if (outputFile != null) {
        out();
        wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_SIGNED_CERT.get(outputFile.getAbsolutePath()));
    }
    return ResultCode.SUCCESS;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) PrivateKey(java.security.PrivateKey) ArrayList(java.util.ArrayList) DN(com.unboundid.ldap.sdk.DN) ASN1BitString(com.unboundid.asn1.ASN1BitString) FileArgument(com.unboundid.util.args.FileArgument) DNArgument(com.unboundid.util.args.DNArgument) IntegerArgument(com.unboundid.util.args.IntegerArgument) TimestampArgument(com.unboundid.util.args.TimestampArgument) KeyPair(java.security.KeyPair) SubCommand(com.unboundid.util.args.SubCommand) PublicKey(java.security.PublicKey) OID(com.unboundid.util.OID) LDAPException(com.unboundid.ldap.sdk.LDAPException) File(java.io.File) InetAddress(java.net.InetAddress) Certificate(java.security.cert.Certificate) BooleanValueArgument(com.unboundid.util.args.BooleanValueArgument) PrintStream(java.io.PrintStream) BooleanArgument(com.unboundid.util.args.BooleanArgument) KeyStore(java.security.KeyStore) Date(java.util.Date) ArgumentException(com.unboundid.util.args.ArgumentException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) LDAPException(com.unboundid.ldap.sdk.LDAPException) IOException(java.io.IOException) StringArgument(com.unboundid.util.args.StringArgument) NotNull(com.unboundid.util.NotNull)

Example 23 with BooleanArgument

use of com.unboundid.util.args.BooleanArgument in project ldapsdk by pingidentity.

the class ManageCertificates method doDisplayCertificateFile.

/**
 * Performs the necessary processing for the display-certificate-file
 * subcommand.
 *
 * @return  A result code that indicates whether the processing completed
 *          successfully.
 */
@NotNull()
private ResultCode doDisplayCertificateFile() {
    // Get the values of a number of configured arguments.
    final FileArgument certificateFileArgument = subCommandParser.getFileArgument("certificate-file");
    final File certificateFile = certificateFileArgument.getValue();
    final BooleanArgument verboseArgument = subCommandParser.getBooleanArgument("verbose");
    final boolean verbose = ((verboseArgument != null) && verboseArgument.isPresent());
    final BooleanArgument displayKeytoolCommandArgument = subCommandParser.getBooleanArgument("display-keytool-command");
    if ((displayKeytoolCommandArgument != null) && displayKeytoolCommandArgument.isPresent()) {
        final ArrayList<String> keytoolArgs = new ArrayList<>(10);
        keytoolArgs.add("-printcert");
        keytoolArgs.add("-file");
        keytoolArgs.add(certificateFile.getAbsolutePath());
        if (verbose) {
            keytoolArgs.add("-v");
        }
        displayKeytoolCommand(keytoolArgs);
    }
    // Read the certificates from the specified file.
    final List<X509Certificate> certificates;
    try {
        certificates = readCertificatesFromFile(certificateFile);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    // If there aren't any certificates in the file, print that.
    if (certificates.isEmpty()) {
        wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_DISPLAY_CERT_NO_CERTS.get(certificateFile.getAbsolutePath()));
    } else {
        for (final X509Certificate c : certificates) {
            out();
            printCertificate(c, "", verbose);
        }
    }
    return ResultCode.SUCCESS;
}
Also used : LDAPException(com.unboundid.ldap.sdk.LDAPException) BooleanArgument(com.unboundid.util.args.BooleanArgument) ArrayList(java.util.ArrayList) ASN1BitString(com.unboundid.asn1.ASN1BitString) FileArgument(com.unboundid.util.args.FileArgument) File(java.io.File) NotNull(com.unboundid.util.NotNull)

Example 24 with BooleanArgument

use of com.unboundid.util.args.BooleanArgument in project ldapsdk by pingidentity.

the class ManageCertificates method doDisplayCertificateSigningRequestFile.

/**
 * Performs the necessary processing for the
 * display-certificate-signing-request-file subcommand.
 *
 * @return  A result code that indicates whether the processing completed
 *          successfully.
 */
@NotNull()
private ResultCode doDisplayCertificateSigningRequestFile() {
    // Get the values of a number of configured arguments.
    final FileArgument csrFileArgument = subCommandParser.getFileArgument("certificate-signing-request-file");
    final File csrFile = csrFileArgument.getValue();
    final BooleanArgument verboseArgument = subCommandParser.getBooleanArgument("verbose");
    final boolean verbose = ((verboseArgument != null) && verboseArgument.isPresent());
    final BooleanArgument displayKeytoolCommandArgument = subCommandParser.getBooleanArgument("display-keytool-command");
    if ((displayKeytoolCommandArgument != null) && displayKeytoolCommandArgument.isPresent()) {
        final ArrayList<String> keytoolArgs = new ArrayList<>(10);
        keytoolArgs.add("-printcertreq");
        keytoolArgs.add("-file");
        keytoolArgs.add(csrFile.getAbsolutePath());
        keytoolArgs.add("-v");
        displayKeytoolCommand(keytoolArgs);
    }
    // Read the certificate signing request from the specified file.
    final PKCS10CertificateSigningRequest csr;
    try {
        csr = readCertificateSigningRequestFromFile(csrFile);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        wrapErr(0, WRAP_COLUMN, le.getMessage());
        return le.getResultCode();
    }
    out();
    printCertificateSigningRequest(csr, verbose, "");
    return ResultCode.SUCCESS;
}
Also used : LDAPException(com.unboundid.ldap.sdk.LDAPException) BooleanArgument(com.unboundid.util.args.BooleanArgument) ArrayList(java.util.ArrayList) ASN1BitString(com.unboundid.asn1.ASN1BitString) FileArgument(com.unboundid.util.args.FileArgument) File(java.io.File) NotNull(com.unboundid.util.NotNull)

Example 25 with BooleanArgument

use of com.unboundid.util.args.BooleanArgument in project ldapsdk by pingidentity.

the class ManageCertificates method getKeystorePassword.

/**
 * Retrieves the password needed to access the keystore.
 *
 * @param  keystoreFile  The path to the keystore file for which to get the
 *                       password.
 * @param  prefix        The prefix string to use for the arguments.  This may
 *                       be {@code null} if no prefix is needed.
 *
 * @return  The password needed to access the keystore, or {@code null} if
 *          no keystore password was configured.
 *
 * @throws  LDAPException  If a problem is encountered while trying to get the
 *                         keystore password.
 */
@Nullable()
private char[] getKeystorePassword(@NotNull final File keystoreFile, @Nullable final String prefix) throws LDAPException {
    final String prefixDash;
    if (prefix == null) {
        prefixDash = "";
    } else {
        prefixDash = prefix + '-';
    }
    final StringArgument keystorePasswordArgument = subCommandParser.getStringArgument(prefixDash + "keystore-password");
    if ((keystorePasswordArgument != null) && keystorePasswordArgument.isPresent()) {
        final char[] keystorePWChars = keystorePasswordArgument.getValue().toCharArray();
        if ((!keystoreFile.exists()) && (keystorePWChars.length < 6)) {
            throw new LDAPException(ResultCode.PARAM_ERROR, ERR_MANAGE_CERTS_GET_KS_PW_TOO_SHORT.get());
        }
        return keystorePWChars;
    }
    final FileArgument keystorePasswordFileArgument = subCommandParser.getFileArgument(prefixDash + "keystore-password-file");
    if ((keystorePasswordFileArgument != null) && keystorePasswordFileArgument.isPresent()) {
        final File f = keystorePasswordFileArgument.getValue();
        try {
            final char[] passwordChars = getPasswordFileReader().readPassword(f);
            if (passwordChars.length < 6) {
                throw new LDAPException(ResultCode.PARAM_ERROR, ERR_MANAGE_CERTS_GET_KS_PW_TOO_SHORT.get());
            }
            return passwordChars;
        } catch (final LDAPException e) {
            Debug.debugException(e);
            throw e;
        } catch (final Exception e) {
            Debug.debugException(e);
            throw new LDAPException(ResultCode.LOCAL_ERROR, ERR_MANAGE_CERTS_GET_KS_PW_ERROR_READING_FILE.get(f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), e);
        }
    }
    final BooleanArgument promptArgument = subCommandParser.getBooleanArgument("prompt-for-" + prefixDash + "keystore-password");
    if ((promptArgument != null) && promptArgument.isPresent()) {
        out();
        if (keystoreFile.exists() && (!"new".equals(prefix))) {
            // We're only going to prompt once.
            if ((prefix != null) && prefix.equals("current")) {
                return promptForPassword(INFO_MANAGE_CERTS_KEY_KS_PW_EXISTING_CURRENT_PROMPT.get(keystoreFile.getAbsolutePath()), false);
            } else {
                return promptForPassword(INFO_MANAGE_CERTS_KEY_KS_PW_EXISTING_PROMPT.get(keystoreFile.getAbsolutePath()), false);
            }
        } else {
            // twice to prevent setting the wrong password because of a typo.
            while (true) {
                final String prompt1;
                if ("new".equals(prefix)) {
                    prompt1 = INFO_MANAGE_CERTS_KEY_KS_PW_EXISTING_NEW_PROMPT.get();
                } else {
                    prompt1 = INFO_MANAGE_CERTS_KEY_KS_PW_NEW_PROMPT_1.get(keystoreFile.getAbsolutePath());
                }
                final char[] pwChars = promptForPassword(prompt1, false);
                if (pwChars.length < 6) {
                    wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_GET_KS_PW_TOO_SHORT.get());
                    err();
                    continue;
                }
                final char[] confirmChars = promptForPassword(INFO_MANAGE_CERTS_KEY_KS_PW_NEW_PROMPT_2.get(), true);
                if (Arrays.equals(pwChars, confirmChars)) {
                    Arrays.fill(confirmChars, '\u0000');
                    return pwChars;
                } else {
                    wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_KEY_KS_PW_PROMPT_MISMATCH.get());
                    err();
                }
            }
        }
    }
    return null;
}
Also used : LDAPException(com.unboundid.ldap.sdk.LDAPException) BooleanArgument(com.unboundid.util.args.BooleanArgument) ASN1BitString(com.unboundid.asn1.ASN1BitString) FileArgument(com.unboundid.util.args.FileArgument) File(java.io.File) ArgumentException(com.unboundid.util.args.ArgumentException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) LDAPException(com.unboundid.ldap.sdk.LDAPException) IOException(java.io.IOException) StringArgument(com.unboundid.util.args.StringArgument) Nullable(com.unboundid.util.Nullable)

Aggregations

BooleanArgument (com.unboundid.util.args.BooleanArgument)65 StringArgument (com.unboundid.util.args.StringArgument)53 FileArgument (com.unboundid.util.args.FileArgument)51 IntegerArgument (com.unboundid.util.args.IntegerArgument)35 DNArgument (com.unboundid.util.args.DNArgument)25 LDAPException (com.unboundid.ldap.sdk.LDAPException)19 File (java.io.File)19 ArgumentException (com.unboundid.util.args.ArgumentException)18 ASN1BitString (com.unboundid.asn1.ASN1BitString)16 NotNull (com.unboundid.util.NotNull)16 FilterArgument (com.unboundid.util.args.FilterArgument)14 ControlArgument (com.unboundid.util.args.ControlArgument)13 IOException (java.io.IOException)13 UnrecoverableKeyException (java.security.UnrecoverableKeyException)12 ArrayList (java.util.ArrayList)12 KeyStore (java.security.KeyStore)10 ScopeArgument (com.unboundid.util.args.ScopeArgument)9 Certificate (java.security.cert.Certificate)8 ArgumentParser (com.unboundid.util.args.ArgumentParser)7 DN (com.unboundid.ldap.sdk.DN)6