OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "content/common/origin_trials/trial_token_validator.h" | 5 #include "content/common/origin_trials/trial_token_validator.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 // Well-formed token, for an insecure origin. | 105 // Well-formed token, for an insecure origin. |
106 // Generate this token with the command (in tools/origin_trials): | 106 // Generate this token with the command (in tools/origin_trials): |
107 // generate_token.py http://valid.example.com Frobulate | 107 // generate_token.py http://valid.example.com Frobulate |
108 // --expire-timestamp=2000000000 | 108 // --expire-timestamp=2000000000 |
109 const char kInsecureOriginToken[] = | 109 const char kInsecureOriginToken[] = |
110 "AjfC47H1q8/Ho5ALFkjkwf9CBK6oUUeRTlFc50Dj+eZEyGGKFIY2WTxMBfy8cLc3" | 110 "AjfC47H1q8/Ho5ALFkjkwf9CBK6oUUeRTlFc50Dj+eZEyGGKFIY2WTxMBfy8cLc3" |
111 "E0nmFroDA3OmABmO5jMCFgkAAABXeyJvcmlnaW4iOiAiaHR0cDovL3ZhbGlkLmV4" | 111 "E0nmFroDA3OmABmO5jMCFgkAAABXeyJvcmlnaW4iOiAiaHR0cDovL3ZhbGlkLmV4" |
112 "YW1wbGUuY29tOjgwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlIiwgImV4cGlyeSI6" | 112 "YW1wbGUuY29tOjgwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlIiwgImV4cGlyeSI6" |
113 "IDIwMDAwMDAwMDB9"; | 113 "IDIwMDAwMDAwMDB9"; |
114 | 114 |
115 // These timestamps should be in the past and future, respectively. Sanity | 115 // This timestamp is set to a time after the expiry timestamp of kExpiredToken, |
116 // checks within the tests assert that that is true, to guard against poorly-set | 116 // but before the expiry timestamp of kValidToken. |
117 // system clocks. (And against the inevitable march of time past the year 2033) | 117 double kNowTimestamp = 1500000000; |
118 double kPastTimestamp = 1000000000; | |
119 double kFutureTimestamp = 2000000000; | |
120 | 118 |
121 class TestOriginTrialPolicy : public OriginTrialPolicy { | 119 class TestOriginTrialPolicy : public OriginTrialPolicy { |
122 public: | 120 public: |
123 base::StringPiece GetPublicKey() const override { | 121 base::StringPiece GetPublicKey() const override { |
124 return base::StringPiece(reinterpret_cast<const char*>(key_), | 122 return base::StringPiece(reinterpret_cast<const char*>(key_), |
125 arraysize(kTestPublicKey)); | 123 arraysize(kTestPublicKey)); |
126 } | 124 } |
127 bool IsFeatureDisabled(base::StringPiece feature) const override { | 125 bool IsFeatureDisabled(base::StringPiece feature) const override { |
128 return disabled_features_.count(feature.as_string()) > 0; | 126 return disabled_features_.count(feature.as_string()) > 0; |
129 } | 127 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 expired_token_signature_( | 181 expired_token_signature_( |
184 std::string(reinterpret_cast<const char*>(kExpiredTokenSignature), | 182 std::string(reinterpret_cast<const char*>(kExpiredTokenSignature), |
185 arraysize(kExpiredTokenSignature))), | 183 arraysize(kExpiredTokenSignature))), |
186 response_headers_(new net::HttpResponseHeaders("")) { | 184 response_headers_(new net::HttpResponseHeaders("")) { |
187 SetPublicKey(kTestPublicKey); | 185 SetPublicKey(kTestPublicKey); |
188 SetContentClient(&test_content_client_); | 186 SetContentClient(&test_content_client_); |
189 } | 187 } |
190 | 188 |
191 ~TrialTokenValidatorTest() override { SetContentClient(nullptr); } | 189 ~TrialTokenValidatorTest() override { SetContentClient(nullptr); } |
192 | 190 |
193 void SetUp() override { | |
194 // Ensure that the system clock is set to a date that the matches the test | |
195 // expectations. If this fails, either the clock on the test device is | |
196 // incorrect, or the actual date is after 2033-05-18, and the tokens need to | |
197 // be regenerated. | |
198 ASSERT_GT(base::Time::Now(), base::Time::FromDoubleT(kPastTimestamp)); | |
199 ASSERT_LT(base::Time::Now(), base::Time::FromDoubleT(kFutureTimestamp)); | |
200 } | |
201 | |
202 void SetPublicKey(const uint8_t* key) { | 191 void SetPublicKey(const uint8_t* key) { |
203 test_content_client_.SetOriginTrialPublicKey(key); | 192 test_content_client_.SetOriginTrialPublicKey(key); |
204 } | 193 } |
205 | 194 |
206 void DisableFeature(const std::string& feature) { | 195 void DisableFeature(const std::string& feature) { |
207 test_content_client_.DisableFeature(feature); | 196 test_content_client_.DisableFeature(feature); |
208 } | 197 } |
209 | 198 |
210 void DisableToken(const std::string& token_signature) { | 199 void DisableToken(const std::string& token_signature) { |
211 test_content_client_.DisableToken(token_signature); | 200 test_content_client_.DisableToken(token_signature); |
212 } | 201 } |
213 | 202 |
| 203 base::Time Now() { return base::Time::FromDoubleT(kNowTimestamp); } |
| 204 |
214 const url::Origin appropriate_origin_; | 205 const url::Origin appropriate_origin_; |
215 const url::Origin inappropriate_origin_; | 206 const url::Origin inappropriate_origin_; |
216 const url::Origin insecure_origin_; | 207 const url::Origin insecure_origin_; |
217 | 208 |
218 std::string valid_token_signature_; | 209 std::string valid_token_signature_; |
219 std::string expired_token_signature_; | 210 std::string expired_token_signature_; |
220 | 211 |
221 scoped_refptr<net::HttpResponseHeaders> response_headers_; | 212 scoped_refptr<net::HttpResponseHeaders> response_headers_; |
222 | 213 |
223 private: | 214 private: |
224 TestContentClient test_content_client_; | 215 TestContentClient test_content_client_; |
225 }; | 216 }; |
226 | 217 |
227 // Flaky on Android swarming bots: crbug.com/672294 | 218 TEST_F(TrialTokenValidatorTest, ValidateValidToken) { |
228 #if defined(OS_ANDROID) | |
229 #define MAYBE_ValidateValidToken DISABLED_ValidateValidToken | |
230 #else | |
231 #define MAYBE_ValidateValidToken ValidateValidToken | |
232 #endif | |
233 TEST_F(TrialTokenValidatorTest, MAYBE_ValidateValidToken) { | |
234 std::string feature; | 219 std::string feature; |
235 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kSuccess, | 220 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kSuccess, |
236 TrialTokenValidator::ValidateToken(kSampleToken, | 221 TrialTokenValidator::ValidateToken( |
237 appropriate_origin_, &feature)); | 222 kSampleToken, appropriate_origin_, &feature, Now())); |
238 EXPECT_EQ(kAppropriateFeatureName, feature); | 223 EXPECT_EQ(kAppropriateFeatureName, feature); |
239 } | 224 } |
240 | 225 |
241 TEST_F(TrialTokenValidatorTest, ValidateInappropriateOrigin) { | 226 TEST_F(TrialTokenValidatorTest, ValidateInappropriateOrigin) { |
242 std::string feature; | 227 std::string feature; |
243 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kWrongOrigin, | 228 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kWrongOrigin, |
244 TrialTokenValidator::ValidateToken( | 229 TrialTokenValidator::ValidateToken( |
245 kSampleToken, inappropriate_origin_, &feature)); | 230 kSampleToken, inappropriate_origin_, &feature, Now())); |
246 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kWrongOrigin, | 231 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kWrongOrigin, |
247 TrialTokenValidator::ValidateToken(kSampleToken, insecure_origin_, | 232 TrialTokenValidator::ValidateToken(kSampleToken, insecure_origin_, |
248 &feature)); | 233 &feature, Now())); |
249 } | 234 } |
250 | 235 |
251 TEST_F(TrialTokenValidatorTest, ValidateInvalidSignature) { | 236 TEST_F(TrialTokenValidatorTest, ValidateInvalidSignature) { |
252 std::string feature; | 237 std::string feature; |
253 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kInvalidSignature, | 238 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kInvalidSignature, |
254 TrialTokenValidator::ValidateToken(kInvalidSignatureToken, | 239 TrialTokenValidator::ValidateToken( |
255 appropriate_origin_, &feature)); | 240 kInvalidSignatureToken, appropriate_origin_, &feature, Now())); |
256 } | 241 } |
257 | 242 |
258 TEST_F(TrialTokenValidatorTest, ValidateUnparsableToken) { | 243 TEST_F(TrialTokenValidatorTest, ValidateUnparsableToken) { |
259 std::string feature; | 244 std::string feature; |
260 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kMalformed, | 245 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kMalformed, |
261 TrialTokenValidator::ValidateToken(kUnparsableToken, | 246 TrialTokenValidator::ValidateToken( |
262 appropriate_origin_, &feature)); | 247 kUnparsableToken, appropriate_origin_, &feature, Now())); |
263 } | 248 } |
264 | 249 |
265 TEST_F(TrialTokenValidatorTest, ValidateExpiredToken) { | 250 TEST_F(TrialTokenValidatorTest, ValidateExpiredToken) { |
266 std::string feature; | 251 std::string feature; |
267 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kExpired, | 252 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kExpired, |
268 TrialTokenValidator::ValidateToken(kExpiredToken, | 253 TrialTokenValidator::ValidateToken( |
269 appropriate_origin_, &feature)); | 254 kExpiredToken, appropriate_origin_, &feature, Now())); |
270 } | 255 } |
271 | 256 |
272 TEST_F(TrialTokenValidatorTest, ValidateValidTokenWithIncorrectKey) { | 257 TEST_F(TrialTokenValidatorTest, ValidateValidTokenWithIncorrectKey) { |
273 std::string feature; | 258 std::string feature; |
274 SetPublicKey(kTestPublicKey2); | 259 SetPublicKey(kTestPublicKey2); |
275 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kInvalidSignature, | 260 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kInvalidSignature, |
276 TrialTokenValidator::ValidateToken(kSampleToken, | 261 TrialTokenValidator::ValidateToken( |
277 appropriate_origin_, &feature)); | 262 kSampleToken, appropriate_origin_, &feature, Now())); |
278 } | 263 } |
279 | 264 |
280 // Flaky on Android swarming bots: crbug.com/672294 | 265 TEST_F(TrialTokenValidatorTest, ValidatorRespectsDisabledFeatures) { |
281 #if defined(OS_ANDROID) | |
282 #define MAYBE_ValidatorRespectsDisabledFeatures DISABLED_ValidatorRespectsDisabl
edFeatures | |
283 #else | |
284 #define MAYBE_ValidatorRespectsDisabledFeatures ValidatorRespectsDisabledFeature
s | |
285 #endif | |
286 TEST_F(TrialTokenValidatorTest, MAYBE_ValidatorRespectsDisabledFeatures) { | |
287 std::string feature; | 266 std::string feature; |
288 // Disable an irrelevant feature; token should still validate | 267 // Disable an irrelevant feature; token should still validate |
289 DisableFeature(kInappropriateFeatureName); | 268 DisableFeature(kInappropriateFeatureName); |
290 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kSuccess, | 269 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kSuccess, |
291 TrialTokenValidator::ValidateToken(kSampleToken, | 270 TrialTokenValidator::ValidateToken( |
292 appropriate_origin_, &feature)); | 271 kSampleToken, appropriate_origin_, &feature, Now())); |
293 EXPECT_EQ(kAppropriateFeatureName, feature); | 272 EXPECT_EQ(kAppropriateFeatureName, feature); |
294 // Disable the token's feature; it should no longer be valid | 273 // Disable the token's feature; it should no longer be valid |
295 DisableFeature(kAppropriateFeatureName); | 274 DisableFeature(kAppropriateFeatureName); |
296 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kFeatureDisabled, | 275 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kFeatureDisabled, |
297 TrialTokenValidator::ValidateToken(kSampleToken, | 276 TrialTokenValidator::ValidateToken( |
298 appropriate_origin_, &feature)); | 277 kSampleToken, appropriate_origin_, &feature, Now())); |
299 } | 278 } |
300 | 279 |
301 TEST_F(TrialTokenValidatorTest, ValidatorRespectsDisabledTokens) { | 280 TEST_F(TrialTokenValidatorTest, ValidatorRespectsDisabledTokens) { |
302 std::string feature; | 281 std::string feature; |
303 // Disable an irrelevant token; token should still validate | 282 // Disable an irrelevant token; token should still validate |
304 DisableToken(expired_token_signature_); | 283 DisableToken(expired_token_signature_); |
305 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kSuccess, | 284 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kSuccess, |
306 TrialTokenValidator::ValidateToken(kSampleToken, | 285 TrialTokenValidator::ValidateToken( |
307 appropriate_origin_, &feature)); | 286 kSampleToken, appropriate_origin_, &feature, Now())); |
308 EXPECT_EQ(kAppropriateFeatureName, feature); | 287 EXPECT_EQ(kAppropriateFeatureName, feature); |
309 // Disable the token; it should no longer be valid | 288 // Disable the token; it should no longer be valid |
310 DisableToken(valid_token_signature_); | 289 DisableToken(valid_token_signature_); |
311 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kTokenDisabled, | 290 EXPECT_EQ(blink::WebOriginTrialTokenStatus::kTokenDisabled, |
312 TrialTokenValidator::ValidateToken(kSampleToken, | 291 TrialTokenValidator::ValidateToken( |
313 appropriate_origin_, &feature)); | 292 kSampleToken, appropriate_origin_, &feature, Now())); |
314 } | 293 } |
315 | 294 |
316 TEST_F(TrialTokenValidatorTest, ValidateRequestInsecure) { | 295 TEST_F(TrialTokenValidatorTest, ValidateRequestInsecure) { |
317 response_headers_->AddHeader(std::string("Origin-Trial: ") + | 296 response_headers_->AddHeader(std::string("Origin-Trial: ") + |
318 kInsecureOriginToken); | 297 kInsecureOriginToken); |
319 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( | 298 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( |
320 GURL(kInsecureOrigin), response_headers_.get(), kAppropriateFeatureName)); | 299 GURL(kInsecureOrigin), response_headers_.get(), kAppropriateFeatureName, |
| 300 Now())); |
321 } | 301 } |
322 | 302 |
323 // Flaky on Android swarming bots: crbug.com/672294 | 303 TEST_F(TrialTokenValidatorTest, ValidateRequestValidToken) { |
324 #if defined(OS_ANDROID) | |
325 #define MAYBE_ValidateRequestValidToken DISABLED_ValidateRequestValidToken | |
326 #else | |
327 #define MAYBE_ValidateRequestValidToken ValidateRequestValidToken | |
328 #endif | |
329 TEST_F(TrialTokenValidatorTest, MAYBE_ValidateRequestValidToken) { | |
330 response_headers_->AddHeader(std::string("Origin-Trial: ") + kSampleToken); | 304 response_headers_->AddHeader(std::string("Origin-Trial: ") + kSampleToken); |
331 EXPECT_TRUE(TrialTokenValidator::RequestEnablesFeature( | 305 EXPECT_TRUE(TrialTokenValidator::RequestEnablesFeature( |
332 GURL(kAppropriateOrigin), response_headers_.get(), | 306 GURL(kAppropriateOrigin), response_headers_.get(), |
333 kAppropriateFeatureName)); | 307 kAppropriateFeatureName, Now())); |
334 } | 308 } |
335 | 309 |
336 TEST_F(TrialTokenValidatorTest, ValidateRequestNoTokens) { | 310 TEST_F(TrialTokenValidatorTest, ValidateRequestNoTokens) { |
337 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( | 311 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( |
338 GURL(kAppropriateOrigin), response_headers_.get(), | 312 GURL(kAppropriateOrigin), response_headers_.get(), |
339 kAppropriateFeatureName)); | 313 kAppropriateFeatureName, Now())); |
340 } | 314 } |
341 | 315 |
342 // Flaky on Android swarming bots: crbug.com/672294 | 316 TEST_F(TrialTokenValidatorTest, ValidateRequestMultipleHeaders) { |
343 #if defined(OS_ANDROID) | |
344 #define MAYBE_ValidateRequestMultipleHeaders DISABLED_ValidateRequestMultipleHea
ders | |
345 #else | |
346 #define MAYBE_ValidateRequestMultipleHeaders ValidateRequestMultipleHeaders | |
347 #endif | |
348 TEST_F(TrialTokenValidatorTest, MAYBE_ValidateRequestMultipleHeaders) { | |
349 response_headers_->AddHeader(std::string("Origin-Trial: ") + kSampleToken); | 317 response_headers_->AddHeader(std::string("Origin-Trial: ") + kSampleToken); |
350 response_headers_->AddHeader(std::string("Origin-Trial: ") + kExpiredToken); | 318 response_headers_->AddHeader(std::string("Origin-Trial: ") + kExpiredToken); |
351 EXPECT_TRUE(TrialTokenValidator::RequestEnablesFeature( | 319 EXPECT_TRUE(TrialTokenValidator::RequestEnablesFeature( |
352 GURL(kAppropriateOrigin), response_headers_.get(), | 320 GURL(kAppropriateOrigin), response_headers_.get(), |
353 kAppropriateFeatureName)); | 321 kAppropriateFeatureName, Now())); |
354 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( | 322 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( |
355 GURL(kAppropriateOrigin), response_headers_.get(), | 323 GURL(kAppropriateOrigin), response_headers_.get(), |
356 kInappropriateFeatureName)); | 324 kInappropriateFeatureName, Now())); |
357 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( | 325 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( |
358 GURL(kInappropriateOrigin), response_headers_.get(), | 326 GURL(kInappropriateOrigin), response_headers_.get(), |
359 kAppropriateFeatureName)); | 327 kAppropriateFeatureName, Now())); |
360 } | 328 } |
361 | 329 |
362 // Flaky on Android swarming bots: crbug.com/672294 | 330 TEST_F(TrialTokenValidatorTest, ValidateRequestMultipleHeaderValues) { |
363 #if defined(OS_ANDROID) | |
364 #define MAYBE_ValidateRequestMultipleHeaderValues DISABLED_ValidateRequestMultip
leHeaderValues | |
365 #else | |
366 #define MAYBE_ValidateRequestMultipleHeaderValues ValidateRequestMultipleHeaderV
alues | |
367 #endif | |
368 TEST_F(TrialTokenValidatorTest, MAYBE_ValidateRequestMultipleHeaderValues) { | |
369 response_headers_->AddHeader(std::string("Origin-Trial: ") + kExpiredToken + | 331 response_headers_->AddHeader(std::string("Origin-Trial: ") + kExpiredToken + |
370 ", " + kSampleToken); | 332 ", " + kSampleToken); |
371 EXPECT_TRUE(TrialTokenValidator::RequestEnablesFeature( | 333 EXPECT_TRUE(TrialTokenValidator::RequestEnablesFeature( |
372 GURL(kAppropriateOrigin), response_headers_.get(), | 334 GURL(kAppropriateOrigin), response_headers_.get(), |
373 kAppropriateFeatureName)); | 335 kAppropriateFeatureName, Now())); |
374 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( | 336 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( |
375 GURL(kAppropriateOrigin), response_headers_.get(), | 337 GURL(kAppropriateOrigin), response_headers_.get(), |
376 kInappropriateFeatureName)); | 338 kInappropriateFeatureName, Now())); |
377 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( | 339 EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( |
378 GURL(kInappropriateOrigin), response_headers_.get(), | 340 GURL(kInappropriateOrigin), response_headers_.get(), |
379 kAppropriateFeatureName)); | 341 kAppropriateFeatureName, Now())); |
380 } | 342 } |
381 | 343 |
382 } // namespace content | 344 } // namespace content |
OLD | NEW |