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

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

Issue 439133002: Extend ProofVerifierChromium and ProofVerifyDetailsChromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 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
« no previous file with comments | « net/quic/crypto/proof_verifier_chromium.h ('k') | net/quic/quic_client_session.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram.h"
12 #include "base/stl_util.h" 13 #include "base/stl_util.h"
13 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
14 #include "crypto/signature_verifier.h" 15 #include "crypto/signature_verifier.h"
15 #include "net/base/net_errors.h" 16 #include "net/base/net_errors.h"
16 #include "net/base/net_log.h" 17 #include "net/base/net_log.h"
17 #include "net/cert/asn1_util.h" 18 #include "net/cert/asn1_util.h"
18 #include "net/cert/cert_status_flags.h" 19 #include "net/cert/cert_status_flags.h"
19 #include "net/cert/cert_verifier.h" 20 #include "net/cert/cert_verifier.h"
20 #include "net/cert/cert_verify_result.h" 21 #include "net/cert/cert_verify_result.h"
21 #include "net/cert/single_request_cert_verifier.h" 22 #include "net/cert/single_request_cert_verifier.h"
22 #include "net/cert/x509_certificate.h" 23 #include "net/cert/x509_certificate.h"
23 #include "net/cert/x509_util.h" 24 #include "net/cert/x509_util.h"
25 #include "net/http/transport_security_state.h"
24 #include "net/quic/crypto/crypto_protocol.h" 26 #include "net/quic/crypto/crypto_protocol.h"
25 #include "net/ssl/ssl_config_service.h" 27 #include "net/ssl/ssl_config_service.h"
26 28
27 using base::StringPiece; 29 using base::StringPiece;
28 using base::StringPrintf; 30 using base::StringPrintf;
29 using std::string; 31 using std::string;
30 using std::vector; 32 using std::vector;
31 33
32 namespace net { 34 namespace net {
33 35
34 ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const { 36 ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const {
35 ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium; 37 ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium;
36 other->cert_verify_result = cert_verify_result; 38 other->cert_verify_result = cert_verify_result;
37 return other; 39 return other;
38 } 40 }
39 41
40 // A Job handles the verification of a single proof. It is owned by the 42 // A Job handles the verification of a single proof. It is owned by the
41 // ProofVerifier. If the verification can not complete synchronously, it 43 // ProofVerifier. If the verification can not complete synchronously, it
42 // will notify the ProofVerifier upon completion. 44 // will notify the ProofVerifier upon completion.
43 class ProofVerifierChromium::Job { 45 class ProofVerifierChromium::Job {
44 public: 46 public:
45 Job(ProofVerifierChromium* proof_verifier, 47 Job(ProofVerifierChromium* proof_verifier,
46 CertVerifier* cert_verifier, 48 CertVerifier* cert_verifier,
49 TransportSecurityState* transport_security_state,
47 const BoundNetLog& net_log); 50 const BoundNetLog& net_log);
48 51
49 // Starts the proof verification. If |QUIC_PENDING| is returned, then 52 // Starts the proof verification. If |QUIC_PENDING| is returned, then
50 // |callback| will be invoked asynchronously when the verification completes. 53 // |callback| will be invoked asynchronously when the verification completes.
51 QuicAsyncStatus VerifyProof(const std::string& hostname, 54 QuicAsyncStatus VerifyProof(const std::string& hostname,
52 const std::string& server_config, 55 const std::string& server_config,
53 const std::vector<std::string>& certs, 56 const std::vector<std::string>& certs,
54 const std::string& signature, 57 const std::string& signature,
55 std::string* error_details, 58 std::string* error_details,
56 scoped_ptr<ProofVerifyDetails>* verify_details, 59 scoped_ptr<ProofVerifyDetails>* verify_details,
(...skipping 14 matching lines...) Expand all
71 bool VerifySignature(const std::string& signed_data, 74 bool VerifySignature(const std::string& signed_data,
72 const std::string& signature, 75 const std::string& signature,
73 const std::string& cert); 76 const std::string& cert);
74 77
75 // Proof verifier to notify when this jobs completes. 78 // Proof verifier to notify when this jobs completes.
76 ProofVerifierChromium* proof_verifier_; 79 ProofVerifierChromium* proof_verifier_;
77 80
78 // The underlying verifier used for verifying certificates. 81 // The underlying verifier used for verifying certificates.
79 scoped_ptr<SingleRequestCertVerifier> verifier_; 82 scoped_ptr<SingleRequestCertVerifier> verifier_;
80 83
84 TransportSecurityState* transport_security_state_;
85
81 // |hostname| specifies the hostname for which |certs| is a valid chain. 86 // |hostname| specifies the hostname for which |certs| is a valid chain.
82 std::string hostname_; 87 std::string hostname_;
83 88
84 scoped_ptr<ProofVerifierCallback> callback_; 89 scoped_ptr<ProofVerifierCallback> callback_;
85 scoped_ptr<ProofVerifyDetailsChromium> verify_details_; 90 scoped_ptr<ProofVerifyDetailsChromium> verify_details_;
86 std::string error_details_; 91 std::string error_details_;
87 92
88 // X509Certificate from a chain of DER encoded certificates. 93 // X509Certificate from a chain of DER encoded certificates.
89 scoped_refptr<X509Certificate> cert_; 94 scoped_refptr<X509Certificate> cert_;
90 95
91 State next_state_; 96 State next_state_;
92 97
93 BoundNetLog net_log_; 98 BoundNetLog net_log_;
94 99
95 DISALLOW_COPY_AND_ASSIGN(Job); 100 DISALLOW_COPY_AND_ASSIGN(Job);
96 }; 101 };
97 102
98 ProofVerifierChromium::Job::Job(ProofVerifierChromium* proof_verifier, 103 ProofVerifierChromium::Job::Job(
99 CertVerifier* cert_verifier, 104 ProofVerifierChromium* proof_verifier,
100 const BoundNetLog& net_log) 105 CertVerifier* cert_verifier,
106 TransportSecurityState* transport_security_state,
107 const BoundNetLog& net_log)
101 : proof_verifier_(proof_verifier), 108 : proof_verifier_(proof_verifier),
102 verifier_(new SingleRequestCertVerifier(cert_verifier)), 109 verifier_(new SingleRequestCertVerifier(cert_verifier)),
110 transport_security_state_(transport_security_state),
103 next_state_(STATE_NONE), 111 next_state_(STATE_NONE),
104 net_log_(net_log) { 112 net_log_(net_log) {
105 } 113 }
106 114
107 QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof( 115 QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
108 const string& hostname, 116 const string& hostname,
109 const string& server_config, 117 const string& server_config,
110 const vector<string>& certs, 118 const vector<string>& certs,
111 const string& signature, 119 const string& signature,
112 std::string* error_details, 120 std::string* error_details,
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 SSLConfigService::GetCRLSet().get(), 229 SSLConfigService::GetCRLSet().get(),
222 &verify_details_->cert_verify_result, 230 &verify_details_->cert_verify_result,
223 base::Bind(&ProofVerifierChromium::Job::OnIOComplete, 231 base::Bind(&ProofVerifierChromium::Job::OnIOComplete,
224 base::Unretained(this)), 232 base::Unretained(this)),
225 net_log_); 233 net_log_);
226 } 234 }
227 235
228 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) { 236 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
229 verifier_.reset(); 237 verifier_.reset();
230 238
239 #if defined(OFFICIAL_BUILD) && !defined(OS_ANDROID) && !defined(OS_IOS)
240 // TODO(wtc): The following code was copied from ssl_client_socket_nss.cc.
241 // Convert it to a new function that can be called by both files. These
242 // variables simulate the arguments to the new function.
243 const CertVerifyResult& cert_verify_result =
244 verify_details_->cert_verify_result;
245 bool sni_available = true;
246 const std::string& host = hostname_;
247 TransportSecurityState* transport_security_state = transport_security_state_;
248 std::string* pinning_failure_log = &verify_details_->pinning_failure_log;
249
250 // Take care of any mandates for public key pinning.
251 //
252 // Pinning is only enabled for official builds to make sure that others don't
253 // end up with pins that cannot be easily updated.
254 //
255 // TODO(agl): We might have an issue here where a request for foo.example.com
256 // merges into a SPDY connection to www.example.com, and gets a different
257 // certificate.
258
259 // Perform pin validation if, and only if, all these conditions obtain:
260 //
261 // * a TransportSecurityState object is available;
262 // * the server's certificate chain is valid (or suffers from only a minor
263 // error);
264 // * the server's certificate chain chains up to a known root (i.e. not a
265 // user-installed trust anchor); and
266 // * the build is recent (very old builds should fail open so that users
267 // have some chance to recover).
268 //
269 const CertStatus cert_status = cert_verify_result.cert_status;
270 if (transport_security_state &&
271 (result == OK ||
272 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
273 cert_verify_result.is_issued_by_known_root &&
274 TransportSecurityState::IsBuildTimely()) {
275 if (transport_security_state->HasPublicKeyPins(host, sni_available)) {
276 if (!transport_security_state->CheckPublicKeyPins(
277 host,
278 sni_available,
279 cert_verify_result.public_key_hashes,
280 pinning_failure_log)) {
281 LOG(ERROR) << *pinning_failure_log;
282 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
283 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false);
284 TransportSecurityState::ReportUMAOnPinFailure(host);
285 } else {
286 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true);
287 }
288 }
289 }
290 #endif
291
231 if (result != OK) { 292 if (result != OK) {
232 error_details_ = StringPrintf("Failed to verify certificate chain: %s", 293 error_details_ = StringPrintf("Failed to verify certificate chain: %s",
233 ErrorToString(result)); 294 ErrorToString(result));
234 DLOG(WARNING) << error_details_; 295 DLOG(WARNING) << error_details_;
235 } 296 }
236 297
237 // Exit DoLoop and return the result to the caller to VerifyProof. 298 // Exit DoLoop and return the result to the caller to VerifyProof.
238 DCHECK_EQ(STATE_NONE, next_state_); 299 DCHECK_EQ(STATE_NONE, next_state_);
239 return result; 300 return result;
240 } 301 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 369
309 if (!verifier.VerifyFinal()) { 370 if (!verifier.VerifyFinal()) {
310 DLOG(WARNING) << "VerifyFinal failed"; 371 DLOG(WARNING) << "VerifyFinal failed";
311 return false; 372 return false;
312 } 373 }
313 374
314 DVLOG(1) << "VerifyFinal success"; 375 DVLOG(1) << "VerifyFinal success";
315 return true; 376 return true;
316 } 377 }
317 378
318 ProofVerifierChromium::ProofVerifierChromium(CertVerifier* cert_verifier) 379 ProofVerifierChromium::ProofVerifierChromium(
319 : cert_verifier_(cert_verifier) {} 380 CertVerifier* cert_verifier,
381 TransportSecurityState* transport_security_state)
382 : cert_verifier_(cert_verifier),
383 transport_security_state_(transport_security_state) {
384 }
320 385
321 ProofVerifierChromium::~ProofVerifierChromium() { 386 ProofVerifierChromium::~ProofVerifierChromium() {
322 STLDeleteElements(&active_jobs_); 387 STLDeleteElements(&active_jobs_);
323 } 388 }
324 389
325 QuicAsyncStatus ProofVerifierChromium::VerifyProof( 390 QuicAsyncStatus ProofVerifierChromium::VerifyProof(
326 const std::string& hostname, 391 const std::string& hostname,
327 const std::string& server_config, 392 const std::string& server_config,
328 const std::vector<std::string>& certs, 393 const std::vector<std::string>& certs,
329 const std::string& signature, 394 const std::string& signature,
330 const ProofVerifyContext* verify_context, 395 const ProofVerifyContext* verify_context,
331 std::string* error_details, 396 std::string* error_details,
332 scoped_ptr<ProofVerifyDetails>* verify_details, 397 scoped_ptr<ProofVerifyDetails>* verify_details,
333 ProofVerifierCallback* callback) { 398 ProofVerifierCallback* callback) {
334 if (!verify_context) { 399 if (!verify_context) {
335 *error_details = "Missing context"; 400 *error_details = "Missing context";
336 return QUIC_FAILURE; 401 return QUIC_FAILURE;
337 } 402 }
338 const ProofVerifyContextChromium* chromium_context = 403 const ProofVerifyContextChromium* chromium_context =
339 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context); 404 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
340 scoped_ptr<Job> job(new Job(this, cert_verifier_, chromium_context->net_log)); 405 scoped_ptr<Job> job(new Job(this,
406 cert_verifier_,
407 transport_security_state_,
408 chromium_context->net_log));
341 QuicAsyncStatus status = job->VerifyProof(hostname, server_config, certs, 409 QuicAsyncStatus status = job->VerifyProof(hostname, server_config, certs,
342 signature, error_details, 410 signature, error_details,
343 verify_details, callback); 411 verify_details, callback);
344 if (status == QUIC_PENDING) { 412 if (status == QUIC_PENDING) {
345 active_jobs_.insert(job.release()); 413 active_jobs_.insert(job.release());
346 } 414 }
347 return status; 415 return status;
348 } 416 }
349 417
350 void ProofVerifierChromium::OnJobComplete(Job* job) { 418 void ProofVerifierChromium::OnJobComplete(Job* job) {
351 active_jobs_.erase(job); 419 active_jobs_.erase(job);
352 delete job; 420 delete job;
353 } 421 }
354 422
355 } // namespace net 423 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/proof_verifier_chromium.h ('k') | net/quic/quic_client_session.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698