Search in sources :

Example 1 with X509CertificateExtension

use of com.unboundid.util.ssl.cert.X509CertificateExtension in project ldapsdk by pingidentity.

the class PromptTrustManagerProcessorTestCase method testIssuerCertificateWithInvalidSignature.

/**
 * Tests the behavior with an issuer certificate that has an invalid
 * signature.
 *
 * @throws  Exception  If an unexpected problem occurs.
 */
@Test()
public void testIssuerCertificateWithInvalidSignature() throws Exception {
    // Create a bunch of variables with file paths and other values to use
    // during testing.
    final File tempDir = createTempDir();
    final String caCertificateAlias = "ca-cert";
    final String caKeyStorePath = new File(tempDir, caCertificateAlias + "-keystore.jks").getAbsolutePath();
    final String caCertificatePath = new File(tempDir, caCertificateAlias + ".cert").getAbsolutePath();
    final String serverCertificateAlias = "server-cert";
    final String serverKeyStorePath = new File(tempDir, serverCertificateAlias + "-keystore.jks").getAbsolutePath();
    final String serverCSRPath = new File(tempDir, serverCertificateAlias + ".csr").getAbsolutePath();
    final String serverCertificatePath = new File(tempDir, serverCertificateAlias + ".cert").getAbsolutePath();
    // Create a JKS keystore with just a CA certificate.
    manageCertificates("generate-self-signed-certificate", "--keystore", caKeyStorePath, "--keystore-password", "password", "--keystore-type", "JKS", "--alias", caCertificateAlias, "--subject-dn", "CN=Example Root CA,O=Example Corporation,C=US", "--days-valid", "7300", "--key-algorithm", "RSA", "--key-size-bits", "2048", "--signature-algorithm", "SHA256withRSA", "--subject-alternative-name-email-address", "ca@example.com", "--basic-constraints-is-ca", "true", "--key-usage", "key-cert-sign", "--display-keytool-command");
    manageCertificates("export-certificate", "--keystore", caKeyStorePath, "--keystore-password", "password", "--alias", caCertificateAlias, "--output-format", "PEM", "--output-file", caCertificatePath, "--display-keytool-command");
    // Create a JKS keystore with a server certificate that is signed by the CA.
    manageCertificates("generate-certificate-signing-request", "--output-file", serverCSRPath, "--keystore", serverKeyStorePath, "--keystore-password", "password", "--keystore-type", "JKS", "--alias", serverCertificateAlias, "--subject-dn", "CN=ldap.example.com,O=Example Corporation,C=US", "--key-algorithm", "RSA", "--key-size-bits", "2048", "--signature-algorithm", "SHA256withRSA", "--subject-alternative-name-dns", "ldap.example.com", "--subject-alternative-name-dns", "ldap", "--subject-alternative-name-dns", "ds.example.com", "--subject-alternative-name-dns", "ds", "--subject-alternative-name-dns", "localhost", "--subject-alternative-name-ip-address", "127.0.0.1", "--subject-alternative-name-ip-address", "::1", "--extended-key-usage", "server-auth", "--extended-key-usage", "client-auth", "--display-keytool-command");
    manageCertificates("sign-certificate-signing-request", "--request-input-file", serverCSRPath, "--certificate-output-file", serverCertificatePath, "--output-format", "PEM", "--keystore", caKeyStorePath, "--keystore-password", "password", "--signing-certificate-alias", caCertificateAlias, "--days-valid", "365", "--include-requested-extensions", "--no-prompt", "--display-keytool-command");
    manageCertificates("import-certificate", "--certificate-file", serverCertificatePath, "--certificate-file", caCertificatePath, "--keystore", serverKeyStorePath, "--keystore-password", "password", "--alias", serverCertificateAlias, "--no-prompt", "--display-keytool-command");
    // Load the keystore and get the certificate chain.
    final KeyStore keystore = CryptoHelper.getKeyStore("JKS");
    try (FileInputStream inputStream = new FileInputStream(serverKeyStorePath)) {
        keystore.load(inputStream, "password".toCharArray());
    }
    final Certificate[] javaChain = keystore.getCertificateChain(serverCertificateAlias);
    final X509Certificate[] ldapSDKChain = PromptTrustManager.convertChain(javaChain);
    final List<X509CertificateExtension> extensionList = ldapSDKChain[1].getExtensions();
    final X509CertificateExtension[] extensionArray = new X509CertificateExtension[extensionList.size()];
    extensionList.toArray(extensionArray);
    final boolean[] validSignatureBits = ldapSDKChain[1].getSignatureValue().getBits();
    final boolean[] invalidSignatureBits = new boolean[validSignatureBits.length];
    final ASN1BitString invalidSignatureValue = new ASN1BitString(invalidSignatureBits);
    ldapSDKChain[1] = InternalCertHelper.createX509Certificate(ldapSDKChain[1].getVersion(), ldapSDKChain[1].getSerialNumber(), ldapSDKChain[1].getSignatureAlgorithmOID(), ldapSDKChain[1].getSignatureAlgorithmParameters(), invalidSignatureValue, ldapSDKChain[1].getIssuerDN(), ldapSDKChain[1].getNotBeforeTime(), ldapSDKChain[1].getNotAfterTime(), ldapSDKChain[1].getSubjectDN(), ldapSDKChain[1].getPublicKeyAlgorithmOID(), ldapSDKChain[1].getPublicKeyAlgorithmParameters(), ldapSDKChain[1].getEncodedPublicKey(), ldapSDKChain[1].getDecodedPublicKey(), ldapSDKChain[1].getIssuerUniqueID(), ldapSDKChain[1].getSubjectUniqueID(), extensionArray);
    // Invoke the shouldPrompt method and examine the result.
    final ObjectPair<Boolean, List<String>> promptResult = PromptTrustManagerProcessor.shouldPrompt(PromptTrustManager.getCacheKey(javaChain[0]), ldapSDKChain, true, true, Collections.<String, Boolean>emptyMap(), Collections.singletonList("ldap.example.com"));
    assertNotNull(promptResult.getFirst());
    assertEquals(promptResult.getFirst(), Boolean.TRUE);
    assertNotNull(promptResult.getSecond());
    assertFalse(promptResult.getSecond().isEmpty());
    assertEquals(promptResult.getSecond().size(), 1);
}
Also used : X509CertificateExtension(com.unboundid.util.ssl.cert.X509CertificateExtension) ASN1BitString(com.unboundid.asn1.ASN1BitString) KeyStore(java.security.KeyStore) FileInputStream(java.io.FileInputStream) X509Certificate(com.unboundid.util.ssl.cert.X509Certificate) ASN1BitString(com.unboundid.asn1.ASN1BitString) List(java.util.List) File(java.io.File) X509Certificate(com.unboundid.util.ssl.cert.X509Certificate) Certificate(java.security.cert.Certificate) Test(org.testng.annotations.Test)

