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

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

Issue 2210693002: 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, 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 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/chromium/crypto/proof_verifier_chromium.h" 5 #include "net/quic/chromium/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 std::unique_ptr<ProofVerifierCallback> callback); 79 std::unique_ptr<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 std::unique_ptr<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 std::unique_ptr<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 (!signature.empty() && 231 if (!VerifySignature(server_config, quic_version, chlo_hash, signature,
241 !VerifySignature(server_config, quic_version, chlo_hash, signature,
242 certs[0])) { 232 certs[0])) {
243 *error_details = "Failed to verify signature of server config"; 233 *error_details = "Failed to verify signature of server config";
244 DLOG(WARNING) << *error_details; 234 DLOG(WARNING) << *error_details;
245 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; 235 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
246 *verify_details = std::move(verify_details_); 236 *verify_details = std::move(verify_details_);
247 return QUIC_FAILURE; 237 return QUIC_FAILURE;
248 } 238 }
249 239
250 DCHECK(enforce_policy_checking_);
251 return VerifyCert(hostname, port, error_details, verify_details,
252 std::move(callback));
253 }
254
255 QuicAsyncStatus ProofVerifierChromium::Job::VerifyCertChain(
256 const string& hostname,
257 const vector<string>& certs,
258 std::string* error_details,
259 std::unique_ptr<ProofVerifyDetails>* verify_details,
260 std::unique_ptr<ProofVerifierCallback> callback) {
261 DCHECK(error_details);
262 DCHECK(verify_details);
263 DCHECK(callback);
264
265 error_details->clear();
266
267 if (STATE_NONE != next_state_) {
268 *error_details = "Certificate is already set and VerifyCertChain has begun";
269 DLOG(DFATAL) << *error_details;
270 return QUIC_FAILURE;
271 }
272
273 verify_details_.reset(new ProofVerifyDetailsChromium);
274
275 // Converts |certs| to |cert_|.
276 if (!GetX509Certificate(certs, error_details, verify_details))
277 return QUIC_FAILURE;
278
279 enforce_policy_checking_ = false;
280 // |port| is not needed because |enforce_policy_checking_| is false.
281 return VerifyCert(hostname, /*port=*/0, error_details, verify_details,
282 std::move(callback));
283 }
284
285 bool ProofVerifierChromium::Job::GetX509Certificate(
286 const vector<string>& certs,
287 std::string* error_details,
288 std::unique_ptr<ProofVerifyDetails>* verify_details) {
289 if (certs.empty()) {
290 *error_details = "Failed to create certificate chain. Certs are empty.";
291 DLOG(WARNING) << *error_details;
292 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
293 *verify_details = std::move(verify_details_);
294 return false;
295 }
296
297 // Convert certs to X509Certificate.
298 vector<StringPiece> cert_pieces(certs.size());
299 for (unsigned i = 0; i < certs.size(); i++) {
300 cert_pieces[i] = base::StringPiece(certs[i]);
301 }
302 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
303 if (!cert_.get()) {
304 *error_details = "Failed to create certificate chain";
305 DLOG(WARNING) << *error_details;
306 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
307 *verify_details = std::move(verify_details_);
308 return false;
309 }
310 return true;
311 }
312
313 QuicAsyncStatus ProofVerifierChromium::Job::VerifyCert(
314 const string& hostname,
315 const uint16_t port,
316 std::string* error_details,
317 std::unique_ptr<ProofVerifyDetails>* verify_details,
318 std::unique_ptr<ProofVerifierCallback> callback) {
319 hostname_ = hostname; 240 hostname_ = hostname;
320 port_ = port; 241 port_ = port;
321 242
322 next_state_ = STATE_VERIFY_CERT; 243 next_state_ = STATE_VERIFY_CERT;
323 switch (DoLoop(OK)) { 244 switch (DoLoop(OK)) {
324 case OK: 245 case OK:
325 *verify_details = std::move(verify_details_); 246 *verify_details = std::move(verify_details_);
326 return QUIC_SUCCESS; 247 return QUIC_SUCCESS;
327 case ERR_IO_PENDING: 248 case ERR_IO_PENDING:
328 callback_ = std::move(callback); 249 callback_ = std::move(callback);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 308
388 const CertVerifyResult& cert_verify_result = 309 const CertVerifyResult& cert_verify_result =
389 verify_details_->cert_verify_result; 310 verify_details_->cert_verify_result;
390 const CertStatus cert_status = cert_verify_result.cert_status; 311 const CertStatus cert_status = cert_verify_result.cert_status;
391 verify_details_->ct_verify_result.ct_policies_applied = result == OK; 312 verify_details_->ct_verify_result.ct_policies_applied = result == OK;
392 verify_details_->ct_verify_result.ev_policy_compliance = 313 verify_details_->ct_verify_result.ev_policy_compliance =
393 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; 314 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
394 315
395 // If the connection was good, check HPKP and CT status simultaneously, 316 // If the connection was good, check HPKP and CT status simultaneously,
396 // 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.
397 if (enforce_policy_checking_ && 318 if ((result == OK ||
398 (result == OK ||
399 (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) { 319 (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
400 if ((cert_verify_result.cert_status & CERT_STATUS_IS_EV)) { 320 if ((cert_verify_result.cert_status & CERT_STATUS_IS_EV)) {
401 ct::EVPolicyCompliance ev_policy_compliance = 321 ct::EVPolicyCompliance ev_policy_compliance =
402 policy_enforcer_->DoesConformToCTEVPolicy( 322 policy_enforcer_->DoesConformToCTEVPolicy(
403 cert_verify_result.verified_cert.get(), 323 cert_verify_result.verified_cert.get(),
404 SSLConfigService::GetEVCertsWhitelist().get(), 324 SSLConfigService::GetEVCertsWhitelist().get(),
405 verify_details_->ct_verify_result.verified_scts, net_log_); 325 verify_details_->ct_verify_result.verified_scts, net_log_);
406 verify_details_->ct_verify_result.ev_policy_compliance = 326 verify_details_->ct_verify_result.ev_policy_compliance =
407 ev_policy_compliance; 327 ev_policy_compliance;
408 if (ev_policy_compliance != 328 if (ev_policy_compliance !=
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 } 498 }
579 const ProofVerifyContextChromium* chromium_context = 499 const ProofVerifyContextChromium* chromium_context =
580 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context); 500 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
581 std::unique_ptr<Job> job( 501 std::unique_ptr<Job> job(
582 new Job(this, cert_verifier_, ct_policy_enforcer_, 502 new Job(this, cert_verifier_, ct_policy_enforcer_,
583 transport_security_state_, cert_transparency_verifier_, 503 transport_security_state_, cert_transparency_verifier_,
584 chromium_context->cert_verify_flags, chromium_context->net_log)); 504 chromium_context->cert_verify_flags, chromium_context->net_log));
585 QuicAsyncStatus status = job->VerifyProof( 505 QuicAsyncStatus status = job->VerifyProof(
586 hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct, 506 hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
587 signature, error_details, verify_details, std::move(callback)); 507 signature, error_details, verify_details, std::move(callback));
588 if (status == QUIC_PENDING) 508 if (status == QUIC_PENDING) {
589 active_jobs_.insert(job.release()); 509 active_jobs_.insert(job.release());
510 }
590 return status; 511 return status;
591 } 512 }
592 513
593 QuicAsyncStatus ProofVerifierChromium::VerifyCertChain(
594 const std::string& hostname,
595 const std::vector<std::string>& certs,
596 const ProofVerifyContext* verify_context,
597 std::string* error_details,
598 std::unique_ptr<ProofVerifyDetails>* verify_details,
599 std::unique_ptr<ProofVerifierCallback> callback) {
600 if (!verify_context) {
601 *error_details = "Missing context";
602 return QUIC_FAILURE;
603 }
604 const ProofVerifyContextChromium* chromium_context =
605 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
606 std::unique_ptr<Job> job(
607 new Job(this, cert_verifier_, ct_policy_enforcer_,
608 transport_security_state_, cert_transparency_verifier_,
609 chromium_context->cert_verify_flags, chromium_context->net_log));
610 QuicAsyncStatus status = job->VerifyCertChain(
611 hostname, certs, error_details, verify_details, std::move(callback));
612 if (status == QUIC_PENDING)
613 active_jobs_.insert(job.release());
614 return status;
615 }
616
617 void ProofVerifierChromium::OnJobComplete(Job* job) { 514 void ProofVerifierChromium::OnJobComplete(Job* job) {
618 active_jobs_.erase(job); 515 active_jobs_.erase(job);
619 delete job; 516 delete job;
620 } 517 }
621 518
622 } // namespace net 519 } // namespace net
OLDNEW
« 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