| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/chrome_fraudulent_certificate_reporter.h" | 5 #include "chrome/browser/net/chrome_fraudulent_certificate_reporter.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 net::URLRequestContext* request_context) | 33 net::URLRequestContext* request_context) |
| 34 : request_context_(request_context), | 34 : request_context_(request_context), |
| 35 pinning_violation_upload_url_(kFraudulentCertificateUploadEndpoint), | 35 pinning_violation_upload_url_(kFraudulentCertificateUploadEndpoint), |
| 36 invalid_chain_upload_url_(kInvalidCertificateChainUploadEndpoint) { | 36 invalid_chain_upload_url_(kInvalidCertificateChainUploadEndpoint) { |
| 37 } | 37 } |
| 38 | 38 |
| 39 ChromeFraudulentCertificateReporter::~ChromeFraudulentCertificateReporter() { | 39 ChromeFraudulentCertificateReporter::~ChromeFraudulentCertificateReporter() { |
| 40 STLDeleteElements(&inflight_requests_); | 40 STLDeleteElements(&inflight_requests_); |
| 41 } | 41 } |
| 42 | 42 |
| 43 static std::string BuildReport(const std::string& hostname, | 43 // Helper function for |BuildReport|. |
| 44 const net::SSLInfo& ssl_info) { | 44 static void AddCertChainToReport(const scoped_refptr<net::X509Certificate> cert, |
| 45 std::string* chain_from_report) { |
| 46 std::vector<std::string> pem_encoded_chain; |
| 47 if (!cert || !cert->GetPEMEncodedChain(&pem_encoded_chain)) { |
| 48 LOG(ERROR) << "Could not get PEM encoded chain."; |
| 49 } |
| 50 for (size_t i = 0; i < pem_encoded_chain.size(); ++i) |
| 51 *chain_from_report += pem_encoded_chain[i]; |
| 52 } |
| 53 |
| 54 std::string ChromeFraudulentCertificateReporter::BuildReport( |
| 55 ChromeFraudulentCertificateReporter::ReportType type, |
| 56 const std::string& hostname, |
| 57 const net::SSLInfo& ssl_info) { |
| 45 CertLoggerRequest request; | 58 CertLoggerRequest request; |
| 46 base::Time now = base::Time::Now(); | 59 base::Time now = base::Time::Now(); |
| 47 request.set_time_usec(now.ToInternalValue()); | 60 request.set_time_usec(now.ToInternalValue()); |
| 48 request.set_hostname(hostname); | 61 request.set_hostname(hostname); |
| 49 | 62 |
| 50 std::vector<std::string> pem_encoded_chain; | 63 AddCertChainToReport(ssl_info.cert, request.mutable_cert_chain()); |
| 51 if (!ssl_info.cert->GetPEMEncodedChain(&pem_encoded_chain)) { | 64 if (type == |
| 52 LOG(ERROR) << "Could not get PEM encoded chain."; | 65 ChromeFraudulentCertificateReporter::REPORT_TYPE_EXTENDED_REPORTING) { |
| 66 AddCertChainToReport(ssl_info.unverified_server_cert, |
| 67 request.mutable_unverified_server_cert_chain()); |
| 53 } | 68 } |
| 54 std::string* cert_chain = request.mutable_cert_chain(); | |
| 55 for (size_t i = 0; i < pem_encoded_chain.size(); ++i) | |
| 56 *cert_chain += pem_encoded_chain[i]; | |
| 57 | 69 |
| 58 request.add_pin(ssl_info.pinning_failure_log); | 70 request.add_pin(ssl_info.pinning_failure_log); |
| 59 | 71 |
| 60 std::string out; | 72 std::string out; |
| 61 request.SerializeToString(&out); | 73 request.SerializeToString(&out); |
| 62 return out; | 74 return out; |
| 63 } | 75 } |
| 64 | 76 |
| 65 scoped_ptr<net::URLRequest> | 77 scoped_ptr<net::URLRequest> |
| 66 ChromeFraudulentCertificateReporter::CreateURLRequest( | 78 ChromeFraudulentCertificateReporter::CreateURLRequest( |
| 67 net::URLRequestContext* context, | 79 net::URLRequestContext* context, |
| 68 const GURL& upload_url) { | 80 const GURL& upload_url) { |
| 69 scoped_ptr<net::URLRequest> request = | 81 scoped_ptr<net::URLRequest> request = |
| 70 context->CreateRequest(upload_url, net::DEFAULT_PRIORITY, this, NULL); | 82 context->CreateRequest(upload_url, net::DEFAULT_PRIORITY, this, NULL); |
| 71 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 83 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
| 72 net::LOAD_DO_NOT_SAVE_COOKIES); | 84 net::LOAD_DO_NOT_SAVE_COOKIES); |
| 73 return request.Pass(); | 85 return request.Pass(); |
| 74 } | 86 } |
| 75 | 87 |
| 76 void ChromeFraudulentCertificateReporter::SendReport( | 88 void ChromeFraudulentCertificateReporter::SendReport( |
| 77 ReportType type, | 89 ReportType type, |
| 78 const std::string& hostname, | 90 const std::string& hostname, |
| 79 const net::SSLInfo& ssl_info) { | 91 const net::SSLInfo& ssl_info) { |
| 80 if (type == REPORT_TYPE_EXTENDED_REPORTING) { | 92 if (type == REPORT_TYPE_EXTENDED_REPORTING) { |
| 81 // TODO(estark): Double-check that the user is opted in. | 93 // TODO(estark): Double-check that the user is opted in. |
| 82 | 94 |
| 83 // TODO(estark): Temporarily, since there is no upload endpoint, just log | 95 // TODO(estark): Temporarily, since there is no upload endpoint, just log |
| 84 // the information. | 96 // the information. |
| 85 LOG(ERROR) << "SSL report for " << hostname << ":\n" | 97 LOG(ERROR) << "SSL report for " << hostname << ":\n" |
| 86 << BuildReport(hostname, ssl_info) << "\n\n"; | 98 << BuildReport(type, hostname, ssl_info) << "\n\n"; |
| 87 return; | 99 return; |
| 88 } | 100 } |
| 89 | 101 |
| 90 // We do silent/automatic reporting ONLY for Google properties. For other | 102 // We do silent/automatic reporting ONLY for Google properties. For other |
| 91 // domains (when we start supporting that), we will ask for user permission. | 103 // domains (when we start supporting that), we will ask for user permission. |
| 92 if (!net::TransportSecurityState::IsGooglePinnedProperty(hostname)) { | 104 if (!net::TransportSecurityState::IsGooglePinnedProperty(hostname)) { |
| 93 return; | 105 return; |
| 94 } | 106 } |
| 95 | 107 |
| 96 std::string report = BuildReport(hostname, ssl_info); | 108 std::string report = BuildReport(type, hostname, ssl_info); |
| 97 | 109 |
| 98 scoped_ptr<net::URLRequest> url_request = | 110 scoped_ptr<net::URLRequest> url_request = |
| 99 CreateURLRequest(request_context_, pinning_violation_upload_url_); | 111 CreateURLRequest(request_context_, pinning_violation_upload_url_); |
| 100 url_request->set_method("POST"); | 112 url_request->set_method("POST"); |
| 101 | 113 |
| 102 scoped_ptr<net::UploadElementReader> reader( | 114 scoped_ptr<net::UploadElementReader> reader( |
| 103 net::UploadOwnedBytesElementReader::CreateWithString(report)); | 115 net::UploadOwnedBytesElementReader::CreateWithString(report)); |
| 104 url_request->set_upload( | 116 url_request->set_upload( |
| 105 net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0)); | 117 net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0)); |
| 106 | 118 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 LOG(WARNING) << "Certificate upload HTTP status: " | 153 LOG(WARNING) << "Certificate upload HTTP status: " |
| 142 << request->GetResponseCode(); | 154 << request->GetResponseCode(); |
| 143 } | 155 } |
| 144 RequestComplete(request); | 156 RequestComplete(request); |
| 145 } | 157 } |
| 146 | 158 |
| 147 void ChromeFraudulentCertificateReporter::OnReadCompleted( | 159 void ChromeFraudulentCertificateReporter::OnReadCompleted( |
| 148 net::URLRequest* request, int bytes_read) {} | 160 net::URLRequest* request, int bytes_read) {} |
| 149 | 161 |
| 150 } // namespace chrome_browser_net | 162 } // namespace chrome_browser_net |
| OLD | NEW |