Example 2 with X509CertificateExtension

use of com.unboundid.util.ssl.cert.X509CertificateExtension in project ldapsdk by pingidentity.

the class JVMDefaultTrustManager method checkIncompleteChain.

/**
 * Checks to determine whether the provided certificate chain may be
 * incomplete, and if so, whether we can find and trust the issuer of the last
 * certificate in the chain.
 *
 * @param  chain  The chain to validate.
 *
 * @return  {@code true} if the chain could be validated, or {@code false} if
 *          not.
 */
private boolean checkIncompleteChain(@NotNull final X509Certificate[] chain) {
    try {
        // Get the last certificate in the chain and decode it as one that we can
        // more fully inspect.
        final com.unboundid.util.ssl.cert.X509Certificate c = new com.unboundid.util.ssl.cert.X509Certificate(chain[chain.length - 1].getEncoded());
        // If the certificate is self-signed, then it can't be trusted.
        if (c.isSelfSigned()) {
            return false;
        }
        // so, then use it to try to find the issuer.
        for (final X509CertificateExtension e : c.getExtensions()) {
            if (e instanceof AuthorityKeyIdentifierExtension) {
                final AuthorityKeyIdentifierExtension akie = (AuthorityKeyIdentifierExtension) e;
                final ASN1OctetString authorityKeyID = new ASN1OctetString(akie.getKeyIdentifier().getValue());
                final com.unboundid.util.ssl.cert.X509Certificate issuer = trustedCertsByKeyID.get(authorityKeyID);
                if ((issuer != null) && issuer.isWithinValidityWindow()) {
                    c.verifySignature(issuer);
                    return true;
                }
            }
        }
    } catch (final Exception e) {
        Debug.debugException(e);
    }
    return false;
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) X509CertificateExtension(com.unboundid.util.ssl.cert.X509CertificateExtension) AuthorityKeyIdentifierExtension(com.unboundid.util.ssl.cert.AuthorityKeyIdentifierExtension) X509Certificate(java.security.cert.X509Certificate) CertificateNotYetValidException(java.security.cert.CertificateNotYetValidException) CertificateExpiredException(java.security.cert.CertificateExpiredException) CertificateException(java.security.cert.CertificateException)

