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

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

Issue 9415040: Refactor TransportSecurityState. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « net/base/transport_security_state.cc ('k') | net/base/x509_cert_types.h » ('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/base/transport_security_state.h" 5 #include "net/base/transport_security_state.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
(...skipping 25 matching lines...) Expand all
36 virtual void SetUp() { 36 virtual void SetUp() {
37 #if defined(USE_OPENSSL) 37 #if defined(USE_OPENSSL)
38 crypto::EnsureOpenSSLInit(); 38 crypto::EnsureOpenSSLInit();
39 #else 39 #else
40 crypto::EnsureNSSInit(); 40 crypto::EnsureNSSInit();
41 #endif 41 #endif
42 } 42 }
43 }; 43 };
44 44
45 TEST_F(TransportSecurityStateTest, BogusHeaders) { 45 TEST_F(TransportSecurityStateTest, BogusHeaders) {
46 int max_age = 42; 46 TransportSecurityState::DomainState state;
47 bool include_subdomains = false; 47 base::Time now = base::Time::Now();
48 48
49 EXPECT_FALSE(TransportSecurityState::ParseHeader( 49 EXPECT_FALSE(state.ParseSTSHeader(now, ""));
50 "", &max_age, &include_subdomains)); 50 EXPECT_FALSE(state.ParseSTSHeader(now, " "));
51 EXPECT_FALSE(TransportSecurityState::ParseHeader( 51 EXPECT_FALSE(state.ParseSTSHeader(now, "abc"));
52 " ", &max_age, &include_subdomains)); 52 EXPECT_FALSE(state.ParseSTSHeader(now, " abc"));
53 EXPECT_FALSE(TransportSecurityState::ParseHeader( 53 EXPECT_FALSE(state.ParseSTSHeader(now, " abc "));
54 "abc", &max_age, &include_subdomains)); 54 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age"));
55 EXPECT_FALSE(TransportSecurityState::ParseHeader( 55 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age"));
56 " abc", &max_age, &include_subdomains)); 56 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age "));
57 EXPECT_FALSE(TransportSecurityState::ParseHeader( 57 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age="));
58 " abc ", &max_age, &include_subdomains)); 58 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age="));
59 EXPECT_FALSE(TransportSecurityState::ParseHeader( 59 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age ="));
60 "max-age", &max_age, &include_subdomains)); 60 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age= "));
61 EXPECT_FALSE(TransportSecurityState::ParseHeader( 61 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age = "));
62 " max-age", &max_age, &include_subdomains)); 62 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age = xy"));
63 EXPECT_FALSE(TransportSecurityState::ParseHeader( 63 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age = 3488a923"));
64 " max-age ", &max_age, &include_subdomains)); 64 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488a923 "));
65 EXPECT_FALSE(TransportSecurityState::ParseHeader( 65 EXPECT_FALSE(state.ParseSTSHeader(now, "max-ag=3488923"));
66 "max-age=", &max_age, &include_subdomains)); 66 EXPECT_FALSE(state.ParseSTSHeader(now, "max-aged=3488923"));
67 EXPECT_FALSE(TransportSecurityState::ParseHeader( 67 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age==3488923"));
68 " max-age=", &max_age, &include_subdomains)); 68 EXPECT_FALSE(state.ParseSTSHeader(now, "amax-age=3488923"));
69 EXPECT_FALSE(TransportSecurityState::ParseHeader( 69 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=-3488923"));
70 " max-age =", &max_age, &include_subdomains)); 70 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923;"));
71 EXPECT_FALSE(TransportSecurityState::ParseHeader( 71 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923 e"));
72 " max-age= ", &max_age, &include_subdomains)); 72 EXPECT_FALSE(state.ParseSTSHeader(
73 EXPECT_FALSE(TransportSecurityState::ParseHeader( 73 now, "max-age=3488923 includesubdomain"));
74 " max-age = ", &max_age, &include_subdomains)); 74 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923includesubdomains"));
75 EXPECT_FALSE(TransportSecurityState::ParseHeader( 75 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923=includesubdomains"));
76 " max-age = xy", &max_age, &include_subdomains)); 76 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923 includesubdomainx"));
77 EXPECT_FALSE(TransportSecurityState::ParseHeader( 77 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923 includesubdomain="));
78 " max-age = 3488a923", &max_age, &include_subdomains)); 78 EXPECT_FALSE(state.ParseSTSHeader(
79 EXPECT_FALSE(TransportSecurityState::ParseHeader( 79 now, "max-age=3488923 includesubdomain=true"));
80 "max-age=3488a923 ", &max_age, &include_subdomains)); 80 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923 includesubdomainsx"));
81 EXPECT_FALSE(TransportSecurityState::ParseHeader( 81 EXPECT_FALSE(state.ParseSTSHeader(
82 "max-ag=3488923", &max_age, &include_subdomains)); 82 now, "max-age=3488923 includesubdomains x"));
83 EXPECT_FALSE(TransportSecurityState::ParseHeader( 83 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=34889.23 includesubdomains"));
84 "max-aged=3488923", &max_age, &include_subdomains)); 84 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=34889 includesubdomains"));
85 EXPECT_FALSE(TransportSecurityState::ParseHeader(
86 "max-age==3488923", &max_age, &include_subdomains));
87 EXPECT_FALSE(TransportSecurityState::ParseHeader(
88 "amax-age=3488923", &max_age, &include_subdomains));
89 EXPECT_FALSE(TransportSecurityState::ParseHeader(
90 "max-age=-3488923", &max_age, &include_subdomains));
91 EXPECT_FALSE(TransportSecurityState::ParseHeader(
92 "max-age=3488923;", &max_age, &include_subdomains));
93 EXPECT_FALSE(TransportSecurityState::ParseHeader(
94 "max-age=3488923 e", &max_age, &include_subdomains));
95 EXPECT_FALSE(TransportSecurityState::ParseHeader(
96 "max-age=3488923 includesubdomain", &max_age, &include_subdomains));
97 EXPECT_FALSE(TransportSecurityState::ParseHeader(
98 "max-age=3488923includesubdomains", &max_age, &include_subdomains));
99 EXPECT_FALSE(TransportSecurityState::ParseHeader(
100 "max-age=3488923=includesubdomains", &max_age, &include_subdomains));
101 EXPECT_FALSE(TransportSecurityState::ParseHeader(
102 "max-age=3488923 includesubdomainx", &max_age, &include_subdomains));
103 EXPECT_FALSE(TransportSecurityState::ParseHeader(
104 "max-age=3488923 includesubdomain=", &max_age, &include_subdomains));
105 EXPECT_FALSE(TransportSecurityState::ParseHeader(
106 "max-age=3488923 includesubdomain=true", &max_age, &include_subdomains));
107 EXPECT_FALSE(TransportSecurityState::ParseHeader(
108 "max-age=3488923 includesubdomainsx", &max_age, &include_subdomains));
109 EXPECT_FALSE(TransportSecurityState::ParseHeader(
110 "max-age=3488923 includesubdomains x", &max_age, &include_subdomains));
111 EXPECT_FALSE(TransportSecurityState::ParseHeader(
112 "max-age=34889.23 includesubdomains", &max_age, &include_subdomains));
113 EXPECT_FALSE(TransportSecurityState::ParseHeader(
114 "max-age=34889 includesubdomains", &max_age, &include_subdomains));
115 85
116 EXPECT_EQ(max_age, 42); 86 // Check that |state| was not updated by expecting the default
117 EXPECT_FALSE(include_subdomains); 87 // values for its predictable fields.
88 EXPECT_EQ(state.upgrade_mode,
89 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
90 EXPECT_FALSE(state.include_subdomains);
91 }
92
93 static bool GetPublicKeyHash(const net::X509Certificate::OSCertHandle& cert,
94 SHA1Fingerprint* fingerprint) {
95 std::string der_bytes;
96 if (!net::X509Certificate::GetDEREncoded(cert, &der_bytes))
97 return false;
98
99 base::StringPiece spki;
100 if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki))
101 return false;
102
103 base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(spki.data()),
104 spki.size(), fingerprint->data);
105 return true;
118 } 106 }
119 107
120 static std::string GetPinFromCert(X509Certificate* cert) { 108 static std::string GetPinFromCert(X509Certificate* cert) {
121 SHA1Fingerprint spki_hash; 109 SHA1Fingerprint spki_hash;
122 if (!TransportSecurityState::GetPublicKeyHash(*cert, &spki_hash)) 110 EXPECT_TRUE(GetPublicKeyHash(cert->os_cert_handle(), &spki_hash));
123 return ""; 111
124 std::string base64; 112 std::string base64;
125 base::Base64Encode(base::StringPiece(reinterpret_cast<char*>(spki_hash.data), 113 base::Base64Encode(base::StringPiece(reinterpret_cast<char*>(spki_hash.data),
126 sizeof(spki_hash.data)), 114 sizeof(spki_hash.data)),
127 &base64); 115 &base64);
128 return "pin-sha1=" + HttpUtil::Quote(base64); 116 return "pin-sha1=" + HttpUtil::Quote(base64);
129 } 117 }
130 118
131 TEST_F(TransportSecurityStateTest, BogusPinsHeaders) { 119 TEST_F(TransportSecurityStateTest, BogusPinsHeaders) {
132 TransportSecurityState::DomainState state; 120 TransportSecurityState::DomainState state;
133 state.max_age = 42;
134 SSLInfo ssl_info; 121 SSLInfo ssl_info;
135 ssl_info.cert = 122 ssl_info.cert =
136 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem"); 123 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
137 std::string good_pin = GetPinFromCert(ssl_info.cert); 124 std::string good_pin = GetPinFromCert(ssl_info.cert);
125 base::Time now = base::Time::Now();
138 126
139 // The backup pin is fake --- it just has to not be in the chain. 127 // The backup pin is fake --- it just has to not be in the chain.
140 std::string backup_pin = "pin-sha1=" + 128 std::string backup_pin = "pin-sha1=" +
141 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); 129 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g=");
142 130
143 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 131 EXPECT_FALSE(state.ParsePinsHeader(now, "", ssl_info));
144 "", ssl_info, &state)); 132 EXPECT_FALSE(state.ParsePinsHeader(now, " ", ssl_info));
145 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 133 EXPECT_FALSE(state.ParsePinsHeader(now, "abc", ssl_info));
146 " ", ssl_info, &state)); 134 EXPECT_FALSE(state.ParsePinsHeader(now, " abc", ssl_info));
147 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 135 EXPECT_FALSE(state.ParsePinsHeader(now, " abc ", ssl_info));
148 "abc", ssl_info, &state)); 136 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age", ssl_info));
149 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 137 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age", ssl_info));
150 " abc", ssl_info, &state)); 138 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age ", ssl_info));
151 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 139 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=", ssl_info));
152 " abc ", ssl_info, &state)); 140 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age=", ssl_info));
153 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 141 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age =", ssl_info));
154 "max-age", ssl_info, &state)); 142 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age= ", ssl_info));
155 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 143 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age = ", ssl_info));
156 " max-age", ssl_info, &state)); 144 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age = xy", ssl_info));
157 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 145 EXPECT_FALSE(state.ParsePinsHeader(
158 " max-age ", ssl_info, &state)); 146 now,
159 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 147 " max-age = 3488a923",
160 "max-age=", ssl_info, &state)); 148 ssl_info));
161 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 149 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=3488a923 ", ssl_info));
162 " max-age=", ssl_info, &state)); 150 EXPECT_FALSE(state.ParsePinsHeader(now,
163 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader(
164 " max-age =", ssl_info, &state));
165 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader(
166 " max-age= ", ssl_info, &state));
167 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader(
168 " max-age = ", ssl_info, &state));
169 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader(
170 " max-age = xy", ssl_info, &state));
171 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader(
172 " max-age = 3488a923", ssl_info, &state));
173 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader(
174 "max-age=3488a923 ", ssl_info, &state));
175 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader(
176 "max-ag=3488923pins=" + good_pin + "," + backup_pin, 151 "max-ag=3488923pins=" + good_pin + "," + backup_pin,
177 ssl_info, &state)); 152 ssl_info));
178 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 153 EXPECT_FALSE(state.ParsePinsHeader(now, "max-aged=3488923" + backup_pin,
179 "max-aged=3488923" + backup_pin, 154 ssl_info));
180 ssl_info, &state)); 155 EXPECT_FALSE(state.ParsePinsHeader(now, "max-aged=3488923; " + backup_pin,
181 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 156 ssl_info));
182 "max-aged=3488923; " + backup_pin, 157 EXPECT_FALSE(state.ParsePinsHeader(now,
183 ssl_info, &state));
184 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader(
185 "max-aged=3488923; " + backup_pin + ";" + backup_pin, 158 "max-aged=3488923; " + backup_pin + ";" + backup_pin,
186 ssl_info, &state)); 159 ssl_info));
187 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 160 EXPECT_FALSE(state.ParsePinsHeader(now,
188 "max-aged=3488923; " + good_pin + ";" + good_pin, 161 "max-aged=3488923; " + good_pin + ";" + good_pin,
189 ssl_info, &state)); 162 ssl_info));
190 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 163 EXPECT_FALSE(state.ParsePinsHeader(now, "max-aged=3488923; " + good_pin,
191 "max-aged=3488923; " + good_pin, 164 ssl_info));
192 ssl_info, &state)); 165 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age==3488923", ssl_info));
193 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 166 EXPECT_FALSE(state.ParsePinsHeader(now, "amax-age=3488923", ssl_info));
194 "max-age==3488923", ssl_info, &state)); 167 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=-3488923", ssl_info));
195 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 168 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=3488923;", ssl_info));
196 "amax-age=3488923", ssl_info, &state)); 169 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=3488923 e", ssl_info));
197 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 170 EXPECT_FALSE(state.ParsePinsHeader(
198 "max-age=-3488923", ssl_info, &state)); 171 now,
199 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 172 "max-age=3488923 includesubdomain",
200 "max-age=3488923;", ssl_info, &state)); 173 ssl_info));
201 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( 174 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=34889.23", ssl_info));
202 "max-age=3488923 e", ssl_info, &state));
203 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader(
204 "max-age=3488923 includesubdomain", ssl_info, &state));
205 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader(
206 "max-age=34889.23", ssl_info, &state));
207 175
208 EXPECT_EQ(state.max_age, 42); 176 // Check that |state| was not updated by expecting the default
177 // values for its predictable fields.
178 EXPECT_EQ(state.upgrade_mode,
179 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
180 EXPECT_FALSE(state.include_subdomains);
209 } 181 }
210 182
211 TEST_F(TransportSecurityStateTest, ValidHeaders) { 183 TEST_F(TransportSecurityStateTest, ValidSTSHeaders) {
212 int max_age = 42; 184 TransportSecurityState::DomainState state;
213 bool include_subdomains = true; 185 base::Time expiry;
186 base::Time now = base::Time::Now();
214 187
215 EXPECT_TRUE(TransportSecurityState::ParseHeader( 188 EXPECT_TRUE(state.ParseSTSHeader(now, "max-age=243"));
216 "max-age=243", &max_age, &include_subdomains)); 189 expiry = now + base::TimeDelta::FromSeconds(243);
217 EXPECT_EQ(max_age, 243); 190 EXPECT_EQ(expiry, state.upgrade_expiry);
218 EXPECT_FALSE(include_subdomains); 191 EXPECT_FALSE(state.include_subdomains);
219 192
220 EXPECT_TRUE(TransportSecurityState::ParseHeader( 193 EXPECT_TRUE(state.ParseSTSHeader(now, " Max-agE = 567"));
221 " Max-agE = 567", &max_age, &include_subdomains)); 194 expiry = now + base::TimeDelta::FromSeconds(567);
222 EXPECT_EQ(max_age, 567); 195 EXPECT_EQ(expiry, state.upgrade_expiry);
223 EXPECT_FALSE(include_subdomains); 196 EXPECT_FALSE(state.include_subdomains);
224 197
225 EXPECT_TRUE(TransportSecurityState::ParseHeader( 198 EXPECT_TRUE(state.ParseSTSHeader(now, " mAx-aGe = 890 "));
226 " mAx-aGe = 890 ", &max_age, &include_subdomains)); 199 expiry = now + base::TimeDelta::FromSeconds(890);
227 EXPECT_EQ(max_age, 890); 200 EXPECT_EQ(expiry, state.upgrade_expiry);
228 EXPECT_FALSE(include_subdomains); 201 EXPECT_FALSE(state.include_subdomains);
229 202
230 EXPECT_TRUE(TransportSecurityState::ParseHeader( 203 EXPECT_TRUE(state.ParseSTSHeader(now, "max-age=123;incLudesUbdOmains"));
231 "max-age=123;incLudesUbdOmains", &max_age, &include_subdomains)); 204 expiry = now + base::TimeDelta::FromSeconds(123);
232 EXPECT_EQ(max_age, 123); 205 EXPECT_EQ(expiry, state.upgrade_expiry);
233 EXPECT_TRUE(include_subdomains); 206 EXPECT_TRUE(state.include_subdomains);
234 207
235 EXPECT_TRUE(TransportSecurityState::ParseHeader( 208 EXPECT_TRUE(state.ParseSTSHeader(now, "max-age=394082; incLudesUbdOmains"));
236 "max-age=394082; incLudesUbdOmains", &max_age, &include_subdomains)); 209 expiry = now + base::TimeDelta::FromSeconds(394082);
237 EXPECT_EQ(max_age, 394082); 210 EXPECT_EQ(expiry, state.upgrade_expiry);
238 EXPECT_TRUE(include_subdomains); 211 EXPECT_TRUE(state.include_subdomains);
239 212
240 EXPECT_TRUE(TransportSecurityState::ParseHeader( 213 EXPECT_TRUE(state.ParseSTSHeader(
241 "max-age=39408299 ;incLudesUbdOmains", &max_age, &include_subdomains)); 214 now, "max-age=39408299 ;incLudesUbdOmains"));
242 EXPECT_EQ(max_age, 215 expiry = now + base::TimeDelta::FromSeconds(
243 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 39408299l)); 216 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 39408299l));
244 EXPECT_TRUE(include_subdomains); 217 EXPECT_EQ(expiry, state.upgrade_expiry);
218 EXPECT_TRUE(state.include_subdomains);
245 219
246 EXPECT_TRUE(TransportSecurityState::ParseHeader( 220 EXPECT_TRUE(state.ParseSTSHeader(
247 "max-age=394082038 ; incLudesUbdOmains", &max_age, 221 now, "max-age=394082038 ; incLudesUbdOmains"));
248 &include_subdomains)); 222 expiry = now + base::TimeDelta::FromSeconds(
249 EXPECT_EQ(max_age, 223 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 394082038l));
250 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 394082038l)); 224 EXPECT_EQ(expiry, state.upgrade_expiry);
251 EXPECT_TRUE(include_subdomains); 225 EXPECT_TRUE(state.include_subdomains);
252 226
253 EXPECT_TRUE(TransportSecurityState::ParseHeader( 227 EXPECT_TRUE(state.ParseSTSHeader(
254 " max-age=0 ; incLudesUbdOmains ", &max_age, &include_subdomains)); 228 now, " max-age=0 ; incLudesUbdOmains "));
255 EXPECT_EQ(max_age, 0); 229 expiry = now + base::TimeDelta::FromSeconds(0);
256 EXPECT_TRUE(include_subdomains); 230 EXPECT_EQ(expiry, state.upgrade_expiry);
231 EXPECT_TRUE(state.include_subdomains);
257 232
258 EXPECT_TRUE(TransportSecurityState::ParseHeader( 233 EXPECT_TRUE(state.ParseSTSHeader(
234 now,
259 " max-age=999999999999999999999999999999999999999999999 ;" 235 " max-age=999999999999999999999999999999999999999999999 ;"
260 " incLudesUbdOmains ", 236 " incLudesUbdOmains "));
261 &max_age, &include_subdomains)); 237 expiry = now + base::TimeDelta::FromSeconds(
262 EXPECT_EQ(max_age, TransportSecurityState::kMaxHSTSAgeSecs); 238 TransportSecurityState::kMaxHSTSAgeSecs);
263 EXPECT_TRUE(include_subdomains); 239 EXPECT_EQ(expiry, state.upgrade_expiry);
240 EXPECT_TRUE(state.include_subdomains);
264 } 241 }
265 242
266 TEST_F(TransportSecurityStateTest, ValidPinsHeaders) { 243 TEST_F(TransportSecurityStateTest, ValidPinsHeaders) {
267 TransportSecurityState::DomainState state; 244 TransportSecurityState::DomainState state;
268 state.max_age = 42; 245 base::Time expiry;
246 base::Time now = base::Time::Now();
269 247
270 // Set up a realistic SSLInfo with a realistic cert chain. 248 // Set up a realistic SSLInfo with a realistic cert chain.
271 FilePath certs_dir = GetTestCertsDirectory(); 249 FilePath certs_dir = GetTestCertsDirectory();
272 scoped_refptr<X509Certificate> ee_cert = 250 scoped_refptr<X509Certificate> ee_cert =
273 ImportCertFromFile(certs_dir, "2048-rsa-ee-by-2048-rsa-intermediate.pem"); 251 ImportCertFromFile(certs_dir, "2048-rsa-ee-by-2048-rsa-intermediate.pem");
274 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); 252 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert);
275 scoped_refptr<X509Certificate> intermediate = 253 scoped_refptr<X509Certificate> intermediate =
276 ImportCertFromFile(certs_dir, "2048-rsa-intermediate.pem"); 254 ImportCertFromFile(certs_dir, "2048-rsa-intermediate.pem");
277 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate); 255 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate);
278 X509Certificate::OSCertHandles intermediates; 256 X509Certificate::OSCertHandles intermediates;
(...skipping 23 matching lines...) Expand all
302 // Normally, ssl_client_socket_nss would do this, but for a unit test we 280 // Normally, ssl_client_socket_nss would do this, but for a unit test we
303 // fake it. 281 // fake it.
304 ssl_info.public_key_hashes = result.public_key_hashes; 282 ssl_info.public_key_hashes = result.public_key_hashes;
305 std::string good_pin = GetPinFromCert(ssl_info.cert); 283 std::string good_pin = GetPinFromCert(ssl_info.cert);
306 284
307 // The backup pin is fake --- we just need an SPKI hash that does not match 285 // The backup pin is fake --- we just need an SPKI hash that does not match
308 // the hash of any SPKI in the certificate chain. 286 // the hash of any SPKI in the certificate chain.
309 std::string backup_pin = "pin-sha1=" + 287 std::string backup_pin = "pin-sha1=" +
310 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); 288 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g=");
311 289
312 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( 290 EXPECT_TRUE(state.ParsePinsHeader(
291 now,
313 "max-age=243; " + good_pin + ";" + backup_pin, 292 "max-age=243; " + good_pin + ";" + backup_pin,
314 ssl_info, &state)); 293 ssl_info));
315 EXPECT_EQ(state.max_age, 243); 294 expiry = now + base::TimeDelta::FromSeconds(243);
295 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry);
316 296
317 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( 297 EXPECT_TRUE(state.ParsePinsHeader(
298 now,
318 " " + good_pin + "; " + backup_pin + " ; Max-agE = 567", 299 " " + good_pin + "; " + backup_pin + " ; Max-agE = 567",
319 ssl_info, &state)); 300 ssl_info));
320 EXPECT_EQ(state.max_age, 567); 301 expiry = now + base::TimeDelta::FromSeconds(567);
302 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry);
321 303
322 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( 304 EXPECT_TRUE(state.ParsePinsHeader(
305 now,
323 good_pin + ";" + backup_pin + " ; mAx-aGe = 890 ", 306 good_pin + ";" + backup_pin + " ; mAx-aGe = 890 ",
324 ssl_info, &state)); 307 ssl_info));
325 EXPECT_EQ(state.max_age, 890); 308 expiry = now + base::TimeDelta::FromSeconds(890);
309 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry);
326 310
327 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( 311 EXPECT_TRUE(state.ParsePinsHeader(
312 now,
328 good_pin + ";" + backup_pin + "; max-age=123;IGNORED;", 313 good_pin + ";" + backup_pin + "; max-age=123;IGNORED;",
329 ssl_info, &state)); 314 ssl_info));
330 EXPECT_EQ(state.max_age, 123); 315 expiry = now + base::TimeDelta::FromSeconds(123);
316 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry);
331 317
332 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( 318 EXPECT_TRUE(state.ParsePinsHeader(
319 now,
333 "max-age=394082;" + backup_pin + ";" + good_pin + "; ", 320 "max-age=394082;" + backup_pin + ";" + good_pin + "; ",
334 ssl_info, &state)); 321 ssl_info));
335 EXPECT_EQ(state.max_age, 394082); 322 expiry = now + base::TimeDelta::FromSeconds(394082);
323 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry);
336 324
337 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( 325 EXPECT_TRUE(state.ParsePinsHeader(
326 now,
338 "max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ", 327 "max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ",
339 ssl_info, &state)); 328 ssl_info));
340 EXPECT_EQ(state.max_age, 329 expiry = now + base::TimeDelta::FromSeconds(
341 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 39408299l)); 330 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 39408299l));
331 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry);
342 332
343 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( 333 EXPECT_TRUE(state.ParsePinsHeader(
334 now,
344 "max-age=39408038 ; cybers=39408038 ; " + 335 "max-age=39408038 ; cybers=39408038 ; " +
345 good_pin + ";" + backup_pin + "; ", 336 good_pin + ";" + backup_pin + "; ",
346 ssl_info, &state)); 337 ssl_info));
347 EXPECT_EQ(state.max_age, 338 expiry = now + base::TimeDelta::FromSeconds(
348 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 394082038l)); 339 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 394082038l));
340 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry);
349 341
350 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( 342 EXPECT_TRUE(state.ParsePinsHeader(
343 now,
351 " max-age=0 ; " + good_pin + ";" + backup_pin, 344 " max-age=0 ; " + good_pin + ";" + backup_pin,
352 ssl_info, &state)); 345 ssl_info));
353 EXPECT_EQ(state.max_age, 0); 346 expiry = now + base::TimeDelta::FromSeconds(0);
347 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry);
354 348
355 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( 349 EXPECT_TRUE(state.ParsePinsHeader(
350 now,
356 " max-age=999999999999999999999999999999999999999999999 ; " + 351 " max-age=999999999999999999999999999999999999999999999 ; " +
357 backup_pin + ";" + good_pin + "; ", 352 backup_pin + ";" + good_pin + "; ",
358 ssl_info, &state)); 353 ssl_info));
359 EXPECT_EQ(state.max_age, TransportSecurityState::kMaxHSTSAgeSecs); 354 expiry = now +
355 base::TimeDelta::FromSeconds(TransportSecurityState::kMaxHSTSAgeSecs);
356 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry);
360 } 357 }
361 358
362 TEST_F(TransportSecurityStateTest, SimpleMatches) { 359 TEST_F(TransportSecurityStateTest, SimpleMatches) {
363 TransportSecurityState state(""); 360 TransportSecurityState state;
364 TransportSecurityState::DomainState domain_state; 361 TransportSecurityState::DomainState domain_state;
365 const base::Time current_time(base::Time::Now()); 362 const base::Time current_time(base::Time::Now());
366 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 363 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
367 364
368 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); 365 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
369 domain_state.expiry = expiry; 366 domain_state.upgrade_expiry = expiry;
370 state.EnableHost("yahoo.com", domain_state); 367 state.EnableHost("yahoo.com", domain_state);
371 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); 368 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
372 } 369 }
373 370
374 TEST_F(TransportSecurityStateTest, MatchesCase1) { 371 TEST_F(TransportSecurityStateTest, MatchesCase1) {
375 TransportSecurityState state(""); 372 TransportSecurityState state;
376 TransportSecurityState::DomainState domain_state; 373 TransportSecurityState::DomainState domain_state;
377 const base::Time current_time(base::Time::Now()); 374 const base::Time current_time(base::Time::Now());
378 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 375 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
379 376
380 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); 377 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
381 domain_state.expiry = expiry; 378 domain_state.upgrade_expiry = expiry;
382 state.EnableHost("YAhoo.coM", domain_state); 379 state.EnableHost("YAhoo.coM", domain_state);
383 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); 380 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
384 } 381 }
385 382
386 TEST_F(TransportSecurityStateTest, MatchesCase2) { 383 TEST_F(TransportSecurityStateTest, MatchesCase2) {
387 TransportSecurityState state(""); 384 TransportSecurityState state;
388 TransportSecurityState::DomainState domain_state; 385 TransportSecurityState::DomainState domain_state;
389 const base::Time current_time(base::Time::Now()); 386 const base::Time current_time(base::Time::Now());
390 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 387 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
391 388
392 EXPECT_FALSE(state.GetDomainState(&domain_state, "YAhoo.coM", true)); 389 EXPECT_FALSE(state.GetDomainState("YAhoo.coM", true, &domain_state));
393 domain_state.expiry = expiry; 390 domain_state.upgrade_expiry = expiry;
394 state.EnableHost("yahoo.com", domain_state); 391 state.EnableHost("yahoo.com", domain_state);
395 EXPECT_TRUE(state.GetDomainState(&domain_state, "YAhoo.coM", true)); 392 EXPECT_TRUE(state.GetDomainState("YAhoo.coM", true, &domain_state));
396 } 393 }
397 394
398 TEST_F(TransportSecurityStateTest, SubdomainMatches) { 395 TEST_F(TransportSecurityStateTest, SubdomainMatches) {
399 TransportSecurityState state(""); 396 TransportSecurityState state;
400 TransportSecurityState::DomainState domain_state; 397 TransportSecurityState::DomainState domain_state;
401 const base::Time current_time(base::Time::Now()); 398 const base::Time current_time(base::Time::Now());
402 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 399 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
403 400
404 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); 401 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
405 domain_state.expiry = expiry; 402 domain_state.upgrade_expiry = expiry;
406 domain_state.include_subdomains = true; 403 domain_state.include_subdomains = true;
407 state.EnableHost("yahoo.com", domain_state); 404 state.EnableHost("yahoo.com", domain_state);
408 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); 405 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
409 EXPECT_TRUE(state.GetDomainState(&domain_state, "foo.yahoo.com", true)); 406 EXPECT_TRUE(state.GetDomainState("foo.yahoo.com", true, &domain_state));
410 EXPECT_TRUE(state.GetDomainState(&domain_state, 407 EXPECT_TRUE(state.GetDomainState("foo.bar.yahoo.com", true, &domain_state));
411 "foo.bar.yahoo.com", 408 EXPECT_TRUE(state.GetDomainState("foo.bar.baz.yahoo.com", true,
412 true)); 409 &domain_state));
413 EXPECT_TRUE(state.GetDomainState(&domain_state, 410 EXPECT_FALSE(state.GetDomainState("com", true, &domain_state));
414 "foo.bar.baz.yahoo.com",
415 true));
416 EXPECT_FALSE(state.GetDomainState(&domain_state, "com", true));
417 }
418
419 TEST_F(TransportSecurityStateTest, Serialise1) {
420 TransportSecurityState state("");
421 std::string output;
422 bool dirty;
423 state.Serialise(&output);
424 EXPECT_TRUE(state.LoadEntries(output, &dirty));
425 EXPECT_FALSE(dirty);
426 }
427
428 TEST_F(TransportSecurityStateTest, Serialise2) {
429 TransportSecurityState state("");
430 TransportSecurityState::DomainState domain_state;
431 const base::Time current_time(base::Time::Now());
432 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
433
434 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true));
435 domain_state.mode = TransportSecurityState::DomainState::MODE_STRICT;
436 domain_state.expiry = expiry;
437 domain_state.include_subdomains = true;
438 state.EnableHost("yahoo.com", domain_state);
439
440 std::string output;
441 bool dirty;
442 state.Serialise(&output);
443 EXPECT_TRUE(state.LoadEntries(output, &dirty));
444
445 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true));
446 EXPECT_EQ(domain_state.mode,
447 TransportSecurityState::DomainState::MODE_STRICT);
448 EXPECT_TRUE(state.GetDomainState(&domain_state, "foo.yahoo.com", true));
449 EXPECT_EQ(domain_state.mode,
450 TransportSecurityState::DomainState::MODE_STRICT);
451 EXPECT_TRUE(state.GetDomainState(&domain_state,
452 "foo.bar.yahoo.com",
453 true));
454 EXPECT_EQ(domain_state.mode,
455 TransportSecurityState::DomainState::MODE_STRICT);
456 EXPECT_TRUE(state.GetDomainState(&domain_state,
457 "foo.bar.baz.yahoo.com",
458 true));
459 EXPECT_EQ(domain_state.mode,
460 TransportSecurityState::DomainState::MODE_STRICT);
461 EXPECT_FALSE(state.GetDomainState(&domain_state, "com", true));
462 } 411 }
463 412
464 TEST_F(TransportSecurityStateTest, DeleteSince) { 413 TEST_F(TransportSecurityStateTest, DeleteSince) {
465 TransportSecurityState state(""); 414 TransportSecurityState state;
466 TransportSecurityState::DomainState domain_state; 415 TransportSecurityState::DomainState domain_state;
467 const base::Time current_time(base::Time::Now()); 416 const base::Time current_time(base::Time::Now());
468 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 417 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
469 const base::Time older = current_time - base::TimeDelta::FromSeconds(1000); 418 const base::Time older = current_time - base::TimeDelta::FromSeconds(1000);
470 419
471 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); 420 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
472 domain_state.mode = TransportSecurityState::DomainState::MODE_STRICT; 421 domain_state.upgrade_mode =
473 domain_state.expiry = expiry; 422 TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
423 domain_state.upgrade_expiry = expiry;
474 state.EnableHost("yahoo.com", domain_state); 424 state.EnableHost("yahoo.com", domain_state);
475 425
476 state.DeleteSince(expiry); 426 state.DeleteSince(expiry);
477 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); 427 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
478 state.DeleteSince(older); 428 state.DeleteSince(older);
479 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); 429 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
480 } 430 }
481 431
482 TEST_F(TransportSecurityStateTest, DeleteHost) { 432 TEST_F(TransportSecurityStateTest, DeleteHost) {
483 TransportSecurityState state(""); 433 TransportSecurityState state;
484 TransportSecurityState::DomainState domain_state; 434 TransportSecurityState::DomainState domain_state;
485 const base::Time current_time(base::Time::Now()); 435 const base::Time current_time(base::Time::Now());
486 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 436 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
487 domain_state.mode = TransportSecurityState::DomainState::MODE_STRICT; 437 domain_state.upgrade_mode =
488 domain_state.expiry = expiry; 438 TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
439 domain_state.upgrade_expiry = expiry;
489 state.EnableHost("yahoo.com", domain_state); 440 state.EnableHost("yahoo.com", domain_state);
490 441
491 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); 442 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
492 EXPECT_FALSE(state.GetDomainState(&domain_state, "example.com", true)); 443 EXPECT_FALSE(state.GetDomainState("example.com", true, &domain_state));
493 EXPECT_TRUE(state.DeleteHost("yahoo.com")); 444 EXPECT_TRUE(state.DeleteHost("yahoo.com"));
494 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); 445 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
495 }
496
497 TEST_F(TransportSecurityStateTest, SerialiseOld) {
498 TransportSecurityState state("");
499 // This is an old-style piece of transport state JSON, which has no creation
500 // date.
501 std::string output =
502 "{ "
503 "\"NiyD+3J1r6z1wjl2n1ALBu94Zj9OsEAMo0kCN8js0Uk=\": {"
504 "\"expiry\": 1266815027.983453, "
505 "\"include_subdomains\": false, "
506 "\"mode\": \"strict\" "
507 "}"
508 "}";
509 bool dirty;
510 EXPECT_TRUE(state.LoadEntries(output, &dirty));
511 EXPECT_TRUE(dirty);
512 } 446 }
513 447
514 TEST_F(TransportSecurityStateTest, IsPreloaded) { 448 TEST_F(TransportSecurityStateTest, IsPreloaded) {
515 TransportSecurityState state("");
516
517 const std::string paypal = 449 const std::string paypal =
518 TransportSecurityState::CanonicalizeHost("paypal.com"); 450 TransportSecurityState::CanonicalizeHost("paypal.com");
519 const std::string www_paypal = 451 const std::string www_paypal =
520 TransportSecurityState::CanonicalizeHost("www.paypal.com"); 452 TransportSecurityState::CanonicalizeHost("www.paypal.com");
521 const std::string a_www_paypal = 453 const std::string a_www_paypal =
522 TransportSecurityState::CanonicalizeHost("a.www.paypal.com"); 454 TransportSecurityState::CanonicalizeHost("a.www.paypal.com");
523 const std::string abc_paypal = 455 const std::string abc_paypal =
524 TransportSecurityState::CanonicalizeHost("a.b.c.paypal.com"); 456 TransportSecurityState::CanonicalizeHost("a.b.c.paypal.com");
525 const std::string example = 457 const std::string example =
526 TransportSecurityState::CanonicalizeHost("example.com"); 458 TransportSecurityState::CanonicalizeHost("example.com");
527 const std::string aypal = 459 const std::string aypal =
528 TransportSecurityState::CanonicalizeHost("aypal.com"); 460 TransportSecurityState::CanonicalizeHost("aypal.com");
529 461
462 TransportSecurityState state;
530 TransportSecurityState::DomainState domain_state; 463 TransportSecurityState::DomainState domain_state;
531 EXPECT_FALSE(state.IsPreloadedSTS(paypal, true, &domain_state)); 464
532 EXPECT_TRUE(state.IsPreloadedSTS(www_paypal, true, &domain_state)); 465 EXPECT_FALSE(state.GetStaticDomainState(paypal, true, &domain_state));
466 EXPECT_TRUE(state.GetStaticDomainState(www_paypal, true, &domain_state));
533 EXPECT_FALSE(domain_state.include_subdomains); 467 EXPECT_FALSE(domain_state.include_subdomains);
534 EXPECT_FALSE(state.IsPreloadedSTS(a_www_paypal, true, &domain_state)); 468 EXPECT_FALSE(state.GetStaticDomainState(a_www_paypal, true, &domain_state));
535 EXPECT_FALSE(state.IsPreloadedSTS(abc_paypal, true, &domain_state)); 469 EXPECT_FALSE(state.GetStaticDomainState(abc_paypal, true, &domain_state));
536 EXPECT_FALSE(state.IsPreloadedSTS(example, true, &domain_state)); 470 EXPECT_FALSE(state.GetStaticDomainState(example, true, &domain_state));
537 EXPECT_FALSE(state.IsPreloadedSTS(aypal, true, &domain_state)); 471 EXPECT_FALSE(state.GetStaticDomainState(aypal, true, &domain_state));
538 } 472 }
539 473
540 TEST_F(TransportSecurityStateTest, PreloadedDomainSet) { 474 TEST_F(TransportSecurityStateTest, PreloadedDomainSet) {
541 TransportSecurityState state(""); 475 TransportSecurityState state;
542 TransportSecurityState::DomainState domain_state; 476 TransportSecurityState::DomainState domain_state;
543 477
544 // The domain wasn't being set, leading to a blank string in the 478 // The domain wasn't being set, leading to a blank string in the
545 // chrome://net-internals/#hsts UI. So test that. 479 // chrome://net-internals/#hsts UI. So test that.
546 EXPECT_TRUE(state.GetDomainState(&domain_state, 480 EXPECT_TRUE(state.GetDomainState("market.android.com", true, &domain_state));
547 "market.android.com",
548 true));
549 EXPECT_EQ(domain_state.domain, "market.android.com"); 481 EXPECT_EQ(domain_state.domain, "market.android.com");
550 EXPECT_TRUE(state.GetDomainState(&domain_state, 482 EXPECT_TRUE(state.GetDomainState("sub.market.android.com", true,
551 "sub.market.android.com", 483 &domain_state));
552 true));
553 EXPECT_EQ(domain_state.domain, "market.android.com"); 484 EXPECT_EQ(domain_state.domain, "market.android.com");
554 } 485 }
555 486
556 static bool ShouldRedirect(const char* hostname) { 487 static bool ShouldRedirect(const char* hostname) {
557 TransportSecurityState state(""); 488 TransportSecurityState state;
558 TransportSecurityState::DomainState domain_state; 489 TransportSecurityState::DomainState domain_state;
559 return state.GetDomainState(&domain_state, hostname, true /* SNI ok */) && 490 return state.GetDomainState(hostname, true /* SNI ok */, &domain_state) &&
560 domain_state.ShouldRedirectHTTPToHTTPS(); 491 domain_state.ShouldRedirectHTTPToHTTPS();
561 } 492 }
562 493
563 static bool HasState(const char *hostname) { 494 static bool HasState(const char* hostname) {
564 TransportSecurityState state(""); 495 TransportSecurityState state;
565 TransportSecurityState::DomainState domain_state; 496 TransportSecurityState::DomainState domain_state;
566 return state.GetDomainState(&domain_state, hostname, true /* SNI ok */); 497 return state.GetDomainState(hostname, true /* SNI ok */, &domain_state);
567 } 498 }
568 499
569 static bool HasPins(const char *hostname) { 500 static bool HasPins(const char* hostname, bool sni_enabled) {
570 TransportSecurityState state(""); 501 TransportSecurityState state;
571 TransportSecurityState::DomainState domain_state; 502 TransportSecurityState::DomainState domain_state;
572 return state.HasPinsForHost(&domain_state, hostname, true /* SNI ok */); 503 if (!state.GetDomainState(hostname, sni_enabled, &domain_state))
504 return false;
505
506 return domain_state.HasPins();
507 }
508
509 static bool HasPins(const char* hostname) {
510 return HasPins(hostname, true);
573 } 511 }
574 512
575 static bool OnlyPinning(const char *hostname) { 513 static bool OnlyPinning(const char *hostname) {
576 TransportSecurityState state(""); 514 TransportSecurityState state;
577 TransportSecurityState::DomainState domain_state; 515 TransportSecurityState::DomainState domain_state;
578 return state.HasPinsForHost(&domain_state, hostname, true /* SNI ok */) && 516 if (!state.GetDomainState(hostname, true /* SNI ok */, &domain_state))
517 return false;
518
519 return (domain_state.static_spki_hashes.size() > 0 ||
520 domain_state.bad_static_spki_hashes.size() > 0 ||
521 domain_state.dynamic_spki_hashes.size() > 0) &&
579 !domain_state.ShouldRedirectHTTPToHTTPS(); 522 !domain_state.ShouldRedirectHTTPToHTTPS();
580 } 523 }
581 524
582 TEST_F(TransportSecurityStateTest, Preloaded) { 525 TEST_F(TransportSecurityStateTest, Preloaded) {
583 TransportSecurityState state(""); 526 TransportSecurityState state;
584 TransportSecurityState::DomainState domain_state; 527 TransportSecurityState::DomainState domain_state;
585 528
586 // We do more extensive checks for the first domain. 529 // We do more extensive checks for the first domain.
587 EXPECT_TRUE(state.GetDomainState(&domain_state, "www.paypal.com", true)); 530 EXPECT_TRUE(state.GetDomainState("www.paypal.com", true, &domain_state));
588 EXPECT_EQ(domain_state.mode, 531 EXPECT_EQ(domain_state.upgrade_mode,
589 TransportSecurityState::DomainState::MODE_STRICT); 532 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
590 EXPECT_TRUE(domain_state.preloaded);
591 EXPECT_FALSE(domain_state.include_subdomains); 533 EXPECT_FALSE(domain_state.include_subdomains);
592 534
593 EXPECT_FALSE(HasState("paypal.com")); 535 EXPECT_FALSE(HasState("paypal.com"));
594 EXPECT_FALSE(HasState("www2.paypal.com")); 536 EXPECT_FALSE(HasState("www2.paypal.com"));
595 EXPECT_FALSE(HasState("www2.paypal.com")); 537 EXPECT_FALSE(HasState("www2.paypal.com"));
596 538
597 // Google hosts: 539 // Google hosts:
598 540
599 EXPECT_TRUE(ShouldRedirect("chrome.google.com")); 541 EXPECT_TRUE(ShouldRedirect("chrome.google.com"));
600 EXPECT_TRUE(ShouldRedirect("checkout.google.com")); 542 EXPECT_TRUE(ShouldRedirect("checkout.google.com"));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 EXPECT_TRUE(OnlyPinning("www.google-analytics.com")); 581 EXPECT_TRUE(OnlyPinning("www.google-analytics.com"));
640 EXPECT_TRUE(OnlyPinning("googleapis.com")); 582 EXPECT_TRUE(OnlyPinning("googleapis.com"));
641 EXPECT_TRUE(OnlyPinning("googleadservices.com")); 583 EXPECT_TRUE(OnlyPinning("googleadservices.com"));
642 EXPECT_TRUE(OnlyPinning("googlecode.com")); 584 EXPECT_TRUE(OnlyPinning("googlecode.com"));
643 EXPECT_TRUE(OnlyPinning("appspot.com")); 585 EXPECT_TRUE(OnlyPinning("appspot.com"));
644 EXPECT_TRUE(OnlyPinning("googlesyndication.com")); 586 EXPECT_TRUE(OnlyPinning("googlesyndication.com"));
645 EXPECT_TRUE(OnlyPinning("doubleclick.net")); 587 EXPECT_TRUE(OnlyPinning("doubleclick.net"));
646 EXPECT_TRUE(OnlyPinning("googlegroups.com")); 588 EXPECT_TRUE(OnlyPinning("googlegroups.com"));
647 589
648 // Tests for domains that don't work without SNI. 590 // Tests for domains that don't work without SNI.
649 EXPECT_FALSE(state.GetDomainState(&domain_state, "gmail.com", false)); 591 EXPECT_FALSE(state.GetDomainState("gmail.com", false, &domain_state));
650 EXPECT_FALSE(state.GetDomainState(&domain_state, "www.gmail.com", false)); 592 EXPECT_FALSE(state.GetDomainState("www.gmail.com", false, &domain_state));
651 EXPECT_FALSE(state.GetDomainState(&domain_state, "m.gmail.com", false)); 593 EXPECT_FALSE(state.GetDomainState("m.gmail.com", false, &domain_state));
652 EXPECT_FALSE(state.GetDomainState(&domain_state, "googlemail.com", false)); 594 EXPECT_FALSE(state.GetDomainState("googlemail.com", false, &domain_state));
653 EXPECT_FALSE(state.GetDomainState(&domain_state, 595 EXPECT_FALSE(state.GetDomainState("www.googlemail.com", false,
654 "www.googlemail.com", 596 &domain_state));
655 false)); 597 EXPECT_FALSE(state.GetDomainState("m.googlemail.com", false, &domain_state));
656 EXPECT_FALSE(state.GetDomainState(&domain_state,
657 "m.googlemail.com",
658 false));
659 598
660 // Other hosts: 599 // Other hosts:
661 600
662 EXPECT_TRUE(ShouldRedirect("aladdinschools.appspot.com")); 601 EXPECT_TRUE(ShouldRedirect("aladdinschools.appspot.com"));
663 602
664 EXPECT_TRUE(ShouldRedirect("ottospora.nl")); 603 EXPECT_TRUE(ShouldRedirect("ottospora.nl"));
665 EXPECT_TRUE(ShouldRedirect("www.ottospora.nl")); 604 EXPECT_TRUE(ShouldRedirect("www.ottospora.nl"));
666 605
667 EXPECT_TRUE(ShouldRedirect("www.paycheckrecords.com")); 606 EXPECT_TRUE(ShouldRedirect("www.paycheckrecords.com"));
668 607
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 EXPECT_TRUE(ShouldRedirect("simon.butcher.name")); 685 EXPECT_TRUE(ShouldRedirect("simon.butcher.name"));
747 EXPECT_TRUE(ShouldRedirect("foo.simon.butcher.name")); 686 EXPECT_TRUE(ShouldRedirect("foo.simon.butcher.name"));
748 687
749 EXPECT_TRUE(ShouldRedirect("linx.net")); 688 EXPECT_TRUE(ShouldRedirect("linx.net"));
750 EXPECT_TRUE(ShouldRedirect("foo.linx.net")); 689 EXPECT_TRUE(ShouldRedirect("foo.linx.net"));
751 690
752 EXPECT_TRUE(ShouldRedirect("dropcam.com")); 691 EXPECT_TRUE(ShouldRedirect("dropcam.com"));
753 EXPECT_TRUE(ShouldRedirect("www.dropcam.com")); 692 EXPECT_TRUE(ShouldRedirect("www.dropcam.com"));
754 EXPECT_FALSE(HasState("foo.dropcam.com")); 693 EXPECT_FALSE(HasState("foo.dropcam.com"));
755 694
756 EXPECT_TRUE(state.GetDomainState(&domain_state, 695 EXPECT_TRUE(state.GetDomainState("torproject.org", false, &domain_state));
757 "torproject.org", 696 EXPECT_FALSE(domain_state.static_spki_hashes.empty());
758 false)); 697 EXPECT_TRUE(state.GetDomainState("www.torproject.org", false,
759 EXPECT_FALSE(domain_state.preloaded_spki_hashes.empty()); 698 &domain_state));
760 EXPECT_TRUE(state.GetDomainState(&domain_state, 699 EXPECT_FALSE(domain_state.static_spki_hashes.empty());
761 "www.torproject.org", 700 EXPECT_TRUE(state.GetDomainState("check.torproject.org", false,
762 false)); 701 &domain_state));
763 EXPECT_FALSE(domain_state.preloaded_spki_hashes.empty()); 702 EXPECT_FALSE(domain_state.static_spki_hashes.empty());
764 EXPECT_TRUE(state.GetDomainState(&domain_state, 703 EXPECT_TRUE(state.GetDomainState("blog.torproject.org", false,
765 "check.torproject.org", 704 &domain_state));
766 false)); 705 EXPECT_FALSE(domain_state.static_spki_hashes.empty());
767 EXPECT_FALSE(domain_state.preloaded_spki_hashes.empty());
768 EXPECT_TRUE(state.GetDomainState(&domain_state,
769 "blog.torproject.org",
770 false));
771 EXPECT_FALSE(domain_state.preloaded_spki_hashes.empty());
772 EXPECT_TRUE(ShouldRedirect("ebanking.indovinabank.com.vn")); 706 EXPECT_TRUE(ShouldRedirect("ebanking.indovinabank.com.vn"));
773 EXPECT_TRUE(ShouldRedirect("foo.ebanking.indovinabank.com.vn")); 707 EXPECT_TRUE(ShouldRedirect("foo.ebanking.indovinabank.com.vn"));
774 708
775 EXPECT_TRUE(ShouldRedirect("epoxate.com")); 709 EXPECT_TRUE(ShouldRedirect("epoxate.com"));
776 EXPECT_FALSE(HasState("foo.epoxate.com")); 710 EXPECT_FALSE(HasState("foo.epoxate.com"));
777 711
778 EXPECT_TRUE(HasPins("torproject.org")); 712 EXPECT_TRUE(HasPins("torproject.org"));
779 EXPECT_TRUE(HasPins("www.torproject.org")); 713 EXPECT_TRUE(HasPins("www.torproject.org"));
780 EXPECT_TRUE(HasPins("check.torproject.org")); 714 EXPECT_TRUE(HasPins("check.torproject.org"));
781 EXPECT_TRUE(HasPins("blog.torproject.org")); 715 EXPECT_TRUE(HasPins("blog.torproject.org"));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 EXPECT_TRUE(ShouldRedirect("bigshinylock.minazo.net")); 764 EXPECT_TRUE(ShouldRedirect("bigshinylock.minazo.net"));
831 EXPECT_TRUE(ShouldRedirect("foo.bigshinylock.minazo.net")); 765 EXPECT_TRUE(ShouldRedirect("foo.bigshinylock.minazo.net"));
832 766
833 EXPECT_TRUE(ShouldRedirect("crate.io")); 767 EXPECT_TRUE(ShouldRedirect("crate.io"));
834 EXPECT_TRUE(ShouldRedirect("foo.crate.io")); 768 EXPECT_TRUE(ShouldRedirect("foo.crate.io"));
835 769
836 EXPECT_TRUE(HasPins("www.twitter.com")); 770 EXPECT_TRUE(HasPins("www.twitter.com"));
837 } 771 }
838 772
839 TEST_F(TransportSecurityStateTest, LongNames) { 773 TEST_F(TransportSecurityStateTest, LongNames) {
840 TransportSecurityState state(""); 774 TransportSecurityState state;
841 const char kLongName[] = 775 const char kLongName[] =
842 "lookupByWaveIdHashAndWaveIdIdAndWaveIdDomainAndWaveletIdIdAnd" 776 "lookupByWaveIdHashAndWaveIdIdAndWaveIdDomainAndWaveletIdIdAnd"
843 "WaveletIdDomainAndBlipBlipid"; 777 "WaveletIdDomainAndBlipBlipid";
844 TransportSecurityState::DomainState domain_state; 778 TransportSecurityState::DomainState domain_state;
845 // Just checks that we don't hit a NOTREACHED. 779 // Just checks that we don't hit a NOTREACHED.
846 EXPECT_FALSE(state.GetDomainState(&domain_state, kLongName, true)); 780 EXPECT_FALSE(state.GetDomainState(kLongName, true, &domain_state));
847 }
848
849 TEST_F(TransportSecurityStateTest, PublicKeyHashes) {
850 TransportSecurityState state("");
851 TransportSecurityState::DomainState domain_state;
852 EXPECT_FALSE(state.GetDomainState(&domain_state, "example.com", false));
853 FingerprintVector hashes;
854 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(hashes));
855
856 SHA1Fingerprint hash;
857 memset(hash.data, '1', sizeof(hash.data));
858 domain_state.preloaded_spki_hashes.push_back(hash);
859
860 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes));
861 hashes.push_back(hash);
862 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(hashes));
863 hashes[0].data[0] = '2';
864 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes));
865
866 const base::Time current_time(base::Time::Now());
867 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
868 domain_state.expiry = expiry;
869 state.EnableHost("example.com", domain_state);
870 std::string ser;
871 EXPECT_TRUE(state.Serialise(&ser));
872 bool dirty;
873 EXPECT_TRUE(state.LoadEntries(ser, &dirty));
874 EXPECT_TRUE(state.GetDomainState(&domain_state, "example.com", false));
875 EXPECT_EQ(1u, domain_state.preloaded_spki_hashes.size());
876 EXPECT_EQ(0, memcmp(domain_state.preloaded_spki_hashes[0].data, hash.data,
877 sizeof(hash.data)));
878 } 781 }
879 782
880 TEST_F(TransportSecurityStateTest, BuiltinCertPins) { 783 TEST_F(TransportSecurityStateTest, BuiltinCertPins) {
881 TransportSecurityState state(""); 784 TransportSecurityState state;
882 TransportSecurityState::DomainState domain_state; 785 TransportSecurityState::DomainState domain_state;
883 EXPECT_TRUE(state.GetDomainState(&domain_state, 786
884 "chrome.google.com", 787 EXPECT_TRUE(state.GetDomainState("chrome.google.com", true, &domain_state));
885 true)); 788 EXPECT_TRUE(HasPins("chrome.google.com"));
886 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "chrome.google.com", true)); 789
887 FingerprintVector hashes; 790 FingerprintVector hashes;
888 // This essential checks that a built-in list does exist. 791 // Checks that a built-in list does exist.
889 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes)); 792 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes));
890 EXPECT_FALSE(state.HasPinsForHost(&domain_state, "www.paypal.com", true)); 793 EXPECT_FALSE(HasPins("www.paypal.com"));
891 794
892 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "docs.google.com", true)); 795 EXPECT_TRUE(HasPins("docs.google.com"));
893 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "1.docs.google.com", true)); 796 EXPECT_TRUE(HasPins("1.docs.google.com"));
894 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "sites.google.com", true)); 797 EXPECT_TRUE(HasPins("sites.google.com"));
895 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "drive.google.com", true)); 798 EXPECT_TRUE(HasPins("drive.google.com"));
896 EXPECT_TRUE(state.HasPinsForHost(&domain_state, 799 EXPECT_TRUE(HasPins("spreadsheets.google.com"));
897 "spreadsheets.google.com", 800 EXPECT_TRUE(HasPins("health.google.com"));
898 true)); 801 EXPECT_TRUE(HasPins("checkout.google.com"));
899 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "health.google.com", true)); 802 EXPECT_TRUE(HasPins("appengine.google.com"));
900 EXPECT_TRUE(state.HasPinsForHost(&domain_state, 803 EXPECT_TRUE(HasPins("market.android.com"));
901 "checkout.google.com", 804 EXPECT_TRUE(HasPins("encrypted.google.com"));
902 true)); 805 EXPECT_TRUE(HasPins("accounts.google.com"));
903 EXPECT_TRUE(state.HasPinsForHost(&domain_state, 806 EXPECT_TRUE(HasPins("profiles.google.com"));
904 "appengine.google.com", 807 EXPECT_TRUE(HasPins("mail.google.com"));
905 true)); 808 EXPECT_TRUE(HasPins("chatenabled.mail.google.com"));
906 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "market.android.com", true)); 809 EXPECT_TRUE(HasPins("talkgadget.google.com"));
907 EXPECT_TRUE(state.HasPinsForHost(&domain_state, 810 EXPECT_TRUE(HasPins("hostedtalkgadget.google.com"));
908 "encrypted.google.com", 811 EXPECT_TRUE(HasPins("talk.google.com"));
909 true)); 812 EXPECT_TRUE(HasPins("plus.google.com"));
910 EXPECT_TRUE(state.HasPinsForHost(&domain_state, 813 EXPECT_TRUE(HasPins("groups.google.com"));
911 "accounts.google.com", 814 EXPECT_TRUE(HasPins("apis.google.com"));
912 true));
913 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
914 "profiles.google.com",
915 true));
916 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "mail.google.com", true));
917 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
918 "chatenabled.mail.google.com",
919 true));
920 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
921 "talkgadget.google.com",
922 true));
923 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
924 "hostedtalkgadget.google.com",
925 true));
926 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "talk.google.com", true));
927 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "plus.google.com", true));
928 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "groups.google.com", true));
929 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "apis.google.com", true));
930 815
931 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "ssl.gstatic.com", true)); 816 EXPECT_TRUE(HasPins("ssl.gstatic.com"));
932 EXPECT_FALSE(state.HasPinsForHost(&domain_state, "www.gstatic.com", true)); 817 EXPECT_FALSE(HasPins("www.gstatic.com"));
933 EXPECT_TRUE(state.HasPinsForHost(&domain_state, 818 EXPECT_TRUE(HasPins("ssl.google-analytics.com"));
934 "ssl.google-analytics.com", 819 EXPECT_TRUE(HasPins("www.googleplex.com"));
935 true));
936 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "www.googleplex.com", true));
937 820
938 // Disabled in order to help track down pinning failures --agl 821 // Disabled in order to help track down pinning failures --agl
939 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "twitter.com", true)); 822 EXPECT_TRUE(HasPins("twitter.com"));
940 EXPECT_FALSE(state.HasPinsForHost(&domain_state, "foo.twitter.com", true)); 823 EXPECT_FALSE(HasPins("foo.twitter.com"));
941 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "www.twitter.com", true)); 824 EXPECT_TRUE(HasPins("www.twitter.com"));
942 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "api.twitter.com", true)); 825 EXPECT_TRUE(HasPins("api.twitter.com"));
943 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "oauth.twitter.com", true)); 826 EXPECT_TRUE(HasPins("oauth.twitter.com"));
944 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "mobile.twitter.com", true)); 827 EXPECT_TRUE(HasPins("mobile.twitter.com"));
945 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "dev.twitter.com", true)); 828 EXPECT_TRUE(HasPins("dev.twitter.com"));
946 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "business.twitter.com", 829 EXPECT_TRUE(HasPins("business.twitter.com"));
947 true)); 830 EXPECT_TRUE(HasPins("platform.twitter.com"));
948 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "platform.twitter.com", 831 EXPECT_TRUE(HasPins("si0.twimg.com"));
949 true)); 832 EXPECT_TRUE(HasPins("twimg0-a.akamaihd.net"));
950 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "si0.twimg.com", true));
951 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "twimg0-a.akamaihd.net",
952 true));
953 } 833 }
954 834
955 static bool AddHash(const std::string& type_and_base64, 835 static bool AddHash(const std::string& type_and_base64,
956 FingerprintVector* out) { 836 FingerprintVector* out) {
957 std::string hash_str; 837 std::string hash_str;
958 if (type_and_base64.find("sha1/") == 0 && 838 if (type_and_base64.find("sha1/") == 0 &&
959 base::Base64Decode(type_and_base64.substr(5, type_and_base64.size() - 5), 839 base::Base64Decode(type_and_base64.substr(5, type_and_base64.size() - 5),
960 &hash_str) && 840 &hash_str) &&
961 hash_str.size() == base::kSHA1Length) { 841 hash_str.size() == base::kSHA1Length) {
962 SHA1Fingerprint hash; 842 SHA1Fingerprint hash;
(...skipping 25 matching lines...) Expand all
988 868
989 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes; 869 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes;
990 870
991 for (size_t i = 0; kGoodPath[i]; i++) { 871 for (size_t i = 0; kGoodPath[i]; i++) {
992 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); 872 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes));
993 } 873 }
994 for (size_t i = 0; kBadPath[i]; i++) { 874 for (size_t i = 0; kBadPath[i]; i++) {
995 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); 875 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes));
996 } 876 }
997 877
998 TransportSecurityState state(""); 878 TransportSecurityState state;
999 TransportSecurityState::DomainState domain_state; 879 TransportSecurityState::DomainState domain_state;
1000 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "plus.google.com", true)); 880 EXPECT_TRUE(state.GetDomainState("plus.google.com", true, &domain_state));
881 EXPECT_TRUE(domain_state.HasPins());
1001 882
1002 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes)); 883 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes));
1003 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes)); 884 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes));
1004 } 885 }
1005 886
1006 TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) { 887 TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) {
1007 // kGoodPath is blog.torproject.org. 888 // kGoodPath is blog.torproject.org.
1008 static const char* kGoodPath[] = { 889 static const char* kGoodPath[] = {
1009 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=", 890 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=",
1010 "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=", 891 "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=",
(...skipping 12 matching lines...) Expand all
1023 904
1024 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes; 905 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes;
1025 906
1026 for (size_t i = 0; kGoodPath[i]; i++) { 907 for (size_t i = 0; kGoodPath[i]; i++) {
1027 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); 908 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes));
1028 } 909 }
1029 for (size_t i = 0; kBadPath[i]; i++) { 910 for (size_t i = 0; kBadPath[i]; i++) {
1030 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); 911 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes));
1031 } 912 }
1032 913
1033 TransportSecurityState state(""); 914 TransportSecurityState state;
1034 TransportSecurityState::DomainState domain_state; 915 TransportSecurityState::DomainState domain_state;
1035 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "blog.torproject.org", true)); 916 EXPECT_TRUE(state.GetDomainState("blog.torproject.org", true, &domain_state));
917 EXPECT_TRUE(domain_state.HasPins());
1036 918
1037 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes)); 919 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes));
1038 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes)); 920 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes));
1039 } 921 }
1040 922
1041 TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) { 923 TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) {
1042 TransportSecurityState state(""); 924 TransportSecurityState state;
1043 TransportSecurityState::DomainState domain_state; 925 TransportSecurityState::DomainState domain_state;
926
1044 EXPECT_FALSE(ShouldRedirect("www.google-analytics.com")); 927 EXPECT_FALSE(ShouldRedirect("www.google-analytics.com"));
1045 EXPECT_FALSE(state.HasPinsForHost(&domain_state,
1046 "www.google-analytics.com",
1047 false));
1048 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
1049 "www.google-analytics.com",
1050 true));
1051 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "google.com", true));
1052 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "www.google.com", true));
1053 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
1054 "mail-attachment.googleusercontent.com",
1055 true));
1056 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "www.youtube.com", true));
1057 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "i.ytimg.com", true));
1058 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "googleapis.com", true));
1059 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
1060 "ajax.googleapis.com",
1061 true));
1062 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
1063 "googleadservices.com",
1064 true));
1065 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
1066 "pagead2.googleadservices.com",
1067 true));
1068 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "googlecode.com", true));
1069 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
1070 "kibbles.googlecode.com",
1071 true));
1072 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "appspot.com", true));
1073 EXPECT_TRUE(state.HasPinsForHost(&domain_state,
1074 "googlesyndication.com",
1075 true));
1076 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "doubleclick.net", true));
1077 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "ad.doubleclick.net", true));
1078 EXPECT_FALSE(state.HasPinsForHost(&domain_state,
1079 "learn.doubleclick.net",
1080 true));
1081 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "a.googlegroups.com", true));
1082 EXPECT_FALSE(state.HasPinsForHost(&domain_state,
1083 "a.googlegroups.com",
1084 false));
1085 }
1086 928
1087 TEST_F(TransportSecurityStateTest, ForcePreloads) { 929 EXPECT_FALSE(HasPins("www.google-analytics.com", false));
1088 // This is a docs.google.com override. 930 EXPECT_TRUE(HasPins("www.google-analytics.com"));
1089 std::string preload("{" 931 EXPECT_TRUE(HasPins("google.com"));
1090 "\"4AGT3lHihuMSd5rUj7B4u6At0jlSH3HFePovjPR+oLE=\": {" 932 EXPECT_TRUE(HasPins("www.google.com"));
1091 "\"created\": 0.0," 933 EXPECT_TRUE(HasPins("mail-attachment.googleusercontent.com"));
1092 "\"expiry\": 2000000000.0," 934 EXPECT_TRUE(HasPins("www.youtube.com"));
1093 "\"include_subdomains\": false," 935 EXPECT_TRUE(HasPins("i.ytimg.com"));
1094 "\"mode\": \"pinning-only\"" 936 EXPECT_TRUE(HasPins("googleapis.com"));
1095 "}}"); 937 EXPECT_TRUE(HasPins("ajax.googleapis.com"));
1096 938 EXPECT_TRUE(HasPins("googleadservices.com"));
1097 TransportSecurityState state(preload); 939 EXPECT_TRUE(HasPins("pagead2.googleadservices.com"));
1098 TransportSecurityState::DomainState domain_state; 940 EXPECT_TRUE(HasPins("googlecode.com"));
1099 EXPECT_FALSE(state.HasPinsForHost(&domain_state, "docs.google.com", true)); 941 EXPECT_TRUE(HasPins("kibbles.googlecode.com"));
1100 EXPECT_TRUE(state.GetDomainState(&domain_state, "docs.google.com", true)); 942 EXPECT_TRUE(HasPins("appspot.com"));
1101 EXPECT_FALSE(domain_state.ShouldRedirectHTTPToHTTPS()); 943 EXPECT_TRUE(HasPins("googlesyndication.com"));
944 EXPECT_TRUE(HasPins("doubleclick.net"));
945 EXPECT_TRUE(HasPins("ad.doubleclick.net"));
946 EXPECT_FALSE(HasPins("learn.doubleclick.net"));
947 EXPECT_TRUE(HasPins("a.googlegroups.com"));
948 EXPECT_FALSE(HasPins("a.googlegroups.com", false));
1102 } 949 }
1103 950
1104 TEST_F(TransportSecurityStateTest, OverrideBuiltins) { 951 TEST_F(TransportSecurityStateTest, OverrideBuiltins) {
1105 EXPECT_TRUE(HasPins("google.com")); 952 EXPECT_TRUE(HasPins("google.com"));
1106 EXPECT_FALSE(ShouldRedirect("google.com")); 953 EXPECT_FALSE(ShouldRedirect("google.com"));
1107 EXPECT_FALSE(ShouldRedirect("www.google.com")); 954 EXPECT_FALSE(ShouldRedirect("www.google.com"));
1108 955
1109 TransportSecurityState state(""); 956 TransportSecurityState state;
1110 TransportSecurityState::DomainState domain_state; 957 TransportSecurityState::DomainState domain_state;
1111 const base::Time current_time(base::Time::Now()); 958 const base::Time current_time(base::Time::Now());
1112 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 959 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
1113 domain_state.expiry = expiry; 960 domain_state.upgrade_expiry = expiry;
1114 state.EnableHost("www.google.com", domain_state); 961 state.EnableHost("www.google.com", domain_state);
1115 962
1116 EXPECT_TRUE(state.GetDomainState(&domain_state, "www.google.com", true)); 963 EXPECT_TRUE(state.GetDomainState("www.google.com", true, &domain_state));
1117 } 964 }
1118 965
1119 static const uint8 kSidePinLeafSPKI[] = { 966 static const uint8 kSidePinLeafSPKI[] = {
1120 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 967 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
1121 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xe4, 968 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xe4,
1122 0x1d, 0xcc, 0xf2, 0x92, 0xe7, 0x7a, 0xc6, 0x36, 0xf7, 0x1a, 0x62, 0x31, 0x7d, 969 0x1d, 0xcc, 0xf2, 0x92, 0xe7, 0x7a, 0xc6, 0x36, 0xf7, 0x1a, 0x62, 0x31, 0x7d,
1123 0x37, 0xea, 0x0d, 0xa2, 0xa8, 0x12, 0x2b, 0xc2, 0x1c, 0x82, 0x3e, 0xa5, 0x70, 970 0x37, 0xea, 0x0d, 0xa2, 0xa8, 0x12, 0x2b, 0xc2, 0x1c, 0x82, 0x3e, 0xa5, 0x70,
1124 0x4a, 0x83, 0x5d, 0x9b, 0x84, 0x82, 0x70, 0xa4, 0x88, 0x98, 0x98, 0x41, 0x29, 971 0x4a, 0x83, 0x5d, 0x9b, 0x84, 0x82, 0x70, 0xa4, 0x88, 0x98, 0x98, 0x41, 0x29,
1125 0x31, 0xcb, 0x6e, 0x2a, 0x54, 0x65, 0x14, 0x60, 0xcc, 0x00, 0xe8, 0x10, 0x30, 972 0x31, 0xcb, 0x6e, 0x2a, 0x54, 0x65, 0x14, 0x60, 0xcc, 0x00, 0xe8, 0x10, 0x30,
1126 0x0a, 0x4a, 0xd1, 0xa7, 0x52, 0xfe, 0x2d, 0x31, 0x2a, 0x1d, 0x0d, 0x02, 0x03, 973 0x0a, 0x4a, 0xd1, 0xa7, 0x52, 0xfe, 0x2d, 0x31, 0x2a, 0x1d, 0x0d, 0x02, 0x03,
(...skipping 14 matching lines...) Expand all
1141 0xc3, 0x6e, 0x18, 0xdf, 0x79, 0xc0, 0x59, 0xab, 0xd6, 0x77, 0x37, 0x6a, 0x94, 988 0xc3, 0x6e, 0x18, 0xdf, 0x79, 0xc0, 0x59, 0xab, 0xd6, 0x77, 0x37, 0x6a, 0x94,
1142 0x5a, 0x7e, 0xfb, 0xa9, 0xc5, 0x54, 0x14, 0x3a, 0x7b, 0x97, 0x17, 0x2a, 0xb6, 989 0x5a, 0x7e, 0xfb, 0xa9, 0xc5, 0x54, 0x14, 0x3a, 0x7b, 0x97, 0x17, 0x2a, 0xb6,
1143 0x1e, 0x59, 0x4f, 0x2f, 0xb1, 0x15, 0x1a, 0x34, 0x50, 0x32, 0x35, 0x36, 990 0x1e, 0x59, 0x4f, 0x2f, 0xb1, 0x15, 0x1a, 0x34, 0x50, 0x32, 0x35, 0x36,
1144 }; 991 };
1145 992
1146 static const uint8 kSidePinExpectedHash[20] = { 993 static const uint8 kSidePinExpectedHash[20] = {
1147 0xb5, 0x91, 0x66, 0x47, 0x43, 0x16, 0x62, 0x86, 0xd4, 0x1e, 0x5d, 0x36, 0xe1, 994 0xb5, 0x91, 0x66, 0x47, 0x43, 0x16, 0x62, 0x86, 0xd4, 0x1e, 0x5d, 0x36, 0xe1,
1148 0xc4, 0x09, 0x3d, 0x2d, 0x1d, 0xea, 0x1e, 995 0xc4, 0x09, 0x3d, 0x2d, 0x1d, 0xea, 0x1e,
1149 }; 996 };
1150 997
1151 TEST_F(TransportSecurityStateTest, ParseSidePins) {
1152 base::StringPiece leaf_spki(reinterpret_cast<const char*>(kSidePinLeafSPKI),
1153 sizeof(kSidePinLeafSPKI));
1154 base::StringPiece side_info(reinterpret_cast<const char*>(kSidePinInfo),
1155 sizeof(kSidePinInfo));
1156
1157 FingerprintVector pub_key_hashes;
1158 EXPECT_TRUE(TransportSecurityState::ParseSidePin(
1159 leaf_spki, side_info, &pub_key_hashes));
1160 ASSERT_EQ(1u, pub_key_hashes.size());
1161 EXPECT_EQ(0, memcmp(pub_key_hashes[0].data, kSidePinExpectedHash,
1162 sizeof(kSidePinExpectedHash)));
1163 }
1164
1165 TEST_F(TransportSecurityStateTest, ParseSidePinsFailsWithBadData) {
1166 uint8 leaf_spki_copy[sizeof(kSidePinLeafSPKI)];
1167 memcpy(leaf_spki_copy, kSidePinLeafSPKI, sizeof(leaf_spki_copy));
1168
1169 uint8 side_info_copy[sizeof(kSidePinInfo)];
1170 memcpy(side_info_copy, kSidePinInfo, sizeof(kSidePinInfo));
1171
1172 base::StringPiece leaf_spki(reinterpret_cast<const char*>(leaf_spki_copy),
1173 sizeof(leaf_spki_copy));
1174 base::StringPiece side_info(reinterpret_cast<const char*>(side_info_copy),
1175 sizeof(side_info_copy));
1176 FingerprintVector pub_key_hashes;
1177
1178 // Tweak |leaf_spki| and expect a failure.
1179 leaf_spki_copy[10] ^= 1;
1180 EXPECT_FALSE(TransportSecurityState::ParseSidePin(
1181 leaf_spki, side_info, &pub_key_hashes));
1182 ASSERT_EQ(0u, pub_key_hashes.size());
1183
1184 // Undo the change to |leaf_spki| and tweak |side_info|.
1185 leaf_spki_copy[10] ^= 1;
1186 side_info_copy[30] ^= 1;
1187 EXPECT_FALSE(TransportSecurityState::ParseSidePin(
1188 leaf_spki, side_info, &pub_key_hashes));
1189 ASSERT_EQ(0u, pub_key_hashes.size());
1190 }
1191
1192 TEST_F(TransportSecurityStateTest, DISABLED_ParseSidePinsFuzz) {
1193 // Disabled because it's too slow for normal tests. Run manually when
1194 // changing the underlying code.
1195
1196 base::StringPiece leaf_spki(reinterpret_cast<const char*>(kSidePinLeafSPKI),
1197 sizeof(kSidePinLeafSPKI));
1198 uint8 side_info_copy[sizeof(kSidePinInfo)];
1199 base::StringPiece side_info(reinterpret_cast<const char*>(side_info_copy),
1200 sizeof(side_info_copy));
1201 FingerprintVector pub_key_hashes;
1202 static const size_t bit_length = sizeof(kSidePinInfo) * 8;
1203
1204 for (size_t bit_to_flip = 0; bit_to_flip < bit_length; bit_to_flip++) {
1205 memcpy(side_info_copy, kSidePinInfo, sizeof(kSidePinInfo));
1206
1207 size_t byte = bit_to_flip >> 3;
1208 size_t bit = bit_to_flip & 7;
1209 side_info_copy[byte] ^= (1 << bit);
1210
1211 EXPECT_FALSE(TransportSecurityState::ParseSidePin(
1212 leaf_spki, side_info, &pub_key_hashes));
1213 ASSERT_EQ(0u, pub_key_hashes.size());
1214 }
1215 }
1216
1217 TEST_F(TransportSecurityStateTest, GooglePinnedProperties) { 998 TEST_F(TransportSecurityStateTest, GooglePinnedProperties) {
1218 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 999 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1219 "www.example.com", true)); 1000 "www.example.com", true));
1220 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 1001 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1221 "www.paypal.com", true)); 1002 "www.paypal.com", true));
1222 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 1003 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1223 "mail.twitter.com", true)); 1004 "mail.twitter.com", true));
1224 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 1005 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1225 "www.google.com.int", true)); 1006 "www.google.com.int", true));
1226 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 1007 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 // Expect to fail for SNI hosts when not searching the SNI list: 1052 // Expect to fail for SNI hosts when not searching the SNI list:
1272 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 1053 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1273 "gmail.com", false)); 1054 "gmail.com", false));
1274 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 1055 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1275 "googlegroups.com", false)); 1056 "googlegroups.com", false));
1276 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 1057 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1277 "www.googlegroups.com", false)); 1058 "www.googlegroups.com", false));
1278 } 1059 }
1279 1060
1280 } // namespace net 1061 } // namespace net
OLDNEW
« no previous file with comments | « net/base/transport_security_state.cc ('k') | net/base/x509_cert_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698