Chromium Code Reviews| Index: net/cert/cert_verify_proc_whitelist.cc |
| diff --git a/net/cert/cert_verify_proc_whitelist.cc b/net/cert/cert_verify_proc_whitelist.cc |
| index 53489ffa60ab3c99b4ae2ff4dbfe004e769a937f..e562216273f91d1ac24a26dd48f8fa6a794a44d3 100644 |
| --- a/net/cert/cert_verify_proc_whitelist.cc |
| +++ b/net/cert/cert_verify_proc_whitelist.cc |
| @@ -6,6 +6,8 @@ |
| #include <cstdlib> |
| +#include "base/logging.h" |
|
svaldez
2017/01/26 20:54:48
Extra include?
|
| +#include "net/base/lookup_string_in_fixed_set.h" |
| #include "net/cert/x509_certificate.h" |
| namespace net { |
| @@ -55,27 +57,74 @@ int CompareHashValueToRawHash(const void* key, const void* element) { |
| return memcmp(search_key->data(), element, search_key->size()); |
| } |
| +namespace wosign { |
| +#include "net/data/ssl/wosign/wosign_domains-inc.cc" |
| } // namespace |
| -bool IsNonWhitelistedCertificate(const X509Certificate& cert, |
| - const HashValueVector& public_key_hashes) { |
| - // 2016-10-21 00:00:00 UTC |
| - const base::Time last_wosign_cert = |
| - base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1477008000); |
| +} // namespace |
| +bool IsNonWhitelistedCertificate(const X509Certificate& cert, |
| + const HashValueVector& public_key_hashes, |
| + base::StringPiece hostname) { |
| for (const auto& hash : public_key_hashes) { |
| if (hash.tag != HASH_VALUE_SHA256) |
| continue; |
| // Check for WoSign/StartCom certificates. |
| if (bsearch(&hash, kWosignKeys, arraysize(kWosignKeys), |
| - crypto::kSHA256Length, CompareHashValueToRawHash) != nullptr && |
| - (cert.valid_start().is_null() || cert.valid_start().is_max() || |
| - cert.valid_start() > last_wosign_cert)) { |
| - return true; |
| + crypto::kSHA256Length, CompareHashValueToRawHash) != nullptr) { |
| + // 2016-10-21 00:00:00 UTC |
| + const base::Time last_wosign_cert = |
| + base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1477008000); |
| + |
| + // Don't allow new certificates. |
| + if (cert.valid_start().is_null() || cert.valid_start().is_max() || |
| + cert.valid_start() > last_wosign_cert) { |
| + return true; |
| + } |
| + |
| + // Don't allow certificates from non-whitelisted hosts. |
| + return !IsWhitelistedHost(wosign::kDafsa, arraysize(wosign::kDafsa), |
| + hostname); |
| } |
| } |
| return false; |
| } |
| +bool IsWhitelistedHost(const unsigned char* graph, |
| + size_t graph_length, |
| + base::StringPiece host) { |
| + if (host.empty()) |
| + return false; |
| + |
| + size_t end = host.length(); |
| + |
| + // Skip trailing '.', if any. |
| + if (host[end - 1] == '.') { |
| + --end; |
| + } |
| + |
| + // Reverse through each of the domain components, trying to see if the |
| + // domain is on the whitelist. For example, the string |
| + // "www.domain.example.com" would be processed by first searching |
| + // for "com", then "example.com", then "domain.example.com". The |
| + // loop will terminate when there are no more distinct label separators, |
| + // and thus the final check for "www.domain.example.com". |
| + size_t start = end; |
| + while (start != 0 && |
| + (start = host.rfind('.', start - 1)) != base::StringPiece::npos) { |
| + const char* domain_str = host.data() + start + 1; |
| + size_t domain_length = end - start - 1; |
| + if (domain_length == 0) |
| + return false; |
| + if (LookupStringInFixedSet(graph, graph_length, domain_str, |
| + domain_length) != kDafsaNotFound) { |
| + return true; |
| + } |
| + } |
| + |
| + return LookupStringInFixedSet(graph, graph_length, host.data(), end) != |
| + kDafsaNotFound; |
| +} |
| + |
| } // namespace net |