| 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..6cb3a45cd21d80eb1a9065c48d983dae233429ff 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,6 +108,66 @@ 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) {
|
| + 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);
|
| + }
|
| + }
|
| +}
|
| +
|
| +bool g_comodo_dns_experiment_enabled = false;
|
| +
|
| } // namespace
|
|
|
| ChromeNetworkDelegate::ChromeNetworkDelegate(
|
| @@ -134,6 +199,11 @@ void ChromeNetworkDelegate::InitializeReferrersEnabled(
|
| enable_referrers->MoveToThread(BrowserThread::IO);
|
| }
|
|
|
| +// static
|
| +void ChromeNetworkDelegate::EnableComodoDNSExperiment() {
|
| + g_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 (g_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(now);
|
| + 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,
|
|
|