Chromium Code Reviews| Index: net/base/transport_security_state.cc |
| =================================================================== |
| --- net/base/transport_security_state.cc (revision 81709) |
| +++ net/base/transport_security_state.cc (working copy) |
| @@ -5,6 +5,7 @@ |
| #include "net/base/transport_security_state.h" |
| #include "base/base64.h" |
| +#include "base/command_line.h" |
| #include "base/json/json_reader.h" |
| #include "base/json/json_writer.h" |
| #include "base/logging.h" |
| @@ -12,6 +13,7 @@ |
| #include "base/sha1.h" |
| #include "base/string_number_conversions.h" |
| #include "base/string_tokenizer.h" |
| +#include "base/string_split.h" |
| #include "base/string_util.h" |
| #include "base/utf_string_conversions.h" |
| #include "base/values.h" |
| @@ -36,7 +38,7 @@ |
| // TODO(cevans) -- we likely want to permit a host to override a built-in, |
| // for at least the case where the override is stricter (i.e. includes |
| // subdomains, or includes certificate pinning). |
| - bool temp; |
| + DomainState temp; |
| if (IsPreloadedSTS(canonicalized_host, true, &temp)) |
| return; |
| @@ -90,13 +92,8 @@ |
| if (canonicalized_host.empty()) |
| return false; |
| - bool include_subdomains; |
| - if (IsPreloadedSTS(canonicalized_host, sni_available, &include_subdomains)) { |
| - result->created = result->expiry = base::Time::FromTimeT(0); |
| - result->mode = DomainState::MODE_STRICT; |
| - result->include_subdomains = include_subdomains; |
| - result->preloaded = true; |
| - return true; |
| + if (IsPreloadedSTS(canonicalized_host, sni_available, result)) { |
| + return result->mode != DomainState::MODE_NONE; |
| } |
| result->preloaded = false; |
| @@ -336,6 +333,18 @@ |
| return true; |
| } |
| +static void AddHash(const std::string& hash, |
| + std::vector<SHA1Fingerprint>* out) { |
| + std::string hash_str; |
| + SHA1Fingerprint raw_hash; |
| + if (hash.find("sha1/") == 0 && |
| + base::Base64Decode(hash.substr(5, hash.size() - 5), &hash_str) && |
|
abarth-chromium
2011/04/17 05:39:23
It would be nicer if 5 wasn't a magic number here.
|
| + hash_str.size() == base::SHA1_LENGTH) { |
| + memcpy(raw_hash.data, hash_str.data(), sizeof(raw_hash.data)); |
| + out->push_back(raw_hash); |
| + } |
| +} |
| + |
| bool TransportSecurityState::Deserialise(const std::string& input, |
| bool* dirty) { |
| enabled_hosts_.clear(); |
| @@ -372,17 +381,8 @@ |
| size_t num_pins = pins_list->GetSize(); |
| for (size_t i = 0; i < num_pins; ++i) { |
| std::string type_and_base64; |
| - std::string hash_str; |
| - SHA1Fingerprint hash; |
| - if (pins_list->GetString(i, &type_and_base64) && |
| - type_and_base64.find("sha1/") == 0 && |
| - base::Base64Decode( |
| - type_and_base64.substr(5, type_and_base64.size() - 5), |
| - &hash_str) && |
| - hash_str.size() == base::SHA1_LENGTH) { |
| - memcpy(hash.data, hash_str.data(), sizeof(hash.data)); |
| - public_key_hashes.push_back(hash); |
| - } |
| + if (pins_list->GetString(i, &type_and_base64)) |
| + AddHash(type_and_base64, &public_key_hashes); |
| } |
| } |
| @@ -485,7 +485,48 @@ |
| bool TransportSecurityState::IsPreloadedSTS( |
| const std::string& canonicalized_host, |
| bool sni_available, |
| - bool *include_subdomains) { |
| + DomainState* out) { |
| + out->preloaded = true; |
| + out->mode = DomainState::MODE_STRICT; |
| + out->created = out->expiry = base::Time::FromTimeT(0); |
|
abarth-chromium
2011/04/17 05:39:23
I'm not sure this is allowed by the style guide.
|
| + out->include_subdomains = false; |
| + |
| + std::string cmd_line_hsts = |
| + CommandLine::ForCurrentProcess()->GetSwitchValueASCII("hsts-hosts"); |
|
abarth-chromium
2011/04/17 05:39:23
Command line constants should be in a switches.cc
|
| + if (!cmd_line_hsts.empty()) { |
| + std::vector<std::string> hosts; |
| + base::SplitString(cmd_line_hsts, ',', &hosts); |
| + for (std::vector<std::string>::const_iterator i = hosts.begin(); |
| + i != hosts.end(); |
| + ++i) { |
|
abarth-chromium
2011/04/17 05:39:23
I would merge these last two lines.
|
| + std::string host_spec = *i; |
| + std::vector<std::string> parts; |
| + base::SplitString(host_spec, ':', &parts); |
| + if (parts.size() != 4) |
| + continue; |
| + std::string host = CanonicalizeHost(parts[0]); |
| + if (host != canonicalized_host) |
| + continue; |
| + if (parts[1] == "none") |
| + out->mode = DomainState::MODE_NONE; |
| + else if (parts[1] != "strict") |
| + continue; |
| + if (parts[2] == "true") |
|
abarth-chromium
2011/04/17 05:39:23
True? Why not "includeSubdomains" ?
|
| + out->include_subdomains = true; |
| + if (!parts[3].empty()) { |
| + std::vector<SHA1Fingerprint> fingerprints; |
| + std::vector<std::string> str_fingerprints; |
| + base::SplitString(parts[3], '|', &str_fingerprints); |
|
abarth-chromium
2011/04/17 05:39:23
This is getting complicated.
|
| + std::vector<std::string>::const_iterator j; |
| + for (j = str_fingerprints.begin(); j != str_fingerprints.end(); ++j) { |
| + AddHash(*j, &fingerprints); |
| + } |
| + out->public_key_hashes = fingerprints; |
| + } |
| + return true; |
| + } |
| + } |
| + |
| // In the medium term this list is likely to just be hardcoded here. This, |
| // slightly odd, form removes the need for additional relocations records. |
| static const struct { |
| @@ -553,7 +594,7 @@ |
| kPreloadedSTS[j].length) == 0) { |
| if (!kPreloadedSTS[j].include_subdomains && i != 0) |
| return false; |
| - *include_subdomains = kPreloadedSTS[j].include_subdomains; |
| + out->include_subdomains = kPreloadedSTS[j].include_subdomains; |
| return true; |
| } |
| } |
| @@ -564,7 +605,7 @@ |
| kPreloadedSNISTS[j].length) == 0) { |
| if (!kPreloadedSNISTS[j].include_subdomains && i != 0) |
| return false; |
| - *include_subdomains = kPreloadedSNISTS[j].include_subdomains; |
| + out->include_subdomains = kPreloadedSNISTS[j].include_subdomains; |
| return true; |
| } |
| } |
| @@ -613,7 +654,6 @@ |
| } |
| } |
| - |
| LOG(ERROR) << "Rejecting public key chain for domain " << domain |
| << ". Validated chain: " << HashesToBase64String(hashes) |
| << ", expected: " << HashesToBase64String(public_key_hashes); |