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

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: Move OCSP into cert_verify_proc 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 #include <vector> 10 #include <vector>
11 11
12 #include "base/base64.h" 12 #include "base/base64.h"
13 #include "base/build_time.h" 13 #include "base/build_time.h"
14 #include "base/json/json_writer.h" 14 #include "base/json/json_writer.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
18 #include "base/metrics/sparse_histogram.h" 18 #include "base/metrics/sparse_histogram.h"
19 #include "base/sha1.h" 19 #include "base/sha1.h"
20 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h" 22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h" 23 #include "base/strings/utf_string_conversions.h"
24 #include "base/values.h" 24 #include "base/values.h"
25 #include "crypto/sha2.h" 25 #include "crypto/sha2.h"
26 #include "net/base/host_port_pair.h" 26 #include "net/base/host_port_pair.h"
27 #include "net/cert/ct_policy_status.h" 27 #include "net/cert/ct_policy_status.h"
28 #include "net/cert/internal/parse_ocsp.h"
29 #include "net/cert/ocsp_verify_result.h"
28 #include "net/cert/x509_cert_types.h" 30 #include "net/cert/x509_cert_types.h"
29 #include "net/cert/x509_certificate.h" 31 #include "net/cert/x509_certificate.h"
30 #include "net/dns/dns_util.h" 32 #include "net/dns/dns_util.h"
31 #include "net/http/http_security_headers.h" 33 #include "net/http/http_security_headers.h"
32 #include "net/ssl/ssl_info.h" 34 #include "net/ssl/ssl_info.h"
33 35
34 namespace net { 36 namespace net {
35 37
36 namespace { 38 namespace {
37 39
(...skipping 110 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) {
svaldez 2016/06/23 14:03:15 Possibly attach this to ocsp_verify_result?
Ryan Sleevi 2016/06/23 22:11:52 I'm actually supportive of leaving it here, since
Ryan Sleevi 2016/06/23 22:11:52 return "const char*" - don't force a string coerci
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 928 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 } 1110 }
1097 1111
1098 ExpectCTState state; 1112 ExpectCTState state;
1099 if (!GetStaticExpectCTState(host_port_pair.host(), &state)) 1113 if (!GetStaticExpectCTState(host_port_pair.host(), &state))
1100 return; 1114 return;
1101 1115
1102 expect_ct_reporter_->OnExpectCTFailed(host_port_pair, state.report_uri, 1116 expect_ct_reporter_->OnExpectCTFailed(host_port_pair, state.report_uri,
1103 ssl_info); 1117 ssl_info);
1104 } 1118 }
1105 1119
1120 void TransportSecurityState::CheckExpectStaple(
1121 const HostPortPair& host_port_pair,
1122 const X509Certificate& verified_certificate,
1123 const X509Certificate& unverified_certificate,
1124 bool is_issued_by_known_root,
1125 const OCSPVerifyResult& ocsp_verify_result) {
1126 DCHECK(CalledOnValidThread());
1127 if (!enable_static_expect_staple_ || !report_sender_)
1128 return;
1129
1130 // Don't check preload or send report if the staple was good.
1131 if (ocsp_verify_result.cert_status.value_or(
1132 OCSPCertStatus::Status::UNKNOWN) == OCSPCertStatus::Status::GOOD) {
1133 return;
1134 }
1135
1136 // Check to see if the host is preloaded.
1137 ExpectStapleState expect_staple_state;
1138 if (!GetStaticExpectStapleState(host_port_pair.host(), &expect_staple_state))
1139 return;
1140
1141 if (expect_staple_state.report_uri.is_empty())
1142 return;
1143
1144 // Report failure.
1145 std::string serialized_report;
1146 if (!SerializeExpectStapleReport(host_port_pair, unverified_certificate,
1147 is_issued_by_known_root, ocsp_verify_result,
1148 &serialized_report)) {
1149 return;
1150 }
1151 report_sender_->Send(expect_staple_state.report_uri, serialized_report);
1152 }
1153
1106 // static 1154 // static
1107 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { 1155 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
1108 PreloadResult result; 1156 PreloadResult result;
1109 if (!DecodeHSTSPreload(host, &result) || 1157 if (!DecodeHSTSPreload(host, &result) ||
1110 !result.has_pins) { 1158 !result.has_pins) {
1111 return; 1159 return;
1112 } 1160 }
1113 1161
1114 DCHECK(result.domain_id != DOMAIN_NOT_PINNED); 1162 DCHECK(result.domain_id != DOMAIN_NOT_PINNED);
1115 1163
(...skipping 26 matching lines...) Expand all
1142 1190
1143 // HasPublicKeyPins should have returned true in order for this method to have 1191 // HasPublicKeyPins should have returned true in order for this method to have
1144 // been called. 1192 // been called.
1145 DCHECK(found_state); 1193 DCHECK(found_state);
1146 return CheckPinsAndMaybeSendReport( 1194 return CheckPinsAndMaybeSendReport(
1147 host_port_pair, is_issued_by_known_root, pkp_state, hashes, 1195 host_port_pair, is_issued_by_known_root, pkp_state, hashes,
1148 served_certificate_chain, validated_certificate_chain, report_status, 1196 served_certificate_chain, validated_certificate_chain, report_status,
1149 failure_log); 1197 failure_log);
1150 } 1198 }
1151 1199
1200 // static
1201 bool TransportSecurityState::SerializeExpectStapleReport(
1202 const HostPortPair& host_port_pair,
1203 const X509Certificate& unverified_certificate,
1204 bool is_issued_by_known_root,
1205 const OCSPVerifyResult& ocsp_verify_result,
1206 std::string* serialized_report) {
1207 base::DictionaryValue report_dict;
1208 report_dict.SetString("date-time", TimeToISO8601(base::Time::Now()));
1209 report_dict.SetString("hostname", host_port_pair.host());
1210 report_dict.SetInteger("port", host_port_pair.port());
1211
1212 // Add the list of each stapled OCSP response
1213 std::unique_ptr<base::Value> ocsp_responses(new base::ListValue);
1214 for (const auto& staple : ocsp_verify_result.stapled_responses) {
1215 std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue);
1216 response->SetBoolean("is-date-valid", staple.is_date_valid);
1217 response->SetBoolean("is-correct-certificate",
1218 staple.is_correct_certificate);
1219 response->SetString("status", OCSPCertStatusToString(staple.status));
1220 base::ListValue* responses_list =
1221 reinterpret_cast<base::ListValue*>(ocsp_responses.get());
1222 responses_list->Append(std::move(response));
1223 }
1224 report_dict.Set("ocsp-responses", std::move(ocsp_responses));
1225
1226 // Only add the certificate chain to the report if its public
1227 if (is_issued_by_known_root)
1228 report_dict.Set("served-certificate-chain",
1229 GetPEMEncodedChainAsList(&unverified_certificate));
1230
1231 if (!base::JSONWriter::Write(report_dict, serialized_report)) {
1232 LOG(ERROR) << "Failed to serialize Expect-Staple report";
1233 return false;
1234 }
1235 return true;
1236 }
1237
1152 bool TransportSecurityState::GetStaticDomainState(const std::string& host, 1238 bool TransportSecurityState::GetStaticDomainState(const std::string& host,
1153 STSState* sts_state, 1239 STSState* sts_state,
1154 PKPState* pkp_state) const { 1240 PKPState* pkp_state) const {
1155 DCHECK(CalledOnValidThread()); 1241 DCHECK(CalledOnValidThread());
1156 1242
1157 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; 1243 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS;
1158 sts_state->include_subdomains = false; 1244 sts_state->include_subdomains = false;
1159 pkp_state->include_subdomains = false; 1245 pkp_state->include_subdomains = false;
1160 1246
1161 if (!IsBuildTimely()) 1247 if (!IsBuildTimely())
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 TransportSecurityState::PKPStateIterator::PKPStateIterator( 1486 TransportSecurityState::PKPStateIterator::PKPStateIterator(
1401 const TransportSecurityState& state) 1487 const TransportSecurityState& state)
1402 : iterator_(state.enabled_pkp_hosts_.begin()), 1488 : iterator_(state.enabled_pkp_hosts_.begin()),
1403 end_(state.enabled_pkp_hosts_.end()) { 1489 end_(state.enabled_pkp_hosts_.end()) {
1404 } 1490 }
1405 1491
1406 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { 1492 TransportSecurityState::PKPStateIterator::~PKPStateIterator() {
1407 } 1493 }
1408 1494
1409 } // namespace 1495 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698