Index: net/http/transport_security_reporter.cc |
diff --git a/net/http/transport_security_reporter.cc b/net/http/transport_security_reporter.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ff60889075a8a2a3b11b96297d806bd44f908254 |
--- /dev/null |
+++ b/net/http/transport_security_reporter.cc |
@@ -0,0 +1,121 @@ |
+// Copyright 2015 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/http/transport_security_reporter.h" |
+ |
+#include "base/base64.h" |
+#include "base/json/json_writer.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/string_util.h" |
+#include "base/time/time.h" |
+#include "base/values.h" |
+#include "net/ssl/ssl_info.h" |
+#include "net/url_request/url_request_context.h" |
+#include "url/gurl.h" |
+ |
+namespace { |
+ |
+scoped_ptr<base::ListValue> GetPEMEncodedChainAsList( |
+ scoped_refptr<net::X509Certificate> cert_chain) { |
+ if (!cert_chain) |
+ return scoped_ptr<base::ListValue>(new base::ListValue()); |
+ |
+ scoped_ptr<base::ListValue> result(new base::ListValue()); |
+ std::vector<std::string> pem_encoded_chain; |
+ cert_chain->GetPEMEncodedChain(&pem_encoded_chain); |
+ for (std::string cert : pem_encoded_chain) |
+ result->Append(scoped_ptr<base::Value>(new base::StringValue(cert))); |
+ |
+ return result.Pass(); |
+} |
+ |
+} // namespace |
+ |
+namespace net { |
+ |
+TransportSecurityReporter::TransportSecurityReporter( |
+ TransportSecurityState* state, |
+ scoped_ptr<CertificateReportSender> report_sender) |
+ : transport_security_state_(state), report_sender_(report_sender.Pass()) { |
+ transport_security_state_->SetReporter(this); |
+} |
+ |
+TransportSecurityReporter::~TransportSecurityReporter() { |
+ transport_security_state_->SetReporter(nullptr); |
+} |
+ |
+bool TransportSecurityReporter::GetHPKPReportUri( |
+ const TransportSecurityState::DomainState::PKPState& pkp_state, |
+ GURL* report_uri) { |
+ *report_uri = GURL(pkp_state.report_uri); |
+ // TODO(estark): keep track of reports already sent and rate-limit, |
+ // break loops |
+ return !report_uri->is_empty(); |
+} |
+ |
+bool TransportSecurityReporter::BuildHPKPReport( |
+ const std::string& hostname, |
+ uint16_t port, |
+ const base::Time& expiry, |
+ bool include_subdomains, |
+ const std::string& effective_hostname, |
+ const scoped_refptr<X509Certificate>& served_certificate_chain, |
+ const scoped_refptr<X509Certificate>& validated_certificate_chain, |
+ const HashValueVector& spki_hashes, |
+ std::string* serialized_report) { |
+ base::DictionaryValue report; |
+ base::Time now = base::Time::Now(); |
+ // TODO(estark): write times in RFC3339 format. |
+ report.SetString("date-time", base::Int64ToString(now.ToInternalValue())); |
+ report.SetString("hostname", hostname); |
+ report.SetInteger("port", port); |
+ report.SetString("effective-expiration-date", |
+ base::Int64ToString(expiry.ToInternalValue())); |
+ report.SetBoolean("include-subdomains", include_subdomains); |
+ report.SetString("noted-hostname", effective_hostname); |
+ |
+ scoped_ptr<base::ListValue> served_certificate_chain_list = |
+ GetPEMEncodedChainAsList(served_certificate_chain); |
+ scoped_ptr<base::ListValue> validated_certificate_chain_list = |
+ GetPEMEncodedChainAsList(validated_certificate_chain); |
+ report.Set("served-certificate-chain", served_certificate_chain_list.Pass()); |
+ report.Set("validated-certificate-chain", |
+ validated_certificate_chain_list.Pass()); |
+ |
+ scoped_ptr<base::ListValue> knownPinList(new base::ListValue()); |
+ for (const auto& hash_value : spki_hashes) { |
+ std::string known_pin; |
+ |
+ switch (hash_value.tag) { |
+ case HASH_VALUE_SHA1: |
+ known_pin += "pin-sha1="; |
+ break; |
+ case HASH_VALUE_SHA256: |
+ known_pin += "pin-sha256="; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
+ |
+ std::string base64_value; |
+ base::Base64Encode( |
+ base::StringPiece(reinterpret_cast<const char*>(hash_value.data()), |
+ hash_value.size()), |
+ &base64_value); |
+ known_pin += "\"" + base64_value + "\""; |
+ |
+ knownPinList->Append( |
+ scoped_ptr<base::Value>(new base::StringValue(known_pin))); |
+ } |
+ |
+ report.Set("known-pins", knownPinList.Pass()); |
+ |
+ return base::JSONWriter::Write(report, serialized_report); |
+} |
+ |
+void TransportSecurityReporter::SendHPKPReport(const GURL& report_uri, |
+ const std::string& report) { |
+ report_sender_->Send(report_uri, report); |
+} |
+} // namespace net |