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

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

Issue 2144693004: Add the ability to send Expect-Staple reports. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ocsp-verify-result
Patch Set: Clean tests, add documentation. Created 4 years, 5 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 <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList( 233 ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
234 served_certificate_chain, report_served_certificate_chain)); 234 served_certificate_chain, report_served_certificate_chain));
235 235
236 base::ListValue* report_validated_certificate_chain; 236 base::ListValue* report_validated_certificate_chain;
237 EXPECT_TRUE(report_dict->GetList("validated-certificate-chain", 237 EXPECT_TRUE(report_dict->GetList("validated-certificate-chain",
238 &report_validated_certificate_chain)); 238 &report_validated_certificate_chain));
239 ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList( 239 ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
240 validated_certificate_chain, report_validated_certificate_chain)); 240 validated_certificate_chain, report_validated_certificate_chain));
241 } 241 }
242 242
243 void CheckExpectStapleReport(const std::string& report,
244 const HostPortPair& host_port_pair,
245 const SSLInfo& ssl_info,
246 const std::string& ocsp_response,
247 const std::string& response_status,
248 const std::string& cert_status) {
249 std::unique_ptr<base::Value> value(base::JSONReader::Read(report));
250 ASSERT_TRUE(value);
251 ASSERT_TRUE(value->IsType(base::Value::TYPE_DICTIONARY));
252
253 base::DictionaryValue* report_dict;
254 ASSERT_TRUE(value->GetAsDictionary(&report_dict));
255
256 std::string report_hostname;
257 EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname));
258 EXPECT_EQ(host_port_pair.host(), report_hostname);
259
260 int report_port;
261 EXPECT_TRUE(report_dict->GetInteger("port", &report_port));
262 EXPECT_EQ(host_port_pair.port(), report_port);
263
264 std::string report_response_status;
265 EXPECT_TRUE(
266 report_dict->GetString("response-status", &report_response_status));
267 EXPECT_EQ(response_status, report_response_status);
268
269 std::string report_ocsp_response;
270 bool has_ocsp_response =
271 report_dict->GetString("ocsp-response", &report_ocsp_response);
272
273 if (!ocsp_response.empty()) {
274 EXPECT_TRUE(has_ocsp_response);
275 std::string decoded_ocsp_response;
276 EXPECT_TRUE(
277 base::Base64Decode(report_ocsp_response, &decoded_ocsp_response));
278 EXPECT_EQ(ocsp_response, decoded_ocsp_response);
279 } else {
280 EXPECT_FALSE(has_ocsp_response);
281 }
282
283 std::string report_cert_status;
284 bool has_cert_status =
285 report_dict->GetString("cert-status", &report_cert_status);
286 if (!cert_status.empty()) {
287 EXPECT_TRUE(has_cert_status);
288 EXPECT_EQ(cert_status, report_cert_status);
289 } else {
290 EXPECT_FALSE(has_cert_status);
291 }
292
293 base::ListValue* report_served_certificate_chain;
294 bool has_served_chain = report_dict->GetList(
295 "served-certificate-chain", &report_served_certificate_chain);
296
297 base::ListValue* report_validated_certificate_chain;
298 bool has_validated_chain = report_dict->GetList(
299 "validated-certificate-chain", &report_validated_certificate_chain);
300
301 if (ssl_info.is_issued_by_known_root) {
302 EXPECT_TRUE(has_served_chain);
303 EXPECT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
304 ssl_info.unverified_cert, report_served_certificate_chain));
305
306 EXPECT_TRUE(has_validated_chain);
307 EXPECT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
308 ssl_info.cert, report_validated_certificate_chain));
309 } else {
310 EXPECT_FALSE(has_served_chain);
311 EXPECT_FALSE(has_validated_chain);
312 }
313 }
314
315 void CheckExpectStaple(TransportSecurityState* state,
316 MockCertificateReportSender* reporter,
317 const SSLInfo& ssl_info,
318 const std::string& ocsp_response,
319 const std::string& response_status,
320 const std::string& cert_status) {
321 HostPortPair host_port(kExpectStapleStaticHostname, 443);
Ryan Sleevi 2016/07/19 19:11:05 Where does this come from and why? The test lacks
dadrian 2016/07/19 21:21:46 Yup, it's baked into the preload list itself as a
322 state->SetReportSender(reporter);
323 state->ProcessExpectStaple(host_port, ssl_info, ocsp_response);
324 EXPECT_EQ(GURL(kExpectStapleStaticReportURI), reporter->latest_report_uri());
325 std::string serialized_report = reporter->latest_report();
326 EXPECT_NO_FATAL_FAILURE(
327 CheckExpectStapleReport(serialized_report, host_port, ssl_info,
328 ocsp_response, response_status, cert_status));
329 }
330
243 } // namespace 331 } // namespace
244 332
245 class TransportSecurityStateTest : public testing::Test { 333 class TransportSecurityStateTest : public testing::Test {
246 public: 334 public:
247 void SetUp() override { 335 void SetUp() override {
248 crypto::EnsureOpenSSLInit(); 336 crypto::EnsureOpenSSLInit();
249 } 337 }
250 338
251 static void DisableStaticPins(TransportSecurityState* state) { 339 static void DisableStaticPins(TransportSecurityState* state) {
252 state->enable_static_pins_ = false; 340 state->enable_static_pins_ = false;
(...skipping 1642 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 state.ProcessExpectCTHeader("preload", host_port, ssl_info); 1983 state.ProcessExpectCTHeader("preload", host_port, ssl_info);
1896 EXPECT_EQ(1u, reporter.num_failures()); 1984 EXPECT_EQ(1u, reporter.num_failures());
1897 EXPECT_TRUE(reporter.ssl_info().ct_compliance_details_available); 1985 EXPECT_TRUE(reporter.ssl_info().ct_compliance_details_available);
1898 EXPECT_EQ(ssl_info.ct_cert_policy_compliance, 1986 EXPECT_EQ(ssl_info.ct_cert_policy_compliance,
1899 reporter.ssl_info().ct_cert_policy_compliance); 1987 reporter.ssl_info().ct_cert_policy_compliance);
1900 EXPECT_EQ(host_port.host(), reporter.host_port_pair().host()); 1988 EXPECT_EQ(host_port.host(), reporter.host_port_pair().host());
1901 EXPECT_EQ(host_port.port(), reporter.host_port_pair().port()); 1989 EXPECT_EQ(host_port.port(), reporter.host_port_pair().port());
1902 EXPECT_EQ(GURL(kExpectCTStaticReportURI), reporter.report_uri()); 1990 EXPECT_EQ(GURL(kExpectCTStaticReportURI), reporter.report_uri());
1903 } 1991 }
1904 1992
1993 static const struct ExpectStapleErrorResponseData {
1994 OCSPVerifyResult::ResponseStatus response_status;
1995 std::string response_status_string;
1996 } kExpectStapleReportData[] = {
1997 {OCSPVerifyResult::MISSING, "MISSING"},
1998 {OCSPVerifyResult::ERROR_RESPONSE, "ERROR_RESPONSE"},
1999 {OCSPVerifyResult::BAD_PRODUCED_AT, "BAD_PRODUCED_AT"},
2000 {OCSPVerifyResult::NO_MATCHING_RESPONSE, "NO_MATCHING_RESPONSE"},
2001 {OCSPVerifyResult::INVALID_DATE, "INVALID_DATE"},
2002 {OCSPVerifyResult::PARSE_RESPONSE_ERROR, "PARSE_RESPONSE_ERROR"},
2003 {OCSPVerifyResult::PARSE_RESPONSE_DATA_ERROR, "PARSE_RESPONSE_DATA_ERROR"},
2004 };
2005
2006 class ExpectStapleErrorResponseTest
2007 : public TransportSecurityStateTest,
2008 public testing::WithParamInterface<ExpectStapleErrorResponseData> {};
2009
2010 TEST_P(ExpectStapleErrorResponseTest, CheckResponseStatusSerialization) {
Ryan Sleevi 2016/07/19 19:11:05 Improve high-level docs for the test
dadrian 2016/07/19 21:21:46 Done.
2011 TransportSecurityState state;
2012 TransportSecurityStateTest::EnableStaticExpectStaple(&state);
2013 MockCertificateReportSender reporter;
2014 ExpectStapleErrorResponseData test = GetParam();
2015
2016 std::string ocsp_response;
2017 if (test.response_status != OCSPVerifyResult::MISSING)
2018 ocsp_response = "dummy_response";
2019
2020 // Two dummy certs to use as the server-sent and validated chains. The
2021 // contents don't matter.
2022 scoped_refptr<X509Certificate> cert1 =
2023 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
2024 scoped_refptr<X509Certificate> cert2 =
2025 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
2026
2027 SSLInfo ssl_info;
2028 ssl_info.cert = cert1;
2029 ssl_info.unverified_cert = cert2;
2030 ssl_info.ocsp_result.response_status = test.response_status;
2031
2032 ssl_info.is_issued_by_known_root = true;
2033 ASSERT_NO_FATAL_FAILURE(
2034 CheckExpectStaple(&state, &reporter, ssl_info, ocsp_response,
2035 test.response_status_string, std::string()));
2036
2037 ssl_info.is_issued_by_known_root = false;
2038 ASSERT_NO_FATAL_FAILURE(
2039 CheckExpectStaple(&state, &reporter, ssl_info, ocsp_response,
2040 test.response_status_string, std::string()));
Ryan Sleevi 2016/07/19 19:11:05 These tests (2081 - 2089) could benefit from impro
dadrian 2016/07/19 21:21:46 Done.
2041 }
2042
2043 INSTANTIATE_TEST_CASE_P(ExpectStaple,
2044 ExpectStapleErrorResponseTest,
2045 testing::ValuesIn(kExpectStapleReportData));
2046
2047 static const struct ExpectStapleErrorCertStatusData {
2048 OCSPRevocationStatus revocation_status;
2049 std::string cert_status_string;
2050 } kExpectStapleErrorCertStatusData[] = {
2051 {OCSPRevocationStatus::REVOKED, "REVOKED"},
2052 {OCSPRevocationStatus::UNKNOWN, "UNKNOWN"},
2053 };
2054
2055 class ExpectStapleErrorCertStatusTest
2056 : public TransportSecurityStateTest,
2057 public testing::WithParamInterface<ExpectStapleErrorCertStatusData> {};
2058
2059 TEST_P(ExpectStapleErrorCertStatusTest, CheckCertStatusSerialization) {
Ryan Sleevi 2016/07/19 19:11:04 Improve high-level docs for the test
dadrian 2016/07/19 21:21:46 Done.
2060 TransportSecurityState state;
2061 TransportSecurityStateTest::EnableStaticExpectStaple(&state);
2062 MockCertificateReportSender reporter;
2063 ExpectStapleErrorCertStatusData test = GetParam();
2064 std::string ocsp_response = "dummy_response";
2065
2066 // Two dummy certs to use as the server-sent and validated chains. The
2067 // contents don't matter.
2068 scoped_refptr<X509Certificate> cert1 =
2069 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
2070 scoped_refptr<X509Certificate> cert2 =
2071 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
2072
2073 SSLInfo ssl_info;
2074 ssl_info.cert = cert1;
2075 ssl_info.unverified_cert = cert2;
2076 // |response_status| must be set to PROVIDED for |revocation_status| to have
2077 // meaning.
2078 ssl_info.ocsp_result.response_status = OCSPVerifyResult::PROVIDED;
2079 ssl_info.ocsp_result.revocation_status = test.revocation_status;
2080
2081 ssl_info.is_issued_by_known_root = true;
2082 ASSERT_NO_FATAL_FAILURE(CheckExpectStaple(&state, &reporter, ssl_info,
2083 ocsp_response, "PROVIDED",
2084 test.cert_status_string));
2085
2086 ssl_info.is_issued_by_known_root = false;
2087 ASSERT_NO_FATAL_FAILURE(CheckExpectStaple(&state, &reporter, ssl_info,
2088 ocsp_response, "PROVIDED",
2089 test.cert_status_string));
2090 };
2091
2092 INSTANTIATE_TEST_CASE_P(ExpectStaple,
2093 ExpectStapleErrorCertStatusTest,
2094 testing::ValuesIn(kExpectStapleErrorCertStatusData));
2095
2096 TEST_F(TransportSecurityStateTest, ExpectStapleDoesNotReportValidStaple) {
2097 TransportSecurityState state;
2098 TransportSecurityStateTest::EnableStaticExpectStaple(&state);
2099 MockCertificateReportSender reporter;
2100 state.SetReportSender(&reporter);
2101
2102 HostPortPair host_port(kExpectStapleStaticHostname, 443);
2103
2104 // Two dummy certs to use as the server-sent and validated chains. The
2105 // contents don't matter.
2106 scoped_refptr<X509Certificate> cert1 =
2107 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
2108 scoped_refptr<X509Certificate> cert2 =
2109 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
2110
2111 SSLInfo ssl_info;
2112 ssl_info.is_issued_by_known_root = true;
2113 ssl_info.cert = cert1;
2114 ssl_info.unverified_cert = cert2;
2115 ssl_info.ocsp_result.response_status = OCSPVerifyResult::PROVIDED;
2116 ssl_info.ocsp_result.revocation_status = OCSPRevocationStatus::GOOD;
2117
2118 std::string ocsp_response = "dummy response";
2119
2120 state.ProcessExpectStaple(host_port, ssl_info, ocsp_response);
2121 EXPECT_EQ(GURL(), reporter.latest_report_uri());
2122 EXPECT_TRUE(reporter.latest_report().empty());
2123 }
2124
2125 TEST_F(TransportSecurityStateTest, ExpectStapleRequiresPreload) {
2126 TransportSecurityState state;
2127 TransportSecurityStateTest::EnableStaticExpectStaple(&state);
2128 MockCertificateReportSender reporter;
2129 state.SetReportSender(&reporter);
2130
2131 HostPortPair host_port("not-preloaded.badssl.com", 443);
Ryan Sleevi 2016/07/19 19:11:05 Similar to my remarks above (about it being preloa
dadrian 2016/07/19 21:21:46 Done.
2132
2133 // Two dummy certs to use as the server-sent and validated chains. The
2134 // contents don't matter.
2135 scoped_refptr<X509Certificate> cert1 =
2136 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
2137 scoped_refptr<X509Certificate> cert2 =
2138 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
2139
2140 SSLInfo ssl_info;
2141 ssl_info.is_issued_by_known_root = true;
Ryan Sleevi 2016/07/19 19:11:05 By contrast with your other tests (and part of why
dadrian 2016/07/19 21:21:46 Done.
2142 ssl_info.cert = cert1;
2143 ssl_info.unverified_cert = cert2;
2144 ssl_info.ocsp_result.response_status = OCSPVerifyResult::MISSING;
2145
2146 // Empty response
2147 std::string ocsp_response;
2148
2149 state.ProcessExpectStaple(host_port, ssl_info, ocsp_response);
2150 EXPECT_EQ(GURL(), reporter.latest_report_uri());
2151 EXPECT_TRUE(reporter.latest_report().empty());
2152 }
2153
1905 // Tests that TransportSecurityState always consults the RequireCTDelegate, 2154 // Tests that TransportSecurityState always consults the RequireCTDelegate,
1906 // if supplied. 2155 // if supplied.
1907 TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) { 2156 TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
1908 using ::testing::_; 2157 using ::testing::_;
1909 using ::testing::Return; 2158 using ::testing::Return;
1910 using CTRequirementLevel = 2159 using CTRequirementLevel =
1911 TransportSecurityState::RequireCTDelegate::CTRequirementLevel; 2160 TransportSecurityState::RequireCTDelegate::CTRequirementLevel;
1912 2161
1913 // Dummy cert to use as the validate chain. The contents do not matter. 2162 // Dummy cert to use as the validate chain. The contents do not matter.
1914 scoped_refptr<X509Certificate> cert = 2163 scoped_refptr<X509Certificate> cert =
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2029 base::FieldTrialList::CreateFieldTrial("EnforceCTForProblematicRoots", 2278 base::FieldTrialList::CreateFieldTrial("EnforceCTForProblematicRoots",
2030 "disabled"); 2279 "disabled");
2031 2280
2032 EXPECT_FALSE( 2281 EXPECT_FALSE(
2033 state.ShouldRequireCT("www.example.com", before_cert.get(), hashes)); 2282 state.ShouldRequireCT("www.example.com", before_cert.get(), hashes));
2034 EXPECT_FALSE( 2283 EXPECT_FALSE(
2035 state.ShouldRequireCT("www.example.com", after_cert.get(), hashes)); 2284 state.ShouldRequireCT("www.example.com", after_cert.get(), hashes));
2036 } 2285 }
2037 2286
2038 } // namespace net 2287 } // namespace net
OLDNEW
« net/http/transport_security_state.cc ('K') | « net/http/transport_security_state.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698