OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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.h" | 5 #include "content/common/origin_trials/trial_token.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/strings/string_piece.h" | 10 #include "base/strings/string_piece.h" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "base/test/simple_test_clock.h" | 12 #include "base/test/simple_test_clock.h" |
13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 #include "third_party/WebKit/public/platform/WebOriginTrialTokenStatus.h" |
15 #include "url/gurl.h" | 16 #include "url/gurl.h" |
16 | 17 |
17 namespace content { | 18 namespace content { |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 // This is a sample public key for testing the API. The corresponding private | 22 // This is a sample public key for testing the API. The corresponding private |
22 // key (use this to generate new samples for this test file) is: | 23 // key (use this to generate new samples for this test file) is: |
23 // | 24 // |
24 // 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43, 0x13, | 25 // 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43, 0x13, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 | 69 |
69 // The token should be valid if the current time is kValidTimestamp or earlier. | 70 // The token should be valid if the current time is kValidTimestamp or earlier. |
70 double kValidTimestamp = 1458766276.0; | 71 double kValidTimestamp = 1458766276.0; |
71 | 72 |
72 // The token should be invalid if the current time is kInvalidTimestamp or | 73 // The token should be invalid if the current time is kInvalidTimestamp or |
73 // later. | 74 // later. |
74 double kInvalidTimestamp = 1458766278.0; | 75 double kInvalidTimestamp = 1458766278.0; |
75 | 76 |
76 // Well-formed trial token with an invalid signature. | 77 // Well-formed trial token with an invalid signature. |
77 const char* kInvalidSignatureToken = | 78 const char* kInvalidSignatureToken = |
78 "AYeNXSDktgG9p4ns5B1WKsLq2TytMxfR4whfbi+oyT0rXyzh+qXYfxbDMGmyjU2Z" | 79 "Ap+Q/Qm0ELadZql+dlEGSwnAVsFZKgCEtUZg8idQC3uekkIeSZIY1tftoYdrwhqj" |
79 "lEJ16vQObMXJoOaYUqd8xwkAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l" | 80 "7FO5L22sNvkZZnacLvmfNwsAAABaeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l" |
80 "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5" | 81 "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGV4IiwgImV4cGly" |
81 "IjogMTQ1ODc2NjI3N30="; | 82 "eSI6IDE0NTg3NjYyNzd9"; |
82 | 83 |
83 // Trial token truncated in the middle of the length field; too short to | 84 // Trial token truncated in the middle of the length field; too short to |
84 // possibly be valid. | 85 // possibly be valid. |
85 const char kTruncatedToken[] = | 86 const char kTruncatedToken[] = |
86 "Ap+Q/Qm0ELadZql+dlEGSwnAVsFZKgCEtUZg8idQC3uekkIeSZIY1tftoYdrwhqj" | 87 "Ap+Q/Qm0ELadZql+dlEGSwnAVsFZKgCEtUZg8idQC3uekkIeSZIY1tftoYdrwhqj" |
87 "7FO5L22sNvkZZnacLvmfNwsA"; | 88 "7FO5L22sNvkZZnacLvmfNwsA"; |
88 | 89 |
89 // Trial token with an incorrectly-declared length, but with a valid signature. | 90 // Trial token with an incorrectly-declared length, but with a valid signature. |
90 const char kIncorrectLengthToken[] = | 91 const char kIncorrectLengthToken[] = |
91 "Ao06eNl/CZuM88qurWKX4RfoVEpHcVHWxdOTrEXZkaC1GUHyb/8L4sthADiVWdc9" | 92 "Ao06eNl/CZuM88qurWKX4RfoVEpHcVHWxdOTrEXZkaC1GUHyb/8L4sthADiVWdc9" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 valid_timestamp_(base::Time::FromDoubleT(kValidTimestamp)), | 147 valid_timestamp_(base::Time::FromDoubleT(kValidTimestamp)), |
147 invalid_timestamp_(base::Time::FromDoubleT(kInvalidTimestamp)), | 148 invalid_timestamp_(base::Time::FromDoubleT(kInvalidTimestamp)), |
148 correct_public_key_( | 149 correct_public_key_( |
149 base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey), | 150 base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey), |
150 arraysize(kTestPublicKey))), | 151 arraysize(kTestPublicKey))), |
151 incorrect_public_key_( | 152 incorrect_public_key_( |
152 base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey2), | 153 base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey2), |
153 arraysize(kTestPublicKey2))) {} | 154 arraysize(kTestPublicKey2))) {} |
154 | 155 |
155 protected: | 156 protected: |
156 std::unique_ptr<std::string> Extract(const std::string& token_text, | 157 blink::WebOriginTrialTokenStatus Extract(const std::string& token_text, |
157 base::StringPiece public_key) { | 158 base::StringPiece public_key, |
158 return TrialToken::Extract(token_text, public_key); | 159 std::string* token_payload) { |
| 160 return TrialToken::Extract(token_text, public_key, token_payload); |
159 } | 161 } |
| 162 |
| 163 blink::WebOriginTrialTokenStatus ExtractIgnorePayload( |
| 164 const std::string& token_text, |
| 165 base::StringPiece public_key) { |
| 166 std::string token_payload; |
| 167 return Extract(token_text, public_key, &token_payload); |
| 168 } |
| 169 |
160 std::unique_ptr<TrialToken> Parse(const std::string& token_payload) { | 170 std::unique_ptr<TrialToken> Parse(const std::string& token_payload) { |
161 return TrialToken::Parse(token_payload); | 171 return TrialToken::Parse(token_payload); |
162 } | 172 } |
163 | 173 |
164 bool ValidateOrigin(TrialToken* token, const url::Origin origin) { | 174 bool ValidateOrigin(TrialToken* token, const url::Origin origin) { |
165 return token->ValidateOrigin(origin); | 175 return token->ValidateOrigin(origin); |
166 } | 176 } |
167 | 177 |
168 bool ValidateFeatureName(TrialToken* token, const char* feature_name) { | 178 bool ValidateFeatureName(TrialToken* token, const char* feature_name) { |
169 return token->ValidateFeatureName(feature_name); | 179 return token->ValidateFeatureName(feature_name); |
(...skipping 19 matching lines...) Expand all Loading... |
189 base::StringPiece incorrect_public_key_; | 199 base::StringPiece incorrect_public_key_; |
190 }; | 200 }; |
191 | 201 |
192 // Test the extraction of the signed payload from token strings. This includes | 202 // Test the extraction of the signed payload from token strings. This includes |
193 // checking the included version identifier, payload length, and cryptographic | 203 // checking the included version identifier, payload length, and cryptographic |
194 // signature. | 204 // signature. |
195 | 205 |
196 // Test verification of signature and extraction of token JSON from signed | 206 // Test verification of signature and extraction of token JSON from signed |
197 // token. | 207 // token. |
198 TEST_F(TrialTokenTest, ValidateValidSignature) { | 208 TEST_F(TrialTokenTest, ValidateValidSignature) { |
199 std::unique_ptr<std::string> token_payload = | 209 std::string token_payload; |
200 Extract(kSampleToken, correct_public_key()); | 210 blink::WebOriginTrialTokenStatus status = |
201 ASSERT_TRUE(token_payload); | 211 Extract(kSampleToken, correct_public_key(), &token_payload); |
202 EXPECT_STREQ(kSampleTokenJSON, token_payload.get()->c_str()); | 212 ASSERT_EQ(blink::WebOriginTrialTokenStatus::Success, status); |
| 213 EXPECT_STREQ(kSampleTokenJSON, token_payload.c_str()); |
203 } | 214 } |
204 | 215 |
205 TEST_F(TrialTokenTest, ValidateInvalidSignature) { | 216 TEST_F(TrialTokenTest, ValidateInvalidSignature) { |
206 std::unique_ptr<std::string> token_payload = | 217 blink::WebOriginTrialTokenStatus status = |
207 Extract(kInvalidSignatureToken, correct_public_key()); | 218 ExtractIgnorePayload(kInvalidSignatureToken, correct_public_key()); |
208 ASSERT_FALSE(token_payload); | 219 EXPECT_EQ(blink::WebOriginTrialTokenStatus::InvalidSignature, status); |
209 } | 220 } |
210 | 221 |
211 TEST_F(TrialTokenTest, ValidateSignatureWithIncorrectKey) { | 222 TEST_F(TrialTokenTest, ValidateSignatureWithIncorrectKey) { |
212 std::unique_ptr<std::string> token_payload = | 223 blink::WebOriginTrialTokenStatus status = |
213 Extract(kSampleToken, incorrect_public_key()); | 224 ExtractIgnorePayload(kSampleToken, incorrect_public_key()); |
214 ASSERT_FALSE(token_payload); | 225 EXPECT_EQ(blink::WebOriginTrialTokenStatus::InvalidSignature, status); |
215 } | 226 } |
216 | 227 |
217 TEST_F(TrialTokenTest, ValidateEmptyToken) { | 228 TEST_F(TrialTokenTest, ValidateEmptyToken) { |
218 std::unique_ptr<std::string> token_payload = | 229 blink::WebOriginTrialTokenStatus status = |
219 Extract("", correct_public_key()); | 230 ExtractIgnorePayload("", correct_public_key()); |
220 ASSERT_FALSE(token_payload); | 231 EXPECT_EQ(blink::WebOriginTrialTokenStatus::Malformed, status); |
221 } | 232 } |
222 | 233 |
223 TEST_F(TrialTokenTest, ValidateShortToken) { | 234 TEST_F(TrialTokenTest, ValidateShortToken) { |
224 std::unique_ptr<std::string> token_payload = | 235 blink::WebOriginTrialTokenStatus status = |
225 Extract(kTruncatedToken, correct_public_key()); | 236 ExtractIgnorePayload(kTruncatedToken, correct_public_key()); |
226 ASSERT_FALSE(token_payload); | 237 EXPECT_EQ(blink::WebOriginTrialTokenStatus::Malformed, status); |
227 } | 238 } |
228 | 239 |
229 TEST_F(TrialTokenTest, ValidateUnsupportedVersion) { | 240 TEST_F(TrialTokenTest, ValidateUnsupportedVersion) { |
230 std::unique_ptr<std::string> token_payload = | 241 blink::WebOriginTrialTokenStatus status = |
231 Extract(kIncorrectVersionToken, correct_public_key()); | 242 ExtractIgnorePayload(kIncorrectVersionToken, correct_public_key()); |
232 ASSERT_FALSE(token_payload); | 243 EXPECT_EQ(blink::WebOriginTrialTokenStatus::WrongVersion, status); |
233 } | 244 } |
234 | 245 |
235 TEST_F(TrialTokenTest, ValidateSignatureWithIncorrectLength) { | 246 TEST_F(TrialTokenTest, ValidateSignatureWithIncorrectLength) { |
236 std::unique_ptr<std::string> token_payload = | 247 blink::WebOriginTrialTokenStatus status = |
237 Extract(kIncorrectLengthToken, correct_public_key()); | 248 ExtractIgnorePayload(kIncorrectLengthToken, correct_public_key()); |
238 ASSERT_FALSE(token_payload); | 249 EXPECT_EQ(blink::WebOriginTrialTokenStatus::Malformed, status); |
239 } | 250 } |
240 | 251 |
241 // Test parsing of fields from JSON token. | 252 // Test parsing of fields from JSON token. |
242 | 253 |
243 TEST_F(TrialTokenTest, ParseEmptyString) { | 254 TEST_F(TrialTokenTest, ParseEmptyString) { |
244 std::unique_ptr<TrialToken> empty_token = Parse(""); | 255 std::unique_ptr<TrialToken> empty_token = Parse(""); |
245 EXPECT_FALSE(empty_token); | 256 EXPECT_FALSE(empty_token); |
246 } | 257 } |
247 | 258 |
248 TEST_P(TrialTokenTest, ParseInvalidString) { | 259 TEST_P(TrialTokenTest, ParseInvalidString) { |
(...skipping 23 matching lines...) Expand all Loading... |
272 token.get(), base::ToUpperASCII(kExpectedFeatureName).c_str())); | 283 token.get(), base::ToUpperASCII(kExpectedFeatureName).c_str())); |
273 EXPECT_FALSE(ValidateFeatureName( | 284 EXPECT_FALSE(ValidateFeatureName( |
274 token.get(), base::ToLowerASCII(kExpectedFeatureName).c_str())); | 285 token.get(), base::ToLowerASCII(kExpectedFeatureName).c_str())); |
275 EXPECT_TRUE(ValidateDate(token.get(), valid_timestamp_)); | 286 EXPECT_TRUE(ValidateDate(token.get(), valid_timestamp_)); |
276 EXPECT_FALSE(ValidateDate(token.get(), invalid_timestamp_)); | 287 EXPECT_FALSE(ValidateDate(token.get(), invalid_timestamp_)); |
277 } | 288 } |
278 | 289 |
279 TEST_F(TrialTokenTest, TokenIsValidForFeature) { | 290 TEST_F(TrialTokenTest, TokenIsValidForFeature) { |
280 std::unique_ptr<TrialToken> token = Parse(kSampleTokenJSON); | 291 std::unique_ptr<TrialToken> token = Parse(kSampleTokenJSON); |
281 ASSERT_TRUE(token); | 292 ASSERT_TRUE(token); |
282 EXPECT_TRUE(token->IsValidForFeature(expected_origin_, kExpectedFeatureName, | 293 EXPECT_EQ(blink::WebOriginTrialTokenStatus::Success, |
283 valid_timestamp_)); | 294 token->IsValidForFeature(expected_origin_, kExpectedFeatureName, |
284 EXPECT_FALSE(token->IsValidForFeature( | 295 valid_timestamp_)); |
285 expected_origin_, base::ToUpperASCII(kExpectedFeatureName), | 296 EXPECT_EQ(blink::WebOriginTrialTokenStatus::WrongFeature, |
286 valid_timestamp_)); | 297 token->IsValidForFeature(expected_origin_, |
287 EXPECT_FALSE(token->IsValidForFeature( | 298 base::ToUpperASCII(kExpectedFeatureName), |
288 expected_origin_, base::ToLowerASCII(kExpectedFeatureName), | 299 valid_timestamp_)); |
289 valid_timestamp_)); | 300 EXPECT_EQ(blink::WebOriginTrialTokenStatus::WrongFeature, |
290 EXPECT_FALSE(token->IsValidForFeature(invalid_origin_, kExpectedFeatureName, | 301 token->IsValidForFeature(expected_origin_, |
291 valid_timestamp_)); | 302 base::ToLowerASCII(kExpectedFeatureName), |
292 EXPECT_FALSE(token->IsValidForFeature(insecure_origin_, kExpectedFeatureName, | 303 valid_timestamp_)); |
293 valid_timestamp_)); | 304 EXPECT_EQ(blink::WebOriginTrialTokenStatus::WrongOrigin, |
294 EXPECT_FALSE(token->IsValidForFeature(expected_origin_, kInvalidFeatureName, | 305 token->IsValidForFeature(invalid_origin_, kExpectedFeatureName, |
295 valid_timestamp_)); | 306 valid_timestamp_)); |
296 EXPECT_FALSE(token->IsValidForFeature(expected_origin_, kExpectedFeatureName, | 307 EXPECT_EQ(blink::WebOriginTrialTokenStatus::WrongOrigin, |
297 invalid_timestamp_)); | 308 token->IsValidForFeature(insecure_origin_, kExpectedFeatureName, |
| 309 valid_timestamp_)); |
| 310 EXPECT_EQ(blink::WebOriginTrialTokenStatus::WrongFeature, |
| 311 token->IsValidForFeature(expected_origin_, kInvalidFeatureName, |
| 312 valid_timestamp_)); |
| 313 EXPECT_EQ(blink::WebOriginTrialTokenStatus::Expired, |
| 314 token->IsValidForFeature(expected_origin_, kExpectedFeatureName, |
| 315 invalid_timestamp_)); |
| 316 } |
| 317 |
| 318 // Test overall extraction, to ensure output status matches returned token |
| 319 TEST_F(TrialTokenTest, ExtractValidToken) { |
| 320 blink::WebOriginTrialTokenStatus status; |
| 321 std::unique_ptr<TrialToken> token = |
| 322 TrialToken::From(kSampleToken, correct_public_key(), &status); |
| 323 EXPECT_TRUE(token); |
| 324 EXPECT_EQ(blink::WebOriginTrialTokenStatus::Success, status); |
| 325 } |
| 326 |
| 327 TEST_F(TrialTokenTest, ExtractInvalidSignature) { |
| 328 blink::WebOriginTrialTokenStatus status; |
| 329 std::unique_ptr<TrialToken> token = |
| 330 TrialToken::From(kSampleToken, incorrect_public_key(), &status); |
| 331 EXPECT_FALSE(token); |
| 332 EXPECT_EQ(blink::WebOriginTrialTokenStatus::InvalidSignature, status); |
| 333 } |
| 334 |
| 335 TEST_F(TrialTokenTest, ExtractMalformedToken) { |
| 336 blink::WebOriginTrialTokenStatus status; |
| 337 std::unique_ptr<TrialToken> token = |
| 338 TrialToken::From(kIncorrectLengthToken, correct_public_key(), &status); |
| 339 EXPECT_FALSE(token); |
| 340 EXPECT_EQ(blink::WebOriginTrialTokenStatus::Malformed, status); |
298 } | 341 } |
299 | 342 |
300 } // namespace content | 343 } // namespace content |
OLD | NEW |