Chromium Code Reviews| Index: net/cert/cert_verify_proc.cc |
| diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc |
| index 49a170d3cb55b929e0659e6757b6f7089c3086ad..19c1367e18df2b2c19f09854fc07ce1f38266563 100644 |
| --- a/net/cert/cert_verify_proc.cc |
| +++ b/net/cert/cert_verify_proc.cc |
| @@ -182,6 +182,78 @@ bool IsPastSHA1DeprecationDate(const X509Certificate& cert) { |
| return start >= kSHA1DeprecationDate; |
| } |
| +bool CompareCertIDToCertificate(const OCSPCertID& cert_id, |
| + const X509Certificate& certificate) { |
| + // TODO(dadrian): Verify name and key hashes. https://crbug.com/620005 |
| + der::Input serial(&certificate.serial_number()); |
| + return serial == cert_id.serial_number; |
| +} |
| + |
| +void CheckOCSP(const std::string& raw_response, |
| + CertVerifyResult* verify_result) { |
| + verify_result->ocsp.Reset(); |
| + |
| + if (raw_response.empty()) { |
| + verify_result->ocsp.response_status = OCSPVerifyResult::MISSING; |
| + return; |
| + } |
| + der::Input response_der(&raw_response); |
| + |
| + OCSPResponse response; |
| + if (!ParseOCSPResponse(response_der, &response)) { |
| + verify_result->ocsp.response_status = OCSPVerifyResult::PARSE_RESPONSE; |
| + return; |
| + } |
| + |
| + // If the OCSP response isn't status SUCCESSFUL, don't parse the rest of the |
| + // data. |
| + if (response.status != OCSPResponse::ResponseStatus::SUCCESSFUL) { |
| + verify_result->ocsp.response_status = OCSPVerifyResult::BAD_RESPONSE; |
| + return; |
| + } |
| + |
| + OCSPResponseData response_data; |
| + if (!ParseOCSPResponseData(response.data, &response_data)) { |
| + verify_result->ocsp.response_status = OCSPVerifyResult::PARSE_RESPONSE_DATA; |
| + return; |
| + } |
| + |
| + // TODO(svaldez): Unify with GetOCSPCertStatus. |
| + bool contains_correct_response = false; |
| + verify_result->ocsp.response_status = OCSPVerifyResult::NO_MATCHING_RESPONSE; |
| + base::Time verify_time = base::Time::Now(); |
| + base::TimeDelta max_age = base::TimeDelta::FromDays(7); |
| + for (const auto& single_response_der : response_data.responses) { |
| + OCSPSingleResponse single_response; |
| + OCSPVerifyResult::SingleResult single_result; |
| + if (ParseOCSPSingleResponse(single_response_der, &single_response)) { |
| + single_result.did_parse = true; |
| + single_result.status = single_response.cert_status.status; |
| + single_result.is_date_valid = |
| + CheckOCSPDateValid(single_response, verify_time, max_age); |
| + OCSPCertID cert_id; |
| + if (ParseOCSPCertID(single_response.cert_id_tlv, &cert_id)) { |
| + single_result.is_correct_certificate = |
| + CompareCertIDToCertificate(cert_id, *verify_result->verified_cert); |
| + } |
| + if (single_result.is_date_valid && single_result.is_correct_certificate) { |
| + contains_correct_response = true; |
| + if (single_response.cert_status.status >= |
| + verify_result->ocsp.cert_status.value_or( |
| + OCSPCertStatus::Status::GOOD)) { |
| + verify_result->ocsp.cert_status = single_response.cert_status.status; |
| + } |
| + } |
| + } |
| + verify_result->ocsp.stapled_responses.push_back(single_result); |
| + } |
| + |
| + if (contains_correct_response) { |
| + verify_result->ocsp.response_status = OCSPVerifyResult::PROVIDED; |
| + } |
| + return; |
|
svaldez
2016/06/23 14:03:15
nit: omit.
|
| +} |
| + |
| // Comparison functor used for binary searching whether a given HashValue, |
| // which MUST be a SHA-256 hash, is contained with an array of SHA-256 |
| // hashes. |
| @@ -258,6 +330,9 @@ int CertVerifyProc::Verify(X509Certificate* cert, |
| verify_result->common_name_fallback_used); |
| } |
| + // Check OCSP information |
| + CheckOCSP(ocsp_response, verify_result); |
|
svaldez
2016/06/23 14:03:15
Should this be done even for blacklisted keys?
|
| + |
| // This check is done after VerifyInternal so that VerifyInternal can fill |
| // in the list of public key hashes. |
| if (IsPublicKeyBlacklisted(verify_result->public_key_hashes)) { |