OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/net/certificate_error_reporter.h" | 5 #include "chrome/browser/net/certificate_error_reporter.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "chrome/browser/net/encrypted_cert_logger.pb.h" | 10 #include "chrome/browser/net/encrypted_cert_logger.pb.h" |
11 | 11 |
12 #if defined(USE_OPENSSL) | 12 #if defined(USE_OPENSSL) |
13 #include "crypto/aead_openssl.h" | 13 #include "crypto/aead_openssl.h" |
14 #endif | 14 #endif |
15 | 15 |
16 #include "crypto/curve25519.h" | 16 #include "crypto/curve25519.h" |
17 #include "crypto/hkdf.h" | 17 #include "crypto/hkdf.h" |
18 #include "crypto/random.h" | 18 #include "crypto/random.h" |
19 #include "net/base/elements_upload_data_stream.h" | 19 #include "net/http/certificate_report_sender.h" |
20 #include "net/base/load_flags.h" | 20 #include "net/http/certificate_report_sender_impl.h" |
21 #include "net/base/request_priority.h" | |
22 #include "net/base/upload_bytes_element_reader.h" | |
23 #include "net/url_request/url_request_context.h" | 21 #include "net/url_request/url_request_context.h" |
24 | 22 |
25 namespace { | 23 namespace { |
26 | 24 |
27 // Constants used for crypto | 25 // Constants used for crypto |
28 static const uint8 kServerPublicKey[] = { | 26 static const uint8 kServerPublicKey[] = { |
29 0x51, 0xcc, 0x52, 0x67, 0x42, 0x47, 0x3b, 0x10, 0xe8, 0x63, 0x18, | 27 0x51, 0xcc, 0x52, 0x67, 0x42, 0x47, 0x3b, 0x10, 0xe8, 0x63, 0x18, |
30 0x3c, 0x61, 0xa7, 0x96, 0x76, 0x86, 0x91, 0x40, 0x71, 0x39, 0x5f, | 28 0x3c, 0x61, 0xa7, 0x96, 0x76, 0x86, 0x91, 0x40, 0x71, 0x39, 0x5f, |
31 0x31, 0x1a, 0x39, 0x5b, 0x76, 0xb1, 0x6b, 0x3d, 0x6a, 0x2b}; | 29 0x31, 0x1a, 0x39, 0x5b, 0x76, 0xb1, 0x6b, 0x3d, 0x6a, 0x2b}; |
32 static const uint32 kServerPublicKeyVersion = 1; | 30 static const uint32 kServerPublicKeyVersion = 1; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 } | 78 } |
81 #endif | 79 #endif |
82 | 80 |
83 } // namespace | 81 } // namespace |
84 | 82 |
85 namespace chrome_browser_net { | 83 namespace chrome_browser_net { |
86 | 84 |
87 CertificateErrorReporter::CertificateErrorReporter( | 85 CertificateErrorReporter::CertificateErrorReporter( |
88 net::URLRequestContext* request_context, | 86 net::URLRequestContext* request_context, |
89 const GURL& upload_url, | 87 const GURL& upload_url, |
90 CookiesPreference cookies_preference) | 88 net::CertificateReportSender::CookiesPreference cookies_preference) |
91 : CertificateErrorReporter(request_context, | 89 : CertificateErrorReporter( |
92 upload_url, | 90 upload_url, |
93 cookies_preference, | 91 kServerPublicKey, |
94 kServerPublicKey, | 92 kServerPublicKeyVersion, |
95 kServerPublicKeyVersion) { | 93 scoped_ptr<net::CertificateReportSender>( |
| 94 new net::CertificateReportSenderImpl(request_context, |
| 95 cookies_preference))) { |
96 } | 96 } |
97 | 97 |
98 CertificateErrorReporter::CertificateErrorReporter( | 98 CertificateErrorReporter::CertificateErrorReporter( |
99 net::URLRequestContext* request_context, | |
100 const GURL& upload_url, | 99 const GURL& upload_url, |
101 CookiesPreference cookies_preference, | |
102 const uint8 server_public_key[32], | 100 const uint8 server_public_key[32], |
103 const uint32 server_public_key_version) | 101 const uint32 server_public_key_version, |
104 : request_context_(request_context), | 102 scoped_ptr<net::CertificateReportSender> certificate_report_sender) |
| 103 : certificate_report_sender_(certificate_report_sender.Pass()), |
105 upload_url_(upload_url), | 104 upload_url_(upload_url), |
106 cookies_preference_(cookies_preference), | |
107 server_public_key_(server_public_key), | 105 server_public_key_(server_public_key), |
108 server_public_key_version_(server_public_key_version) { | 106 server_public_key_version_(server_public_key_version) { |
| 107 DCHECK(certificate_report_sender_); |
109 DCHECK(!upload_url.is_empty()); | 108 DCHECK(!upload_url.is_empty()); |
110 } | 109 } |
111 | 110 |
112 CertificateErrorReporter::~CertificateErrorReporter() { | 111 CertificateErrorReporter::~CertificateErrorReporter() { |
113 STLDeleteElements(&inflight_requests_); | |
114 } | 112 } |
115 | 113 |
116 void CertificateErrorReporter::SendReport( | 114 void CertificateErrorReporter::SendReport( |
117 ReportType type, | 115 ReportType type, |
118 const std::string& serialized_report) { | 116 const std::string& serialized_report) { |
119 switch (type) { | 117 switch (type) { |
120 case REPORT_TYPE_PINNING_VIOLATION: | 118 case REPORT_TYPE_PINNING_VIOLATION: |
121 SendSerializedRequest(serialized_report); | 119 certificate_report_sender_->Send(upload_url_, serialized_report); |
122 break; | 120 break; |
123 case REPORT_TYPE_EXTENDED_REPORTING: | 121 case REPORT_TYPE_EXTENDED_REPORTING: |
124 if (upload_url_.SchemeIsCryptographic()) { | 122 if (upload_url_.SchemeIsCryptographic()) { |
125 SendSerializedRequest(serialized_report); | 123 certificate_report_sender_->Send(upload_url_, serialized_report); |
126 } else { | 124 } else { |
127 DCHECK(IsHttpUploadUrlSupported()); | 125 DCHECK(IsHttpUploadUrlSupported()); |
128 #if defined(USE_OPENSSL) | 126 #if defined(USE_OPENSSL) |
129 EncryptedCertLoggerRequest encrypted_report; | 127 EncryptedCertLoggerRequest encrypted_report; |
130 if (!EncryptSerializedReport(server_public_key_, | 128 if (!EncryptSerializedReport(server_public_key_, |
131 server_public_key_version_, | 129 server_public_key_version_, |
132 serialized_report, &encrypted_report)) { | 130 serialized_report, &encrypted_report)) { |
133 LOG(ERROR) << "Failed to encrypt serialized report."; | 131 LOG(ERROR) << "Failed to encrypt serialized report."; |
134 return; | 132 return; |
135 } | 133 } |
136 std::string serialized_encrypted_report; | 134 std::string serialized_encrypted_report; |
137 encrypted_report.SerializeToString(&serialized_encrypted_report); | 135 encrypted_report.SerializeToString(&serialized_encrypted_report); |
138 SendSerializedRequest(serialized_encrypted_report); | 136 certificate_report_sender_->Send(upload_url_, |
| 137 serialized_encrypted_report); |
139 #endif | 138 #endif |
140 } | 139 } |
141 break; | 140 break; |
142 default: | 141 default: |
143 NOTREACHED(); | 142 NOTREACHED(); |
144 } | 143 } |
145 } | 144 } |
146 | 145 |
147 void CertificateErrorReporter::OnResponseStarted(net::URLRequest* request) { | |
148 const net::URLRequestStatus& status(request->status()); | |
149 if (!status.is_success()) { | |
150 LOG(WARNING) << "Certificate upload failed" | |
151 << " status:" << status.status() | |
152 << " error:" << status.error(); | |
153 } else if (request->GetResponseCode() != 200) { | |
154 LOG(WARNING) << "Certificate upload HTTP status: " | |
155 << request->GetResponseCode(); | |
156 } | |
157 RequestComplete(request); | |
158 } | |
159 | |
160 void CertificateErrorReporter::OnReadCompleted(net::URLRequest* request, | |
161 int bytes_read) { | |
162 } | |
163 | |
164 scoped_ptr<net::URLRequest> CertificateErrorReporter::CreateURLRequest( | |
165 net::URLRequestContext* context) { | |
166 scoped_ptr<net::URLRequest> request = | |
167 context->CreateRequest(upload_url_, net::DEFAULT_PRIORITY, this); | |
168 if (cookies_preference_ != SEND_COOKIES) { | |
169 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | |
170 net::LOAD_DO_NOT_SAVE_COOKIES); | |
171 } | |
172 return request.Pass(); | |
173 } | |
174 | |
175 bool CertificateErrorReporter::IsHttpUploadUrlSupported() { | 146 bool CertificateErrorReporter::IsHttpUploadUrlSupported() { |
176 #if defined(USE_OPENSSL) | 147 #if defined(USE_OPENSSL) |
177 return true; | 148 return true; |
178 #else | 149 #else |
179 return false; | 150 return false; |
180 #endif | 151 #endif |
181 } | 152 } |
182 | 153 |
183 // Used only by tests. | 154 // Used only by tests. |
184 #if defined(USE_OPENSSL) | 155 #if defined(USE_OPENSSL) |
(...skipping 19 matching lines...) Expand all Loading... |
204 aead.Init(&key); | 175 aead.Init(&key); |
205 | 176 |
206 // Use an all-zero nonce because the key is random per-message. | 177 // Use an all-zero nonce because the key is random per-message. |
207 std::string nonce(aead.NonceLength(), 0); | 178 std::string nonce(aead.NonceLength(), 0); |
208 | 179 |
209 return aead.Open(encrypted_report.encrypted_report(), nonce, std::string(), | 180 return aead.Open(encrypted_report.encrypted_report(), nonce, std::string(), |
210 decrypted_serialized_report); | 181 decrypted_serialized_report); |
211 } | 182 } |
212 #endif | 183 #endif |
213 | 184 |
214 void CertificateErrorReporter::SendSerializedRequest( | |
215 const std::string& serialized_request) { | |
216 scoped_ptr<net::URLRequest> url_request = CreateURLRequest(request_context_); | |
217 url_request->set_method("POST"); | |
218 | |
219 scoped_ptr<net::UploadElementReader> reader( | |
220 net::UploadOwnedBytesElementReader::CreateWithString(serialized_request)); | |
221 url_request->set_upload( | |
222 net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0)); | |
223 | |
224 net::HttpRequestHeaders headers; | |
225 headers.SetHeader(net::HttpRequestHeaders::kContentType, | |
226 "x-application/chrome-fraudulent-cert-report"); | |
227 url_request->SetExtraRequestHeaders(headers); | |
228 | |
229 net::URLRequest* raw_url_request = url_request.get(); | |
230 inflight_requests_.insert(url_request.release()); | |
231 raw_url_request->Start(); | |
232 } | |
233 | |
234 void CertificateErrorReporter::RequestComplete(net::URLRequest* request) { | |
235 std::set<net::URLRequest*>::iterator i = inflight_requests_.find(request); | |
236 DCHECK(i != inflight_requests_.end()); | |
237 scoped_ptr<net::URLRequest> url_request(*i); | |
238 inflight_requests_.erase(i); | |
239 } | |
240 | |
241 } // namespace chrome_browser_net | 185 } // namespace chrome_browser_net |
OLD | NEW |