OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/cert/cert_verify_proc.h" | 5 #include "net/cert/cert_verify_proc.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
13 #include "base/sha1.h" | 13 #include "base/sha1.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
17 #include "build/build_config.h" | 17 #include "build/build_config.h" |
18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
19 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 19 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
20 #include "net/base/url_util.h" | 20 #include "net/base/url_util.h" |
21 #include "net/cert/asn1_util.h" | |
21 #include "net/cert/cert_status_flags.h" | 22 #include "net/cert/cert_status_flags.h" |
22 #include "net/cert/cert_verifier.h" | 23 #include "net/cert/cert_verifier.h" |
23 #include "net/cert/cert_verify_proc_whitelist.h" | 24 #include "net/cert/cert_verify_proc_whitelist.h" |
24 #include "net/cert/cert_verify_result.h" | 25 #include "net/cert/cert_verify_result.h" |
25 #include "net/cert/crl_set.h" | 26 #include "net/cert/crl_set.h" |
26 #include "net/cert/internal/parse_ocsp.h" | 27 #include "net/cert/internal/parse_ocsp.h" |
27 #include "net/cert/ocsp_revocation_status.h" | 28 #include "net/cert/ocsp_revocation_status.h" |
28 #include "net/cert/x509_certificate.h" | 29 #include "net/cert/x509_certificate.h" |
29 #include "net/der/encode_values.h" | 30 #include "net/der/encode_values.h" |
30 #include "url/url_canon.h" | 31 #include "url/url_canon.h" |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 current_status = ocsp_result->revocation_status; | 303 current_status = ocsp_result->revocation_status; |
303 } | 304 } |
304 if (current_status == OCSPRevocationStatus::GOOD || | 305 if (current_status == OCSPRevocationStatus::GOOD || |
305 single_response.cert_status.status == OCSPRevocationStatus::REVOKED) { | 306 single_response.cert_status.status == OCSPRevocationStatus::REVOKED) { |
306 ocsp_result->revocation_status = single_response.cert_status.status; | 307 ocsp_result->revocation_status = single_response.cert_status.status; |
307 } | 308 } |
308 ocsp_result->response_status = OCSPVerifyResult::PROVIDED; | 309 ocsp_result->response_status = OCSPVerifyResult::PROVIDED; |
309 } | 310 } |
310 } | 311 } |
311 | 312 |
313 // Records histograms indicating whether the certificate |cert|, which | |
314 // is assumed to have been validated chaining to a private root, | |
315 // contains the TLS Feature Extension (https://tools.ietf.org/html/rfc7633) and | |
316 // has valid OCSP information stapled. | |
317 void RecordTLSFeatureExtensionWithPrivateRoot( | |
318 X509Certificate* cert, | |
319 const OCSPVerifyResult& ocsp_result) { | |
320 std::string cert_der; | |
321 if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(), &cert_der)) | |
322 return; | |
323 | |
324 bool has_tls_feature_extension; | |
325 if (!asn1::HasTLSFeatureExtension(cert_der, &has_tls_feature_extension)) | |
eroman
2016/10/21 01:49:23
Should we be checking more specifically for the pr
estark
2016/10/21 02:11:29
My understanding is that the extension is only use
| |
326 return; | |
327 | |
328 UMA_HISTOGRAM_BOOLEAN("Net.Certificate.TLSFeatureExtensionWithPrivateRoot", | |
329 has_tls_feature_extension); | |
330 if (!has_tls_feature_extension) | |
331 return; | |
332 | |
333 UMA_HISTOGRAM_BOOLEAN( | |
334 "Net.Certificate.TLSFeatureExtensionWithPrivateRootHasOCSP", | |
335 (ocsp_result.response_status != OCSPVerifyResult::MISSING)); | |
336 } | |
337 | |
312 // Comparison functor used for binary searching whether a given HashValue, | 338 // Comparison functor used for binary searching whether a given HashValue, |
313 // which MUST be a SHA-256 hash, is contained with an array of SHA-256 | 339 // which MUST be a SHA-256 hash, is contained with an array of SHA-256 |
314 // hashes. | 340 // hashes. |
315 struct HashToArrayComparator { | 341 struct HashToArrayComparator { |
316 template <size_t N> | 342 template <size_t N> |
317 bool operator()(const uint8_t(&lhs)[N], const HashValue& rhs) const { | 343 bool operator()(const uint8_t(&lhs)[N], const HashValue& rhs) const { |
318 static_assert(N == crypto::kSHA256Length, | 344 static_assert(N == crypto::kSHA256Length, |
319 "Only SHA-256 hashes are supported"); | 345 "Only SHA-256 hashes are supported"); |
320 return memcmp(lhs, rhs.data(), crypto::kSHA256Length) < 0; | 346 return memcmp(lhs, rhs.data(), crypto::kSHA256Length) < 0; |
321 } | 347 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
465 // now treat it as a warning and do not map it to an error return value. | 491 // now treat it as a warning and do not map it to an error return value. |
466 } | 492 } |
467 | 493 |
468 // Flag certificates using too long validity periods. | 494 // Flag certificates using too long validity periods. |
469 if (verify_result->is_issued_by_known_root && HasTooLongValidity(*cert)) { | 495 if (verify_result->is_issued_by_known_root && HasTooLongValidity(*cert)) { |
470 verify_result->cert_status |= CERT_STATUS_VALIDITY_TOO_LONG; | 496 verify_result->cert_status |= CERT_STATUS_VALIDITY_TOO_LONG; |
471 if (rv == OK) | 497 if (rv == OK) |
472 rv = MapCertStatusToNetError(verify_result->cert_status); | 498 rv = MapCertStatusToNetError(verify_result->cert_status); |
473 } | 499 } |
474 | 500 |
501 // Record a histogram for the presence of the TLS feature extension in | |
502 // a certificate chaining to a private root. | |
503 if (rv == OK && !verify_result->is_issued_by_known_root) | |
504 RecordTLSFeatureExtensionWithPrivateRoot(cert, verify_result->ocsp_result); | |
505 | |
475 return rv; | 506 return rv; |
476 } | 507 } |
477 | 508 |
478 // static | 509 // static |
479 bool CertVerifyProc::IsBlacklisted(X509Certificate* cert) { | 510 bool CertVerifyProc::IsBlacklisted(X509Certificate* cert) { |
480 // CloudFlare revoked all certificates issued prior to April 2nd, 2014. Thus | 511 // CloudFlare revoked all certificates issued prior to April 2nd, 2014. Thus |
481 // all certificates where the CN ends with ".cloudflare.com" with a prior | 512 // all certificates where the CN ends with ".cloudflare.com" with a prior |
482 // issuance date are rejected. | 513 // issuance date are rejected. |
483 // | 514 // |
484 // The old certs had a lifetime of five years, so this can be removed April | 515 // The old certs had a lifetime of five years, so this can be removed April |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
709 return true; | 740 return true; |
710 | 741 |
711 // For certificates issued after 1 April 2015: 39 months. | 742 // For certificates issued after 1 April 2015: 39 months. |
712 if (start >= time_2015_04_01 && month_diff > 39) | 743 if (start >= time_2015_04_01 && month_diff > 39) |
713 return true; | 744 return true; |
714 | 745 |
715 return false; | 746 return false; |
716 } | 747 } |
717 | 748 |
718 } // namespace net | 749 } // namespace net |
OLD | NEW |