| 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
|
|
|