Example 3 with X509CertificateExtension

use of com.unboundid.util.ssl.cert.X509CertificateExtension in project ldapsdk by pingidentity.

the class PromptTrustManagerProcessor method shouldPrompt.

/**
 * Indicates whether the trust manager should prompt about whether to trust
 * the provided certificate chain.
 *
 * @param  cacheKey                 The key that should be used to identify
 *                                  this certificate chain in the cache.  It
 *                                  should be an all-lowercase hexadecimal
 *                                  representation of the end certificate's
 *                                  subject.
 * @param  chain                    The certificate chain to be examined.  It
 *                                  must not be {@code null} or empty.
 * @param  isServerChain            Indicates whether the provided certificate
 *                                  chain was provided by a server (if
 *                                  {@code true}) or a client (if
 *                                  {@code false}).
 * @param  examineValidityDates     Indicates whether to examine the
 *                                  certificate's validity dates in the course
 *                                  of determining about whether to prompt
 *                                  about whether to trust the given
 *                                  certificate chain.
 * @param  acceptedCertificates     A cache of the certificates that have
 *                                  already been accepted.  The entries in the
 *                                  cache will be mapped from an all-lowercase
 *                                  hex representation of a previously-trusted
 *                                  certificate's signature to a Boolean value
 *                                  that indicates whether the certificate has
 *                                  been declared trusted even if the
 *                                  certificate is outside the validity
 *                                  window.
 * @param  expectedServerAddresses  A list containing the addresses that the
 *                                  client is expected to use to connect to a
 *                                  target server.  If this is {@code null} or
 *                                  empty, then no address validation will be
 *                                  performed.  This will be ignored if
 *                                  {@code isServerChain} is {@code false}.
 *
 * @return  An object pair in which the first element is a {@code Boolean}
 *          indicating whether the trust manager should prompt about whether
 *          to trust the certificate chain, and the second element is a
 *          (possibly empty) list of warning messages about the certificate
 *          chain that should be displayed to the user if they should be
 *          prompted.
 */
