Index: content/common/origin_trials/trial_token_unittest.cc |
diff --git a/content/common/origin_trials/trial_token_unittest.cc b/content/common/origin_trials/trial_token_unittest.cc |
index dd8350860fc34a3e994efaab11c9a8dff7998072..d10f5b6dd66025011fc04ab17f640dc3a9ba5b19 100644 |
--- a/content/common/origin_trials/trial_token_unittest.cc |
+++ b/content/common/origin_trials/trial_token_unittest.cc |
@@ -49,13 +49,11 @@ const uint8_t kTestPublicKey2[] = { |
// This is a good trial token, signed with the above test private key. |
const char* kSampleToken = |
- "1|UsEO0cNxoUtBnHDJdGPWTlXuLENjXcEIPL7Bs7sbvicPCcvAtyqhQuTJ9h/u1R3VZpWigtI+" |
- "SdUwk7Dyk/qbDw==|https://valid.example.com|Frobulate|1458766277"; |
-const uint8_t kExpectedVersion = 1; |
-const char* kExpectedSignature = |
- "UsEO0cNxoUtBnHDJdGPWTlXuLENjXcEIPL7Bs7sbvicPCcvAtyqhQuTJ9h/u1R3VZpWigtI+S" |
- "dUwk7Dyk/qbDw=="; |
-const char* kExpectedData = "https://valid.example.com|Frobulate|1458766277"; |
+ "AesWbWX2tRJ0+oGm0ybp9ccm8YTjbV0z5aMVyw2a5zr59hjUU9zLFTgPSz0SPsSU" |
+ "0c4y51N/9Gx/oLI9W93ZHQkAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l" |
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5" |
+ "IjogMTQ1ODc2NjI3N30="; |
+ |
const char* kExpectedFeatureName = "Frobulate"; |
const char* kExpectedOrigin = "https://valid.example.com"; |
const uint64_t kExpectedExpiry = 1458766277; |
@@ -74,39 +72,64 @@ double kInvalidTimestamp = 1458766278.0; |
// Well-formed trial token with an invalid signature. |
const char* kInvalidSignatureToken = |
- "1|CO8hDne98QeFeOJ0DbRZCBN3uE0nyaPgaLlkYhSWnbRoDfEAg+TXELaYfQPfEvKYFauBg/" |
- "hnxmba765hz0mXMc==|https://valid.example.com|Frobulate|1458766277"; |
+ "AYeNXSDktgG9p4ns5B1WKsLq2TytMxfR4whfbi+oyT0rXyzh+qXYfxbDMGmyjU2Z" |
+ "lEJ16vQObMXJoOaYUqd8xwkAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l" |
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5" |
+ "IjogMTQ1ODc2NjI3N30="; |
+ |
+// Trial token truncated in the middle of the length field; too short to |
+// possibly be valid. |
+const char kTruncatedToken[] = |
+ "AesWbWX2tRJ0+oGm0ybp9ccm8YTjbV0z5aMVyw2a5zr59hjUU9zLFTgPSz0SPsSU" |
+ "0c4y51N/9Gx/oLI9W93ZHQkA"; |
+ |
+// Trial token with an incorrectly-declared length, but with a valid signature. |
+const char kIncorrectLengthToken[] = |
+ "AQruItutcZelo3W81CdbVHuUFygSJ6Zpktgnl1JIE+QHEMz0ZqjITe1nWdq7c1VC" |
+ "EdMFVozO5VIgX3mUWYLsTw4AAABaeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l" |
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5" |
+ "IjogMTQ1ODc2NjI3N30="; |
+ |
+// Trial token with a misidentified version (2). |
+const char kIncorrectVersionToken[] = |
+ "Ap+Q/Qm0ELadZql+dlEGSwnAVsFZKgCEtUZg8idQC3uekkIeSZIY1tftoYdrwhqj" |
+ "7FO5L22sNvkZZnacLvmfNwsAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l" |
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5" |
+ "IjogMTQ1ODc2NjI3N30="; |
+ |
+const char kSampleTokenJSON[] = |
+ "{\"origin\": \"https://valid.example.com:443\", \"feature\": " |
+ "\"Frobulate\", \"expiry\": 1458766277}"; |
// Various ill-formed trial tokens. These should all fail to parse. |
const char* kInvalidTokens[] = { |
- // Invalid - only one part |
+ // Invalid - Not JSON at all |
"abcde", |
- // Not enough parts |
- "https://valid.example.com|FeatureName|1458766277", |
- "Signature|https://valid.example.com|FeatureName|1458766277", |
- // Non-numeric version |
- "a|Signature|https://valid.example.com|FeatureName|1458766277", |
- "1x|Signature|https://valid.example.com|FeatureName|1458766277", |
- // Unsupported version (< min, > max, negative, overflow) |
- "0|Signature|https://valid.example.com|FeatureName|1458766277", |
- "2|Signature|https://valid.example.com|FeatureName|1458766277", |
- "-1|Signature|https://valid.example.com|FeatureName|1458766277", |
- "99999|Signature|https://valid.example.com|FeatureName|1458766277", |
- // Delimiter in feature name |
- "1|Signature|https://valid.example.com|Feature|Name|1458766277", |
- // Extra string field |
- "1|Signature|https://valid.example.com|FeatureName|1458766277|ExtraField", |
- // Extra numeric field |
- "1|Signature|https://valid.example.com|FeatureName|1458766277|1458766277", |
- // Non-numeric expiry timestamp |
- "1|Signature|https://valid.example.com|FeatureName|abcdefghij", |
- "1|Signature|https://valid.example.com|FeatureName|1458766277x", |
+ // Invalid JSON |
+ "{", |
+ // Not an object |
+ "\"abcde\"", |
+ "123.4", |
+ "[0, 1, 2]", |
+ // Missing keys |
+ "{}", |
+ "{\"something\": 1}", |
+ "{\"origin\": \"https://a.a\"}", |
+ "{\"origin\": \"https://a.a\", \"feature\": \"a\"}" |
+ "{\"origin\": \"https://a.a\", \"expiry\": 1458766277}", |
+ "{\"feature\": \"FeatureName\", \"expiry\": 1458766277}", |
+ // Incorrect types |
+ "{\"origin\": 1, \"feature\": \"a\", \"expiry\": 1458766277}", |
+ "{\"origin\": \"https://a.a\", \"feature\": 1, \"expiry\": 1458766277}", |
+ "{\"origin\": \"https://a.a\", \"feature\": \"a\", \"expiry\": \"1\"}", |
// Negative expiry timestamp |
- "1|Signature|https://valid.example.com|FeatureName|-1458766277", |
+ "{\"origin\": \"https://a.a\", \"feature\": \"a\", \"expiry\": -1}", |
// Origin not a proper origin URL |
- "1|Signature|abcdef|FeatureName|1458766277", |
- "1|Signature|data:text/plain,abcdef|FeatureName|1458766277", |
- "1|Signature|javascript:alert(1)|FeatureName|1458766277"}; |
+ "{\"origin\": \"abcdef\", \"feature\": \"a\", \"expiry\": 1458766277}", |
+ "{\"origin\": \"data:text/plain,abcdef\", \"feature\": \"a\", \"expiry\": " |
+ "1458766277}", |
+ "{\"origin\": \"javascript:alert(1)\", \"feature\": \"a\", \"expiry\": " |
+ "1458766277}"}; |
const size_t kNumInvalidTokens = arraysize(kInvalidTokens); |
} // namespace |
@@ -154,6 +177,57 @@ class TrialTokenTest : public testing::Test { |
base::StringPiece incorrect_public_key_; |
}; |
+// Test the extraction of the signed payload from token strings. This includes |
+// checking the included version identifier, payload length, and cryptographic |
+// signature. |
+ |
+/* Test verification of signature and extraction of token JSON from signed token |
+ */ |
+TEST_F(TrialTokenTest, ValidateValidSignature) { |
+ scoped_ptr<std::string> tokenJSON = |
+ TrialToken::Extract(kSampleToken, correct_public_key()); |
+ ASSERT_TRUE(tokenJSON); |
+ EXPECT_STREQ(kSampleTokenJSON, tokenJSON.get()->c_str()); |
+} |
+ |
+TEST_F(TrialTokenTest, ValidateInvalidSignature) { |
+ scoped_ptr<std::string> tokenJSON = |
+ TrialToken::Extract(kInvalidSignatureToken, correct_public_key()); |
+ ASSERT_FALSE(tokenJSON); |
+} |
+ |
+TEST_F(TrialTokenTest, ValidateSignatureWithIncorrectKey) { |
+ scoped_ptr<std::string> tokenJSON = |
+ TrialToken::Extract(kSampleToken, incorrect_public_key()); |
+ ASSERT_FALSE(tokenJSON); |
+} |
+ |
+TEST_F(TrialTokenTest, ValidateEmptyToken) { |
+ scoped_ptr<std::string> tokenJSON = |
+ TrialToken::Extract("", correct_public_key()); |
+ ASSERT_FALSE(tokenJSON); |
+} |
+ |
+TEST_F(TrialTokenTest, ValidateShortToken) { |
+ scoped_ptr<std::string> tokenJSON = |
+ TrialToken::Extract(kTruncatedToken, correct_public_key()); |
+ ASSERT_FALSE(tokenJSON); |
+} |
+ |
+TEST_F(TrialTokenTest, ValidateUnsupportedVersion) { |
+ scoped_ptr<std::string> tokenJSON = |
+ TrialToken::Extract(kIncorrectVersionToken, correct_public_key()); |
+ ASSERT_FALSE(tokenJSON); |
+} |
+ |
+TEST_F(TrialTokenTest, ValidateSignatureWithIncorrectLength) { |
+ scoped_ptr<std::string> token = |
+ TrialToken::Extract(kIncorrectLengthToken, correct_public_key()); |
+ ASSERT_FALSE(token); |
+} |
+ |
+/* Test parsing of fields from JSON token */ |
+ |
TEST_F(TrialTokenTest, ParseEmptyString) { |
scoped_ptr<TrialToken> empty_token = TrialToken::Parse(""); |
EXPECT_FALSE(empty_token); |
@@ -168,18 +242,15 @@ TEST_F(TrialTokenTest, ParseInvalidStrings) { |
} |
TEST_F(TrialTokenTest, ParseValidToken) { |
- scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
+ scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleTokenJSON); |
ASSERT_TRUE(token); |
- EXPECT_EQ(kExpectedVersion, token->version()); |
EXPECT_EQ(kExpectedFeatureName, token->feature_name()); |
- EXPECT_EQ(kExpectedSignature, token->signature()); |
- EXPECT_EQ(kExpectedData, token->data()); |
EXPECT_EQ(expected_origin_, token->origin()); |
EXPECT_EQ(base::Time::FromDoubleT(kExpectedExpiry), token->expiry_time()); |
} |
TEST_F(TrialTokenTest, ValidateValidToken) { |
- scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
+ scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleTokenJSON); |
ASSERT_TRUE(token); |
EXPECT_TRUE(ValidateOrigin(token.get(), expected_origin_)); |
EXPECT_FALSE(ValidateOrigin(token.get(), invalid_origin_)); |
@@ -197,7 +268,7 @@ TEST_F(TrialTokenTest, ValidateValidToken) { |
} |
TEST_F(TrialTokenTest, TokenIsAppropriateForOriginAndFeature) { |
- scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
+ scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleTokenJSON); |
ASSERT_TRUE(token); |
EXPECT_TRUE(token->IsAppropriate(expected_origin_, kExpectedFeatureName)); |
EXPECT_FALSE(token->IsAppropriate(expected_origin_, |
@@ -209,35 +280,5 @@ TEST_F(TrialTokenTest, TokenIsAppropriateForOriginAndFeature) { |
EXPECT_FALSE(token->IsAppropriate(expected_origin_, kInvalidFeatureName)); |
} |
-TEST_F(TrialTokenTest, ValidateValidSignature) { |
- scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
- ASSERT_TRUE(token); |
- EXPECT_TRUE(ValidateSignature(token.get(), correct_public_key())); |
-} |
- |
-TEST_F(TrialTokenTest, ValidateInvalidSignature) { |
- scoped_ptr<TrialToken> token = TrialToken::Parse(kInvalidSignatureToken); |
- ASSERT_TRUE(token); |
- EXPECT_FALSE(ValidateSignature(token.get(), correct_public_key())); |
-} |
- |
-TEST_F(TrialTokenTest, ValidateTokenWithCorrectKey) { |
- scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
- ASSERT_TRUE(token); |
- EXPECT_TRUE(token->IsValid(base::Time::FromDoubleT(kValidTimestamp), |
- correct_public_key())); |
-} |
- |
-TEST_F(TrialTokenTest, ValidateSignatureWithIncorrectKey) { |
- scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
- ASSERT_TRUE(token); |
- EXPECT_FALSE(token->IsValid(base::Time::FromDoubleT(kValidTimestamp), |
- incorrect_public_key())); |
-} |
- |
-TEST_F(TrialTokenTest, ValidateWhenNotExpired) { |
- scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
- ASSERT_TRUE(token); |
-} |
} // namespace content |