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/http/transport_security_state.h" | 5 #include "net/http/transport_security_state.h" |
6 | 6 |
7 #if defined(USE_OPENSSL) | 7 #if defined(USE_OPENSSL) |
8 #include <openssl/ecdsa.h> | 8 #include <openssl/ecdsa.h> |
9 #include <openssl/ssl.h> | 9 #include <openssl/ssl.h> |
10 #else // !defined(USE_OPENSSL) | 10 #else // !defined(USE_OPENSSL) |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 | 291 |
292 if (delegate_) | 292 if (delegate_) |
293 delegate_->StateIsDirty(this); | 293 delegate_->StateIsDirty(this); |
294 } | 294 } |
295 | 295 |
296 // static | 296 // static |
297 std::string TransportSecurityState::CanonicalizeHost(const std::string& host) { | 297 std::string TransportSecurityState::CanonicalizeHost(const std::string& host) { |
298 // We cannot perform the operations as detailed in the spec here as |host| | 298 // We cannot perform the operations as detailed in the spec here as |host| |
299 // has already undergone IDN processing before it reached us. Thus, we check | 299 // has already undergone IDN processing before it reached us. Thus, we check |
300 // that there are no invalid characters in the host and lowercase the result. | 300 // that there are no invalid characters in the host and lowercase the result. |
301 | |
davidben
2015/05/20 19:21:09
Stray change?
Ryan Sleevi
2015/05/20 19:26:39
Readability ;)
| |
302 std::string new_host; | 301 std::string new_host; |
303 if (!DNSDomainFromDot(host, &new_host)) { | 302 if (!DNSDomainFromDot(host, &new_host)) { |
304 // DNSDomainFromDot can fail if any label is > 63 bytes or if the whole | 303 // DNSDomainFromDot can fail if any label is > 63 bytes or if the whole |
305 // name is >255 bytes. However, search terms can have those properties. | 304 // name is >255 bytes. However, search terms can have those properties. |
306 return std::string(); | 305 return std::string(); |
307 } | 306 } |
308 | 307 |
309 for (size_t i = 0; new_host[i]; i += new_host[i] + 1) { | 308 for (size_t i = 0; new_host[i]; i += new_host[i] + 1) { |
310 const unsigned label_length = static_cast<unsigned>(new_host[i]); | 309 const unsigned label_length = static_cast<unsigned>(new_host[i]); |
311 if (!label_length) | 310 if (!label_length) |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
488 // In the dispatch table, the zero character represents the "end of string" | 487 // In the dispatch table, the zero character represents the "end of string" |
489 // (which is the *beginning* of a hostname since we process it backwards). The | 488 // (which is the *beginning* of a hostname since we process it backwards). The |
490 // value in that case is special -- rather than an offset to another trie node, | 489 // value in that case is special -- rather than an offset to another trie node, |
491 // it contains the HSTS information: whether subdomains are included, pinsets | 490 // it contains the HSTS information: whether subdomains are included, pinsets |
492 // etc. If an "end of string" matches a period in the hostname then the | 491 // etc. If an "end of string" matches a period in the hostname then the |
493 // information is remembered because, if no more specific node is found, then | 492 // information is remembered because, if no more specific node is found, then |
494 // that information applies to the hostname. | 493 // that information applies to the hostname. |
495 // | 494 // |
496 // Dispatch tables are always given in order, but the "end of string" (zero) | 495 // Dispatch tables are always given in order, but the "end of string" (zero) |
497 // value always comes before an entry for '.'. | 496 // value always comes before an entry for '.'. |
498 bool DecodeHSTSPreloadRaw(const std::string& hostname, | 497 bool DecodeHSTSPreloadRaw(const std::string& search_hostname, |
499 bool* out_found, | 498 bool* out_found, |
500 PreloadResult* out) { | 499 PreloadResult* out) { |
501 HuffmanDecoder huffman(kHSTSHuffmanTree, sizeof(kHSTSHuffmanTree)); | 500 HuffmanDecoder huffman(kHSTSHuffmanTree, sizeof(kHSTSHuffmanTree)); |
502 BitReader reader(kPreloadedHSTSData, kPreloadedHSTSBits); | 501 BitReader reader(kPreloadedHSTSData, kPreloadedHSTSBits); |
503 size_t bit_offset = kHSTSRootPosition; | 502 size_t bit_offset = kHSTSRootPosition; |
504 static const char kEndOfString = 0; | 503 static const char kEndOfString = 0; |
505 static const char kEndOfTable = 127; | 504 static const char kEndOfTable = 127; |
506 | 505 |
507 *out_found = false; | 506 *out_found = false; |
508 | 507 |
508 // Normalize any trailing '.' used for DNS suffix searches | |
davidben
2015/05/20 19:21:08
Nit: period
| |
509 std::string hostname = search_hostname; | |
510 size_t found = hostname.find_last_not_of('.'); | |
511 if (found != std::string::npos) { | |
512 hostname.erase(found + 1); | |
513 } else { | |
514 hostname.clear(); | |
515 } | |
516 | |
517 // |hostname| has already undergone IDN conversion, so should be | |
518 // entirely A-Labels. The preload data is entirely normalized to | |
519 // lower case | |
davidben
2015/05/20 19:21:09
Nit: period
| |
520 base::StringToLowerASCII(&hostname); | |
521 | |
509 if (hostname.empty()) { | 522 if (hostname.empty()) { |
510 return true; | 523 return true; |
511 } | 524 } |
525 | |
512 // hostname_offset contains one more than the index of the current character | 526 // hostname_offset contains one more than the index of the current character |
513 // in the hostname that is being considered. It's one greater so that we can | 527 // in the hostname that is being considered. It's one greater so that we can |
514 // represent the position just before the beginning (with zero). | 528 // represent the position just before the beginning (with zero). |
515 size_t hostname_offset = hostname.size(); | 529 size_t hostname_offset = hostname.size(); |
516 | 530 |
517 for (;;) { | 531 for (;;) { |
518 // Seek to the desired location. | 532 // Seek to the desired location. |
519 if (!reader.Seek(bit_offset)) { | 533 if (!reader.Seek(bit_offset)) { |
520 return false; | 534 return false; |
521 } | 535 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
718 const base::Time& expiry, | 732 const base::Time& expiry, |
719 bool include_subdomains, | 733 bool include_subdomains, |
720 const HashValueVector& hashes) { | 734 const HashValueVector& hashes) { |
721 DCHECK(CalledOnValidThread()); | 735 DCHECK(CalledOnValidThread()); |
722 AddHPKPInternal(host, base::Time::Now(), expiry, include_subdomains, hashes); | 736 AddHPKPInternal(host, base::Time::Now(), expiry, include_subdomains, hashes); |
723 } | 737 } |
724 | 738 |
725 // static | 739 // static |
726 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { | 740 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { |
727 PreloadResult result; | 741 PreloadResult result; |
728 return DecodeHSTSPreload(host, &result) && result.has_pins && | 742 return !CanonicalizeHost(host).empty() && DecodeHSTSPreload(host, &result) && |
davidben
2015/05/20 19:21:09
Would it be better to move the CanonicalizeHost ch
| |
743 result.has_pins && | |
729 kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; | 744 kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; |
730 } | 745 } |
731 | 746 |
732 // static | 747 // static |
733 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { | 748 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { |
734 PreloadResult result; | 749 PreloadResult result; |
735 if (!DecodeHSTSPreload(host, &result) || | 750 if (CanonicalizeHost(host).empty() || !DecodeHSTSPreload(host, &result) || |
736 !result.has_pins) { | 751 !result.has_pins) { |
737 return; | 752 return; |
738 } | 753 } |
739 | 754 |
740 DCHECK(result.domain_id != DOMAIN_NOT_PINNED); | 755 DCHECK(result.domain_id != DOMAIN_NOT_PINNED); |
741 | 756 |
742 UMA_HISTOGRAM_SPARSE_SLOWLY( | 757 UMA_HISTOGRAM_SPARSE_SLOWLY( |
743 "Net.PublicKeyPinFailureDomain", result.domain_id); | 758 "Net.PublicKeyPinFailureDomain", result.domain_id); |
744 } | 759 } |
745 | 760 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
781 DCHECK(CalledOnValidThread()); | 796 DCHECK(CalledOnValidThread()); |
782 | 797 |
783 out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; | 798 out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; |
784 out->sts.include_subdomains = false; | 799 out->sts.include_subdomains = false; |
785 out->pkp.include_subdomains = false; | 800 out->pkp.include_subdomains = false; |
786 | 801 |
787 if (!IsBuildTimely()) | 802 if (!IsBuildTimely()) |
788 return false; | 803 return false; |
789 | 804 |
790 PreloadResult result; | 805 PreloadResult result; |
791 if (!DecodeHSTSPreload(host, &result)) | 806 if (CanonicalizeHost(host).empty() || !DecodeHSTSPreload(host, &result)) |
792 return false; | 807 return false; |
793 | 808 |
794 out->sts.domain = host.substr(result.hostname_offset); | 809 out->sts.domain = host.substr(result.hostname_offset); |
795 out->pkp.domain = out->sts.domain; | 810 out->pkp.domain = out->sts.domain; |
796 out->sts.include_subdomains = result.sts_include_subdomains; | 811 out->sts.include_subdomains = result.sts_include_subdomains; |
797 out->sts.last_observed = base::GetBuildTime(); | 812 out->sts.last_observed = base::GetBuildTime(); |
798 out->sts.upgrade_mode = | 813 out->sts.upgrade_mode = |
799 TransportSecurityState::DomainState::MODE_DEFAULT; | 814 TransportSecurityState::DomainState::MODE_DEFAULT; |
800 if (result.force_https) { | 815 if (result.force_https) { |
801 out->sts.upgrade_mode = | 816 out->sts.upgrade_mode = |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
970 TransportSecurityState::DomainState::STSState::~STSState() { | 985 TransportSecurityState::DomainState::STSState::~STSState() { |
971 } | 986 } |
972 | 987 |
973 TransportSecurityState::DomainState::PKPState::PKPState() { | 988 TransportSecurityState::DomainState::PKPState::PKPState() { |
974 } | 989 } |
975 | 990 |
976 TransportSecurityState::DomainState::PKPState::~PKPState() { | 991 TransportSecurityState::DomainState::PKPState::~PKPState() { |
977 } | 992 } |
978 | 993 |
979 } // namespace | 994 } // namespace |
OLD | NEW |