@NotNull()
static ObjectPair<Boolean, List<String>> shouldPrompt(@NotNull final String cacheKey, @NotNull final X509Certificate[] chain, final boolean isServerChain, final boolean examineValidityDates, @NotNull final Map<String, Boolean> acceptedCertificates, @Nullable final List<String> expectedServerAddresses) {
    // See if any of the certificates is outside the validity window.
    boolean outsideValidityWindow = false;
    final List<String> warningMessages = new ArrayList<>(5);
    final long currentTime = System.currentTimeMillis();
    for (int i = 0; i < chain.length; i++) {
        if (!chain[i].isWithinValidityWindow(currentTime)) {
            outsideValidityWindow = true;
            final String identifier;
            if (i == 0) {
                if (isServerChain) {
                    identifier = WARN_PROMPT_PROCESSOR_LABEL_SERVER.get();
                } else {
                    identifier = WARN_PROMPT_PROCESSOR_LABEL_CLIENT.get();
                }
            } else {
                identifier = WARN_PROMPT_PROCESSOR_LABEL_ISSUER.get();
            }
            if (currentTime > chain[i].getNotAfterTime()) {
                final long expiredSecondsAgo = Math.round(((currentTime - chain[i].getNotAfterTime()) / 1000.0d));
                warningMessages.add(WARN_PROMPT_PROCESSOR_CERT_EXPIRED.get(identifier, String.valueOf(chain[i].getSubjectDN()), formatDate(chain[i].getNotAfterDate()), StaticUtils.secondsToHumanReadableDuration(expiredSecondsAgo)));
            } else {
                final long secondsUntilValid = Math.round(((chain[i].getNotBeforeTime() - currentTime) / 1000.0d));
                warningMessages.add(WARN_PROMPT_PROCESSOR_CERT_NOT_YET_VALID.get(identifier, String.valueOf(chain[i].getSubjectDN()), formatDate(chain[i].getNotBeforeDate()), StaticUtils.secondsToHumanReadableDuration(secondsUntilValid)));
            }
        }
    }
    // If the certificate at the head of the chain has an extended key usage
    // extension, then make sure it includes either the serverAuth usage (for a
    // server certificate) or the clientAuth usage (for a client certificate).
    SubjectAlternativeNameExtension san = null;
    for (final X509CertificateExtension extension : chain[0].getExtensions()) {
        if (extension instanceof ExtendedKeyUsageExtension) {
            final ExtendedKeyUsageExtension eku = (ExtendedKeyUsageExtension) extension;
            if (isServerChain) {
                if (!eku.getKeyPurposeIDs().contains(ExtendedKeyUsageID.TLS_SERVER_AUTHENTICATION.getOID())) {
                    warningMessages.add(WARN_PROMPT_PROCESSOR_EKU_MISSING_SERVER_AUTH.get(chain[0].getSubjectDN()));
                }
            } else {
                if (!eku.getKeyPurposeIDs().contains(ExtendedKeyUsageID.TLS_CLIENT_AUTHENTICATION.getOID())) {
                    warningMessages.add(WARN_PROMPT_PROCESSOR_EKU_MISSING_CLIENT_AUTH.get(chain[0].getSubjectDN()));
                }
            }
        } else if (extension instanceof SubjectAlternativeNameExtension) {
            san = (SubjectAlternativeNameExtension) extension;
        }
    }
    // extensions in the issuer certificates.
    if (chain.length == 1) {
        if (chain[0].isSelfSigned()) {
            warningMessages.add(WARN_PROMPT_PROCESSOR_CERT_IS_SELF_SIGNED.get());
            try {
                chain[0].verifySignature(chain[0]);
            } catch (final CertException ce) {
                Debug.debugException(ce);
                warningMessages.add(ce.getMessage());
            }
        } else {
            warningMessages.add(WARN_PROMPT_PROCESSOR_CHAIN_NOT_COMPLETE.get(chain[0].getSubjectDN()));
        }
    } else {
        for (int i = 1; i < chain.length; i++) {
            if (chain[i].isIssuerFor(chain[i - 1])) {
                try {
                    chain[i - 1].verifySignature(chain[i]);
                } catch (final CertException ce) {
                    Debug.debugException(ce);
                    warningMessages.add(ce.getMessage());
                }
            } else {
                warningMessages.add(WARN_PROMPT_PROCESSOR_CHAIN_ISSUER_MISMATCH.get(chain[i].getSubjectDN(), chain[i - 1].getSubjectDN()));
            }
            BasicConstraintsExtension bc = null;
            KeyUsageExtension ku = null;
            for (final X509CertificateExtension extension : chain[i].getExtensions()) {
                if (extension instanceof BasicConstraintsExtension) {
                    bc = (BasicConstraintsExtension) extension;
                } else if (extension instanceof KeyUsageExtension) {
                    ku = (KeyUsageExtension) extension;
                }
            }
            if (bc == null) {
                warningMessages.add(WARN_PROMPT_PROCESSOR_NO_BC_EXTENSION.get(chain[i].getSubjectDN()));
            } else if (!bc.isCA()) {
                warningMessages.add(WARN_PROMPT_PROCESSOR_BC_NOT_CA.get(chain[i].getSubjectDN()));
            } else if ((bc.getPathLengthConstraint() != null) && ((i - 1) > bc.getPathLengthConstraint())) {
                if (bc.getPathLengthConstraint() == 0) {
                    warningMessages.add(WARN_PROMPT_PROCESSOR_BC_DISALLOWED_INTERMEDIATE.get(chain[i].getSubjectDN()));
                } else {
                    warningMessages.add(WARN_PROMPT_PROCESSOR_BC_TOO_MANY_INTERMEDIATES.get(chain[i].getSubjectDN(), bc.getPathLengthConstraint(), (i - 1)));
                }
            }
            if ((ku != null) && (!ku.isKeyCertSignBitSet())) {
                warningMessages.add(WARN_PROMPT_PROCESSOR_KU_NO_KEY_CERT_SIGN.get(chain[i].getSubjectDN()));
            }
        }
        if (chain[chain.length - 1].isSelfSigned()) {
            try {
                chain[chain.length - 1].verifySignature(chain[chain.length - 1]);
            } catch (final CertException ce) {
                Debug.debugException(ce);
                warningMessages.add(ce.getMessage());
            }
        } else {
            warningMessages.add(WARN_PROMPT_PROCESSOR_CHAIN_NOT_COMPLETE.get(chain[chain.length - 1].getSubjectDN()));
        }
    }
    // addresses.
    if (isServerChain && (expectedServerAddresses != null) && (!expectedServerAddresses.isEmpty())) {
        // Get the CN attribute from the certificate subject.
        boolean hasAllowedAddress = false;
        final StringBuilder addressBuffer = new StringBuilder();
        for (final RDN rdn : chain[0].getSubjectDN().getRDNs()) {
            final String[] names = rdn.getAttributeNames();
            for (int i = 0; i < names.length; i++) {
                if (names[i].equalsIgnoreCase("cn") || names[i].equalsIgnoreCase("commonName") || names[i].equalsIgnoreCase("2.5.4.3")) {
                    final String cnValue = rdn.getAttributeValues()[i];
                    final String lowerCNValue = StaticUtils.toLowerCase(cnValue);
                    if (isHostnameOrIPAddress(lowerCNValue)) {
                        commaAppend(addressBuffer, cnValue);
                        if (isAllowedHostnameOrIPAddress(lowerCNValue, expectedServerAddresses)) {
                            hasAllowedAddress = true;
                            break;
                        }
                    }
                }
            }
            if (hasAllowedAddress) {
                break;
            }
        }
        // check its DNS names.
        if ((!hasAllowedAddress) && (san != null)) {
            for (final String dnsName : san.getDNSNames()) {
                commaAppend(addressBuffer, dnsName);
                if (isAllowedHostnameOrIPAddress(dnsName, expectedServerAddresses)) {
                    hasAllowedAddress = true;
                    break;
                }
            }
            if (!hasAllowedAddress) {
                for (final InetAddress ipAddress : san.getIPAddresses()) {
                    commaAppend(addressBuffer, ipAddress.getHostAddress());
                    if (isAllowedIPAddress(ipAddress, expectedServerAddresses)) {
                        hasAllowedAddress = true;
                        break;
                    }
                }
            }
        }
        if (!hasAllowedAddress) {
            if (addressBuffer.length() == 0) {
            // The certificate doesn't indicate the server with which it should be
            // used.  This isn't desirable, but we won't warn about it.
            } else if (addressBuffer.indexOf(",") > 0) {
                warningMessages.add(WARN_PROMPT_PROCESSOR_MULTIPLE_ADDRESSES_NOT_MATCHED.get(chain[0].getSubjectDN(), addressBuffer));
            } else {
                warningMessages.add(WARN_PROMPT_PROCESSOR_SINGLE_ADDRESS_NOT_MATCHED.get(chain[0].getSubjectDN(), addressBuffer));
            }
        }
    }
    // See if the provided certificate is in the cache.  If not, then we will
    // definitely prompt.  If the cache indicates that the certificate has been
    // accepted even outside the validity window, then we will not prompt.
    // Otherwise, we'll prompt only if the certificate is outside the validity
    // window.
    final Boolean acceptedEvenWithBadValidity = acceptedCertificates.get(cacheKey);
    if (acceptedEvenWithBadValidity == null) {
        return new ObjectPair<>(Boolean.TRUE, warningMessages);
    } else if (acceptedEvenWithBadValidity) {
        return new ObjectPair<>(Boolean.FALSE, warningMessages);
    } else {
        return new ObjectPair<>(outsideValidityWindow, warningMessages);
    }
}
Also used : ExtendedKeyUsageExtension(com.unboundid.util.ssl.cert.ExtendedKeyUsageExtension) X509CertificateExtension(com.unboundid.util.ssl.cert.X509CertificateExtension) SubjectAlternativeNameExtension(com.unboundid.util.ssl.cert.SubjectAlternativeNameExtension) ArrayList(java.util.ArrayList) CertException(com.unboundid.util.ssl.cert.CertException) BasicConstraintsExtension(com.unboundid.util.ssl.cert.BasicConstraintsExtension) RDN(com.unboundid.ldap.sdk.RDN) InetAddress(java.net.InetAddress) KeyUsageExtension(com.unboundid.util.ssl.cert.KeyUsageExtension) ExtendedKeyUsageExtension(com.unboundid.util.ssl.cert.ExtendedKeyUsageExtension) ObjectPair(com.unboundid.util.ObjectPair) NotNull(com.unboundid.util.NotNull)

