Chromium Code Reviews| Index: net/base/cert_verify_proc_nss.cc |
| diff --git a/net/base/cert_verify_proc_nss.cc b/net/base/cert_verify_proc_nss.cc |
| index 3108555455e1023d385ec0fb621b4d64c7d2f182..afe795f5ea7a77cf00ecd4b415fdabc5e8906541 100644 |
| --- a/net/base/cert_verify_proc_nss.cc |
| +++ b/net/base/cert_verify_proc_nss.cc |
| @@ -576,27 +576,6 @@ SECOidTag GetFirstCertPolicy(X509Certificate::OSCertHandle cert_handle) { |
| return SECOID_AddEntry(&od); |
| } |
| -bool CheckCertPolicies(X509Certificate::OSCertHandle cert_handle, |
| - SECOidTag ev_policy_tag) { |
| - CERTCertificatePolicies* policies = DecodeCertPolicies(cert_handle); |
| - if (!policies) { |
| - LOG(ERROR) << "Cert has no policies extension or extension couldn't be " |
| - "decoded."; |
| - return false; |
| - } |
| - ScopedCERTCertificatePolicies scoped_policies(policies); |
| - CERTPolicyInfo** policy_infos = policies->policyInfos; |
| - while (*policy_infos != NULL) { |
| - CERTPolicyInfo* policy_info = *policy_infos++; |
| - SECOidTag oid_tag = policy_info->oid; |
| - if (oid_tag == SEC_OID_UNKNOWN) |
| - continue; |
| - if (oid_tag == ev_policy_tag) |
| - return true; |
| - } |
| - return false; |
| -} |
| - |
| SHA1Fingerprint CertPublicKeyHash(CERTCertificate* cert) { |
| SHA1Fingerprint hash; |
| SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, hash.data, |
| @@ -617,6 +596,35 @@ void AppendPublicKeyHashes(CERTCertList* cert_list, |
| hashes->push_back(CertPublicKeyHash(root_cert)); |
| } |
| +// Returns true if |cert_handle| contains a policy OID that is an EV policy |
| +// OID according to |metadata|, storing the resulting policy OID in |
| +// |*ev_policy_oid|. A true return is not sufficient to establish that a |
| +// certificate is EV, but a false return is sufficient to establish the |
| +// certificate cannot be EV. |
| +bool IsEVCandidate(EVRootCAMetadata* metadata, |
|
agl
2012/08/15 22:57:53
Is the assumption that there'll only be one EV OID
Ryan Sleevi
2012/08/15 23:04:58
That's what I'm not sure about. That's certainly t
|
| + CERTCertificate* cert_handle, |
| + SECOidTag* ev_policy_oid) { |
| + DCHECK(cert_handle); |
| + ScopedCERTCertificatePolicies policies(DecodeCertPolicies(cert_handle)); |
| + if (!policies.get()) |
| + return false; |
| + |
| + CERTPolicyInfo** policy_infos = policies->policyInfos; |
| + while (*policy_infos != NULL) { |
| + CERTPolicyInfo* policy_info = *policy_infos++; |
| + // If the Policy OID is unknown, that implicitly means it has not been |
| + // registered as an EV policy. |
| + if (policy_info->oid == SEC_OID_UNKNOWN) |
| + continue; |
| + if (metadata->IsEVPolicyOID(policy_info->oid)) { |
| + *ev_policy_oid = policy_info->oid; |
| + return true; |
| + } |
| + } |
| + |
| + return false; |
| +} |
| + |
| // Studied Mozilla's code (esp. security/manager/ssl/src/nsIdentityChecking.cpp |
| // and nsNSSCertHelper.cpp) to learn how to verify EV certificate. |
| // TODO(wtc): A possible optimization is that we get the trust anchor from |
| @@ -627,6 +635,11 @@ void AppendPublicKeyHashes(CERTCertList* cert_list, |
| bool VerifyEV(CERTCertificate* cert_handle, int flags, CRLSet* crl_set) { |
| EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance(); |
| + SECOidTag ev_policy_oid = SEC_OID_UNKNOWN; |
| + bool is_ev_candidate = IsEVCandidate(metadata, cert_handle, &ev_policy_oid); |
| + if (!is_ev_candidate) |
| + return false; |
| + |
| CERTValOutParam cvout[3]; |
| int cvout_index = 0; |
| cvout[cvout_index].type = cert_po_certList; |
| @@ -640,12 +653,16 @@ bool VerifyEV(CERTCertificate* cert_handle, int flags, CRLSet* crl_set) { |
| cvout[cvout_index].type = cert_po_end; |
| ScopedCERTValOutParam scoped_cvout(cvout); |
| + bool rev_checking_enabled = |
| + (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED) || |
| + (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED_EV_ONLY); |
| + |
| SECStatus status = PKIXVerifyCert( |
| cert_handle, |
| - flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED, |
| + rev_checking_enabled, |
| flags & X509Certificate::VERIFY_CERT_IO_ENABLED, |
| - metadata->GetPolicyOIDs(), |
| - metadata->NumPolicyOIDs(), |
| + &ev_policy_oid, |
| + 1, |
| cvout); |
| if (status != SECSuccess) |
| return false; |
| @@ -669,17 +686,7 @@ bool VerifyEV(CERTCertificate* cert_handle, int flags, CRLSet* crl_set) { |
| SHA1Fingerprint fingerprint = |
| X509Certificate::CalculateFingerprint(root_ca); |
| - std::vector<SECOidTag> ev_policy_tags; |
| - if (!metadata->GetPolicyOIDsForCA(fingerprint, &ev_policy_tags)) |
| - return false; |
| - DCHECK(!ev_policy_tags.empty()); |
| - |
| - for (std::vector<SECOidTag>::const_iterator |
| - i = ev_policy_tags.begin(); i != ev_policy_tags.end(); ++i) { |
| - if (CheckCertPolicies(cert_handle, *i)) |
| - return true; |
| - } |
| - return false; |
| + return metadata->HasEVPolicyOID(fingerprint, ev_policy_oid); |
| } |
| } // namespace |
| @@ -773,6 +780,11 @@ int CertVerifyProcNSS::VerifyInternal(X509Certificate* cert, |
| if ((flags & X509Certificate::VERIFY_EV_CERT) && |
| VerifyEV(cert_handle, flags, crl_set)) { |
| verify_result->cert_status |= CERT_STATUS_IS_EV; |
| + if (cert_io_enabled && |
| + (flags & (X509Certificate::VERIFY_REV_CHECKING_ENABLED | |
| + X509Certificate::VERIFY_REV_CHECKING_ENABLED_EV_ONLY)) { |
| + verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; |
| + } |
| } |
| return OK; |