OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |