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

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: Address comments from estark@ 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
« no previous file with comments | « net/http/transport_security_state.h ('k') | net/http/transport_security_state_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/expect_staple_report.h"
28 #include "net/cert/internal/parse_ocsp.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 922 matching lines...) Expand 10 before | Expand all | Expand 10 after
1090 } 1104 }
1091 1105
1092 ExpectCTState state; 1106 ExpectCTState state;
1093 if (!GetStaticExpectCTState(host_port_pair.host(), &state)) 1107 if (!GetStaticExpectCTState(host_port_pair.host(), &state))
1094 return; 1108 return;
1095 1109
1096 expect_ct_reporter_->OnExpectCTFailed(host_port_pair, state.report_uri, 1110 expect_ct_reporter_->OnExpectCTFailed(host_port_pair, state.report_uri,
1097 ssl_info); 1111 ssl_info);
1098 } 1112 }
1099 1113
1114 void TransportSecurityState::CheckExpectStaple(
1115 const HostPortPair& host_port_pair,
1116 const X509Certificate& verified_certificate,
1117 const X509Certificate& unverified_certificate,
1118 const base::Time& verify_time,
1119 const base::TimeDelta& max_age,
1120 const std::string& ocsp_response) {
1121 DCHECK(CalledOnValidThread());
1122 if (!enable_static_expect_staple_ || !report_sender_)
1123 return;
1124
1125 // Check to see if the host is preloaded.
1126 ExpectStapleState expect_staple_state;
1127 if (!GetStaticExpectStapleState(host_port_pair.host(), &expect_staple_state))
1128 return;
1129
1130 if (expect_staple_state.report_uri.is_empty())
1131 return;
1132
1133 // Check the stapled information.
1134 std::unique_ptr<ExpectStapleReport> report =
1135 ExpectStapleReport::FromRawOCSPResponse(ocsp_response, verify_time,
1136 max_age, verified_certificate);
1137
1138 // Report on failure.
1139 if (report->staple_error() == ExpectStapleReport::StapleError::OK)
1140 return;
1141 std::string serialized_report;
1142 if (!SerializeExpectStapleReport(host_port_pair, unverified_certificate,
1143 *report, &serialized_report))
1144 return;
1145 report_sender_->Send(expect_staple_state.report_uri, serialized_report);
1146 }
1147
1100 // static 1148 // static
1101 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { 1149 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
1102 PreloadResult result; 1150 PreloadResult result;
1103 if (!DecodeHSTSPreload(host, &result) || 1151 if (!DecodeHSTSPreload(host, &result) ||
1104 !result.has_pins) { 1152 !result.has_pins) {
1105 return; 1153 return;
1106 } 1154 }
1107 1155
1108 DCHECK(result.domain_id != DOMAIN_NOT_PINNED); 1156 DCHECK(result.domain_id != DOMAIN_NOT_PINNED);
1109 1157
(...skipping 25 matching lines...) Expand all
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, is_issued_by_known_root, pkp_state, hashes, 1188 host_port_pair, is_issued_by_known_root, pkp_state, hashes,
1141 served_certificate_chain, validated_certificate_chain, report_status, 1189 served_certificate_chain, validated_certificate_chain, report_status,
1142 failure_log); 1190 failure_log);
1143 } 1191 }
1144 1192
1193 // static
1194 bool TransportSecurityState::SerializeExpectStapleReport(
1195 const HostPortPair& host_port_pair,
1196 const X509Certificate& unverified_certificate,
1197 const ExpectStapleReport& report,
1198 std::string* serialized_report) {
1199 base::DictionaryValue report_dict;
1200 report_dict.SetString("date-time", TimeToISO8601(report.verify_time()));
1201 report_dict.SetString("hostname", host_port_pair.host());
1202 report_dict.SetInteger("port", host_port_pair.port());
1203
1204 // Add the list of each stapled OCSP response
1205 std::unique_ptr<base::Value> ocsp_responses(new base::ListValue);
1206 for (const auto& staple : report.stapled_responses()) {
1207 std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue);
1208 response->SetBoolean("is-date-valid", staple.is_date_valid);
1209 response->SetBoolean("is-correct-certificate",
1210 staple.is_correct_certificate);
1211 response->SetString("status", OCSPCertStatusToString(staple.status));
1212 base::ListValue* responses_list =
1213 reinterpret_cast<base::ListValue*>(ocsp_responses.get());
1214 responses_list->Append(std::move(response));
1215 }
1216 report_dict.Set("ocsp-responses", std::move(ocsp_responses));
1217 report_dict.Set("served-certificate-chain",
estark 2016/06/15 02:38:37 important note: only include this if |is_issued_by
dadrian 2016/06/15 20:59:03 Done.
1218 GetPEMEncodedChainAsList(&unverified_certificate));
1219
1220 if (!base::JSONWriter::Write(report_dict, serialized_report)) {
1221 LOG(ERROR) << "Failed to serialize Expect-Staple report";
1222 return false;
1223 }
1224 return true;
1225 }
1226
1145 bool TransportSecurityState::GetStaticDomainState(const std::string& host, 1227 bool TransportSecurityState::GetStaticDomainState(const std::string& host,
1146 STSState* sts_state, 1228 STSState* sts_state,
1147 PKPState* pkp_state) const { 1229 PKPState* pkp_state) const {
1148 DCHECK(CalledOnValidThread()); 1230 DCHECK(CalledOnValidThread());
1149 1231
1150 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; 1232 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS;
1151 sts_state->include_subdomains = false; 1233 sts_state->include_subdomains = false;
1152 pkp_state->include_subdomains = false; 1234 pkp_state->include_subdomains = false;
1153 1235
1154 if (!IsBuildTimely()) 1236 if (!IsBuildTimely())
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 TransportSecurityState::PKPStateIterator::PKPStateIterator( 1483 TransportSecurityState::PKPStateIterator::PKPStateIterator(
1402 const TransportSecurityState& state) 1484 const TransportSecurityState& state)
1403 : iterator_(state.enabled_pkp_hosts_.begin()), 1485 : iterator_(state.enabled_pkp_hosts_.begin()),
1404 end_(state.enabled_pkp_hosts_.end()) { 1486 end_(state.enabled_pkp_hosts_.end()) {
1405 } 1487 }
1406 1488
1407 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { 1489 TransportSecurityState::PKPStateIterator::~PKPStateIterator() {
1408 } 1490 }
1409 1491
1410 } // namespace 1492 } // namespace
OLDNEW
« no previous file with comments | « net/http/transport_security_state.h ('k') | net/http/transport_security_state_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698