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

Unified Diff: net/quic/chromium/crypto/proof_verifier_chromium.cc

Issue 2120703003: QUIC - Race Cert Verification with host resolution if certs are (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix for buildbot failure. Created 4 years, 4 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/quic/chromium/crypto/proof_verifier_chromium.cc
diff --git a/net/quic/chromium/crypto/proof_verifier_chromium.cc b/net/quic/chromium/crypto/proof_verifier_chromium.cc
index d66b9ff7bb081f60b3214381d26fe078bab44a4c..9a7396eb798887a98bd60d23f7cff066ae7cb61f 100644
--- a/net/quic/chromium/crypto/proof_verifier_chromium.cc
+++ b/net/quic/chromium/crypto/proof_verifier_chromium.cc
@@ -78,6 +78,16 @@ class ProofVerifierChromium::Job {
std::unique_ptr<ProofVerifyDetails>* verify_details,
std::unique_ptr<ProofVerifierCallback> callback);
+ // Starts the certificate chain verification of |certs|. If |QUIC_PENDING| is
+ // returned, then |callback| will be invoked asynchronously when the
+ // verification completes.
+ QuicAsyncStatus VerifyCertChain(
+ const std::string& hostname,
+ const std::vector<std::string>& certs,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* verify_details,
+ std::unique_ptr<ProofVerifierCallback> callback);
+
private:
enum State {
STATE_NONE,
@@ -85,6 +95,19 @@ class ProofVerifierChromium::Job {
STATE_VERIFY_CERT_COMPLETE,
};
+ // Convert |certs| to |cert_|(X509Certificate). Returns true if successful.
+ bool GetX509Certificate(const vector<string>& certs,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* verify_details);
+
+ // Start the cert verification.
+ QuicAsyncStatus VerifyCert(
+ const string& hostname,
+ const uint16_t port,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* verify_details,
+ std::unique_ptr<ProofVerifierCallback> callback);
+
int DoLoop(int last_io_result);
void OnIOComplete(int result);
int DoVerifyCert(int result);
@@ -125,6 +148,9 @@ class ProofVerifierChromium::Job {
// passed to CertVerifier::Verify.
int cert_verify_flags_;
+ // If set to true, enforces policy checking in DoVerifyCertComplete().
+ bool enforce_policy_checking_;
+
State next_state_;
base::TimeTicks start_time_;
@@ -148,6 +174,7 @@ ProofVerifierChromium::Job::Job(
transport_security_state_(transport_security_state),
cert_transparency_verifier_(cert_transparency_verifier),
cert_verify_flags_(cert_verify_flags),
+ enforce_policy_checking_(true),
next_state_(STATE_NONE),
start_time_(base::TimeTicks::Now()),
net_log_(net_log) {
@@ -195,27 +222,9 @@ QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
verify_details_.reset(new ProofVerifyDetailsChromium);
- if (certs.empty()) {
- *error_details = "Failed to create certificate chain. Certs are empty.";
- DLOG(WARNING) << *error_details;
- verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
- *verify_details = std::move(verify_details_);
- return QUIC_FAILURE;
- }
-
- // Convert certs to X509Certificate.
- vector<StringPiece> cert_pieces(certs.size());
- for (unsigned i = 0; i < certs.size(); i++) {
- cert_pieces[i] = base::StringPiece(certs[i]);
- }
- cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
- if (!cert_.get()) {
- *error_details = "Failed to create certificate chain";
- DLOG(WARNING) << *error_details;
- verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
- *verify_details = std::move(verify_details_);
+ // Converts |certs| to |cert_|.
+ if (!GetX509Certificate(certs, error_details, verify_details))
return QUIC_FAILURE;
- }
if (!cert_sct.empty()) {
// Note that this is a completely synchronous operation: The CT Log Verifier
@@ -228,7 +237,8 @@ QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
// We call VerifySignature first to avoid copying of server_config and
// signature.
- if (!VerifySignature(server_config, quic_version, chlo_hash, signature,
+ if (!signature.empty() &&
+ !VerifySignature(server_config, quic_version, chlo_hash, signature,
certs[0])) {
*error_details = "Failed to verify signature of server config";
DLOG(WARNING) << *error_details;
@@ -237,6 +247,75 @@ QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
return QUIC_FAILURE;
}
+ DCHECK(enforce_policy_checking_);
+ return VerifyCert(hostname, port, error_details, verify_details,
+ std::move(callback));
+}
+
+QuicAsyncStatus ProofVerifierChromium::Job::VerifyCertChain(
+ const string& hostname,
+ const vector<string>& certs,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* verify_details,
+ std::unique_ptr<ProofVerifierCallback> callback) {
+ DCHECK(error_details);
+ DCHECK(verify_details);
+ DCHECK(callback);
+
+ error_details->clear();
+
+ if (STATE_NONE != next_state_) {
+ *error_details = "Certificate is already set and VerifyCertChain has begun";
+ DLOG(DFATAL) << *error_details;
+ return QUIC_FAILURE;
+ }
+
+ verify_details_.reset(new ProofVerifyDetailsChromium);
+
+ // Converts |certs| to |cert_|.
+ if (!GetX509Certificate(certs, error_details, verify_details))
+ return QUIC_FAILURE;
+
+ enforce_policy_checking_ = false;
+ // |port| is not needed because |enforce_policy_checking_| is false.
+ return VerifyCert(hostname, /*port=*/0, error_details, verify_details,
+ std::move(callback));
+}
+
+bool ProofVerifierChromium::Job::GetX509Certificate(
+ const vector<string>& certs,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* verify_details) {
+ if (certs.empty()) {
+ *error_details = "Failed to create certificate chain. Certs are empty.";
+ DLOG(WARNING) << *error_details;
+ verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
+ *verify_details = std::move(verify_details_);
+ return false;
+ }
+
+ // Convert certs to X509Certificate.
+ vector<StringPiece> cert_pieces(certs.size());
+ for (unsigned i = 0; i < certs.size(); i++) {
+ cert_pieces[i] = base::StringPiece(certs[i]);
+ }
+ cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
+ if (!cert_.get()) {
+ *error_details = "Failed to create certificate chain";
+ DLOG(WARNING) << *error_details;
+ verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
+ *verify_details = std::move(verify_details_);
+ return false;
+ }
+ return true;
+}
+
+QuicAsyncStatus ProofVerifierChromium::Job::VerifyCert(
+ const string& hostname,
+ const uint16_t port,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* verify_details,
+ std::unique_ptr<ProofVerifierCallback> callback) {
hostname_ = hostname;
port_ = port;
@@ -315,7 +394,8 @@ int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
// If the connection was good, check HPKP and CT status simultaneously,
// but prefer to treat the HPKP error as more serious, if there was one.
- if ((result == OK ||
+ if (enforce_policy_checking_ &&
+ (result == OK ||
(IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
if ((cert_verify_result.cert_status & CERT_STATUS_IS_EV)) {
ct::EVPolicyCompliance ev_policy_compliance =
@@ -505,9 +585,32 @@ QuicAsyncStatus ProofVerifierChromium::VerifyProof(
QuicAsyncStatus status = job->VerifyProof(
hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
signature, error_details, verify_details, std::move(callback));
- if (status == QUIC_PENDING) {
+ if (status == QUIC_PENDING)
active_jobs_.insert(job.release());
+ return status;
+}
+
+QuicAsyncStatus ProofVerifierChromium::VerifyCertChain(
+ const std::string& hostname,
+ const std::vector<std::string>& certs,
+ const ProofVerifyContext* verify_context,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* verify_details,
+ std::unique_ptr<ProofVerifierCallback> callback) {
+ if (!verify_context) {
+ *error_details = "Missing context";
+ return QUIC_FAILURE;
}
+ const ProofVerifyContextChromium* chromium_context =
+ reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
+ std::unique_ptr<Job> job(
+ new Job(this, cert_verifier_, ct_policy_enforcer_,
+ transport_security_state_, cert_transparency_verifier_,
+ chromium_context->cert_verify_flags, chromium_context->net_log));
+ QuicAsyncStatus status = job->VerifyCertChain(
+ hostname, certs, error_details, verify_details, std::move(callback));
+ if (status == QUIC_PENDING)
+ active_jobs_.insert(job.release());
return status;
}
« no previous file with comments | « net/quic/chromium/crypto/proof_verifier_chromium.h ('k') | net/quic/chromium/crypto/proof_verifier_chromium_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698