| 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 |