bug 990603 - mozilla::pkix: defer reporting end-entity cert errors until after path building r=briansmith

This commit is contained in:
David Keeler 2014-04-08 09:49:36 -07:00
parent 97de7a7ec6
commit 281f1bd79b
3 changed files with 31 additions and 23 deletions

View File

@ -79,7 +79,13 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKI
check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID
: 0,
certificateUsageVerifyCA);
check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE,
// In mozilla::pkix (but not classic verification), certificate chain
// properties are checked before the end-entity. Thus, if we're using
// mozilla::pkix and the root certificate has been distrusted, the error
// will be "untrusted issuer" and not "inadequate cert type".
check_cert_err_generic(ee_cert, (!isRootCA && useMozillaPKIX)
? SEC_ERROR_UNTRUSTED_ISSUER
: SEC_ERROR_INADEQUATE_CERT_TYPE,
certificateUsageStatusResponder);
@ -137,7 +143,13 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKI
check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID
: 0,
certificateUsageVerifyCA);
check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE,
// In mozilla::pkix (but not classic verification), certificate chain
// properties are checked before the end-entity. Thus, if we're using
// mozilla::pkix and the root certificate has been distrusted, the error
// will be "untrusted issuer" and not "inadequate cert type".
check_cert_err_generic(ee_cert, (!isRootCA && useMozillaPKIX)
? SEC_ERROR_UNTRUSTED_ISSUER
: SEC_ERROR_INADEQUATE_CERT_TYPE,
certificateUsageStatusResponder);
// Inherited trust SSL

View File

@ -53,12 +53,10 @@ namespace mozilla { namespace pkix {
// The ranking is:
//
// 1. Active distrust (SEC_ERROR_UNTRUSTED_CERT).
// 2. Problems with issuer-independent properties other than
// notBefore/notAfter.
// 3. For CA certificates: Expiration.
// 4. Unknown issuer (SEC_ERROR_UNKNOWN_ISSUER).
// 5. For end-entity certificates: Expiration.
// 6. Revocation.
// 2. Problems with issuer-independent properties for CA certificates.
// 3. Unknown issuer (SEC_ERROR_UNKNOWN_ISSUER).
// 4. Problems with issuer-independent properties for EE certificates.
// 5. Revocation.
//
// In particular, if BuildCertChain returns SEC_ERROR_UNKNOWN_ISSUER then the
// caller can call CERT_CheckCertValidTimes to determine if the certificate is

View File

@ -206,21 +206,20 @@ BuildForward(TrustDomain& trustDomain,
Result rv;
TrustDomain::TrustLevel trustLevel;
bool expiredEndEntity = false;
// If this is an end-entity and not a trust anchor, we defer reporting
// any error found here until after attempting to find a valid chain.
// See the explanation of error prioritization in pkix.h.
rv = CheckIssuerIndependentProperties(trustDomain, subject, time,
endEntityOrCA,
requiredKeyUsagesIfPresent,
requiredEKUIfPresent, requiredPolicy,
subCACount, &trustLevel);
PRErrorCode deferredEndEntityError = 0;
if (rv != Success) {
// CheckIssuerIndependentProperties checks for expiration last, so if
// it returned SEC_ERROR_EXPIRED_CERTIFICATE we know that is the only
// problem with the cert found so far. Keep going to see if we can build
// a path; if not, it's better to return the path building failure.
expiredEndEntity = endEntityOrCA == MustBeEndEntity &&
trustLevel != TrustDomain::TrustAnchor &&
PR_GetError() == SEC_ERROR_EXPIRED_CERTIFICATE;
if (!expiredEndEntity) {
if (endEntityOrCA == MustBeEndEntity &&
trustLevel != TrustDomain::TrustAnchor) {
deferredEndEntityError = PR_GetError();
} else {
return rv;
}
}
@ -256,12 +255,11 @@ BuildForward(TrustDomain& trustDomain,
n->cert, stapledOCSPResponse, subCACount,
results);
if (rv == Success) {
if (expiredEndEntity) {
// We deferred returning this error to see if we should return
// "unknown issuer" instead. Since we found a valid issuer, it's
// time to return "expired."
PR_SetError(SEC_ERROR_EXPIRED_CERTIFICATE, 0);
return RecoverableError;
// If we found a valid chain but deferred reporting an error with the
// end-entity certificate, report it now.
if (deferredEndEntityError != 0) {
PR_SetError(deferredEndEntityError, 0);
return FatalError;
}
SECStatus srv = trustDomain.CheckRevocation(endEntityOrCA,