Example 4 with X509CertificateExtension

use of com.unboundid.util.ssl.cert.X509CertificateExtension in project ldapsdk by pingidentity.

the class JVMDefaultTrustManager method findIssuer.

/**
 * Finds the issuer for the provided certificate, if it is in the JVM-default
 * trust store.
 *
 * @param  cert         The certificate for which to find the issuer.  It must
 *                      have already been retrieved from the JVM-default trust
 *                      store.
 * @param  currentDate  The current date to use when verifying validity.
 *
 * @return  The issuer for the provided certificate, or {@code null} if the
 *          provided certificate is self-signed.
 *
 * @throws  CertificateException  If the provided certificate is not
 *                                self-signed but its issuer could not be
 *                                found, or if the issuer certificate is
 *                                not currently valid.
 */
@Nullable()
private X509Certificate findIssuer(@NotNull final X509Certificate cert, @NotNull final Date currentDate) throws CertificateException {
    try {
        // More fully decode the provided certificate so that we can better
        // examine it.
        final com.unboundid.util.ssl.cert.X509Certificate c = new com.unboundid.util.ssl.cert.X509Certificate(cert.getEncoded());
        // If the certificate is self-signed, then it doesn't have an issuer.
        if (c.isSelfSigned()) {
            return null;
        }
        // so, then use it to try to find the issuer.
        for (final X509CertificateExtension e : c.getExtensions()) {
            if (e instanceof AuthorityKeyIdentifierExtension) {
                final AuthorityKeyIdentifierExtension akie = (AuthorityKeyIdentifierExtension) e;
                final ASN1OctetString authorityKeyID = new ASN1OctetString(akie.getKeyIdentifier().getValue());
                final com.unboundid.util.ssl.cert.X509Certificate issuer = trustedCertsByKeyID.get(authorityKeyID);
                if ((issuer != null) && issuer.isWithinValidityWindow(currentDate)) {
                    c.verifySignature(issuer);
                    return (X509Certificate) issuer.toCertificate();
                }
            }
        }
    } catch (final Exception e) {
        Debug.debugException(e);
    }
    throw new CertificateException(ERR_JVM_DEFAULT_TRUST_MANAGER_CANNOT_FIND_ISSUER.get(String.valueOf(cert.getSubjectDN())));
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) X509CertificateExtension(com.unboundid.util.ssl.cert.X509CertificateExtension) AuthorityKeyIdentifierExtension(com.unboundid.util.ssl.cert.AuthorityKeyIdentifierExtension) CertificateException(java.security.cert.CertificateException) X509Certificate(java.security.cert.X509Certificate) CertificateNotYetValidException(java.security.cert.CertificateNotYetValidException) CertificateExpiredException(java.security.cert.CertificateExpiredException) CertificateException(java.security.cert.CertificateException) Nullable(com.unboundid.util.Nullable)

