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/x509_certificate.h" | 5 #include "net/cert/x509_certificate.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
11 #include <string> | 11 #include <string> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/base64.h" | 14 #include "base/base64.h" |
15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/memory/singleton.h" | 17 #include "base/memory/singleton.h" |
18 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
19 #include "base/pickle.h" | 19 #include "base/pickle.h" |
20 #include "base/sha1.h" | 20 #include "base/sha1.h" |
21 #include "base/string_util.h" | 21 #include "base/string_util.h" |
22 #include "base/strings/string_piece.h" | 22 #include "base/strings/string_piece.h" |
23 #include "base/synchronization/lock.h" | 23 #include "base/synchronization/lock.h" |
24 #include "base/time.h" | 24 #include "base/time.h" |
25 #include "googleurl/src/url_canon_ip.h" | 25 #include "googleurl/src/url_canon_ip.h" |
26 #include "net/base/net_util.h" | 26 #include "net/base/net_util.h" |
27 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | |
27 #include "net/cert/pem_tokenizer.h" | 28 #include "net/cert/pem_tokenizer.h" |
28 | 29 |
29 namespace net { | 30 namespace net { |
30 | 31 |
31 namespace { | 32 namespace { |
32 | 33 |
33 // Indicates the order to use when trying to decode binary data, which is | 34 // Indicates the order to use when trying to decode binary data, which is |
34 // based on (speculation) as to what will be most common -> least common | 35 // based on (speculation) as to what will be most common -> least common |
35 const X509Certificate::Format kFormatDecodePriority[] = { | 36 const X509Certificate::Format kFormatDecodePriority[] = { |
36 X509Certificate::FORMAT_SINGLE_CERTIFICATE, | 37 X509Certificate::FORMAT_SINGLE_CERTIFICATE, |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 // |reference_domain| is the remainder of |host| after the leading host | 546 // |reference_domain| is the remainder of |host| after the leading host |
546 // component is stripped off, but includes the leading dot e.g. | 547 // component is stripped off, but includes the leading dot e.g. |
547 // "www.f.com" -> ".f.com". | 548 // "www.f.com" -> ".f.com". |
548 // If there is no meaningful domain part to |host| (e.g. it contains no dots) | 549 // If there is no meaningful domain part to |host| (e.g. it contains no dots) |
549 // then |reference_domain| will be empty. | 550 // then |reference_domain| will be empty. |
550 base::StringPiece reference_host, reference_domain; | 551 base::StringPiece reference_host, reference_domain; |
551 SplitOnChar(reference_name, '.', &reference_host, &reference_domain); | 552 SplitOnChar(reference_name, '.', &reference_host, &reference_domain); |
552 bool allow_wildcards = false; | 553 bool allow_wildcards = false; |
553 if (!reference_domain.empty()) { | 554 if (!reference_domain.empty()) { |
554 DCHECK(reference_domain.starts_with(".")); | 555 DCHECK(reference_domain.starts_with(".")); |
555 // We required at least 3 components (i.e. 2 dots) as a basic protection | 556 |
556 // against too-broad wild-carding. | 557 // Do not allow wildcards for public/ICANN registry controlled domains - |
557 // Also we don't attempt wildcard matching on a purely numerical hostname. | 558 // that is, prevent *.com or *.co.uk as valid presented names, but do not |
wtc
2013/05/16 18:03:08
Nit: but do not => but not ?
| |
558 allow_wildcards = reference_domain.rfind('.') != 0 && | 559 // *.appspot.com (a private registry controlled domain). |
560 // In addition, unknown top-level domains (such as 'intranet' domains or | |
561 // new TLDs/gTLDs not yet added to the registry controlled domain dataset) | |
562 // are also implicitly prevented. | |
563 // Because |reference_domain| must contain at least one name component that | |
564 // is not registry controlled, this ensures that all reference domains | |
565 // contain at least three domain components when using wildcards. | |
566 size_t registry_length = | |
567 registry_controlled_domains::GetRegistryLength( | |
568 reference_name, | |
569 registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES, | |
570 registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); | |
571 | |
572 // Because |reference_name| was already canonicalized, the following | |
573 // should never happen. | |
574 CHECK_NE(std::string::npos, registry_length); | |
575 | |
576 // Account for the leading dot in |reference_domain|. | |
577 bool is_registry_controlled = | |
578 registry_length != 0 && | |
579 registry_length == (reference_domain.size() - 1); | |
580 | |
581 // Additionally, do not attempt wildcard matching for purely numeric | |
582 // hostnames. | |
583 allow_wildcards = | |
584 !is_registry_controlled && | |
559 reference_name.find_first_not_of("0123456789.") != std::string::npos; | 585 reference_name.find_first_not_of("0123456789.") != std::string::npos; |
560 } | 586 } |
561 | 587 |
562 // Now step through the DNS names doing wild card comparison (if necessary) | 588 // Now step through the DNS names doing wild card comparison (if necessary) |
563 // on each against the reference name. If subjectAltName is empty, then | 589 // on each against the reference name. If subjectAltName is empty, then |
564 // fallback to use the common name instead. | 590 // fallback to use the common name instead. |
565 std::vector<std::string> common_name_as_vector; | 591 std::vector<std::string> common_name_as_vector; |
566 const std::vector<std::string>* presented_names = &cert_san_dns_names; | 592 const std::vector<std::string>* presented_names = &cert_san_dns_names; |
567 if (common_name_fallback) { | 593 if (common_name_fallback) { |
568 // Note: there's a small possibility cert_common_name is an international | 594 // Note: there's a small possibility cert_common_name is an international |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
615 !(pattern_begin.empty() && pattern_end.empty())) | 641 !(pattern_begin.empty() && pattern_end.empty())) |
616 continue; | 642 continue; |
617 | 643 |
618 if (reference_host.starts_with(pattern_begin) && | 644 if (reference_host.starts_with(pattern_begin) && |
619 reference_host.ends_with(pattern_end)) | 645 reference_host.ends_with(pattern_end)) |
620 return true; | 646 return true; |
621 } | 647 } |
622 return false; | 648 return false; |
623 } | 649 } |
624 | 650 |
625 #if !defined(USE_NSS) | |
626 bool X509Certificate::VerifyNameMatch(const std::string& hostname) const { | 651 bool X509Certificate::VerifyNameMatch(const std::string& hostname) const { |
627 std::vector<std::string> dns_names, ip_addrs; | 652 std::vector<std::string> dns_names, ip_addrs; |
628 GetSubjectAltName(&dns_names, &ip_addrs); | 653 GetSubjectAltName(&dns_names, &ip_addrs); |
629 return VerifyHostname(hostname, subject_.common_name, dns_names, ip_addrs); | 654 return VerifyHostname(hostname, subject_.common_name, dns_names, ip_addrs); |
630 } | 655 } |
631 #endif | |
632 | 656 |
633 // static | 657 // static |
634 bool X509Certificate::GetPEMEncoded(OSCertHandle cert_handle, | 658 bool X509Certificate::GetPEMEncoded(OSCertHandle cert_handle, |
635 std::string* pem_encoded) { | 659 std::string* pem_encoded) { |
636 std::string der_encoded; | 660 std::string der_encoded; |
637 if (!GetDEREncoded(cert_handle, &der_encoded) || der_encoded.empty()) | 661 if (!GetDEREncoded(cert_handle, &der_encoded) || der_encoded.empty()) |
638 return false; | 662 return false; |
639 std::string b64_encoded; | 663 std::string b64_encoded; |
640 if (!base::Base64Encode(der_encoded, &b64_encoded) || b64_encoded.empty()) | 664 if (!base::Base64Encode(der_encoded, &b64_encoded) || b64_encoded.empty()) |
641 return false; | 665 return false; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
692 RemoveFromCache(cert_handle_); | 716 RemoveFromCache(cert_handle_); |
693 FreeOSCertHandle(cert_handle_); | 717 FreeOSCertHandle(cert_handle_); |
694 } | 718 } |
695 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { | 719 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { |
696 RemoveFromCache(intermediate_ca_certs_[i]); | 720 RemoveFromCache(intermediate_ca_certs_[i]); |
697 FreeOSCertHandle(intermediate_ca_certs_[i]); | 721 FreeOSCertHandle(intermediate_ca_certs_[i]); |
698 } | 722 } |
699 } | 723 } |
700 | 724 |
701 } // namespace net | 725 } // namespace net |
OLD | NEW |