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

Side by Side Diff: net/quic/crypto/proof_verifier_chromium.cc

Issue 2131813002: Revert of QUIC - Race Cert Verification with host resolution if certs are (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/crypto/proof_verifier_chromium.h" 5 #include "net/quic/crypto/proof_verifier_chromium.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 const std::string& server_config, 71 const std::string& server_config,
72 QuicVersion quic_version, 72 QuicVersion quic_version,
73 base::StringPiece chlo_hash, 73 base::StringPiece chlo_hash,
74 const std::vector<std::string>& certs, 74 const std::vector<std::string>& certs,
75 const std::string& cert_sct, 75 const std::string& cert_sct,
76 const std::string& signature, 76 const std::string& signature,
77 std::string* error_details, 77 std::string* error_details,
78 std::unique_ptr<ProofVerifyDetails>* verify_details, 78 std::unique_ptr<ProofVerifyDetails>* verify_details,
79 ProofVerifierCallback* callback); 79 ProofVerifierCallback* callback);
80 80
81 // Starts the certificate chain verification of |certs|. If |QUIC_PENDING| is
82 // returned, then |callback| will be invoked asynchronously when the
83 // verification completes.
84 QuicAsyncStatus VerifyCertChain(
85 const std::string& hostname,
86 const std::vector<std::string>& certs,
87 std::string* error_details,
88 std::unique_ptr<ProofVerifyDetails>* verify_details,
89 ProofVerifierCallback* callback);
90
91 private: 81 private:
92 enum State { 82 enum State {
93 STATE_NONE, 83 STATE_NONE,
94 STATE_VERIFY_CERT, 84 STATE_VERIFY_CERT,
95 STATE_VERIFY_CERT_COMPLETE, 85 STATE_VERIFY_CERT_COMPLETE,
96 }; 86 };
97 87
98 // Convert |certs| to |cert_|(X509Certificate). Returns true if successful.
99 bool GetX509Certificate(const vector<string>& certs,
100 std::string* error_details,
101 std::unique_ptr<ProofVerifyDetails>* verify_details);
102
103 // Start the cert verification.
104 QuicAsyncStatus VerifyCert(
105 const string& hostname,
106 const uint16_t port,
107 std::string* error_details,
108 std::unique_ptr<ProofVerifyDetails>* verify_details,
109 ProofVerifierCallback* callback);
110
111 int DoLoop(int last_io_result); 88 int DoLoop(int last_io_result);
112 void OnIOComplete(int result); 89 void OnIOComplete(int result);
113 int DoVerifyCert(int result); 90 int DoVerifyCert(int result);
114 int DoVerifyCertComplete(int result); 91 int DoVerifyCertComplete(int result);
115 92
116 bool VerifySignature(const std::string& signed_data, 93 bool VerifySignature(const std::string& signed_data,
117 QuicVersion quic_version, 94 QuicVersion quic_version,
118 StringPiece chlo_hash, 95 StringPiece chlo_hash,
119 const std::string& signature, 96 const std::string& signature,
120 const std::string& cert); 97 const std::string& cert);
(...skipping 20 matching lines...) Expand all
141 std::unique_ptr<ProofVerifyDetailsChromium> verify_details_; 118 std::unique_ptr<ProofVerifyDetailsChromium> verify_details_;
142 std::string error_details_; 119 std::string error_details_;
143 120
144 // X509Certificate from a chain of DER encoded certificates. 121 // X509Certificate from a chain of DER encoded certificates.
145 scoped_refptr<X509Certificate> cert_; 122 scoped_refptr<X509Certificate> cert_;
146 123
147 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is 124 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is
148 // passed to CertVerifier::Verify. 125 // passed to CertVerifier::Verify.
149 int cert_verify_flags_; 126 int cert_verify_flags_;
150 127
151 // If set to true, enforces policy checking in DoVerifyCertComplete().
152 bool enforce_policy_checking_;
153
154 State next_state_; 128 State next_state_;
155 129
156 base::TimeTicks start_time_; 130 base::TimeTicks start_time_;
157 131
158 BoundNetLog net_log_; 132 BoundNetLog net_log_;
159 133
160 DISALLOW_COPY_AND_ASSIGN(Job); 134 DISALLOW_COPY_AND_ASSIGN(Job);
161 }; 135 };
162 136
163 ProofVerifierChromium::Job::Job( 137 ProofVerifierChromium::Job::Job(
164 ProofVerifierChromium* proof_verifier, 138 ProofVerifierChromium* proof_verifier,
165 CertVerifier* cert_verifier, 139 CertVerifier* cert_verifier,
166 CTPolicyEnforcer* ct_policy_enforcer, 140 CTPolicyEnforcer* ct_policy_enforcer,
167 TransportSecurityState* transport_security_state, 141 TransportSecurityState* transport_security_state,
168 CTVerifier* cert_transparency_verifier, 142 CTVerifier* cert_transparency_verifier,
169 int cert_verify_flags, 143 int cert_verify_flags,
170 const BoundNetLog& net_log) 144 const BoundNetLog& net_log)
171 : proof_verifier_(proof_verifier), 145 : proof_verifier_(proof_verifier),
172 verifier_(cert_verifier), 146 verifier_(cert_verifier),
173 policy_enforcer_(ct_policy_enforcer), 147 policy_enforcer_(ct_policy_enforcer),
174 transport_security_state_(transport_security_state), 148 transport_security_state_(transport_security_state),
175 cert_transparency_verifier_(cert_transparency_verifier), 149 cert_transparency_verifier_(cert_transparency_verifier),
176 cert_verify_flags_(cert_verify_flags), 150 cert_verify_flags_(cert_verify_flags),
177 enforce_policy_checking_(true),
178 next_state_(STATE_NONE), 151 next_state_(STATE_NONE),
179 start_time_(base::TimeTicks::Now()), 152 start_time_(base::TimeTicks::Now()),
180 net_log_(net_log) { 153 net_log_(net_log) {
181 CHECK(proof_verifier_); 154 CHECK(proof_verifier_);
182 CHECK(verifier_); 155 CHECK(verifier_);
183 CHECK(policy_enforcer_); 156 CHECK(policy_enforcer_);
184 CHECK(transport_security_state_); 157 CHECK(transport_security_state_);
185 CHECK(cert_transparency_verifier_); 158 CHECK(cert_transparency_verifier_);
186 } 159 }
187 160
(...skipping 27 matching lines...) Expand all
215 error_details->clear(); 188 error_details->clear();
216 189
217 if (STATE_NONE != next_state_) { 190 if (STATE_NONE != next_state_) {
218 *error_details = "Certificate is already set and VerifyProof has begun"; 191 *error_details = "Certificate is already set and VerifyProof has begun";
219 DLOG(DFATAL) << *error_details; 192 DLOG(DFATAL) << *error_details;
220 return QUIC_FAILURE; 193 return QUIC_FAILURE;
221 } 194 }
222 195
223 verify_details_.reset(new ProofVerifyDetailsChromium); 196 verify_details_.reset(new ProofVerifyDetailsChromium);
224 197
225 // Converts |certs| to |cert_|. 198 if (certs.empty()) {
226 if (!GetX509Certificate(certs, error_details, verify_details)) 199 *error_details = "Failed to create certificate chain. Certs are empty.";
200 DLOG(WARNING) << *error_details;
201 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
202 *verify_details = std::move(verify_details_);
227 return QUIC_FAILURE; 203 return QUIC_FAILURE;
204 }
205
206 // Convert certs to X509Certificate.
207 vector<StringPiece> cert_pieces(certs.size());
208 for (unsigned i = 0; i < certs.size(); i++) {
209 cert_pieces[i] = base::StringPiece(certs[i]);
210 }
211 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
212 if (!cert_.get()) {
213 *error_details = "Failed to create certificate chain";
214 DLOG(WARNING) << *error_details;
215 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
216 *verify_details = std::move(verify_details_);
217 return QUIC_FAILURE;
218 }
228 219
229 if (!cert_sct.empty()) { 220 if (!cert_sct.empty()) {
230 // Note that this is a completely synchronous operation: The CT Log Verifier 221 // Note that this is a completely synchronous operation: The CT Log Verifier
231 // gets all the data it needs for SCT verification and does not do any 222 // gets all the data it needs for SCT verification and does not do any
232 // external communication. 223 // external communication.
233 cert_transparency_verifier_->Verify(cert_.get(), std::string(), cert_sct, 224 cert_transparency_verifier_->Verify(cert_.get(), std::string(), cert_sct,
234 &verify_details_->ct_verify_result, 225 &verify_details_->ct_verify_result,
235 net_log_); 226 net_log_);
236 } 227 }
237 228
238 // We call VerifySignature first to avoid copying of server_config and 229 // We call VerifySignature first to avoid copying of server_config and
239 // signature. 230 // signature.
240 if (!VerifySignature(server_config, quic_version, chlo_hash, signature, 231 if (!VerifySignature(server_config, quic_version, chlo_hash, signature,
241 certs[0])) { 232 certs[0])) {
242 *error_details = "Failed to verify signature of server config"; 233 *error_details = "Failed to verify signature of server config";
243 DLOG(WARNING) << *error_details; 234 DLOG(WARNING) << *error_details;
244 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; 235 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
245 *verify_details = std::move(verify_details_); 236 *verify_details = std::move(verify_details_);
246 return QUIC_FAILURE; 237 return QUIC_FAILURE;
247 } 238 }
248 239
249 DCHECK(enforce_policy_checking_);
250 return VerifyCert(hostname, port, error_details, verify_details, callback);
251 }
252
253 QuicAsyncStatus ProofVerifierChromium::Job::VerifyCertChain(
254 const string& hostname,
255 const vector<string>& certs,
256 std::string* error_details,
257 std::unique_ptr<ProofVerifyDetails>* verify_details,
258 ProofVerifierCallback* callback) {
259 DCHECK(error_details);
260 DCHECK(verify_details);
261 DCHECK(callback);
262
263 error_details->clear();
264
265 if (STATE_NONE != next_state_) {
266 *error_details = "Certificate is already set and VerifyCertChain has begun";
267 DLOG(DFATAL) << *error_details;
268 return QUIC_FAILURE;
269 }
270
271 verify_details_.reset(new ProofVerifyDetailsChromium);
272
273 // Converts |certs| to |cert_|.
274 if (!GetX509Certificate(certs, error_details, verify_details))
275 return QUIC_FAILURE;
276
277 enforce_policy_checking_ = false;
278 // |port| is not needed because |enforce_policy_checking_| is false.
279 return VerifyCert(hostname, /*port=*/0, error_details, verify_details,
280 callback);
281 }
282
283 bool ProofVerifierChromium::Job::GetX509Certificate(
284 const vector<string>& certs,
285 std::string* error_details,
286 std::unique_ptr<ProofVerifyDetails>* verify_details) {
287 if (certs.empty()) {
288 *error_details = "Failed to create certificate chain. Certs are empty.";
289 DLOG(WARNING) << *error_details;
290 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
291 *verify_details = std::move(verify_details_);
292 return false;
293 }
294
295 // Convert certs to X509Certificate.
296 vector<StringPiece> cert_pieces(certs.size());
297 for (unsigned i = 0; i < certs.size(); i++) {
298 cert_pieces[i] = base::StringPiece(certs[i]);
299 }
300 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
301 if (!cert_.get()) {
302 *error_details = "Failed to create certificate chain";
303 DLOG(WARNING) << *error_details;
304 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
305 *verify_details = std::move(verify_details_);
306 return false;
307 }
308 return true;
309 }
310
311 QuicAsyncStatus ProofVerifierChromium::Job::VerifyCert(
312 const string& hostname,
313 const uint16_t port,
314 std::string* error_details,
315 std::unique_ptr<ProofVerifyDetails>* verify_details,
316 ProofVerifierCallback* callback) {
317 hostname_ = hostname; 240 hostname_ = hostname;
318 port_ = port; 241 port_ = port;
319 242
320 next_state_ = STATE_VERIFY_CERT; 243 next_state_ = STATE_VERIFY_CERT;
321 switch (DoLoop(OK)) { 244 switch (DoLoop(OK)) {
322 case OK: 245 case OK:
323 *verify_details = std::move(verify_details_); 246 *verify_details = std::move(verify_details_);
324 return QUIC_SUCCESS; 247 return QUIC_SUCCESS;
325 case ERR_IO_PENDING: 248 case ERR_IO_PENDING:
326 callback_.reset(callback); 249 callback_.reset(callback);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 308
386 const CertVerifyResult& cert_verify_result = 309 const CertVerifyResult& cert_verify_result =
387 verify_details_->cert_verify_result; 310 verify_details_->cert_verify_result;
388 const CertStatus cert_status = cert_verify_result.cert_status; 311 const CertStatus cert_status = cert_verify_result.cert_status;
389 verify_details_->ct_verify_result.ct_policies_applied = result == OK; 312 verify_details_->ct_verify_result.ct_policies_applied = result == OK;
390 verify_details_->ct_verify_result.ev_policy_compliance = 313 verify_details_->ct_verify_result.ev_policy_compliance =
391 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; 314 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
392 315
393 // If the connection was good, check HPKP and CT status simultaneously, 316 // If the connection was good, check HPKP and CT status simultaneously,
394 // but prefer to treat the HPKP error as more serious, if there was one. 317 // but prefer to treat the HPKP error as more serious, if there was one.
395 if (enforce_policy_checking_ && 318 if ((result == OK ||
396 (result == OK ||
397 (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) { 319 (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
398 if ((cert_verify_result.cert_status & CERT_STATUS_IS_EV)) { 320 if ((cert_verify_result.cert_status & CERT_STATUS_IS_EV)) {
399 ct::EVPolicyCompliance ev_policy_compliance = 321 ct::EVPolicyCompliance ev_policy_compliance =
400 policy_enforcer_->DoesConformToCTEVPolicy( 322 policy_enforcer_->DoesConformToCTEVPolicy(
401 cert_verify_result.verified_cert.get(), 323 cert_verify_result.verified_cert.get(),
402 SSLConfigService::GetEVCertsWhitelist().get(), 324 SSLConfigService::GetEVCertsWhitelist().get(),
403 verify_details_->ct_verify_result.verified_scts, net_log_); 325 verify_details_->ct_verify_result.verified_scts, net_log_);
404 verify_details_->ct_verify_result.ev_policy_compliance = 326 verify_details_->ct_verify_result.ev_policy_compliance =
405 ev_policy_compliance; 327 ev_policy_compliance;
406 if (ev_policy_compliance != 328 if (ev_policy_compliance !=
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 } 498 }
577 const ProofVerifyContextChromium* chromium_context = 499 const ProofVerifyContextChromium* chromium_context =
578 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context); 500 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
579 std::unique_ptr<Job> job( 501 std::unique_ptr<Job> job(
580 new Job(this, cert_verifier_, ct_policy_enforcer_, 502 new Job(this, cert_verifier_, ct_policy_enforcer_,
581 transport_security_state_, cert_transparency_verifier_, 503 transport_security_state_, cert_transparency_verifier_,
582 chromium_context->cert_verify_flags, chromium_context->net_log)); 504 chromium_context->cert_verify_flags, chromium_context->net_log));
583 QuicAsyncStatus status = job->VerifyProof( 505 QuicAsyncStatus status = job->VerifyProof(
584 hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct, 506 hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
585 signature, error_details, verify_details, callback); 507 signature, error_details, verify_details, callback);
586 if (status == QUIC_PENDING) 508 if (status == QUIC_PENDING) {
587 active_jobs_.insert(job.release()); 509 active_jobs_.insert(job.release());
510 }
588 return status; 511 return status;
589 } 512 }
590 513
591 QuicAsyncStatus ProofVerifierChromium::VerifyCertChain(
592 const std::string& hostname,
593 const std::vector<std::string>& certs,
594 const ProofVerifyContext* verify_context,
595 std::string* error_details,
596 std::unique_ptr<ProofVerifyDetails>* verify_details,
597 ProofVerifierCallback* callback) {
598 if (!verify_context) {
599 *error_details = "Missing context";
600 return QUIC_FAILURE;
601 }
602 const ProofVerifyContextChromium* chromium_context =
603 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
604 std::unique_ptr<Job> job(
605 new Job(this, cert_verifier_, ct_policy_enforcer_,
606 transport_security_state_, cert_transparency_verifier_,
607 chromium_context->cert_verify_flags, chromium_context->net_log));
608 QuicAsyncStatus status = job->VerifyCertChain(hostname, certs, error_details,
609 verify_details, callback);
610 if (status == QUIC_PENDING)
611 active_jobs_.insert(job.release());
612 return status;
613 }
614
615 void ProofVerifierChromium::OnJobComplete(Job* job) { 514 void ProofVerifierChromium::OnJobComplete(Job* job) {
616 active_jobs_.erase(job); 515 active_jobs_.erase(job);
617 delete job; 516 delete job;
618 } 517 }
619 518
620 } // namespace net 519 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/proof_verifier_chromium.h ('k') | net/quic/crypto/proof_verifier_chromium_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698