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

Side by Side Diff: net/http/transport_security_state.cc

Issue 2040513003: Implement Expect-Staple (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove call to GetSSLInfo Created 4 years, 6 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 unified diff | Download patch
OLDNEW
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 "net/http/transport_security_state.h" 5 #include "net/http/transport_security_state.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/base64.h" 11 #include "base/base64.h"
12 #include "base/build_time.h" 12 #include "base/build_time.h"
13 #include "base/json/json_writer.h" 13 #include "base/json/json_writer.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
17 #include "base/metrics/sparse_histogram.h" 17 #include "base/metrics/sparse_histogram.h"
18 #include "base/sha1.h" 18 #include "base/sha1.h"
19 #include "base/strings/string_number_conversions.h" 19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
23 #include "base/values.h" 23 #include "base/values.h"
24 #include "crypto/sha2.h" 24 #include "crypto/sha2.h"
25 #include "net/base/host_port_pair.h" 25 #include "net/base/host_port_pair.h"
26 #include "net/cert/ct_policy_status.h" 26 #include "net/cert/ct_policy_status.h"
27 #include "net/cert/internal/parse_ocsp.h"
28 #include "net/cert/ocsp_staple.h"
27 #include "net/cert/x509_cert_types.h" 29 #include "net/cert/x509_cert_types.h"
28 #include "net/cert/x509_certificate.h" 30 #include "net/cert/x509_certificate.h"
29 #include "net/dns/dns_util.h" 31 #include "net/dns/dns_util.h"
30 #include "net/http/http_security_headers.h" 32 #include "net/http/http_security_headers.h"
31 #include "net/ssl/ssl_info.h" 33 #include "net/ssl/ssl_info.h"
32 #include "url/gurl.h" 34 #include "url/gurl.h"
33 35
34 namespace net { 36 namespace net {
35 37
36 namespace { 38 namespace {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 report.SetString("effective-expiration-date", 150 report.SetString("effective-expiration-date",
149 TimeToISO8601(pkp_state.expiry)); 151 TimeToISO8601(pkp_state.expiry));
150 if (!base::JSONWriter::Write(report, serialized_report)) { 152 if (!base::JSONWriter::Write(report, serialized_report)) {
151 LOG(ERROR) << "Failed to serialize HPKP violation report."; 153 LOG(ERROR) << "Failed to serialize HPKP violation report.";
152 return false; 154 return false;
153 } 155 }
154 156
155 return true; 157 return true;
156 } 158 }
157 159
160 std::string OCSPCertStatusToString(OCSPCertStatus::Status status) {
161 switch (status) {
162 case OCSPCertStatus::Status::GOOD:
163 return "GOOD";
164 case OCSPCertStatus::Status::REVOKED:
165 return "REVOKED";
166 case OCSPCertStatus::Status::UNKNOWN:
167 return "UNKNOWN";
168 }
169 return "";
170 }
171
158 // Do not send a report over HTTPS to the same host that set the 172 // Do not send a report over HTTPS to the same host that set the
159 // pin. Such report URIs will result in loops. (A.com has a pinning 173 // pin. Such report URIs will result in loops. (A.com has a pinning
160 // violation which results in a report being sent to A.com, which 174 // violation which results in a report being sent to A.com, which
161 // results in a pinning violation which results in a report being sent 175 // results in a pinning violation which results in a report being sent
162 // to A.com, etc.) 176 // to A.com, etc.)
163 bool IsReportUriValidForHost(const GURL& report_uri, const std::string& host) { 177 bool IsReportUriValidForHost(const GURL& report_uri, const std::string& host) {
164 return (report_uri.host_piece() != host || 178 return (report_uri.host_piece() != host ||
165 !report_uri.SchemeIsCryptographic()); 179 !report_uri.SchemeIsCryptographic());
166 } 180 }
167 181
(...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 } 1105 }
1092 1106
1093 ExpectCTState state; 1107 ExpectCTState state;
1094 if (!GetStaticExpectCTState(host_port_pair.host(), &state)) 1108 if (!GetStaticExpectCTState(host_port_pair.host(), &state))
1095 return; 1109 return;
1096 1110
1097 expect_ct_reporter_->OnExpectCTFailed(host_port_pair, state.report_uri, 1111 expect_ct_reporter_->OnExpectCTFailed(host_port_pair, state.report_uri,
1098 ssl_info); 1112 ssl_info);
1099 } 1113 }
1100 1114
1115 void TransportSecurityState::CheckExpectStaple(
1116 const HostPortPair& host_port_pair,
1117 const X509Certificate& verified_certificate,
1118 const X509Certificate& unverified_certificate,
1119 const base::Time& verify_time,
1120 const base::TimeDelta& max_age,
1121 const std::string& ocsp_response) {
1122 DCHECK(CalledOnValidThread());
1123 if (!enable_static_expect_staple_ || !report_sender_)
1124 return;
1125
1126 // Check to see if the host is preloaded.
1127 ExpectStapleState expect_staple_state;
1128 if (!GetStaticExpectStapleState(host_port_pair.host(), &expect_staple_state))
1129 return;
1130
1131 if (expect_staple_state.report_uri.is_empty())
1132 return;
1133
1134 // Check the stapled information.
1135 std::unique_ptr<ExpectStapleReport> report =
1136 ExpectStapleReport::FromRawOCSPResponse(ocsp_response, verify_time,
1137 max_age, verified_certificate);
1138
1139 // Report on failure.
1140 if (report->staple_error() == ExpectStapleReport::StapleError::OK)
1141 return;
1142 std::string serialized_report;
1143 if (!SerializeExpectStapleReport(host_port_pair, unverified_certificate,
1144 *report, &serialized_report))
1145 return;
1146 report_sender_->Send(expect_staple_state.report_uri, serialized_report);
1147 }
1148
1101 // static 1149 // static
1102 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { 1150 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
1103 PreloadResult result; 1151 PreloadResult result;
1104 if (!DecodeHSTSPreload(host, &result) || 1152 if (!DecodeHSTSPreload(host, &result) ||
1105 !result.has_pins) { 1153 !result.has_pins) {
1106 return; 1154 return;
1107 } 1155 }
1108 1156
1109 DCHECK(result.domain_id != DOMAIN_NOT_PINNED); 1157 DCHECK(result.domain_id != DOMAIN_NOT_PINNED);
1110 1158
(...skipping 23 matching lines...) Expand all
1134 // HasPublicKeyPins should have returned true in order for this method 1182 // HasPublicKeyPins should have returned true in order for this method
1135 // to have been called, so if we fall through to here, it's an error. 1183 // to have been called, so if we fall through to here, it's an error.
1136 return false; 1184 return false;
1137 } 1185 }
1138 1186
1139 return CheckPinsAndMaybeSendReport( 1187 return CheckPinsAndMaybeSendReport(
1140 host_port_pair, pkp_state, hashes, served_certificate_chain, 1188 host_port_pair, pkp_state, hashes, served_certificate_chain,
1141 validated_certificate_chain, report_status, failure_log); 1189 validated_certificate_chain, report_status, failure_log);
1142 } 1190 }
1143 1191
1192 // static
1193 bool TransportSecurityState::SerializeExpectStapleReport(
1194 const HostPortPair& host_port_pair,
1195 const X509Certificate& unverified_certificate,
1196 const ExpectStapleReport& report,
1197 std::string* serialized_report) {
1198 base::DictionaryValue report_dict;
1199 report_dict.SetString("date-time", TimeToISO8601(report.verify_time()));
1200 report_dict.SetString("hostname", host_port_pair.host());
1201 report_dict.SetInteger("port", host_port_pair.port());
1202
1203 // Add the list of each stapled OCSP response
1204 std::unique_ptr<base::Value> ocsp_responses(new base::ListValue);
1205 for (const auto& staple : report.stapled_responses()) {
1206 std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue);
1207 response->SetBoolean("is-date-valid", staple.is_date_valid);
1208 response->SetBoolean("is-correct-certificate",
1209 staple.is_correct_certificate);
1210 response->SetString("status", OCSPCertStatusToString(staple.status));
1211 base::ListValue* responses_list =
1212 reinterpret_cast<base::ListValue*>(ocsp_responses.get());
1213 responses_list->Append(std::move(response));
1214 }
1215 report_dict.Set("ocsp-responses", std::move(ocsp_responses));
1216 report_dict.Set("served-certificate-chain",
1217 GetPEMEncodedChainAsList(&unverified_certificate));
1218
1219 if (!base::JSONWriter::Write(report_dict, serialized_report)) {
1220 LOG(ERROR) << "Failed to serialize Expect-Staple report";
1221 return false;
1222 }
1223 return true;
1224 }
1225
1144 bool TransportSecurityState::GetStaticDomainState(const std::string& host, 1226 bool TransportSecurityState::GetStaticDomainState(const std::string& host,
1145 STSState* sts_state, 1227 STSState* sts_state,
1146 PKPState* pkp_state) const { 1228 PKPState* pkp_state) const {
1147 DCHECK(CalledOnValidThread()); 1229 DCHECK(CalledOnValidThread());
1148 1230
1149 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; 1231 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS;
1150 sts_state->include_subdomains = false; 1232 sts_state->include_subdomains = false;
1151 pkp_state->include_subdomains = false; 1233 pkp_state->include_subdomains = false;
1152 1234
1153 if (!IsBuildTimely()) 1235 if (!IsBuildTimely())
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 TransportSecurityState::PKPStateIterator::PKPStateIterator( 1482 TransportSecurityState::PKPStateIterator::PKPStateIterator(
1401 const TransportSecurityState& state) 1483 const TransportSecurityState& state)
1402 : iterator_(state.enabled_pkp_hosts_.begin()), 1484 : iterator_(state.enabled_pkp_hosts_.begin()),
1403 end_(state.enabled_pkp_hosts_.end()) { 1485 end_(state.enabled_pkp_hosts_.end()) {
1404 } 1486 }
1405 1487
1406 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { 1488 TransportSecurityState::PKPStateIterator::~PKPStateIterator() {
1407 } 1489 }
1408 1490
1409 } // namespace 1491 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698