Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Unified Diff: net/http/transport_security_reporter.cc

Issue 1212613004: Build and send HPKP violation reports (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: combine GetHPKPReportUri() and BuildHPKPReport() into GetHPKPReport() Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..9bb15c4a740c8945624e1586a06800921b284315
--- /dev/null
+++ b/net/http/transport_security_reporter.cc
@@ -0,0 +1,122 @@
+// 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(
+ const net::X509Certificate* cert_chain) {
+ if (!cert_chain)
+ return scoped_ptr<base::ListValue>(new base::ListValue());
davidben 2015/07/22 21:36:42 You can also write return make_scoped_ptr(new ba
estark 2015/07/23 00:03:57 Done.
+
+ 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)
davidben 2015/07/22 21:36:42 std::string -> const std::string&
estark 2015/07/23 00:03:57 Done.
+ result->Append(scoped_ptr<base::Value>(new base::StringValue(cert)));
davidben 2015/07/22 21:36:42 I think make_scoped_ptr will work here too.
estark 2015/07/23 00:03:57 Done.
+
+ 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::GetHPKPReport(
+ const std::string& hostname,
+ const TransportSecurityState::PKPState& pkp_state,
+ bool is_static_pin,
+ uint16_t port,
+ const X509Certificate* served_certificate_chain,
+ const X509Certificate* validated_certificate_chain,
+ GURL* report_uri,
+ std::string* serialized_report) {
+ // TODO(estark): keep track of reports already sent and rate-limit,
+ // break loops
+ if (pkp_state.report_uri.is_empty())
+ return false;
+
+ base::DictionaryValue report;
+ base::Time now = base::Time::Now();
+ // TODO(estark): write times in RFC3339 format.
+ report.SetString("date-time", base::Int64ToString(now.ToInternalValue()));
davidben 2015/07/22 21:36:42 Here, you can just nab this code: https://code.goo
estark 2015/07/23 00:03:57 Done. (I just copied and pasted it -- not sure if
+ report.SetString("hostname", hostname);
+ report.SetInteger("port", port);
+ report.SetString("effective-expiration-date",
+ base::Int64ToString(pkp_state.expiry.ToInternalValue()));
+ report.SetBoolean("include-subdomains", pkp_state.include_subdomains);
+ report.SetString("noted-hostname", pkp_state.domain);
+
+ 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 : pkp_state.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();
davidben 2015/07/22 21:36:43 Probably also want a return false; (Or perhaps
estark 2015/07/23 00:03:57 Done (the latter).
+ }
+
+ 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());
+
+ if (!base::JSONWriter::Write(report, serialized_report)) {
+ LOG(ERROR) << "Failed to serialize HPKP violation report.";
+ return false;
+ }
+
+ *report_uri = pkp_state.report_uri;
+ return true;
+}
+
+void TransportSecurityReporter::SendHPKPReport(const GURL& report_uri,
+ const std::string& report) {
+ report_sender_->Send(report_uri, report);
+}
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698