| 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 |
| 11 #include "base/base64.h" | 11 #include "base/base64.h" |
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/files/file_util.h" |
| 13 #include "base/json/json_reader.h" | 14 #include "base/json/json_reader.h" |
| 14 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 15 #include "base/metrics/field_trial.h" | 16 #include "base/metrics/field_trial.h" |
| 17 #include "base/path_service.h" |
| 16 #include "base/rand_util.h" | 18 #include "base/rand_util.h" |
| 17 #include "base/sha1.h" | 19 #include "base/sha1.h" |
| 18 #include "base/strings/string_piece.h" | 20 #include "base/strings/string_piece.h" |
| 19 #include "base/test/histogram_tester.h" | 21 #include "base/test/histogram_tester.h" |
| 20 #include "base/test/mock_entropy_provider.h" | 22 #include "base/test/mock_entropy_provider.h" |
| 21 #include "base/values.h" | 23 #include "base/values.h" |
| 22 #include "crypto/openssl_util.h" | 24 #include "crypto/openssl_util.h" |
| 23 #include "crypto/sha2.h" | 25 #include "crypto/sha2.h" |
| 24 #include "net/base/host_port_pair.h" | 26 #include "net/base/host_port_pair.h" |
| 25 #include "net/base/net_errors.h" | 27 #include "net/base/net_errors.h" |
| (...skipping 1838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1864 EXPECT_EQ(kExpectStapleStaticHostname, expect_staple_state.domain); | 1866 EXPECT_EQ(kExpectStapleStaticHostname, expect_staple_state.domain); |
| 1865 EXPECT_EQ(GURL(kExpectStapleStaticReportURI), expect_staple_state.report_uri); | 1867 EXPECT_EQ(GURL(kExpectStapleStaticReportURI), expect_staple_state.report_uri); |
| 1866 EXPECT_FALSE(expect_staple_state.include_subdomains); | 1868 EXPECT_FALSE(expect_staple_state.include_subdomains); |
| 1867 EXPECT_FALSE(GetExpectStapleState(&state, "pinning-test.badssl.com", | 1869 EXPECT_FALSE(GetExpectStapleState(&state, "pinning-test.badssl.com", |
| 1868 &expect_staple_state)); | 1870 &expect_staple_state)); |
| 1869 std::string subdomain = "subdomain."; | 1871 std::string subdomain = "subdomain."; |
| 1870 subdomain += kExpectStapleStaticHostname; | 1872 subdomain += kExpectStapleStaticHostname; |
| 1871 EXPECT_FALSE(GetExpectStapleState(&state, subdomain, &expect_staple_state)); | 1873 EXPECT_FALSE(GetExpectStapleState(&state, subdomain, &expect_staple_state)); |
| 1872 } | 1874 } |
| 1873 | 1875 |
| 1876 // Tests that all static (preloaded) entries are read correctly. When this |
| 1877 // tests fails, the generation process probably broke. |
| 1878 TEST_F(TransportSecurityStateTest, PreloadedStateBulk) { |
| 1879 struct Pinset { |
| 1880 std::string report_uri; |
| 1881 uint8_t good_spki_hashes = 0; |
| 1882 uint8_t bad_spki_hashes = 0; |
| 1883 }; |
| 1884 TransportSecurityState state; |
| 1885 TransportSecurityStateTest::EnableStaticPins(&state); |
| 1886 TransportSecurityStateTest::EnableStaticExpectCT(&state); |
| 1887 base::ThreadRestrictions::SetIOAllowed(true); |
| 1888 base::FilePath json_path; |
| 1889 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &json_path)); |
| 1890 json_path = json_path.AppendASCII("net"); |
| 1891 json_path = json_path.AppendASCII("http"); |
| 1892 json_path = json_path.AppendASCII("transport_security_state_static.json"); |
| 1893 std::string json_input; |
| 1894 ASSERT_TRUE(base::ReadFileToString(json_path, &json_input)); |
| 1895 base::ThreadRestrictions::SetIOAllowed(false); |
| 1896 std::unique_ptr<base::Value> value(base::JSONReader::Read(json_input)); |
| 1897 ASSERT_TRUE(value.get()); |
| 1898 base::DictionaryValue* dict_value = nullptr; |
| 1899 ASSERT_TRUE(value->GetAsDictionary(&dict_value)); |
| 1900 // Parse the Pinsets in the JSON file to compare them to |state| later. |
| 1901 std::map<std::string, Pinset> pinsets; |
| 1902 const base::ListValue* preloaded_pinsets = nullptr; |
| 1903 ASSERT_TRUE(dict_value->GetList("pinsets", &preloaded_pinsets)); |
| 1904 for (size_t i = 0; i < preloaded_pinsets->GetSize(); ++i) { |
| 1905 const base::DictionaryValue* parsed = nullptr; |
| 1906 ASSERT_TRUE(preloaded_pinsets->GetDictionary(i, &parsed)); |
| 1907 std::string name; |
| 1908 ASSERT_TRUE(parsed->GetString("name", &name)); |
| 1909 Pinset pinset; |
| 1910 std::string report_uri; |
| 1911 parsed->GetString("report_uri", &pinset.report_uri); |
| 1912 const base::ListValue* static_hashes_list = nullptr; |
| 1913 if (parsed->GetList("static_spki_hashes", &static_hashes_list)) { |
| 1914 pinset.good_spki_hashes = static_hashes_list->GetSize(); |
| 1915 } |
| 1916 const base::ListValue* bad_static_hashes_list = nullptr; |
| 1917 if (parsed->GetList("bad_static_spki_hashes", &bad_static_hashes_list)) { |
| 1918 pinset.bad_spki_hashes = bad_static_hashes_list->GetSize(); |
| 1919 } |
| 1920 pinsets.insert(std::pair<std::string, Pinset>(name, pinset)); |
| 1921 } |
| 1922 const base::ListValue* preloaded_entries = nullptr; |
| 1923 ASSERT_TRUE(dict_value->GetList("entries", &preloaded_entries)); |
| 1924 for (size_t i = 0; i < preloaded_entries->GetSize(); ++i) { |
| 1925 const base::DictionaryValue* parsed = nullptr; |
| 1926 ASSERT_TRUE(preloaded_entries->GetDictionary(i, &parsed)); |
| 1927 std::string hostname; |
| 1928 ASSERT_TRUE(parsed->GetString("name", &hostname)); |
| 1929 // Check that the entry exists in |state|. |
| 1930 TransportSecurityState::STSState sts_state; |
| 1931 TransportSecurityState::PKPState pkp_state; |
| 1932 ASSERT_TRUE(GetStaticDomainState(&state, hostname, &sts_state, &pkp_state)); |
| 1933 // Check if |state| matches the HSTS state in the JSON file. |
| 1934 bool include_subdomains = false; |
| 1935 parsed->GetBoolean("include_subdomains", &include_subdomains); |
| 1936 EXPECT_EQ(include_subdomains, sts_state.include_subdomains); |
| 1937 std::string mode; |
| 1938 parsed->GetString("mode", &mode); |
| 1939 TransportSecurityState::STSState::UpgradeMode expected_mode = |
| 1940 TransportSecurityState::STSState::MODE_DEFAULT; |
| 1941 if (mode == "force-https") { |
| 1942 expected_mode = TransportSecurityState::STSState::MODE_FORCE_HTTPS; |
| 1943 } |
| 1944 ASSERT_EQ(expected_mode, sts_state.upgrade_mode); |
| 1945 // Check if |state| matches the HPKP state in the JSON file. |
| 1946 bool hpkp_include_subdomains = false; |
| 1947 parsed->GetBoolean("include_subdomains_for_pinning", |
| 1948 &hpkp_include_subdomains); |
| 1949 ASSERT_EQ(hpkp_include_subdomains, |
| 1950 !include_subdomains && pkp_state.include_subdomains); |
| 1951 std::string pinset; |
| 1952 parsed->GetString("pins", &pinset); |
| 1953 ASSERT_EQ(!pinset.empty(), pkp_state.HasPublicKeyPins()); |
| 1954 // If the entry is associated with a pinset, check if the pinset matches |
| 1955 // the data in the JSON file. |
| 1956 // Note: This doesn't check the actual pins, only |report_uri| and the |
| 1957 // counts. |
| 1958 if (!pinset.empty()) { |
| 1959 const std::map<std::string, Pinset>::iterator it = pinsets.find(pinset); |
| 1960 ASSERT_NE(it, pinsets.cend()); |
| 1961 ASSERT_EQ(it->second.report_uri, pkp_state.report_uri.spec()); |
| 1962 ASSERT_EQ(it->second.good_spki_hashes, pkp_state.spki_hashes.size()); |
| 1963 ASSERT_EQ(it->second.good_spki_hashes, pkp_state.spki_hashes.size()); |
| 1964 } |
| 1965 // Check if |state| matches the Expect-CT state in the JSON file. |
| 1966 TransportSecurityState::ExpectCTState ct_state; |
| 1967 bool has_expect_ct = GetExpectCTState(&state, hostname, &ct_state); |
| 1968 bool expect_ct = false; |
| 1969 parsed->GetBoolean("expect_ct", &expect_ct); |
| 1970 ASSERT_EQ(expect_ct, has_expect_ct); |
| 1971 if (has_expect_ct) { |
| 1972 std::string expect_ct_report_uri; |
| 1973 parsed->GetString("expect_ct_report_uri", &expect_ct_report_uri); |
| 1974 ASSERT_EQ(expect_ct_report_uri, ct_state.report_uri.spec()); |
| 1975 } |
| 1976 // Check if |state| matches the Expect-Staple state in the JSON file. |
| 1977 TransportSecurityState::ExpectStapleState staple_state; |
| 1978 bool has_expect_staple = |
| 1979 GetExpectStapleState(&state, hostname, &staple_state); |
| 1980 if (has_expect_staple) { |
| 1981 std::string expect_staple_report_uri; |
| 1982 parsed->GetString("expect_staple_report_uri", &expect_staple_report_uri); |
| 1983 ASSERT_EQ(expect_staple_report_uri, staple_state.report_uri.spec()); |
| 1984 bool expect_staple_include_subdomains = false; |
| 1985 parsed->GetBoolean("include_subdomains_for_expect_staple", |
| 1986 &expect_staple_include_subdomains); |
| 1987 EXPECT_EQ(expect_staple_include_subdomains, |
| 1988 staple_state.include_subdomains); |
| 1989 } |
| 1990 } |
| 1991 } |
| 1992 |
| 1874 TEST_F(TransportSecurityStateTest, PreloadedExpectStapleIncludeSubdomains) { | 1993 TEST_F(TransportSecurityStateTest, PreloadedExpectStapleIncludeSubdomains) { |
| 1875 TransportSecurityState state; | 1994 TransportSecurityState state; |
| 1876 TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true); | 1995 TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true); |
| 1877 TransportSecurityState::ExpectStapleState expect_staple_state; | 1996 TransportSecurityState::ExpectStapleState expect_staple_state; |
| 1878 std::string subdomain = "subdomain."; | 1997 std::string subdomain = "subdomain."; |
| 1879 subdomain += kExpectStapleStaticIncludeSubdomainsHostname; | 1998 subdomain += kExpectStapleStaticIncludeSubdomainsHostname; |
| 1880 EXPECT_TRUE(GetExpectStapleState(&state, subdomain, &expect_staple_state)); | 1999 EXPECT_TRUE(GetExpectStapleState(&state, subdomain, &expect_staple_state)); |
| 1881 EXPECT_EQ(kExpectStapleStaticIncludeSubdomainsHostname, | 2000 EXPECT_EQ(kExpectStapleStaticIncludeSubdomainsHostname, |
| 1882 expect_staple_state.domain); | 2001 expect_staple_state.domain); |
| 1883 EXPECT_TRUE(expect_staple_state.include_subdomains); | 2002 EXPECT_TRUE(expect_staple_state.include_subdomains); |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2332 base::FieldTrialList::CreateFieldTrial("EnforceCTForProblematicRoots", | 2451 base::FieldTrialList::CreateFieldTrial("EnforceCTForProblematicRoots", |
| 2333 "disabled"); | 2452 "disabled"); |
| 2334 | 2453 |
| 2335 EXPECT_FALSE( | 2454 EXPECT_FALSE( |
| 2336 state.ShouldRequireCT("www.example.com", before_cert.get(), hashes)); | 2455 state.ShouldRequireCT("www.example.com", before_cert.get(), hashes)); |
| 2337 EXPECT_FALSE( | 2456 EXPECT_FALSE( |
| 2338 state.ShouldRequireCT("www.example.com", after_cert.get(), hashes)); | 2457 state.ShouldRequireCT("www.example.com", after_cert.get(), hashes)); |
| 2339 } | 2458 } |
| 2340 | 2459 |
| 2341 } // namespace net | 2460 } // namespace net |
| OLD | NEW |