diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c index 875800eb508..5739862a215 100644 --- a/security/nss/lib/certhigh/certvfy.c +++ b/security/nss/lib/certhigh/certvfy.c @@ -492,7 +492,6 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, int count; int currentPathLen = 0; int pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT; - int flags; unsigned int caCertType; unsigned int requiredCAKeyUsage; unsigned int requiredFlags; @@ -730,36 +729,49 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, * explicitly UNtrusted. We won't know until we examine the * trust bits. */ - if (certUsage == certUsageStatusResponder) { - /* XXX NSS has done this for years, but it seems incorrect. */ - rv = rvFinal; - goto done; - } + unsigned int flags; - /* - * check the trust parms of the issuer - */ - if ( certUsage == certUsageVerifyCA ) { - if ( subjectCert->nsCertType & NS_CERT_TYPE_EMAIL_CA ) { - trustType = trustEmail; - } else if ( subjectCert->nsCertType & NS_CERT_TYPE_SSL_CA ) { - trustType = trustSSL; - } else { - trustType = trustObjectSigning; - } - } - - flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType); - - if (flags & CERTDB_VALID_CA) { - if ( ( flags & requiredFlags ) == requiredFlags) { - /* we found a trusted one, so return */ - rv = rvFinal; - goto done; - } - validCAOverride = PR_TRUE; - } - } + if (certUsage != certUsageAnyCA && + certUsage != certUsageStatusResponder) { + + /* + * check the trust parms of the issuer + */ + if ( certUsage == certUsageVerifyCA ) { + if ( subjectCert->nsCertType & NS_CERT_TYPE_EMAIL_CA ) { + trustType = trustEmail; + } else if ( subjectCert->nsCertType & NS_CERT_TYPE_SSL_CA ) { + trustType = trustSSL; + } else { + trustType = trustObjectSigning; + } + } + + flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType); + + if (flags & CERTDB_VALID_CA) { + if ( ( flags & requiredFlags ) == requiredFlags) { + /* we found a trusted one, so return */ + rv = rvFinal; + goto done; + } + validCAOverride = PR_TRUE; + } + } else { + /* Check if we have any valid trust when cheching for + * certUsageAnyCA or certUsageStatusResponder. */ + for (trustType = trustSSL; trustType < trustTypeNone; + trustType++) { + flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType); + if ((flags & requiredFlags) == requiredFlags) { + rv = rvFinal; + goto done; + } + if (flags & CERTDB_VALID_CA) + validCAOverride = PR_TRUE; + } + } + } if (!validCAOverride) { /* diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c index 7f926902aa9..54ef705d9a6 100755 --- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c +++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c @@ -101,11 +101,37 @@ pkix_pl_Pk11CertStore_CheckTrust( } if (rv == SECSuccess) { - unsigned int certFlags; + unsigned int certFlags; + + if (certUsage != certUsageAnyCA && + certUsage != certUsageStatusResponder) { + CERTCertificate *nssCert = cert->nssCert; + + if (certUsage == certUsageVerifyCA) { + if (nssCert->nsCertType & NS_CERT_TYPE_EMAIL_CA) { + trustType = trustEmail; + } else if (nssCert->nsCertType & NS_CERT_TYPE_SSL_CA) { + trustType = trustSSL; + } else { + trustType = trustObjectSigning; + } + } + certFlags = SEC_GET_TRUST_FLAGS((&trust), trustType); if ((certFlags & requiredFlags) == requiredFlags) { - trusted = PKIX_TRUE; + trusted = PKIX_TRUE; } + } else { + for (trustType = trustSSL; trustType < trustTypeNone; + trustType++) { + certFlags = + SEC_GET_TRUST_FLAGS((&trust), trustType); + if ((certFlags & requiredFlags) == requiredFlags) { + trusted = PKIX_TRUE; + break; + } + } + } } *pTrusted = trusted;