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

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

Powered by Google App Engine
This is Rietveld 408576698