Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1629)

Unified Diff: net/cert/cert_verify_proc.cc

Issue 2100303002: Add OCSPVerifyResult for tracking stapled OCSP responses cross-platform. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ocsp-date-check
Patch Set: Comments from estark Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..3c3b6065c0f01e398f857e108e4a761eb53e7de9 100644
--- a/net/cert/cert_verify_proc.cc
+++ b/net/cert/cert_verify_proc.cc
@@ -23,7 +23,10 @@
#include "net/cert/cert_verify_proc_whitelist.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/crl_set.h"
+#include "net/cert/internal/parse_ocsp.h"
+#include "net/cert/ocsp_revocation_status.h"
#include "net/cert/x509_certificate.h"
+#include "net/der/encode_values.h"
#include "url/url_canon.h"
#if defined(USE_NSS_CERTS)
@@ -182,6 +185,91 @@ bool IsPastSHA1DeprecationDate(const X509Certificate& cert) {
return start >= kSHA1DeprecationDate;
}
+bool CheckCertIDMatchesCertificate(const OCSPCertID& cert_id,
Ryan Sleevi 2016/07/18 20:08:08 Document
dadrian 2016/07/18 22:23:32 Done.
+ const X509Certificate& certificate) {
+ // TODO(dadrian): Verify name and key hashes. https://crbug.com/620005
+ der::Input serial(&certificate.serial_number());
+ return cert_id.serial_number == serial;
+}
+
+void CheckOCSP(const std::string& raw_response,
Ryan Sleevi 2016/07/18 20:08:08 Document
dadrian 2016/07/18 22:23:32 Done.
+ CertVerifyResult* verify_result) {
Ryan Sleevi 2016/07/18 20:08:08 Is CertVerifyResult really the right dependency? I
dadrian 2016/07/18 22:23:31 Done.
+ verify_result->ocsp.Reset();
Ryan Sleevi 2016/07/18 20:08:08 Do we need an explicit reset? Can't you just do a
dadrian 2016/07/18 22:23:32 Done.
+
+ if (raw_response.empty()) {
+ verify_result->ocsp.response_status = OCSPVerifyResult::MISSING;
+ return;
+ }
+ der::Input response_der(&raw_response);
Ryan Sleevi 2016/07/18 20:08:08 move the newline from 204 to 203 :)
dadrian 2016/07/18 22:23:31 Done.
+
+ OCSPResponse response;
+ if (!ParseOCSPResponse(response_der, &response)) {
+ verify_result->ocsp.response_status = OCSPVerifyResult::PARSE_RESPONSE;
Ryan Sleevi 2016/07/18 20:08:07 Is PARSE_RESPONSE a good name for the enum? How do
dadrian 2016/07/18 22:23:32 I changed it to PARSE_RESPONSE_ERROR and PARSE_RES
+ return;
+ }
+
+ // If the OCSP response isn't status SUCCESSFUL, don't parse the rest of the
+ // data.
Ryan Sleevi 2016/07/18 20:08:07 Could you explain the "why" more? Why is this a 'b
dadrian 2016/07/18 22:23:32 Done.
+ if (response.status != OCSPResponse::ResponseStatus::SUCCESSFUL) {
+ verify_result->ocsp.response_status = OCSPVerifyResult::BAD_RESPONSE;
+ return;
+ }
+
+ OCSPResponseData response_data;
+ if (!ParseOCSPResponseData(response.data, &response_data)) {
Ryan Sleevi 2016/07/18 20:08:07 This could benefit from documentation, because Par
dadrian 2016/07/18 22:23:32 Done.
+ verify_result->ocsp.response_status = OCSPVerifyResult::PARSE_RESPONSE_DATA;
+ return;
+ }
+
+ // If producedAt is outside of the certificate validity period, reject the
+ // response.
+ der::GeneralizedTime not_before, not_after;
+ if (!der::EncodeTimeAsGeneralizedTime(
+ verify_result->verified_cert->valid_start(), &not_before) ||
+ !der::EncodeTimeAsGeneralizedTime(
+ verify_result->verified_cert->valid_expiry(), &not_after)) {
Ryan Sleevi 2016/07/18 20:08:08 Just to make sure I understand: We parse the certi
dadrian 2016/07/18 22:23:32 Aren't computers great? :) The other option woul
+ verify_result->ocsp.response_status = OCSPVerifyResult::BAD_PRODUCED_AT;
+ return;
+ }
+ if (response_data.produced_at < not_before ||
+ response_data.produced_at > not_after) {
+ verify_result->ocsp.response_status = OCSPVerifyResult::BAD_PRODUCED_AT;
+ return;
+ }
+
+ // TODO(svaldez): Unify with GetOCSPCertStatus.
Ryan Sleevi 2016/07/18 20:08:08 Is there a Bug #?
dadrian 2016/07/18 22:23:32 There is now. https://crbug.com/629249
+ base::Time verify_time = base::Time::Now();
+ base::TimeDelta max_age = base::TimeDelta::FromDays(7);
Ryan Sleevi 2016/07/18 20:08:08 Should this be a function-level static constant so
dadrian 2016/07/18 22:23:31 Sure? Not sure what the rules are here, but this i
+ verify_result->ocsp.response_status = OCSPVerifyResult::NO_MATCHING_RESPONSE;
+ for (const auto& single_response_der : response_data.responses) {
Ryan Sleevi 2016/07/18 20:08:07 You could do with some high-level documentation ab
dadrian 2016/07/18 22:23:32 Done.
+ OCSPSingleResponse single_response;
+ if (!ParseOCSPSingleResponse(single_response_der, &single_response))
+ continue;
+ OCSPCertID cert_id;
+ if (!ParseOCSPCertID(single_response.cert_id_tlv, &cert_id))
+ continue;
+ if (!CheckCertIDMatchesCertificate(cert_id, *verify_result->verified_cert))
+ continue;
+ if (!CheckOCSPDateValid(single_response, verify_time, max_age)) {
+ if (verify_result->ocsp.response_status != OCSPVerifyResult::PROVIDED)
Ryan Sleevi 2016/07/18 20:08:07 This could benefit from documentation
dadrian 2016/07/18 22:23:32 Done.
+ verify_result->ocsp.response_status = OCSPVerifyResult::INVALID_DATE;
+ continue;
+ }
+ verify_result->ocsp.response_status = OCSPVerifyResult::PROVIDED;
+
+ OCSPRevocationStatus current_status =
+ verify_result->ocsp.revocation_status.value_or(
+ OCSPRevocationStatus::GOOD);
+ // In the case that we receive multiple responses, we keep only the
Ryan Sleevi 2016/07/18 20:08:08 Avoid "we" in comments, especially new code. // I
dadrian 2016/07/18 22:23:32 Done.
+ // strictest status (REVOKED > UNKNOWN > GOOD).
+ if (current_status == OCSPRevocationStatus::GOOD ||
+ single_response.cert_status.status == OCSPRevocationStatus::REVOKED) {
+ verify_result->ocsp.revocation_status =
+ single_response.cert_status.status;
+ }
+ }
+}
+
// 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 +346,8 @@ int CertVerifyProc::Verify(X509Certificate* cert,
verify_result->common_name_fallback_used);
}
+ CheckOCSP(ocsp_response, verify_result);
+
// 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)) {

Powered by Google App Engine
This is Rietveld 408576698