diff --git a/docs/release-notes.html b/docs/release-notes.html index bc63543cd..60b6b4889 100644 --- a/docs/release-notes.html +++ b/docs/release-notes.html @@ -56,6 +56,15 @@

Version 4.0.13



+
  • + Updated the manage-certificates check-certificate-usability command to add an + additional check to see whether the certificate at the root of the chain is + found in the JVM's set of trusted issuer certificates. If the CA certificate + is not found in the JVM's default trust store, a notice will be displayed, but + the tool will still complete with a success result. +

    +
  • +
  • Made the ManageCertificates.readCertificatesFromFile method public so that it can be used outside of the LDAP SDK. This method can be used to read a diff --git a/messages/unboundid-ldapsdk-cert.properties b/messages/unboundid-ldapsdk-cert.properties index 8dc7f26bd..17d08da1e 100644 --- a/messages/unboundid-ldapsdk-cert.properties +++ b/messages/unboundid-ldapsdk-cert.properties @@ -2086,6 +2086,16 @@ ERR_MANAGE_CERTS_CHECK_USABILITY_CHAIN_ISSUER_MISMATCH=ERROR: The \ INFO_MANAGE_CERTS_CHECK_USABILITY_CHAIN_COMPLETE=OK: The certificate chain \ is complete. Each subsequent certificate is the issuer for the previous \ certificate in the chain, and the chain ends with a self-signed certificate. +INFO_MANAGE_CERTS_CHECK_USABILITY_CA_TRUSTED_OK=OK: CA certificate ''{0}'' \ + was found in the JVM's default set of trusted certificates. Most clients \ + will likely trust this issuer. +NOTE_MANAGE_CERTS_CHECK_USABILITY_CA_NOT_IN_JVM_DEFAULT_TS=NOTICE: CA \ + certificate ''{0}'' was not found in the JVM's default set of trusted \ + certificates. Clients will likely need special configuration to trust this \ + certificate chain. +WARN_MANAGE_CERTS_CHECK_USABILITY_CHECK_CA_IN_TS_ERROR=WARNING: An error \ + occurred while attempting to determine whether CA certificate ''{0}'' is \ + contained in the JVM-default trust store: {1} INFO_MANAGE_CERTS_CHECK_USABILITY_CERT_SIGNATURE_VALID=OK: Certificate \ ''{0}'' has a valid signature. ERR_MANAGE_CERTS_CHECK_USABILITY_END_CERT_NOT_YET_VALID=ERROR: Certificate \ diff --git a/src/com/unboundid/util/ssl/cert/ManageCertificates.java b/src/com/unboundid/util/ssl/cert/ManageCertificates.java index 9e841b09b..3968a387a 100644 --- a/src/com/unboundid/util/ssl/cert/ManageCertificates.java +++ b/src/com/unboundid/util/ssl/cert/ManageCertificates.java @@ -8294,6 +8294,73 @@ else if ((chain.length == 1) || (! chain[chain.length - 1].isSelfSigned())) } + // If there are multiple certificates in the chain, and if the last + // certificate in the chain is self-signed, then check to see if it is + // contained in the JVM-default trust manager. If it isn't, then we'll + // display a notice, but we won't consider it a warning in and of itself. + if ((chain.length > 1) && chain[chain.length-1].isSelfSigned()) + { + final X509Certificate caCert = chain[chain.length-1]; + + try + { + final String jvmDefaultTrustStoreType = + inferKeystoreType(JVM_DEFAULT_CACERTS_FILE); + final KeyStore jvmDefaultTrustStore = + KeyStore.getInstance(jvmDefaultTrustStoreType); + try (FileInputStream inputStream = + new FileInputStream(JVM_DEFAULT_CACERTS_FILE)) + { + jvmDefaultTrustStore.load(inputStream, null); + } + + boolean found = false; + final Enumeration aliases = jvmDefaultTrustStore.aliases(); + while (aliases.hasMoreElements()) + { + final String jvmDefaultCertAlias = aliases.nextElement(); + if (jvmDefaultTrustStore.isCertificateEntry(jvmDefaultCertAlias)) + { + final Certificate c = + jvmDefaultTrustStore.getCertificate(jvmDefaultCertAlias); + final X509Certificate xc = new X509Certificate(c.getEncoded()); + if ((caCert.getSubjectDN().equals(xc.getSubjectDN())) && + Arrays.equals(caCert.getSignatureValue().getBits(), + xc.getSignatureValue().getBits())) + { + found = true; + break; + } + } + } + + if (found) + { + out(); + wrapOut(0, WRAP_COLUMN, + INFO_MANAGE_CERTS_CHECK_USABILITY_CA_TRUSTED_OK.get( + caCert.getSubjectDN())); + } + else + { + out(); + wrapOut(0, WRAP_COLUMN, + NOTE_MANAGE_CERTS_CHECK_USABILITY_CA_NOT_IN_JVM_DEFAULT_TS.get( + caCert.getSubjectDN())); + } + } + catch (final Exception e) + { + Debug.debugException(e); + err(); + wrapErr(0, WRAP_COLUMN, + WARN_MANAGE_CERTS_CHECK_USABILITY_CHECK_CA_IN_TS_ERROR.get( + caCert.getSubjectDN(), StaticUtils.getExceptionMessage(e))); + numWarnings++; + } + } + + // Make sure that the signature is valid for each certificate in the // chain. If any certificate has an invalid signature, then that's an // error.