| Index: net/http/transport_security_state.cc
|
| diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
|
| index 34e53713b93524540c9caf36741c32c5aed42250..323fc0bddb5b888101fa25fac8695fabaa6bb8a3 100644
|
| --- a/net/http/transport_security_state.cc
|
| +++ b/net/http/transport_security_state.cc
|
| @@ -24,6 +24,8 @@
|
| #include "crypto/sha2.h"
|
| #include "net/base/host_port_pair.h"
|
| #include "net/cert/ct_policy_status.h"
|
| +#include "net/cert/expect_staple_report.h"
|
| +#include "net/cert/internal/parse_ocsp.h"
|
| #include "net/cert/x509_cert_types.h"
|
| #include "net/cert/x509_certificate.h"
|
| #include "net/dns/dns_util.h"
|
| @@ -155,6 +157,18 @@ bool GetHPKPReport(const HostPortPair& host_port_pair,
|
| return true;
|
| }
|
|
|
| +std::string OCSPCertStatusToString(OCSPCertStatus::Status status) {
|
| + switch (status) {
|
| + case OCSPCertStatus::Status::GOOD:
|
| + return "GOOD";
|
| + case OCSPCertStatus::Status::REVOKED:
|
| + return "REVOKED";
|
| + case OCSPCertStatus::Status::UNKNOWN:
|
| + return "UNKNOWN";
|
| + }
|
| + return "";
|
| +}
|
| +
|
| // Do not send a report over HTTPS to the same host that set the
|
| // pin. Such report URIs will result in loops. (A.com has a pinning
|
| // violation which results in a report being sent to A.com, which
|
| @@ -1097,6 +1111,43 @@ void TransportSecurityState::ProcessExpectCTHeader(
|
| ssl_info);
|
| }
|
|
|
| +void TransportSecurityState::CheckExpectStaple(
|
| + const HostPortPair& host_port_pair,
|
| + const X509Certificate& verified_certificate,
|
| + const X509Certificate& unverified_certificate,
|
| + bool is_issued_by_known_root,
|
| + const base::Time& verify_time,
|
| + const base::TimeDelta& max_age,
|
| + const std::string& ocsp_response) {
|
| + DCHECK(CalledOnValidThread());
|
| + if (!enable_static_expect_staple_ || !report_sender_)
|
| + return;
|
| +
|
| + // Check to see if the host is preloaded.
|
| + ExpectStapleState expect_staple_state;
|
| + if (!GetStaticExpectStapleState(host_port_pair.host(), &expect_staple_state))
|
| + return;
|
| +
|
| + if (expect_staple_state.report_uri.is_empty())
|
| + return;
|
| +
|
| + // Check the stapled information.
|
| + std::unique_ptr<ExpectStapleReport> report =
|
| + ExpectStapleReport::FromRawOCSPResponse(ocsp_response, verify_time,
|
| + max_age, verified_certificate);
|
| +
|
| + // Report on failure.
|
| + if (report->staple_error() == ExpectStapleReport::StapleError::OK)
|
| + return;
|
| + std::string serialized_report;
|
| + if (!SerializeExpectStapleReport(host_port_pair, unverified_certificate,
|
| + is_issued_by_known_root, *report,
|
| + &serialized_report)) {
|
| + return;
|
| + }
|
| + report_sender_->Send(expect_staple_state.report_uri, serialized_report);
|
| +}
|
| +
|
| // static
|
| void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
|
| PreloadResult result;
|
| @@ -1142,6 +1193,44 @@ bool TransportSecurityState::CheckPublicKeyPinsImpl(
|
| failure_log);
|
| }
|
|
|
| +// static
|
| +bool TransportSecurityState::SerializeExpectStapleReport(
|
| + const HostPortPair& host_port_pair,
|
| + const X509Certificate& unverified_certificate,
|
| + bool is_issued_by_known_root,
|
| + const ExpectStapleReport& report,
|
| + std::string* serialized_report) {
|
| + base::DictionaryValue report_dict;
|
| + report_dict.SetString("date-time", TimeToISO8601(report.verify_time()));
|
| + report_dict.SetString("hostname", host_port_pair.host());
|
| + report_dict.SetInteger("port", host_port_pair.port());
|
| +
|
| + // Add the list of each stapled OCSP response
|
| + std::unique_ptr<base::Value> ocsp_responses(new base::ListValue);
|
| + for (const auto& staple : report.stapled_responses()) {
|
| + std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue);
|
| + response->SetBoolean("is-date-valid", staple.is_date_valid);
|
| + response->SetBoolean("is-correct-certificate",
|
| + staple.is_correct_certificate);
|
| + response->SetString("status", OCSPCertStatusToString(staple.status));
|
| + base::ListValue* responses_list =
|
| + reinterpret_cast<base::ListValue*>(ocsp_responses.get());
|
| + responses_list->Append(std::move(response));
|
| + }
|
| + report_dict.Set("ocsp-responses", std::move(ocsp_responses));
|
| +
|
| + // Only add the certificate chain to the report if its public
|
| + if (is_issued_by_known_root)
|
| + report_dict.Set("served-certificate-chain",
|
| + GetPEMEncodedChainAsList(&unverified_certificate));
|
| +
|
| + if (!base::JSONWriter::Write(report_dict, serialized_report)) {
|
| + LOG(ERROR) << "Failed to serialize Expect-Staple report";
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| bool TransportSecurityState::GetStaticDomainState(const std::string& host,
|
| STSState* sts_state,
|
| PKPState* pkp_state) const {
|
|
|