Chromium Code Reviews| Index: chrome/browser/net/chrome_network_delegate.cc |
| diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc |
| index fcc0f5160dc4e486bbefd5e9d16aac0ff6540f04..0d1a88402ecfd48427c05bf630fae27cd2841059 100644 |
| --- a/chrome/browser/net/chrome_network_delegate.cc |
| +++ b/chrome/browser/net/chrome_network_delegate.cc |
| @@ -4,7 +4,9 @@ |
| #include "chrome/browser/net/chrome_network_delegate.h" |
| +#include "base/base64.h" |
| #include "base/logging.h" |
| +#include "base/metrics/histogram.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/content_settings/cookie_settings.h" |
| #include "chrome/browser/content_settings/tab_specific_content_settings.h" |
| @@ -22,8 +24,11 @@ |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/browser/resource_request_info.h" |
| #include "net/base/host_port_pair.h" |
| +#include "net/base/dns_util.h" |
| +#include "net/base/dnsrr_resolver.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/net_log.h" |
| +#include "net/base/public_key_hashes.h" |
| #include "net/cookies/cookie_monster.h" |
| #include "net/http/http_request_headers.h" |
| #include "net/http/http_response_headers.h" |
| @@ -103,8 +108,68 @@ void ForwardRequestStatus( |
| } |
| } |
| +const char* const kComodoCerts[] = { |
| + kSPKIHash_AAACertificateServices, |
| + kSPKIHash_AddTrustClass1CARoot, |
| + kSPKIHash_AddTrustExternalCARoot, |
| + kSPKIHash_AddTrustPublicCARoot, |
| + kSPKIHash_AddTrustQualifiedCARoot, |
| + kSPKIHash_COMODOCertificationAuthority, |
| + kSPKIHash_SecureCertificateServices, |
| + kSPKIHash_TrustedCertificateServices, |
| + kSPKIHash_UTNDATACorpSGC, |
| + kSPKIHash_UTNUSERFirstClientAuthenticationandEmail, |
| + kSPKIHash_UTNUSERFirstHardware, |
| + kSPKIHash_UTNUSERFirstObject, |
| +}; |
| + |
| +// IsComodoCertificate returns true if a known Comodo public key appears in |
| +// |public_key_hashes|. |
| +// TODO(agl): remove once experiment is complete, by July 2012. |
| +static bool IsComodoCertificate( |
| + const std::vector<net::SHA1Fingerprint>& public_key_hashes) { |
| + for (std::vector<net::SHA1Fingerprint>::const_iterator |
| + i = public_key_hashes.begin(); i != public_key_hashes.end(); i++) { |
|
willchan no longer on Chromium
2012/03/19 21:24:33
++i
agl
2012/03/21 16:16:39
Done.
|
| + std::string base64_hash; |
| + base::Base64Encode( |
| + base::StringPiece(reinterpret_cast<const char*>(i->data), |
| + arraysize(i->data)), |
| + &base64_hash); |
| + base64_hash = "sha1/" + base64_hash; |
| + |
| + for (size_t j = 0; j < arraysize(kComodoCerts); j++) { |
| + if (base64_hash == kComodoCerts[j]) |
| + return true; |
| + } |
| + } |
| + |
| + return false; |
| +} |
| + |
| +// RecordComodoDNSResult is a callback from a DNS resolution. It records the |
| +// elapsed time in a histogram. |
| +// TODO(agl): remove once experiment is complete, by July 2012. |
| +static void RecordComodoDNSResult(net::RRResponse* response, |
| + base::TimeTicks start_time, |
| + int result) { |
| + base::TimeDelta total_time = base::TimeTicks::Now() - start_time; |
| + if (total_time.InMilliseconds() > 10) { |
| + // If the reply took > 10 ms there's a good chance that it didn't come from |
| + // a local DNS cache. |
| + if (result == net::OK && |
| + response->rrdatas.size() && |
| + response->rrdatas[0].find("wibble") != std::string::npos) { |
| + UMA_HISTOGRAM_TIMES("Net.ComodoDNSExperimentSuccessTime", total_time); |
| + } else { |
| + UMA_HISTOGRAM_TIMES("Net.ComodoDNSExperimentFailureTime", total_time); |
| + } |
| + } |
| +} |
| + |
| } // namespace |
| +bool ChromeNetworkDelegate::comodo_dns_experiment_enabled_ = false; |
| + |
| ChromeNetworkDelegate::ChromeNetworkDelegate( |
| ExtensionEventRouterForwarder* event_router, |
| ExtensionInfoMap* extension_info_map, |
| @@ -134,6 +199,11 @@ void ChromeNetworkDelegate::InitializeReferrersEnabled( |
| enable_referrers->MoveToThread(BrowserThread::IO); |
| } |
| +// static |
| +void ChromeNetworkDelegate::EnableComodoDNSExperiment() { |
| + comodo_dns_experiment_enabled_ = true; |
| +} |
| + |
| int ChromeNetworkDelegate::OnBeforeURLRequest( |
| net::URLRequest* request, |
| const net::CompletionCallback& callback, |
| @@ -197,6 +267,40 @@ void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest* request) { |
| ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted( |
| profile_, extension_info_map_.get(), request); |
| ForwardProxyErrors(request, event_router_.get(), profile_); |
| + |
| + if (comodo_dns_experiment_enabled_) { |
| + // This is a temporary experiment, in conjuction with Comodo, to measure the |
| + // effectiveness of a possible DNS-based revocation mechanism. |
| + // TODO(agl): remove once experiment is complete, by July 2012. |
| + const net::SSLInfo& ssl_info = request->response_info().ssl_info; |
| + if (request->response_info().was_cached == false && |
| + ssl_info.is_valid() && |
| + ssl_info.is_issued_by_known_root && |
| + IsComodoCertificate(ssl_info.public_key_hashes)) { |
| + if (dnsrr_resolver_.get() == NULL) |
| + dnsrr_resolver_.reset(new net::DnsRRResolver); |
| + |
| + // The Comodo DNS record has a 20 minute TTL, so we won't actually |
| + // request it more than three times an hour because it'll be in the |
| + // DnsRRResolver's cache. However, just in case something goes wrong we |
| + // also implement a hard stop to prevent resolutions more than once |
| + // every ten minutes. |
| + const base::TimeTicks now(base::TimeTicks::Now()); |
| + if (!last_comodo_resolution_time_.is_null() && |
| + (now - last_comodo_resolution_time_).InMinutes() < 10) { |
| + return; |
| + } |
| + last_comodo_resolution_time_ = now; |
| + |
| + net::RRResponse* response = new net::RRResponse; |
| + base::TimeTicks start_time(base::TimeTicks::Now()); |
|
willchan no longer on Chromium
2012/03/19 21:24:33
How about reusing |now|?
agl
2012/03/21 16:16:39
Done.
|
| + dnsrr_resolver_->Resolve( |
| + "wibble.comodoca.com", net::kDNS_TXT, 0 /* flags */, |
| + Bind(RecordComodoDNSResult, base::Owned(response), start_time), |
| + response, 0 /* priority */, |
| + request->net_log()); |
| + } |
| + } |
| } |
| void ChromeNetworkDelegate::OnRawBytesRead(const net::URLRequest& request, |