• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/net/chrome_dns_cert_provenance_checker.h"
6 
7 #include "base/memory/scoped_ptr.h"
8 #include "base/stl_util-inl.h"
9 #include "chrome/browser/net/chrome_url_request_context.h"
10 #include "net/url_request/url_request.h"
11 
12 namespace {
13 
14 class ChromeDnsCertProvenanceChecker :
15     public net::DnsCertProvenanceChecker,
16     public net::DnsCertProvenanceChecker::Delegate {
17  public:
ChromeDnsCertProvenanceChecker(net::DnsRRResolver * dnsrr_resolver,ChromeURLRequestContext * url_req_context)18   ChromeDnsCertProvenanceChecker(
19       net::DnsRRResolver* dnsrr_resolver,
20       ChromeURLRequestContext* url_req_context)
21       : dnsrr_resolver_(dnsrr_resolver),
22         url_req_context_(url_req_context),
23         upload_url_("http://chromecertcheck.appspot.com/upload"),
24         delegate_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
25   }
26 
~ChromeDnsCertProvenanceChecker()27   ~ChromeDnsCertProvenanceChecker() {
28     DCHECK(inflight_requests_.empty());
29   }
30 
31   // DnsCertProvenanceChecker interface
DoAsyncVerification(const std::string & hostname,const std::vector<base::StringPiece> & der_certs)32   virtual void DoAsyncVerification(
33       const std::string& hostname,
34       const std::vector<base::StringPiece>& der_certs) {
35     net::DnsCertProvenanceChecker::DoAsyncLookup(hostname, der_certs,
36                                                  dnsrr_resolver_, this);
37   }
38 
Shutdown()39   virtual void Shutdown() {
40     STLDeleteContainerPointers(inflight_requests_.begin(),
41                                inflight_requests_.end());
42     inflight_requests_.clear();
43   }
44 
45   // DnsCertProvenanceChecker::Delegate interface
OnDnsCertLookupFailed(const std::string & hostname,const std::vector<std::string> & der_certs)46   virtual void OnDnsCertLookupFailed(
47       const std::string& hostname,
48       const std::vector<std::string>& der_certs) {
49     const std::string report = BuildEncryptedReport(hostname, der_certs);
50 
51     net::URLRequest* url_request(new net::URLRequest(upload_url_, &delegate_));
52     url_request->set_context(url_req_context_);
53     url_request->set_method("POST");
54     url_request->AppendBytesToUpload(report.data(), report.size());
55     net::HttpRequestHeaders headers;
56     headers.SetHeader(net::HttpRequestHeaders::kContentType,
57                       "x-application/chrome-cert-provenance-report");
58     url_request->SetExtraRequestHeaders(headers);
59     inflight_requests_.insert(url_request);
60     url_request->Start();
61   }
62 
63  private:
RequestComplete(net::URLRequest * request)64   void RequestComplete(net::URLRequest* request) {
65     std::set<net::URLRequest*>::iterator i = inflight_requests_.find(request);
66     DCHECK(i != inflight_requests_.end());
67     delete *i;
68     inflight_requests_.erase(i);
69   }
70 
71   // URLRequestDelegate is the delegate for the upload. Since this is a
72   // fire-and-forget operation, we don't care if there are any errors in the
73   // upload.
74   class URLRequestDelegate : public net::URLRequest::Delegate {
75    public:
URLRequestDelegate(ChromeDnsCertProvenanceChecker * checker)76     explicit URLRequestDelegate(ChromeDnsCertProvenanceChecker* checker)
77         : checker_(checker) {
78     }
79 
80     // Delegate implementation
OnResponseStarted(net::URLRequest * request)81     void OnResponseStarted(net::URLRequest* request) {
82       const net::URLRequestStatus& status(request->status());
83       if (!status.is_success()) {
84         LOG(WARNING) << "Certificate upload failed"
85                      << " status:" << status.status()
86                      << " os_error:" << status.os_error();
87       } else if (request->GetResponseCode() != 200) {
88         LOG(WARNING) << "Certificate upload HTTP status: "
89                      << request->GetResponseCode();
90       }
91       checker_->RequestComplete(request);
92     }
93 
OnReadCompleted(net::URLRequest * request,int bytes_read)94     void OnReadCompleted(net::URLRequest* request, int bytes_read) {
95       NOTREACHED();
96     }
97 
98    private:
99     ChromeDnsCertProvenanceChecker* const checker_;
100   };
101 
102   net::DnsRRResolver* const dnsrr_resolver_;
103   ChromeURLRequestContext* const url_req_context_;
104   const GURL upload_url_;
105   URLRequestDelegate delegate_;
106   std::set<net::URLRequest*> inflight_requests_;
107 };
108 
109 }  // namespace
110 
CreateChromeDnsCertProvenanceChecker(net::DnsRRResolver * dnsrr_resolver,ChromeURLRequestContext * url_req_context)111 net::DnsCertProvenanceChecker* CreateChromeDnsCertProvenanceChecker(
112     net::DnsRRResolver* dnsrr_resolver,
113     ChromeURLRequestContext* url_req_context) {
114   return new ChromeDnsCertProvenanceChecker(dnsrr_resolver, url_req_context);
115 }
116