summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-15 16:18:43 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-15 16:18:43 +0000
commit93fa0379d245a901428bbd7f0424831a1df091e4 (patch)
tree1079a9c031f5b77831f1f14bdf299c0fe0aea9cd
parent7c6c62215562506e63c70eab0484fbc04fa691bb (diff)
downloadchromium_src-93fa0379d245a901428bbd7f0424831a1df091e4.zip
chromium_src-93fa0379d245a901428bbd7f0424831a1df091e4.tar.gz
chromium_src-93fa0379d245a901428bbd7f0424831a1df091e4.tar.bz2
Revert "net: remove DNS certificate checking code."
This reverts commit r114642 - it broke ChromeOS. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114644 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_browser_main.cc4
-rw-r--r--chrome/browser/io_thread.cc4
-rw-r--r--chrome/browser/io_thread.h2
-rw-r--r--chrome/browser/net/chrome_dns_cert_provenance_checker.cc115
-rw-r--r--chrome/browser/net/chrome_dns_cert_provenance_checker.h33
-rw-r--r--chrome/browser/net/chrome_dns_cert_provenance_checker_factory.cc20
-rw-r--r--chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h38
-rw-r--r--chrome/browser/profiles/off_the_record_profile_io_data.cc2
-rw-r--r--chrome/browser/profiles/profile_impl_io_data.cc3
-rw-r--r--chrome/browser/profiles/profile_io_data.cc4
-rw-r--r--chrome/browser/profiles/profile_io_data.h6
-rw-r--r--chrome/chrome_browser.gypi4
-rw-r--r--content/shell/shell_url_request_context_getter.cc5
-rw-r--r--jingle/notifier/base/proxy_resolving_client_socket.cc1
-rw-r--r--net/http/http_cache.cc4
-rw-r--r--net/http/http_cache.h2
-rw-r--r--net/http/http_network_session.cc1
-rw-r--r--net/http/http_network_session.h3
-rw-r--r--net/http/http_network_transaction_unittest.cc2
-rw-r--r--net/http/http_proxy_client_socket_pool_unittest.cc3
-rw-r--r--net/http/http_stream_factory_impl_unittest.cc2
-rw-r--r--net/net.gyp4
-rw-r--r--net/socket/client_socket_pool_manager_impl.cc5
-rw-r--r--net/socket/client_socket_pool_manager_impl.h3
-rw-r--r--net/socket/dns_cert_provenance_checker.cc364
-rw-r--r--net/socket/dns_cert_provenance_checker.h63
-rw-r--r--net/socket/ssl_client_socket.h5
-rw-r--r--net/socket/ssl_client_socket_nss.h3
-rw-r--r--net/socket/ssl_client_socket_pool.cc2
-rw-r--r--net/socket/ssl_client_socket_pool.h2
-rw-r--r--net/socket/ssl_client_socket_pool_unittest.cc3
-rw-r--r--net/url_request/url_request_context.cc2
-rw-r--r--net/url_request/url_request_context.h9
-rw-r--r--net/url_request/url_request_context_storage.cc7
-rw-r--r--net/url_request/url_request_context_storage.h3
-rw-r--r--webkit/tools/test_shell/test_shell_request_context.cc14
36 files changed, 732 insertions, 15 deletions
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 802d5bd..3898f57 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -53,6 +53,8 @@
#include "chrome/browser/metrics/thread_watcher.h"
#include "chrome/browser/metrics/tracking_synchronizer.h"
#include "chrome/browser/nacl_host/nacl_process_host.h"
+#include "chrome/browser/net/chrome_dns_cert_provenance_checker.h"
+#include "chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h"
#include "chrome/browser/net/chrome_net_log.h"
#include "chrome/browser/net/predictor.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
@@ -281,6 +283,8 @@ void InitializeNetworkOptions(const CommandLine& parsed_command_line) {
net::SpdySessionPool::set_max_sessions_per_domain(value);
}
+ SetDnsCertProvenanceCheckerFactory(CreateChromeDnsCertProvenanceChecker);
+
if (parsed_command_line.HasSwitch(switches::kEnableWebSocketOverSpdy)) {
// Enable WebSocket over SPDY.
net::WebSocketJob::set_websocket_over_spdy_enabled(true);
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 63c7601..8e00a2b 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -41,6 +41,7 @@
#include "net/base/cert_verifier.h"
#include "net/base/cookie_monster.h"
#include "net/base/default_origin_bound_cert_store.h"
+#include "net/base/dnsrr_resolver.h"
#include "net/base/host_cache.h"
#include "net/base/host_resolver.h"
#include "net/base/host_resolver_impl.h"
@@ -58,6 +59,7 @@
#include "net/proxy/proxy_config_service.h"
#include "net/proxy/proxy_script_fetcher_impl.h"
#include "net/proxy/proxy_service.h"
+#include "net/socket/dns_cert_provenance_checker.h"
#if defined(USE_NSS)
#include "net/ocsp/nss_ocsp.h"
@@ -445,6 +447,7 @@ void IOThread::Init() {
globals_->host_resolver.reset(
CreateGlobalHostResolver(net_log_));
globals_->cert_verifier.reset(new net::CertVerifier);
+ globals_->dnsrr_resolver.reset(new net::DnsRRResolver);
globals_->transport_security_state.reset(new net::TransportSecurityState(""));
globals_->ssl_config_service = GetSSLConfigService();
globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
@@ -660,6 +663,7 @@ void IOThread::InitSystemRequestContextOnIOThread() {
globals_->system_origin_bound_cert_service.get();
system_params.transport_security_state =
globals_->transport_security_state.get();
+ system_params.dns_cert_checker = NULL;
system_params.ssl_host_info_factory = NULL;
system_params.proxy_service = globals_->system_proxy_service.get();
system_params.ssl_config_service = globals_->ssl_config_service.get();
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index 277c3ad..6a1f9f5 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -29,6 +29,7 @@ class SystemURLRequestContextGetter;
namespace net {
class CertVerifier;
class CookieStore;
+class DnsRRResolver;
class FtpTransactionFactory;
class HostResolver;
class HttpAuthHandlerFactory;
@@ -73,6 +74,7 @@ class IOThread : public content::BrowserThreadDelegate {
// used to enforce pinning for system requests and will only use built-in
// pins.
scoped_ptr<net::TransportSecurityState> transport_security_state;
+ scoped_ptr<net::DnsRRResolver> dnsrr_resolver;
scoped_refptr<net::SSLConfigService> ssl_config_service;
scoped_ptr<net::HttpAuthHandlerFactory> http_auth_handler_factory;
scoped_ptr<net::HttpServerProperties> http_server_properties;
diff --git a/chrome/browser/net/chrome_dns_cert_provenance_checker.cc b/chrome/browser/net/chrome_dns_cert_provenance_checker.cc
new file mode 100644
index 0000000..77233ae
--- /dev/null
+++ b/chrome/browser/net/chrome_dns_cert_provenance_checker.cc
@@ -0,0 +1,115 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/net/chrome_dns_cert_provenance_checker.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
+#include "chrome/browser/net/chrome_url_request_context.h"
+#include "net/url_request/url_request.h"
+
+namespace {
+
+class ChromeDnsCertProvenanceChecker
+ : public net::DnsCertProvenanceChecker,
+ public net::DnsCertProvenanceChecker::Delegate {
+ public:
+ ChromeDnsCertProvenanceChecker(
+ net::DnsRRResolver* dnsrr_resolver,
+ ChromeURLRequestContext* url_req_context)
+ : dnsrr_resolver_(dnsrr_resolver),
+ url_req_context_(url_req_context),
+ upload_url_("http://chromecertcheck.appspot.com/upload"),
+ delegate_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ }
+
+ ~ChromeDnsCertProvenanceChecker() {
+ DCHECK(inflight_requests_.empty());
+ }
+
+ // DnsCertProvenanceChecker interface
+ virtual void DoAsyncVerification(
+ const std::string& hostname,
+ const std::vector<base::StringPiece>& der_certs) {
+ net::DnsCertProvenanceChecker::DoAsyncLookup(hostname, der_certs,
+ dnsrr_resolver_, this);
+ }
+
+ virtual void Shutdown() {
+ STLDeleteContainerPointers(inflight_requests_.begin(),
+ inflight_requests_.end());
+ inflight_requests_.clear();
+ }
+
+ // DnsCertProvenanceChecker::Delegate interface
+ virtual void OnDnsCertLookupFailed(
+ const std::string& hostname,
+ const std::vector<std::string>& der_certs) {
+ const std::string report = BuildEncryptedReport(hostname, der_certs);
+
+ net::URLRequest* url_request(new net::URLRequest(upload_url_, &delegate_));
+ url_request->set_context(url_req_context_);
+ url_request->set_method("POST");
+ url_request->AppendBytesToUpload(report.data(), report.size());
+ net::HttpRequestHeaders headers;
+ headers.SetHeader(net::HttpRequestHeaders::kContentType,
+ "x-application/chrome-cert-provenance-report");
+ url_request->SetExtraRequestHeaders(headers);
+ inflight_requests_.insert(url_request);
+ url_request->Start();
+ }
+
+ private:
+ void RequestComplete(net::URLRequest* request) {
+ std::set<net::URLRequest*>::iterator i = inflight_requests_.find(request);
+ DCHECK(i != inflight_requests_.end());
+ delete *i;
+ inflight_requests_.erase(i);
+ }
+
+ // URLRequestDelegate is the delegate for the upload. Since this is a
+ // fire-and-forget operation, we don't care if there are any errors in the
+ // upload.
+ class URLRequestDelegate : public net::URLRequest::Delegate {
+ public:
+ explicit URLRequestDelegate(ChromeDnsCertProvenanceChecker* checker)
+ : checker_(checker) {
+ }
+
+ // Delegate implementation
+ void OnResponseStarted(net::URLRequest* request) {
+ const net::URLRequestStatus& status(request->status());
+ if (!status.is_success()) {
+ LOG(WARNING) << "Certificate upload failed"
+ << " status:" << status.status()
+ << " error:" << status.error();
+ } else if (request->GetResponseCode() != 200) {
+ LOG(WARNING) << "Certificate upload HTTP status: "
+ << request->GetResponseCode();
+ }
+ checker_->RequestComplete(request);
+ }
+
+ void OnReadCompleted(net::URLRequest* request, int bytes_read) {
+ NOTREACHED();
+ }
+
+ private:
+ ChromeDnsCertProvenanceChecker* const checker_;
+ };
+
+ net::DnsRRResolver* const dnsrr_resolver_;
+ ChromeURLRequestContext* const url_req_context_;
+ const GURL upload_url_;
+ URLRequestDelegate delegate_;
+ std::set<net::URLRequest*> inflight_requests_;
+};
+
+} // namespace
+
+net::DnsCertProvenanceChecker* CreateChromeDnsCertProvenanceChecker(
+ net::DnsRRResolver* dnsrr_resolver,
+ ChromeURLRequestContext* url_req_context) {
+ return new ChromeDnsCertProvenanceChecker(dnsrr_resolver, url_req_context);
+}
diff --git a/chrome/browser/net/chrome_dns_cert_provenance_checker.h b/chrome/browser/net/chrome_dns_cert_provenance_checker.h
new file mode 100644
index 0000000..304a5ef
--- /dev/null
+++ b/chrome/browser/net/chrome_dns_cert_provenance_checker.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NET_CHROME_DNS_CERT_PROVENANCE_CHECKER
+#define CHROME_BROWSER_NET_CHROME_DNS_CERT_PROVENANCE_CHECKER
+#pragma once
+
+#include "net/socket/dns_cert_provenance_checker.h"
+
+#include <string>
+#include <vector>
+
+#include "base/string_piece.h"
+
+namespace net {
+class DnsRRResolver;
+}
+
+class ChromeURLRequestContext;
+
+// Factory function which creates ChromeDnsCertProvenanceChecker objects.
+//
+// WARNING: do not use this with anything other than the main
+// ChromeURLRequestContext. Eventually we'll want to have the other contexts
+// point to the main ChromeURLRequestContext, which then causes lifetime
+// ordering issues wrt ChromeURLRequestContexts, since we're using a raw
+// pointer, and we'll get shutdown ordering problems.
+net::DnsCertProvenanceChecker* CreateChromeDnsCertProvenanceChecker(
+ net::DnsRRResolver* dnsrr_resolver,
+ ChromeURLRequestContext* url_req_context);
+
+#endif // CHROME_BROWSER_NET_CHROME_DNS_CERT_PROVENANCE_CHECKER
diff --git a/chrome/browser/net/chrome_dns_cert_provenance_checker_factory.cc b/chrome/browser/net/chrome_dns_cert_provenance_checker_factory.cc
new file mode 100644
index 0000000..5206a24
--- /dev/null
+++ b/chrome/browser/net/chrome_dns_cert_provenance_checker_factory.cc
@@ -0,0 +1,20 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h"
+
+static DnsCertProvenanceCheckerFactory g_factory;
+
+net::DnsCertProvenanceChecker* CreateDnsCertProvenanceChecker(
+ net::DnsRRResolver* dnsrr_resolver,
+ ChromeURLRequestContext* url_req_context) {
+ if (!g_factory)
+ return NULL;
+
+ return g_factory(dnsrr_resolver, url_req_context);
+}
+
+void SetDnsCertProvenanceCheckerFactory(DnsCertProvenanceCheckerFactory f) {
+ g_factory = f;
+}
diff --git a/chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h b/chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h
new file mode 100644
index 0000000..36cdc59
--- /dev/null
+++ b/chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NET_CHROME_DNS_CERT_PROVENANCE_CHECKER_FACTORY
+#define CHROME_BROWSER_NET_CHROME_DNS_CERT_PROVENANCE_CHECKER_FACTORY
+#pragma once
+
+#include "net/socket/dns_cert_provenance_checker.h"
+
+// WARNING: This factory abstraction is needed because we cannot link NSS code
+// into a .cc file which is included by both Chrome and Chrome Frame. This
+// factory exists so that common code links only against the factory code.
+// Chrome specific code will link against the NSS using code in
+// chrome_dns_cert_provenance_checker.cc and hand a function pointer to this
+// code.
+
+namespace net {
+class DnsRRResolver;
+}
+
+class ChromeURLRequestContext;
+
+// A DnsCertProvenanceCheckerFactory is a function pointer to a factory
+// function for DnsCertProvenanceCheckerFactory objects.
+typedef net::DnsCertProvenanceChecker* (*DnsCertProvenanceCheckerFactory) (
+ net::DnsRRResolver* dnsrr_resolver,
+ ChromeURLRequestContext* url_req_context);
+
+// Return a new DnsCertProvenanceChecker. Caller takes ownership. May return
+// NULL if no factory function has been set.
+net::DnsCertProvenanceChecker* CreateDnsCertProvenanceChecker(
+ net::DnsRRResolver* dnsrr_resolver,
+ ChromeURLRequestContext* url_req_context);
+
+void SetDnsCertProvenanceCheckerFactory(DnsCertProvenanceCheckerFactory);
+
+#endif // CHROME_BROWSER_NET_CHROME_DNS_CERT_PROVENANCE_CHECKER_FACTORY
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc
index b6eb8eb..bdf0845 100644
--- a/chrome/browser/profiles/off_the_record_profile_io_data.cc
+++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc
@@ -168,6 +168,7 @@ void OffTheRecordProfileIOData::LazyInitializeInternal(
io_thread_globals->cert_verifier.get());
main_context->set_http_auth_handler_factory(
io_thread_globals->http_auth_handler_factory.get());
+ main_context->set_dns_cert_checker(dns_cert_checker());
main_context->set_fraudulent_certificate_reporter(
fraudulent_certificate_reporter());
main_context->set_proxy_service(proxy_service());
@@ -203,6 +204,7 @@ void OffTheRecordProfileIOData::LazyInitializeInternal(
main_context->cert_verifier(),
main_context->origin_bound_cert_service(),
main_context->transport_security_state(),
+ main_context->dns_cert_checker(),
main_context->proxy_service(),
kIncognitoSSLCacheShard,
main_context->ssl_config_service(),
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 5d56035..4ac9eb4 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -290,8 +290,10 @@ void ProfileImplIOData::LazyInitializeInternal(
media_request_context_->set_http_auth_handler_factory(
io_thread_globals->http_auth_handler_factory.get());
+ main_context->set_dns_cert_checker(dns_cert_checker());
main_context->set_fraudulent_certificate_reporter(
fraudulent_certificate_reporter());
+ media_request_context_->set_dns_cert_checker(dns_cert_checker());
media_request_context_->set_fraudulent_certificate_reporter(
fraudulent_certificate_reporter());
@@ -368,6 +370,7 @@ void ProfileImplIOData::LazyInitializeInternal(
main_context->cert_verifier(),
main_context->origin_bound_cert_service(),
main_context->transport_security_state(),
+ main_context->dns_cert_checker(),
main_context->proxy_service(),
"", // pass empty ssl_session_cache_shard to share the SSL session cache
// with everything that doesn't explicitly want a different one.
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 297cee0..d92f4ce 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -26,6 +26,7 @@
#include "chrome/browser/io_thread.h"
#include "chrome/browser/media/media_internals.h"
#include "chrome/browser/net/chrome_cookie_notification_details.h"
+#include "chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h"
#include "chrome/browser/net/chrome_fraudulent_certificate_reporter.h"
#include "chrome/browser/net/chrome_net_log.h"
#include "chrome/browser/net/chrome_network_delegate.h"
@@ -432,6 +433,9 @@ void ProfileIOData::LazyInitialize() const {
profile_params_->profile,
&enable_referrers_));
+ dns_cert_checker_.reset(
+ CreateDnsCertProvenanceChecker(io_thread_globals->dnsrr_resolver.get(),
+ main_request_context_));
fraudulent_certificate_reporter_.reset(
new chrome_browser_net::ChromeFraudulentCertificateReporter(
main_request_context_));
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index 33ec9bb..2bed053 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -44,6 +44,7 @@ class MediaStreamManager;
namespace net {
class CookieStore;
+class DnsCertProvenanceChecker;
class FraudulentCertificateReporter;
class HttpTransactionFactory;
class OriginBoundCertService;
@@ -204,6 +205,10 @@ class ProfileIOData {
return network_delegate_.get();
}
+ net::DnsCertProvenanceChecker* dns_cert_checker() const {
+ return dns_cert_checker_.get();
+ }
+
net::FraudulentCertificateReporter* fraudulent_certificate_reporter() const {
return fraudulent_certificate_reporter_.get();
}
@@ -278,6 +283,7 @@ class ProfileIOData {
chrome_url_data_manager_backend_;
mutable scoped_ptr<net::OriginBoundCertService> origin_bound_cert_service_;
mutable scoped_ptr<net::NetworkDelegate> network_delegate_;
+ mutable scoped_ptr<net::DnsCertProvenanceChecker> dns_cert_checker_;
mutable scoped_ptr<net::FraudulentCertificateReporter>
fraudulent_certificate_reporter_;
mutable scoped_ptr<net::ProxyService> proxy_service_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 80028a7..939582c 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1594,6 +1594,10 @@
'browser/net/browser_url_util.cc',
'browser/net/browser_url_util.h',
'browser/net/chrome_cookie_notification_details.h',
+ 'browser/net/chrome_dns_cert_provenance_checker.cc',
+ 'browser/net/chrome_dns_cert_provenance_checker.h',
+ 'browser/net/chrome_dns_cert_provenance_checker_factory.cc',
+ 'browser/net/chrome_dns_cert_provenance_checker_factory.h',
'browser/net/chrome_fraudulent_certificate_reporter.cc',
'browser/net/chrome_fraudulent_certificate_reporter.h',
'browser/net/chrome_net_log.cc',
diff --git a/content/shell/shell_url_request_context_getter.cc b/content/shell/shell_url_request_context_getter.cc
index 05e4893..a99c6e3 100644
--- a/content/shell/shell_url_request_context_getter.cc
+++ b/content/shell/shell_url_request_context_getter.cc
@@ -80,9 +80,10 @@ net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() {
url_request_context_->host_resolver(),
url_request_context_->cert_verifier(),
url_request_context_->origin_bound_cert_service(),
- NULL, // tranport_security_state
+ NULL, //tranport_security_state
+ NULL, //dns_cert_checker
url_request_context_->proxy_service(),
- "", // ssl_session_cache_shard
+ "" /* ssl_session_cache_shard */,
url_request_context_->ssl_config_service(),
url_request_context_->http_auth_handler_factory(),
NULL, // network_delegate
diff --git a/jingle/notifier/base/proxy_resolving_client_socket.cc b/jingle/notifier/base/proxy_resolving_client_socket.cc
index ab0b679..6b6341a 100644
--- a/jingle/notifier/base/proxy_resolving_client_socket.cc
+++ b/jingle/notifier/base/proxy_resolving_client_socket.cc
@@ -52,6 +52,7 @@ ProxyResolvingClientSocket::ProxyResolvingClientSocket(
session_params.origin_bound_cert_service = NULL;
// transport_security_state is NULL because it's not thread safe.
session_params.transport_security_state = NULL;
+ session_params.dns_cert_checker = request_context->dns_cert_checker();
session_params.proxy_service = request_context->proxy_service();
session_params.ssl_host_info_factory = NULL;
session_params.ssl_config_service = request_context->ssl_config_service();
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc
index 78b0eaf..8d79918 100644
--- a/net/http/http_cache.cc
+++ b/net/http/http_cache.cc
@@ -46,6 +46,7 @@ HttpNetworkSession* CreateNetworkSession(
CertVerifier* cert_verifier,
OriginBoundCertService* origin_bound_cert_service,
TransportSecurityState* transport_security_state,
+ DnsCertProvenanceChecker* dns_cert_checker,
ProxyService* proxy_service,
SSLHostInfoFactory* ssl_host_info_factory,
const std::string& ssl_session_cache_shard,
@@ -59,6 +60,7 @@ HttpNetworkSession* CreateNetworkSession(
params.cert_verifier = cert_verifier;
params.origin_bound_cert_service = origin_bound_cert_service;
params.transport_security_state = transport_security_state;
+ params.dns_cert_checker = dns_cert_checker;
params.proxy_service = proxy_service;
params.ssl_host_info_factory = ssl_host_info_factory;
params.ssl_session_cache_shard = ssl_session_cache_shard;
@@ -319,6 +321,7 @@ HttpCache::HttpCache(HostResolver* host_resolver,
CertVerifier* cert_verifier,
OriginBoundCertService* origin_bound_cert_service,
TransportSecurityState* transport_security_state,
+ DnsCertProvenanceChecker* dns_cert_checker_,
ProxyService* proxy_service,
const std::string& ssl_session_cache_shard,
SSLConfigService* ssl_config_service,
@@ -341,6 +344,7 @@ HttpCache::HttpCache(HostResolver* host_resolver,
cert_verifier,
origin_bound_cert_service,
transport_security_state,
+ dns_cert_checker_,
proxy_service,
ssl_host_info_factory_.get(),
ssl_session_cache_shard,
diff --git a/net/http/http_cache.h b/net/http/http_cache.h
index 00d5b98..62c4668 100644
--- a/net/http/http_cache.h
+++ b/net/http/http_cache.h
@@ -43,6 +43,7 @@ class Entry;
namespace net {
class CertVerifier;
+class DnsCertProvenanceChecker;
class HostResolver;
class HttpAuthHandlerFactory;
class HttpNetworkSession;
@@ -123,6 +124,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory,
CertVerifier* cert_verifier,
OriginBoundCertService* origin_bound_cert_service,
TransportSecurityState* transport_security_state,
+ DnsCertProvenanceChecker* dns_cert_checker,
ProxyService* proxy_service,
const std::string& ssl_session_cache_shard,
SSLConfigService* ssl_config_service,
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index 1a59c9f..1c56bc5 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -41,6 +41,7 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
params.cert_verifier,
params.origin_bound_cert_service,
params.transport_security_state,
+ params.dns_cert_checker,
params.ssl_host_info_factory,
params.ssl_session_cache_shard,
params.proxy_service,
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index 2ccec50..5dcf825 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -27,6 +27,7 @@ namespace net {
class CertVerifier;
class ClientSocketFactory;
+class DnsCertProvenanceChecker;
class HostResolver;
class HttpAuthHandlerFactory;
class HttpNetworkSessionPeer;
@@ -56,6 +57,7 @@ class NET_EXPORT HttpNetworkSession
cert_verifier(NULL),
origin_bound_cert_service(NULL),
transport_security_state(NULL),
+ dns_cert_checker(NULL),
proxy_service(NULL),
ssl_host_info_factory(NULL),
ssl_config_service(NULL),
@@ -69,6 +71,7 @@ class NET_EXPORT HttpNetworkSession
CertVerifier* cert_verifier;
OriginBoundCertService* origin_bound_cert_service;
TransportSecurityState* transport_security_state;
+ DnsCertProvenanceChecker* dns_cert_checker;
ProxyService* proxy_service;
SSLHostInfoFactory* ssl_host_info_factory;
std::string ssl_session_cache_shard;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 9284f76..fd0a4c4 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -370,7 +370,7 @@ template<>
CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
HostResolver* host_resolver,
CertVerifier* cert_verifier)
- : SSLClientSocketPool(0, 0, NULL, host_resolver, cert_verifier, NULL,
+ : SSLClientSocketPool(0, 0, NULL, host_resolver, cert_verifier, NULL, NULL,
NULL, NULL, "", NULL, NULL, NULL, NULL, NULL, NULL) {}
//-----------------------------------------------------------------------------
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc
index 0aa5ee9..4c589e9 100644
--- a/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -68,7 +68,8 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam {
&host_resolver_,
&cert_verifier_,
NULL /* origin_bound_cert_store */,
- NULL /* transport_security_state */,
+ NULL /* dnsrr_resolver */,
+ NULL /* dns_cert_checker */,
NULL /* ssl_host_info_factory */,
"" /* ssl_session_cache_shard */,
&socket_factory_,
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc
index 8c463af..e753d28 100644
--- a/net/http/http_stream_factory_impl_unittest.cc
+++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -274,7 +274,7 @@ CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
template<>
CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
HostResolver* host_resolver, CertVerifier* cert_verifier)
- : SSLClientSocketPool(0, 0, NULL, host_resolver, cert_verifier, NULL,
+ : SSLClientSocketPool(0, 0, NULL, host_resolver, cert_verifier, NULL, NULL,
NULL, NULL, "", NULL, NULL, NULL, NULL, NULL, NULL),
last_num_streams_(-1) {}
diff --git a/net/net.gyp b/net/net.gyp
index 92538f6..040c1e0 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -568,6 +568,8 @@
'socket/client_socket_pool_manager.h',
'socket/client_socket_pool_manager_impl.cc',
'socket/client_socket_pool_manager_impl.h',
+ 'socket/dns_cert_provenance_checker.cc',
+ 'socket/dns_cert_provenance_checker.h',
'socket/nss_ssl_util.cc',
'socket/nss_ssl_util.h',
'socket/server_socket.h',
@@ -803,6 +805,8 @@
'base/x509_util_nss.h',
'ocsp/nss_ocsp.cc',
'ocsp/nss_ocsp.h',
+ 'socket/dns_cert_provenance_check.cc',
+ 'socket/dns_cert_provenance_check.h',
'socket/nss_ssl_util.cc',
'socket/nss_ssl_util.h',
'socket/ssl_client_socket_nss.cc',
diff --git a/net/socket/client_socket_pool_manager_impl.cc b/net/socket/client_socket_pool_manager_impl.cc
index 19e0442..a4f9b72 100644
--- a/net/socket/client_socket_pool_manager_impl.cc
+++ b/net/socket/client_socket_pool_manager_impl.cc
@@ -39,6 +39,7 @@ ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
CertVerifier* cert_verifier,
OriginBoundCertService* origin_bound_cert_service,
TransportSecurityState* transport_security_state,
+ DnsCertProvenanceChecker* dns_cert_checker,
SSLHostInfoFactory* ssl_host_info_factory,
const std::string& ssl_session_cache_shard,
ProxyService* proxy_service,
@@ -49,6 +50,7 @@ ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
cert_verifier_(cert_verifier),
origin_bound_cert_service_(origin_bound_cert_service),
transport_security_state_(transport_security_state),
+ dns_cert_checker_(dns_cert_checker),
ssl_host_info_factory_(ssl_host_info_factory),
ssl_session_cache_shard_(ssl_session_cache_shard),
proxy_service_(proxy_service),
@@ -68,6 +70,7 @@ ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
cert_verifier,
origin_bound_cert_service,
transport_security_state,
+ dns_cert_checker,
ssl_host_info_factory,
ssl_session_cache_shard,
socket_factory,
@@ -288,6 +291,7 @@ ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
cert_verifier_,
origin_bound_cert_service_,
transport_security_state_,
+ dns_cert_checker_,
ssl_host_info_factory_,
ssl_session_cache_shard_,
socket_factory_,
@@ -327,6 +331,7 @@ SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
cert_verifier_,
origin_bound_cert_service_,
transport_security_state_,
+ dns_cert_checker_,
ssl_host_info_factory_,
ssl_session_cache_shard_,
socket_factory_,
diff --git a/net/socket/client_socket_pool_manager_impl.h b/net/socket/client_socket_pool_manager_impl.h
index 96caa31..72c1a0c 100644
--- a/net/socket/client_socket_pool_manager_impl.h
+++ b/net/socket/client_socket_pool_manager_impl.h
@@ -23,6 +23,7 @@ namespace net {
class CertVerifier;
class ClientSocketFactory;
class ClientSocketPoolHistograms;
+class DnsCertProvenanceChecker;
class HttpProxyClientSocketPool;
class HostResolver;
class NetLog;
@@ -63,6 +64,7 @@ class ClientSocketPoolManagerImpl : public base::NonThreadSafe,
CertVerifier* cert_verifier,
OriginBoundCertService* origin_bound_cert_service,
TransportSecurityState* transport_security_state,
+ DnsCertProvenanceChecker* dns_cert_checker,
SSLHostInfoFactory* ssl_host_info_factory,
const std::string& ssl_session_cache_shard,
ProxyService* proxy_service,
@@ -109,6 +111,7 @@ class ClientSocketPoolManagerImpl : public base::NonThreadSafe,
CertVerifier* const cert_verifier_;
OriginBoundCertService* const origin_bound_cert_service_;
TransportSecurityState* const transport_security_state_;
+ DnsCertProvenanceChecker* const dns_cert_checker_;
SSLHostInfoFactory* const ssl_host_info_factory_;
const std::string ssl_session_cache_shard_;
ProxyService* const proxy_service_;
diff --git a/net/socket/dns_cert_provenance_checker.cc b/net/socket/dns_cert_provenance_checker.cc
new file mode 100644
index 0000000..b05a382
--- /dev/null
+++ b/net/socket/dns_cert_provenance_checker.cc
@@ -0,0 +1,364 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/socket/dns_cert_provenance_checker.h"
+
+#if !defined(USE_OPENSSL)
+
+#include <nspr.h>
+
+#include <hasht.h>
+#include <keyhi.h>
+#include <pk11pub.h>
+#include <sechash.h>
+
+#include <set>
+#include <string>
+
+#include "base/base64.h"
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/lazy_instance.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/pickle.h"
+#include "base/threading/non_thread_safe.h"
+#include "crypto/encryptor.h"
+#include "crypto/symmetric_key.h"
+#include "net/base/completion_callback.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"
+
+namespace net {
+
+namespace {
+
+// A DER encoded SubjectPublicKeyInfo structure containing the server's public
+// key.
+const uint8 kServerPublicKey[] = {
+ 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
+ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00,
+ 0x04, 0xc7, 0xea, 0x88, 0x60, 0x52, 0xe3, 0xa3, 0x3e, 0x39, 0x92, 0x0f, 0xa4,
+ 0x3d, 0xba, 0xd8, 0x02, 0x2d, 0x06, 0x4d, 0x64, 0x98, 0x66, 0xb4, 0x82, 0xf0,
+ 0x23, 0xa6, 0xd8, 0x37, 0x55, 0x7c, 0x01, 0xbf, 0x18, 0xd8, 0x16, 0x9e, 0x66,
+ 0xdc, 0x49, 0xbf, 0x2e, 0x86, 0xe3, 0x99, 0xbd, 0xb3, 0x75, 0x25, 0x61, 0x04,
+ 0x6c, 0x2e, 0xfb, 0x32, 0x42, 0x27, 0xe4, 0x23, 0xea, 0xcd, 0x81, 0x62, 0xc1,
+};
+
+const unsigned kMaxUploadsPerSession = 10;
+
+// DnsCertLimits is a singleton class which keeps track of which hosts we have
+// uploaded reports for in this session. Since some users will be behind MITM
+// proxies, they would otherwise upload for every host and we don't wish to
+// spam the upload server.
+class DnsCertLimits {
+ public:
+ DnsCertLimits() { }
+
+ // HaveReachedMaxUploads returns true iff we have uploaded the maximum number
+ // of DNS certificate reports for this session.
+ bool HaveReachedMaxUploads() {
+ return uploaded_hostnames_.size() >= kMaxUploadsPerSession;
+ }
+
+ // HaveReachedMaxUploads returns true iff we have already uploaded a report
+ // about the given hostname in this session.
+ bool HaveUploadedForHostname(const std::string& hostname) {
+ return uploaded_hostnames_.count(hostname) > 0;
+ }
+
+ void DidUpload(const std::string& hostname) {
+ uploaded_hostnames_.insert(hostname);
+ }
+
+ private:
+ friend struct base::DefaultLazyInstanceTraits<DnsCertLimits>;
+
+ std::set<std::string> uploaded_hostnames_;
+
+ DISALLOW_COPY_AND_ASSIGN(DnsCertLimits);
+};
+
+static base::LazyInstance<DnsCertLimits> g_dns_cert_limits =
+ LAZY_INSTANCE_INITIALIZER;
+
+// DnsCertProvenanceCheck performs the DNS lookup of the certificate. This
+// class is self-deleting.
+class DnsCertProvenanceCheck : public base::NonThreadSafe {
+ public:
+ DnsCertProvenanceCheck(
+ const std::string& hostname,
+ DnsRRResolver* dnsrr_resolver,
+ DnsCertProvenanceChecker::Delegate* delegate,
+ const std::vector<base::StringPiece>& der_certs)
+ : hostname_(hostname),
+ dnsrr_resolver_(dnsrr_resolver),
+ delegate_(delegate),
+ der_certs_(der_certs.size()),
+ handle_(DnsRRResolver::kInvalidHandle) {
+ for (size_t i = 0; i < der_certs.size(); i++)
+ der_certs_[i] = der_certs[i].as_string();
+ }
+
+ void Start() {
+ DCHECK(CalledOnValidThread());
+
+ if (der_certs_.empty())
+ return;
+
+ DnsCertLimits* const limits = g_dns_cert_limits.Pointer();
+ if (limits->HaveReachedMaxUploads() ||
+ limits->HaveUploadedForHostname(hostname_)) {
+ return;
+ }
+
+ uint8 fingerprint[SHA1_LENGTH];
+ SECStatus rv = HASH_HashBuf(
+ HASH_AlgSHA1, fingerprint, (uint8*) der_certs_[0].data(),
+ der_certs_[0].size());
+ DCHECK_EQ(SECSuccess, rv);
+ char fingerprint_hex[SHA1_LENGTH * 2 + 1];
+ for (unsigned i = 0; i < sizeof(fingerprint); i++) {
+ static const char hextable[] = "0123456789abcdef";
+ fingerprint_hex[i*2] = hextable[fingerprint[i] >> 4];
+ fingerprint_hex[i*2 + 1] = hextable[fingerprint[i] & 15];
+ }
+ fingerprint_hex[SHA1_LENGTH * 2] = 0;
+
+ static const char kBaseCertName[] = ".certs.googlednstest.com";
+ domain_.assign(fingerprint_hex);
+ domain_.append(kBaseCertName);
+
+ handle_ = dnsrr_resolver_->Resolve(
+ domain_, kDNS_TXT, 0 /* flags */,
+ base::Bind(&DnsCertProvenanceCheck::ResolutionComplete,
+ base::Unretained(this)),
+ &response_, 0 /* priority */, BoundNetLog());
+ if (handle_ == DnsRRResolver::kInvalidHandle) {
+ LOG(ERROR) << "Failed to resolve " << domain_ << " for " << hostname_;
+ delete this;
+ }
+ }
+
+ private:
+ void ResolutionComplete(int status) {
+ DCHECK(CalledOnValidThread());
+
+ if (status == ERR_NAME_NOT_RESOLVED ||
+ (status == OK && response_.rrdatas.empty())) {
+ LOG(ERROR) << "FAILED"
+ << " hostname:" << hostname_
+ << " domain:" << domain_;
+ g_dns_cert_limits.Get().DidUpload(hostname_);
+ LogCertificates(der_certs_);
+ delegate_->OnDnsCertLookupFailed(hostname_, der_certs_);
+ } else if (status == OK) {
+ LOG(ERROR) << "GOOD"
+ << " hostname:" << hostname_
+ << " resp:" << response_.rrdatas[0];
+ } else {
+ LOG(ERROR) << "Unknown error " << status << " for " << domain_;
+ }
+
+ delete this;
+ }
+
+ // LogCertificates writes a certificate chain, in PEM format, to LOG(ERROR).
+ static void LogCertificates(
+ const std::vector<std::string>& der_certs) {
+ std::string dump;
+ bool first = true;
+
+ for (std::vector<std::string>::const_iterator
+ i = der_certs.begin(); i != der_certs.end(); i++) {
+ if (!first)
+ dump += "\n";
+ first = false;
+
+ dump += "-----BEGIN CERTIFICATE-----\n";
+ std::string b64_encoded;
+ base::Base64Encode(*i, &b64_encoded);
+ for (size_t i = 0; i < b64_encoded.size();) {
+ size_t todo = b64_encoded.size() - i;
+ if (todo > 64)
+ todo = 64;
+ dump += b64_encoded.substr(i, todo);
+ dump += "\n";
+ i += todo;
+ }
+ dump += "-----END CERTIFICATE-----";
+ }
+
+ LOG(ERROR) << "Offending certificates:\n" << dump;
+ }
+
+ const std::string hostname_;
+ std::string domain_;
+ DnsRRResolver* dnsrr_resolver_;
+ DnsCertProvenanceChecker::Delegate* const delegate_;
+ std::vector<std::string> der_certs_;
+ RRResponse response_;
+ DnsRRResolver::Handle handle_;
+};
+
+SECKEYPublicKey* GetServerPubKey() {
+ SECItem der;
+ memset(&der, 0, sizeof(der));
+ der.data = const_cast<uint8*>(kServerPublicKey);
+ der.len = sizeof(kServerPublicKey);
+
+ CERTSubjectPublicKeyInfo* spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
+ SECKEYPublicKey* public_key = SECKEY_ExtractPublicKey(spki);
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+
+ return public_key;
+}
+
+} // namespace
+
+DnsCertProvenanceChecker::Delegate::~Delegate() {
+}
+
+DnsCertProvenanceChecker::~DnsCertProvenanceChecker() {
+}
+
+void DnsCertProvenanceChecker::DoAsyncLookup(
+ const std::string& hostname,
+ const std::vector<base::StringPiece>& der_certs,
+ DnsRRResolver* dnsrr_resolver,
+ Delegate* delegate) {
+ DnsCertProvenanceCheck* check = new DnsCertProvenanceCheck(
+ hostname, dnsrr_resolver, delegate, der_certs);
+ check->Start();
+}
+
+// static
+std::string DnsCertProvenanceChecker::BuildEncryptedReport(
+ const std::string& hostname,
+ const std::vector<std::string>& der_certs) {
+ static const int kVersion = 0;
+ static const unsigned kKeySizeInBytes = 16; // AES-128
+ static const unsigned kIVSizeInBytes = 16; // AES's block size
+ static const unsigned kPadSize = 4096; // we pad up to 4KB,
+ // This is a DER encoded, ANSI X9.62 CurveParams object which simply
+ // specifies P256.
+ static const uint8 kANSIX962CurveParams[] = {
+ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
+ };
+
+ Pickle p;
+ p.WriteString(hostname);
+ p.WriteInt(der_certs.size());
+ for (std::vector<std::string>::const_iterator
+ i = der_certs.begin(); i != der_certs.end(); i++) {
+ p.WriteString(*i);
+ }
+ // We pad to eliminate the possibility that someone could see the size of
+ // an upload and use that information to reduce the anonymity set of the
+ // certificate chain.
+ // The "2*sizeof(uint32)" here covers the padding length which we add next
+ // and Pickle's internal length which it includes at the beginning of the
+ // data.
+ unsigned pad_bytes = kPadSize - ((p.size() + 2*sizeof(uint32)) % kPadSize);
+ p.WriteUInt32(pad_bytes);
+ char* padding = new char[pad_bytes];
+ memset(padding, 0, pad_bytes);
+ p.WriteData(padding, pad_bytes);
+ delete[] padding;
+
+ // We generate a random public value and perform a DH key agreement with
+ // the server's fixed value.
+ SECKEYPublicKey* pub_key = NULL;
+ SECKEYPrivateKey* priv_key = NULL;
+ SECItem ec_der_params;
+ memset(&ec_der_params, 0, sizeof(ec_der_params));
+ ec_der_params.data = const_cast<uint8*>(kANSIX962CurveParams);
+ ec_der_params.len = sizeof(kANSIX962CurveParams);
+ priv_key = SECKEY_CreateECPrivateKey(&ec_der_params, &pub_key, NULL);
+ SECKEYPublicKey* server_pub_key = GetServerPubKey();
+
+ // This extracts the big-endian, x value of the shared point.
+ // The values of the arguments match ssl3_SendECDHClientKeyExchange in NSS
+ // 3.12.8's lib/ssl/ssl3ecc.c
+ PK11SymKey* pms = PK11_PubDeriveWithKDF(
+ priv_key, server_pub_key, PR_FALSE /* is sender */,
+ NULL /* random a */, NULL /* random b */, CKM_ECDH1_DERIVE,
+ CKM_TLS_MASTER_KEY_DERIVE_DH, CKA_DERIVE, 0 /* key size */,
+ CKD_NULL /* KDF */, NULL /* shared data */, NULL /* wincx */);
+ SECKEY_DestroyPublicKey(server_pub_key);
+ SECStatus rv = PK11_ExtractKeyValue(pms);
+ DCHECK_EQ(SECSuccess, rv);
+ SECItem* x_data = PK11_GetKeyData(pms);
+
+ // The key and IV are 128-bits and generated from a SHA256 hash of the x
+ // value.
+ char key_data[SHA256_LENGTH];
+ HASH_HashBuf(HASH_AlgSHA256, reinterpret_cast<uint8*>(key_data),
+ x_data->data, x_data->len);
+ PK11_FreeSymKey(pms);
+
+ DCHECK_GE(sizeof(key_data), kKeySizeInBytes + kIVSizeInBytes);
+ std::string raw_key(key_data, kKeySizeInBytes);
+
+ scoped_ptr<crypto::SymmetricKey> symkey(
+ crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, raw_key));
+ std::string iv(key_data + kKeySizeInBytes, kIVSizeInBytes);
+
+ crypto::Encryptor encryptor;
+ bool r = encryptor.Init(symkey.get(), crypto::Encryptor::CBC, iv);
+ CHECK(r);
+
+ std::string plaintext(reinterpret_cast<const char*>(p.data()), p.size());
+ std::string ciphertext;
+ encryptor.Encrypt(plaintext, &ciphertext);
+
+ // We use another Pickle object to serialise the 'outer' wrapping of the
+ // plaintext.
+ Pickle outer;
+ outer.WriteInt(kVersion);
+
+ SECItem* pub_key_serialized = SECKEY_EncodeDERSubjectPublicKeyInfo(pub_key);
+ outer.WriteString(
+ std::string(reinterpret_cast<char*>(pub_key_serialized->data),
+ pub_key_serialized->len));
+ SECITEM_FreeItem(pub_key_serialized, PR_TRUE);
+
+ outer.WriteString(ciphertext);
+
+ SECKEY_DestroyPublicKey(pub_key);
+ SECKEY_DestroyPrivateKey(priv_key);
+
+ return std::string(reinterpret_cast<const char*>(outer.data()),
+ outer.size());
+}
+
+} // namespace net
+
+#else // USE_OPENSSL
+
+namespace net {
+
+DnsCertProvenanceChecker::Delegate::~Delegate() {
+}
+
+DnsCertProvenanceChecker::~DnsCertProvenanceChecker() {
+}
+
+void DnsCertProvenanceChecker::DoAsyncLookup(
+ const std::string& hostname,
+ const std::vector<base::StringPiece>& der_certs,
+ DnsRRResolver* dnsrr_resolver,
+ Delegate* delegate) {
+}
+
+std::string DnsCertProvenanceChecker::BuildEncryptedReport(
+ const std::string& hostname,
+ const std::vector<std::string>& der_certs) {
+ return "";
+}
+
+} // namespace net
+
+#endif // USE_OPENSSL
diff --git a/net/socket/dns_cert_provenance_checker.h b/net/socket/dns_cert_provenance_checker.h
new file mode 100644
index 0000000..e6a41ae
--- /dev/null
+++ b/net/socket/dns_cert_provenance_checker.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SOCKET_DNS_CERT_PROVENANCE_CHECKER_H
+#define NET_SOCKET_DNS_CERT_PROVENANCE_CHECKER_H
+
+#include <string>
+#include <vector>
+
+#include "base/string_piece.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+class DnsRRResolver;
+
+// DnsCertProvenanceChecker is an interface for asynchronously checking HTTPS
+// certificates via a DNS side-channel.
+class NET_EXPORT DnsCertProvenanceChecker {
+ public:
+ class NET_EXPORT Delegate {
+ public:
+ virtual ~Delegate();
+
+ virtual void OnDnsCertLookupFailed(
+ const std::string& hostname,
+ const std::vector<std::string>& der_certs) = 0;
+ };
+
+ virtual ~DnsCertProvenanceChecker();
+
+ virtual void Shutdown() = 0;
+
+ // DoAsyncVerification starts an asynchronous check for the given certificate
+ // chain. It must be run on the network thread.
+ virtual void DoAsyncVerification(
+ const std::string& hostname,
+ const std::vector<base::StringPiece>& der_certs) = 0;
+
+
+ protected:
+ // DoAsyncLookup performs a DNS lookup for the given name and certificate
+ // chain. In the event that the lookup reports a failure, the Delegate is
+ // called back.
+ static void DoAsyncLookup(
+ const std::string& hostname,
+ const std::vector<base::StringPiece>& der_certs,
+ DnsRRResolver* dnsrr_resolver,
+ Delegate* delegate);
+
+ // BuildEncryptedRecord encrypts the certificate chain to a fixed public key
+ // and returns the encrypted blob. Since this code is reporting a possible
+ // HTTPS failure, it would seem silly to use HTTPS to protect the uploaded
+ // report.
+ static std::string BuildEncryptedReport(
+ const std::string& hostname,
+ const std::vector<std::string>& der_certs);
+};
+
+} // namespace net
+
+#endif // NET_SOCKET_DNS_CERT_PROVENANCE_CHECK_H
diff --git a/net/socket/ssl_client_socket.h b/net/socket/ssl_client_socket.h
index e040e38..64ccd78 100644
--- a/net/socket/ssl_client_socket.h
+++ b/net/socket/ssl_client_socket.h
@@ -17,6 +17,7 @@
namespace net {
class CertVerifier;
+class DnsCertProvenanceChecker;
class OriginBoundCertService;
class SSLCertRequestInfo;
class SSLHostInfo;
@@ -31,22 +32,26 @@ struct SSLClientSocketContext {
: cert_verifier(NULL),
origin_bound_cert_service(NULL),
transport_security_state(NULL),
+ dns_cert_checker(NULL),
ssl_host_info_factory(NULL) {}
SSLClientSocketContext(CertVerifier* cert_verifier_arg,
OriginBoundCertService* origin_bound_cert_service_arg,
TransportSecurityState* transport_security_state_arg,
+ DnsCertProvenanceChecker* dns_cert_checker_arg,
SSLHostInfoFactory* ssl_host_info_factory_arg,
const std::string& ssl_session_cache_shard_arg)
: cert_verifier(cert_verifier_arg),
origin_bound_cert_service(origin_bound_cert_service_arg),
transport_security_state(transport_security_state_arg),
+ dns_cert_checker(dns_cert_checker_arg),
ssl_host_info_factory(ssl_host_info_factory_arg),
ssl_session_cache_shard(ssl_session_cache_shard_arg) {}
CertVerifier* cert_verifier;
OriginBoundCertService* origin_bound_cert_service;
TransportSecurityState* transport_security_state;
+ DnsCertProvenanceChecker* dns_cert_checker;
SSLHostInfoFactory* ssl_host_info_factory;
// ssl_session_cache_shard is an opaque string that identifies a shard of the
// SSL session cache. SSL sockets with the same ssl_session_cache_shard may
diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h
index 08f8974..784b92d 100644
--- a/net/socket/ssl_client_socket_nss.h
+++ b/net/socket/ssl_client_socket_nss.h
@@ -283,6 +283,9 @@ class SSLClientSocketNSS : public SSLClientSocket {
// that we found the prediction to be correct.
bool predicted_cert_chain_correct_;
+ // The time when we started waiting for DNSSEC records.
+ base::Time dnssec_wait_start_time_;
+
State next_handshake_state_;
// The NSS SSL state machine
diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc
index 6275b52..fb91d07 100644
--- a/net/socket/ssl_client_socket_pool.cc
+++ b/net/socket/ssl_client_socket_pool.cc
@@ -449,6 +449,7 @@ SSLClientSocketPool::SSLClientSocketPool(
CertVerifier* cert_verifier,
OriginBoundCertService* origin_bound_cert_service,
TransportSecurityState* transport_security_state,
+ DnsCertProvenanceChecker* dns_cert_checker,
SSLHostInfoFactory* ssl_host_info_factory,
const std::string& ssl_session_cache_shard,
ClientSocketFactory* client_socket_factory,
@@ -472,6 +473,7 @@ SSLClientSocketPool::SSLClientSocketPool(
cert_verifier,
origin_bound_cert_service,
transport_security_state,
+ dns_cert_checker,
ssl_host_info_factory,
ssl_session_cache_shard),
net_log)),
diff --git a/net/socket/ssl_client_socket_pool.h b/net/socket/ssl_client_socket_pool.h
index 1be34bd..907c6e5 100644
--- a/net/socket/ssl_client_socket_pool.h
+++ b/net/socket/ssl_client_socket_pool.h
@@ -25,6 +25,7 @@ namespace net {
class CertVerifier;
class ClientSocketFactory;
class ConnectJobFactory;
+class DnsCertProvenanceChecker;
class HostPortPair;
class HttpProxyClientSocketPool;
class HttpProxySocketParams;
@@ -179,6 +180,7 @@ class NET_EXPORT_PRIVATE SSLClientSocketPool
CertVerifier* cert_verifier,
OriginBoundCertService* origin_bound_cert_service,
TransportSecurityState* transport_security_state,
+ DnsCertProvenanceChecker* dns_cert_checker,
SSLHostInfoFactory* ssl_host_info_factory,
const std::string& ssl_session_cache_shard,
ClientSocketFactory* client_socket_factory,
diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc
index 71cd91c..673fa22 100644
--- a/net/socket/ssl_client_socket_pool_unittest.cc
+++ b/net/socket/ssl_client_socket_pool_unittest.cc
@@ -95,7 +95,8 @@ class SSLClientSocketPoolTest : public testing::Test {
NULL /* host_resolver */,
NULL /* cert_verifier */,
NULL /* origin_bound_cert_service */,
- NULL /* transport_security_state */,
+ NULL /* dnsrr_resolver */,
+ NULL /* dns_cert_checker */,
NULL /* ssl_host_info_factory */,
"" /* ssl_session_cache_shard */,
&socket_factory_,
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc
index 13a1b0d..142068e 100644
--- a/net/url_request/url_request_context.cc
+++ b/net/url_request/url_request_context.cc
@@ -19,6 +19,7 @@ URLRequestContext::URLRequestContext()
host_resolver_(NULL),
cert_verifier_(NULL),
origin_bound_cert_service_(NULL),
+ dns_cert_checker_(NULL),
fraudulent_certificate_reporter_(NULL),
http_auth_handler_factory_(NULL),
proxy_service_(NULL),
@@ -37,6 +38,7 @@ void URLRequestContext::CopyFrom(URLRequestContext* other) {
set_host_resolver(other->host_resolver());
set_cert_verifier(other->cert_verifier());
set_origin_bound_cert_service(other->origin_bound_cert_service());
+ set_dns_cert_checker(other->dns_cert_checker());
set_fraudulent_certificate_reporter(other->fraudulent_certificate_reporter());
set_http_auth_handler_factory(other->http_auth_handler_factory());
set_proxy_service(other->proxy_service());
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h
index 7d9d2e6..b3ccd3b 100644
--- a/net/url_request/url_request_context.h
+++ b/net/url_request/url_request_context.h
@@ -25,6 +25,7 @@
namespace net {
class CertVerifier;
class CookieStore;
+class DnsCertProvenanceChecker;
class FraudulentCertificateReporter;
class FtpTransactionFactory;
class HostResolver;
@@ -86,6 +87,13 @@ class NET_EXPORT URLRequestContext
origin_bound_cert_service_ = origin_bound_cert_service;
}
+ DnsCertProvenanceChecker* dns_cert_checker() const {
+ return dns_cert_checker_;
+ }
+ void set_dns_cert_checker(DnsCertProvenanceChecker* dns_cert_checker) {
+ dns_cert_checker_ = dns_cert_checker;
+ }
+
FraudulentCertificateReporter* fraudulent_certificate_reporter() const {
return fraudulent_certificate_reporter_;
}
@@ -208,6 +216,7 @@ class NET_EXPORT URLRequestContext
HostResolver* host_resolver_;
CertVerifier* cert_verifier_;
OriginBoundCertService* origin_bound_cert_service_;
+ DnsCertProvenanceChecker* dns_cert_checker_;
FraudulentCertificateReporter* fraudulent_certificate_reporter_;
HttpAuthHandlerFactory* http_auth_handler_factory_;
ProxyService* proxy_service_;
diff --git a/net/url_request/url_request_context_storage.cc b/net/url_request/url_request_context_storage.cc
index cb29c1b..4f0a2b0 100644
--- a/net/url_request/url_request_context_storage.cc
+++ b/net/url_request/url_request_context_storage.cc
@@ -16,6 +16,7 @@
#include "net/http/http_server_properties.h"
#include "net/http/http_transaction_factory.h"
#include "net/proxy/proxy_service.h"
+#include "net/socket/dns_cert_provenance_checker.h"
#include "net/url_request/fraudulent_certificate_reporter.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_job_factory.h"
@@ -50,6 +51,12 @@ void URLRequestContextStorage::set_origin_bound_cert_service(
origin_bound_cert_service_.reset(origin_bound_cert_service);
}
+void URLRequestContextStorage::set_dns_cert_checker(
+ DnsCertProvenanceChecker* dns_cert_checker) {
+ context_->set_dns_cert_checker(dns_cert_checker);
+ dns_cert_checker_.reset(dns_cert_checker);
+}
+
void URLRequestContextStorage::set_fraudulent_certificate_reporter(
FraudulentCertificateReporter* fraudulent_certificate_reporter) {
context_->set_fraudulent_certificate_reporter(
diff --git a/net/url_request/url_request_context_storage.h b/net/url_request/url_request_context_storage.h
index 8ae2a00..4a2df3d 100644
--- a/net/url_request/url_request_context_storage.h
+++ b/net/url_request/url_request_context_storage.h
@@ -15,6 +15,7 @@ namespace net {
class CertVerifier;
class CookieStore;
+class DnsCertProvenanceChecker;
class FraudulentCertificateReporter;
class FtpTransactionFactory;
class HostResolver;
@@ -48,6 +49,7 @@ class NET_EXPORT URLRequestContextStorage {
void set_cert_verifier(CertVerifier* cert_verifier);
void set_origin_bound_cert_service(
OriginBoundCertService* origin_bound_cert_service);
+ void set_dns_cert_checker(DnsCertProvenanceChecker* dns_cert_checker);
void set_fraudulent_certificate_reporter(
FraudulentCertificateReporter* fraudulent_certificate_reporter);
void set_http_auth_handler_factory(
@@ -76,6 +78,7 @@ class NET_EXPORT URLRequestContextStorage {
scoped_ptr<HostResolver> host_resolver_;
scoped_ptr<CertVerifier> cert_verifier_;
scoped_ptr<OriginBoundCertService> origin_bound_cert_service_;
+ scoped_ptr<DnsCertProvenanceChecker> dns_cert_checker_;
scoped_ptr<FraudulentCertificateReporter> fraudulent_certificate_reporter_;
scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
scoped_ptr<ProxyService> proxy_service_;
diff --git a/webkit/tools/test_shell/test_shell_request_context.cc b/webkit/tools/test_shell/test_shell_request_context.cc
index e8fea2a..c1c3e2c 100644
--- a/webkit/tools/test_shell/test_shell_request_context.cc
+++ b/webkit/tools/test_shell/test_shell_request_context.cc
@@ -93,17 +93,13 @@ void TestShellRequestContext::Init(
cache_path, 0, SimpleResourceLoaderBridge::GetCacheThread());
net::HttpCache* cache =
- new net::HttpCache(host_resolver(),
- cert_verifier(),
- origin_bound_cert_service(),
- NULL, // transport_security_state
+ new net::HttpCache(host_resolver(), cert_verifier(),
+ origin_bound_cert_service(), NULL, NULL,
proxy_service(),
- "", // ssl_session_cache_shard
+ "" /* ssl_session_cache_shard */,
ssl_config_service(),
- http_auth_handler_factory(),
- NULL, // network_delegate
- http_server_properties(),
- NULL, // netlog
+ http_auth_handler_factory(), NULL,
+ http_server_properties(), NULL,
backend);
cache->set_mode(cache_mode);