| 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..2ba4166d4d831d536fd4e682da876dc575fa0451 100644
|
| --- a/net/cert/cert_verify_proc_whitelist.cc
|
| +++ b/net/cert/cert_verify_proc_whitelist.cc
|
| @@ -6,6 +6,7 @@
|
|
|
| #include <cstdlib>
|
|
|
| +#include "net/base/lookup_string_in_fixed_set.h"
|
| #include "net/cert/x509_certificate.h"
|
|
|
| namespace net {
|
| @@ -55,27 +56,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
|
|
|