Example 5 with X509CertificateExtension

use of com.unboundid.util.ssl.cert.X509CertificateExtension in project ldapsdk by pingidentity.

the class PromptTrustManagerProcessorTestCase method testSubjectCertificateWithInvalidSignature.

/**
 * Tests the behavior with a two-certificate chain in which the subject
 * certificate has an invalid signature.
 *
 * @throws  Exception  If an unexpected problem occurs.
 */
@Test()
public void testSubjectCertificateWithInvalidSignature() throws Exception {
    // Create a bunch of variables with file paths and other values to use
    // during testing.
    final File tempDir = createTempDir();
    final String caCertificateAlias = "ca-cert";
    final String caKeyStorePath = new File(tempDir, caCertificateAlias + "-keystore.jks").getAbsolutePath();
    final String caCertificatePath = new File(tempDir, caCertificateAlias + ".cert").getAbsolutePath();
    final String serverCertificateAlias = "server-cert";
    final String serverKeyStorePath = new File(tempDir, serverCertificateAlias + "-keystore.jks").getAbsolutePath();
    final String serverCSRPath = new File(tempDir, serverCertificateAlias + ".csr").getAbsolutePath();
    final String serverCertificatePath = new File(tempDir, serverCertificateAlias + ".cert").getAbsolutePath();
    // Create a JKS keystore with just a CA certificate.
    manageCertificates("generate-self-signed-certificate", "--keystore", caKeyStorePath, "--keystore-password", "password", "--keystore-type", "JKS", "--alias", caCertificateAlias, "--subject-dn", "CN=Example Root CA,O=Example Corporation,C=US", "--days-valid", "7300", "--key-algorithm", "RSA", "--key-size-bits", "2048", "--signature-algorithm", "SHA256withRSA", "--subject-alternative-name-email-address", "ca@example.com", "--basic-constraints-is-ca", "true", "--key-usage", "key-cert-sign", "--display-keytool-command");
    manageCertificates("export-certificate", "--keystore", caKeyStorePath, "--keystore-password", "password", "--alias", caCertificateAlias, "--output-format", "PEM", "--output-file", caCertificatePath, "--display-keytool-command");
    // Create a JKS keystore with a server certificate that is signed by the CA.
    manageCertificates("generate-certificate-signing-request", "--output-file", serverCSRPath, "--keystore", serverKeyStorePath, "--keystore-password", "password", "--keystore-type", "JKS", "--alias", serverCertificateAlias, "--subject-dn", "CN=ldap.example.com,O=Example Corporation,C=US", "--key-algorithm", "RSA", "--key-size-bits", "2048", "--signature-algorithm", "SHA256withRSA", "--subject-alternative-name-dns", "ldap.example.com", "--subject-alternative-name-dns", "ldap", "--subject-alternative-name-dns", "ds.example.com", "--subject-alternative-name-dns", "ds", "--subject-alternative-name-dns", "localhost", "--subject-alternative-name-ip-address", "127.0.0.1", "--subject-alternative-name-ip-address", "::1", "--extended-key-usage", "server-auth", "--extended-key-usage", "client-auth", "--display-keytool-command");
    manageCertificates("sign-certificate-signing-request", "--request-input-file", serverCSRPath, "--certificate-output-file", serverCertificatePath, "--output-format", "PEM", "--keystore", caKeyStorePath, "--keystore-password", "password", "--signing-certificate-alias", caCertificateAlias, "--days-valid", "365", "--include-requested-extensions", "--no-prompt", "--display-keytool-command");
    manageCertificates("import-certificate", "--certificate-file", serverCertificatePath, "--certificate-file", caCertificatePath, "--keystore", serverKeyStorePath, "--keystore-password", "password", "--alias", serverCertificateAlias, "--no-prompt", "--display-keytool-command");
    // Load the keystore and get the certificate chain.
    final KeyStore keystore = CryptoHelper.getKeyStore("JKS");
    try (FileInputStream inputStream = new FileInputStream(serverKeyStorePath)) {
        keystore.load(inputStream, "password".toCharArray());
    }
    final Certificate[] javaChain = keystore.getCertificateChain(serverCertificateAlias);
    final X509Certificate[] ldapSDKChain = PromptTrustManager.convertChain(javaChain);
    final List<X509CertificateExtension> extensionList = ldapSDKChain[0].getExtensions();
    final X509CertificateExtension[] extensionArray = new X509CertificateExtension[extensionList.size()];
    extensionList.toArray(extensionArray);
    final boolean[] validSignatureBits = ldapSDKChain[0].getSignatureValue().getBits();
    final boolean[] invalidSignatureBits = new boolean[validSignatureBits.length];
    final ASN1BitString invalidSignatureValue = new ASN1BitString(invalidSignatureBits);
    ldapSDKChain[0] = InternalCertHelper.createX509Certificate(ldapSDKChain[0].getVersion(), ldapSDKChain[0].getSerialNumber(), ldapSDKChain[0].getSignatureAlgorithmOID(), ldapSDKChain[0].getSignatureAlgorithmParameters(), invalidSignatureValue, ldapSDKChain[0].getIssuerDN(), ldapSDKChain[0].getNotBeforeTime(), ldapSDKChain[0].getNotAfterTime(), ldapSDKChain[0].getSubjectDN(), ldapSDKChain[0].getPublicKeyAlgorithmOID(), ldapSDKChain[0].getPublicKeyAlgorithmParameters(), ldapSDKChain[0].getEncodedPublicKey(), ldapSDKChain[0].getDecodedPublicKey(), ldapSDKChain[0].getIssuerUniqueID(), ldapSDKChain[0].getSubjectUniqueID(), extensionArray);
    // Invoke the shouldPrompt method and examine the result.
    final ObjectPair<Boolean, List<String>> promptResult = PromptTrustManagerProcessor.shouldPrompt(PromptTrustManager.getCacheKey(javaChain[0]), ldapSDKChain, true, true, Collections.<String, Boolean>emptyMap(), Collections.singletonList("ldap.example.com"));
    assertNotNull(promptResult.getFirst());
    assertEquals(promptResult.getFirst(), Boolean.TRUE);
    assertNotNull(promptResult.getSecond());
    assertFalse(promptResult.getSecond().isEmpty());
    assertEquals(promptResult.getSecond().size(), 1);
}
Also used : X509CertificateExtension(com.unboundid.util.ssl.cert.X509CertificateExtension) ASN1BitString(com.unboundid.asn1.ASN1BitString) KeyStore(java.security.KeyStore) FileInputStream(java.io.FileInputStream) X509Certificate(com.unboundid.util.ssl.cert.X509Certificate) ASN1BitString(com.unboundid.asn1.ASN1BitString) List(java.util.List) File(java.io.File) X509Certificate(com.unboundid.util.ssl.cert.X509Certificate) Certificate(java.security.cert.Certificate) Test(org.testng.annotations.Test)

Aggregations

X509CertificateExtension (com.unboundid.util.ssl.cert.X509CertificateExtension)6 ASN1BitString (com.unboundid.asn1.ASN1BitString)3 X509Certificate (com.unboundid.util.ssl.cert.X509Certificate)3 List (java.util.List)3 Test (org.testng.annotations.Test)3 ASN1OctetString (com.unboundid.asn1.ASN1OctetString)2 AuthorityKeyIdentifierExtension (com.unboundid.util.ssl.cert.AuthorityKeyIdentifierExtension)2 File (java.io.File)2 FileInputStream (java.io.FileInputStream)2 KeyStore (java.security.KeyStore)2 Certificate (java.security.cert.Certificate)2 CertificateException (java.security.cert.CertificateException)2 CertificateExpiredException (java.security.cert.CertificateExpiredException)2 CertificateNotYetValidException (java.security.cert.CertificateNotYetValidException)2 X509Certificate (java.security.cert.X509Certificate)2 DN (com.unboundid.ldap.sdk.DN)1 RDN (com.unboundid.ldap.sdk.RDN)1 NotNull (com.unboundid.util.NotNull)1 Nullable (com.unboundid.util.Nullable)1 ObjectPair (com.unboundid.util.ObjectPair)1