| 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/renderer/origin_trials/trial_token.h" | 5 #include "content/renderer/origin_trials/trial_token.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/strings/string_piece.h" |
| 9 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 10 #include "base/test/simple_test_clock.h" | 11 #include "base/test/simple_test_clock.h" |
| 11 #include "base/time/time.h" | 12 #include "base/time/time.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 13 | 14 |
| 14 namespace content { | 15 namespace content { |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 // This is a sample public key for testing the API. The corresponding private | 19 // This is a sample public key for testing the API. The corresponding private |
| 19 // key (use this to generate new samples for this test file) is: | 20 // key (use this to generate new samples for this test file) is: |
| 20 // | 21 // |
| 21 // 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43, 0x13, | 22 // 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43, 0x13, |
| 22 // 0x4c, 0x67, 0xc4, 0xf4, 0x28, 0xc9, 0x90, 0x15, 0x02, 0xe2, 0xba, | 23 // 0x4c, 0x67, 0xc4, 0xf4, 0x28, 0xc9, 0x90, 0x15, 0x02, 0xe2, 0xba, |
| 23 // 0xfd, 0xbb, 0xfa, 0xbc, 0x92, 0x76, 0x8a, 0x2c, 0x4b, 0xc7, 0x75, | 24 // 0xfd, 0xbb, 0xfa, 0xbc, 0x92, 0x76, 0x8a, 0x2c, 0x4b, 0xc7, 0x75, |
| 24 // 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, 0x9a, | 25 // 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, 0x9a, |
| 25 // 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, 0x64, | 26 // 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, 0x64, |
| 26 // 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0 | 27 // 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0 |
| 27 const uint8_t kTestPublicKey[] = { | 28 const uint8_t kTestPublicKey[] = { |
| 28 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, | 29 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, |
| 29 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, | 30 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, |
| 30 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0, | 31 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0, |
| 31 }; | 32 }; |
| 32 | 33 |
| 34 // This is a valid, but incorrect, public key for testing signatures against. |
| 35 // The corresponding private key is: |
| 36 // |
| 37 // 0x21, 0xee, 0xfa, 0x81, 0x6a, 0xff, 0xdf, 0xb8, 0xc1, 0xdd, 0x75, |
| 38 // 0x05, 0x04, 0x29, 0x68, 0x67, 0x60, 0x85, 0x91, 0xd0, 0x50, 0x16, |
| 39 // 0x0a, 0xcf, 0xa2, 0x37, 0xa3, 0x2e, 0x11, 0x7a, 0x17, 0x96, 0x50, |
| 40 // 0x07, 0x4d, 0x76, 0x55, 0x56, 0x42, 0x17, 0x2d, 0x8a, 0x9c, 0x47, |
| 41 // 0x96, 0x25, 0xda, 0x70, 0xaa, 0xb9, 0xfd, 0x53, 0x5d, 0x51, 0x3e, |
| 42 // 0x16, 0xab, 0xb4, 0x86, 0xea, 0xf3, 0x35, 0xc6, 0xca |
| 43 const uint8_t kTestPublicKey2[] = { |
| 44 0x50, 0x07, 0x4d, 0x76, 0x55, 0x56, 0x42, 0x17, 0x2d, 0x8a, 0x9c, |
| 45 0x47, 0x96, 0x25, 0xda, 0x70, 0xaa, 0xb9, 0xfd, 0x53, 0x5d, 0x51, |
| 46 0x3e, 0x16, 0xab, 0xb4, 0x86, 0xea, 0xf3, 0x35, 0xc6, 0xca, |
| 47 }; |
| 48 |
| 33 // This is a good trial token, signed with the above test private key. | 49 // This is a good trial token, signed with the above test private key. |
| 34 const char* kSampleToken = | 50 const char* kSampleToken = |
| 35 "1|UsEO0cNxoUtBnHDJdGPWTlXuLENjXcEIPL7Bs7sbvicPCcvAtyqhQuTJ9h/u1R3VZpWigtI+" | 51 "1|UsEO0cNxoUtBnHDJdGPWTlXuLENjXcEIPL7Bs7sbvicPCcvAtyqhQuTJ9h/u1R3VZpWigtI+" |
| 36 "SdUwk7Dyk/qbDw==|https://valid.example.com|Frobulate|1458766277"; | 52 "SdUwk7Dyk/qbDw==|https://valid.example.com|Frobulate|1458766277"; |
| 37 const uint8_t kExpectedVersion = 1; | 53 const uint8_t kExpectedVersion = 1; |
| 38 const char* kExpectedSignature = | 54 const char* kExpectedSignature = |
| 39 "UsEO0cNxoUtBnHDJdGPWTlXuLENjXcEIPL7Bs7sbvicPCcvAtyqhQuTJ9h/u1R3VZpWigtI+S" | 55 "UsEO0cNxoUtBnHDJdGPWTlXuLENjXcEIPL7Bs7sbvicPCcvAtyqhQuTJ9h/u1R3VZpWigtI+S" |
| 40 "dUwk7Dyk/qbDw=="; | 56 "dUwk7Dyk/qbDw=="; |
| 41 const char* kExpectedData = "https://valid.example.com|Frobulate|1458766277"; | 57 const char* kExpectedData = "https://valid.example.com|Frobulate|1458766277"; |
| 42 const char* kExpectedFeatureName = "Frobulate"; | 58 const char* kExpectedFeatureName = "Frobulate"; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 "1|Signature|abcdef|FeatureName|1458766277", | 106 "1|Signature|abcdef|FeatureName|1458766277", |
| 91 "1|Signature|data:text/plain,abcdef|FeatureName|1458766277", | 107 "1|Signature|data:text/plain,abcdef|FeatureName|1458766277", |
| 92 "1|Signature|javascript:alert(1)|FeatureName|1458766277"}; | 108 "1|Signature|javascript:alert(1)|FeatureName|1458766277"}; |
| 93 const size_t kNumInvalidTokens = arraysize(kInvalidTokens); | 109 const size_t kNumInvalidTokens = arraysize(kInvalidTokens); |
| 94 | 110 |
| 95 } // namespace | 111 } // namespace |
| 96 | 112 |
| 97 class TrialTokenTest : public testing::Test { | 113 class TrialTokenTest : public testing::Test { |
| 98 public: | 114 public: |
| 99 TrialTokenTest() | 115 TrialTokenTest() |
| 100 : public_key_( | 116 : correct_public_key_( |
| 101 base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey), | 117 base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey), |
| 102 arraysize(kTestPublicKey))) {} | 118 arraysize(kTestPublicKey))), |
| 119 incorrect_public_key_( |
| 120 base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey2), |
| 121 arraysize(kTestPublicKey2))) {} |
| 103 | 122 |
| 104 protected: | 123 protected: |
| 105 bool ValidateOrigin(TrialToken* token, const char* origin) { | 124 bool ValidateOrigin(TrialToken* token, const char* origin) { |
| 106 return token->ValidateOrigin(origin); | 125 return token->ValidateOrigin(origin); |
| 107 } | 126 } |
| 108 | 127 |
| 109 bool ValidateFeatureName(TrialToken* token, const char* feature_name) { | 128 bool ValidateFeatureName(TrialToken* token, const char* feature_name) { |
| 110 return token->ValidateFeatureName(feature_name); | 129 return token->ValidateFeatureName(feature_name); |
| 111 } | 130 } |
| 112 | 131 |
| 113 bool ValidateDate(TrialToken* token, const base::Time& now) { | 132 bool ValidateDate(TrialToken* token, const base::Time& now) { |
| 114 return token->ValidateDate(now); | 133 return token->ValidateDate(now); |
| 115 } | 134 } |
| 116 | 135 |
| 117 bool ValidateSignature(TrialToken* token, | 136 bool ValidateSignature(TrialToken* token, |
| 118 const base::StringPiece& public_key) { | 137 const base::StringPiece& public_key) { |
| 119 return token->ValidateSignature(public_key); | 138 return token->ValidateSignature(public_key); |
| 120 } | 139 } |
| 121 | 140 |
| 122 const base::StringPiece& public_key() { return public_key_; }; | 141 const base::StringPiece& correct_public_key() { return correct_public_key_; } |
| 142 const base::StringPiece& incorrect_public_key() { |
| 143 return incorrect_public_key_; |
| 144 } |
| 123 | 145 |
| 124 private: | 146 private: |
| 125 base::StringPiece public_key_; | 147 base::StringPiece correct_public_key_; |
| 148 base::StringPiece incorrect_public_key_; |
| 126 }; | 149 }; |
| 127 | 150 |
| 128 TEST_F(TrialTokenTest, ParseEmptyString) { | 151 TEST_F(TrialTokenTest, ParseEmptyString) { |
| 129 scoped_ptr<TrialToken> empty_token = TrialToken::Parse(""); | 152 scoped_ptr<TrialToken> empty_token = TrialToken::Parse(""); |
| 130 EXPECT_FALSE(empty_token); | 153 EXPECT_FALSE(empty_token); |
| 131 } | 154 } |
| 132 | 155 |
| 133 TEST_F(TrialTokenTest, ParseInvalidStrings) { | 156 TEST_F(TrialTokenTest, ParseInvalidStrings) { |
| 134 for (size_t i = 0; i < kNumInvalidTokens; ++i) { | 157 for (size_t i = 0; i < kNumInvalidTokens; ++i) { |
| 135 scoped_ptr<TrialToken> empty_token = TrialToken::Parse(kInvalidTokens[i]); | 158 scoped_ptr<TrialToken> empty_token = TrialToken::Parse(kInvalidTokens[i]); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 EXPECT_FALSE(token->IsAppropriate(kExpectedOrigin, | 199 EXPECT_FALSE(token->IsAppropriate(kExpectedOrigin, |
| 177 base::ToLowerASCII(kExpectedFeatureName))); | 200 base::ToLowerASCII(kExpectedFeatureName))); |
| 178 EXPECT_FALSE(token->IsAppropriate(kInvalidOrigin, kExpectedFeatureName)); | 201 EXPECT_FALSE(token->IsAppropriate(kInvalidOrigin, kExpectedFeatureName)); |
| 179 EXPECT_FALSE(token->IsAppropriate(kInsecureOrigin, kExpectedFeatureName)); | 202 EXPECT_FALSE(token->IsAppropriate(kInsecureOrigin, kExpectedFeatureName)); |
| 180 EXPECT_FALSE(token->IsAppropriate(kExpectedOrigin, kInvalidFeatureName)); | 203 EXPECT_FALSE(token->IsAppropriate(kExpectedOrigin, kInvalidFeatureName)); |
| 181 } | 204 } |
| 182 | 205 |
| 183 TEST_F(TrialTokenTest, ValidateValidSignature) { | 206 TEST_F(TrialTokenTest, ValidateValidSignature) { |
| 184 scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); | 207 scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
| 185 ASSERT_TRUE(token); | 208 ASSERT_TRUE(token); |
| 186 EXPECT_TRUE(ValidateSignature(token.get(), public_key())); | 209 EXPECT_TRUE(ValidateSignature(token.get(), correct_public_key())); |
| 187 } | 210 } |
| 188 | 211 |
| 189 TEST_F(TrialTokenTest, ValidateInvalidSignature) { | 212 TEST_F(TrialTokenTest, ValidateInvalidSignature) { |
| 190 scoped_ptr<TrialToken> token = TrialToken::Parse(kInvalidSignatureToken); | 213 scoped_ptr<TrialToken> token = TrialToken::Parse(kInvalidSignatureToken); |
| 191 ASSERT_TRUE(token); | 214 ASSERT_TRUE(token); |
| 192 EXPECT_FALSE(ValidateSignature(token.get(), public_key())); | 215 EXPECT_FALSE(ValidateSignature(token.get(), correct_public_key())); |
| 193 } | 216 } |
| 194 | 217 |
| 195 TEST_F(TrialTokenTest, ValidateSignatureOnWrongKey) { | 218 TEST_F(TrialTokenTest, ValidateTokenWithCorrectKey) { |
| 196 scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); | 219 scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
| 197 ASSERT_TRUE(token); | 220 ASSERT_TRUE(token); |
| 198 // Signature will be invalid if tested against the real public key | 221 EXPECT_TRUE(token->IsValid(base::Time::FromDoubleT(kValidTimestamp), |
| 199 EXPECT_FALSE(token->IsValid(base::Time::FromDoubleT(kValidTimestamp))); | 222 correct_public_key())); |
| 223 } |
| 224 |
| 225 TEST_F(TrialTokenTest, ValidateSignatureWithIncorrectKey) { |
| 226 scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
| 227 ASSERT_TRUE(token); |
| 228 EXPECT_FALSE(token->IsValid(base::Time::FromDoubleT(kValidTimestamp), |
| 229 incorrect_public_key())); |
| 200 } | 230 } |
| 201 | 231 |
| 202 TEST_F(TrialTokenTest, ValidateWhenNotExpired) { | 232 TEST_F(TrialTokenTest, ValidateWhenNotExpired) { |
| 203 scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); | 233 scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken); |
| 204 ASSERT_TRUE(token); | 234 ASSERT_TRUE(token); |
| 205 } | 235 } |
| 206 | 236 |
| 207 } // namespace content | 237 } // namespace content |
| OLD | NEW |