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