Chromium Code Reviews| Index: net/base/transport_security_state.cc |
| =================================================================== |
| --- net/base/transport_security_state.cc (revision 80114) |
| +++ net/base/transport_security_state.cc (working copy) |
| @@ -4,6 +4,8 @@ |
| #include "net/base/transport_security_state.h" |
| +#include <set> |
| + |
| #include "base/base64.h" |
| #include "base/json/json_reader.h" |
| #include "base/json/json_writer.h" |
| @@ -17,6 +19,8 @@ |
| #include "base/values.h" |
| #include "googleurl/src/gurl.h" |
| #include "net/base/dns_util.h" |
| +#include "net/base/x509_cert_types.h" |
| +#include "net/base/x509_certificate.h" |
| namespace net { |
| @@ -32,6 +36,9 @@ |
| if (canonicalized_host.empty()) |
| return; |
| + // 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 cert locks). |
| bool temp; |
| if (IsPreloadedSTS(canonicalized_host, &temp)) |
| return; |
| @@ -128,6 +135,40 @@ |
| return false; |
| } |
| +bool TransportSecurityState::IsAcceptableCertificate(const std::string& host, |
| + X509Certificate* cert) { |
| + DomainState state; |
| + if (!IsEnabledForHost(&state, host)) |
| + return true; |
| + |
| + if (state.cert_locks.empty()) |
| + return true; |
| + |
| + std::set<std::string> fingerprints; |
| + X509Certificate::OSCertHandles cert_chain; |
| + X509Certificate::GetCertChainFromCert(cert->os_cert_handle(), &cert_chain); |
| + { |
| + X509Certificate::OSCertHandles::const_iterator i; |
| + for (i = cert_chain.begin(); i != cert_chain.end(); ++i) { |
| + net::SHA1Fingerprint fingerprint = |
| + X509Certificate::CalculateFingerprint(*i); |
| + std::string hash; |
| + for (size_t i = 0; i < sizeof(fingerprint.data); ++i) |
| + hash += StringPrintf("%02X", fingerprint.data[i]); |
|
abarth-chromium
2011/04/04 22:49:36
This code looks pretty low-level. Why can't SHA1F
|
| + fingerprints.insert(hash); |
| + } |
| + } |
| + X509Certificate::DestroyCertChain(&cert_chain); |
| + std::vector<std::string>::const_iterator locks_iter; |
| + for (locks_iter = state.cert_locks.begin(); |
| + locks_iter != state.cert_locks.end(); ++locks_iter) { |
| + std::string cert_lock = *locks_iter; |
| + if (fingerprints.find(cert_lock) != fingerprints.end()) |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| void TransportSecurityState::DeleteSince(const base::Time& time) { |
| bool dirtied = false; |
| @@ -312,6 +353,14 @@ |
| continue; |
| } |
| + ListValue* locks = new ListValue; |
| + std::vector<std::string>::const_iterator lock_strings; |
| + for (lock_strings = i->second.cert_locks.begin(); |
| + lock_strings != i->second.cert_locks.end(); |
| + ++lock_strings) |
| + locks->Append(new StringValue(*lock_strings)); |
| + state->Set("cert_locks", locks); |
|
abarth-chromium
2011/04/04 22:49:36
Again, pin is probably a better term.
|
| + |
| toplevel.Set(HashedDomainToExternalString(i->first), state); |
| } |
| @@ -349,6 +398,17 @@ |
| continue; |
| } |
| + ListValue* locks_list; |
| + std::vector<std::string> cert_locks; |
| + if (state->GetList("cert_locks", &locks_list)) { |
| + size_t num_locks = locks_list->GetSize(); |
| + for (size_t i = 0; i < num_locks; ++i) { |
| + std::string lock_string; |
| + if (locks_list->GetString(i, &lock_string)) |
| + cert_locks.push_back(lock_string); |
| + } |
| + } |
| + |
| DomainState::Mode mode; |
| if (mode_string == "strict") { |
| mode = DomainState::MODE_STRICT; |
| @@ -380,14 +440,17 @@ |
| } |
| std::string hashed = ExternalStringToHashedDomain(*i); |
| - if (hashed.empty()) |
| + if (hashed.empty()) { |
| + dirtied = true; |
| continue; |
| + } |
| DomainState new_state; |
| new_state.mode = mode; |
| new_state.created = created_time; |
| new_state.expiry = expiry_time; |
| new_state.include_subdomains = include_subdomains; |
| + new_state.cert_locks = cert_locks; |
| enabled_hosts_[hashed] = new_state; |
| } |