Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: content/common/experiments/api_key_unittest.cc

Issue 1522813002: Add public key and signature verification to browser-side API keys (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@keys
Patch Set: Remove pk length param; fix broken test Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/experiments/api_key.h" 5 #include "content/common/experiments/api_key.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_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/test/simple_test_clock.h" 10 #include "base/test/simple_test_clock.h"
11 #include "base/time/time.h" 11 #include "base/time/time.h"
12 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
13 13
14 namespace content { 14 namespace content {
15 15
16 namespace { 16 namespace {
17 17
18 /*
19 This is a sample public key for testing the API. The corresponding private
20 key (use this to generate new samples for this test file) is
21
22 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43,
23 0x13, 0x4c, 0x67, 0xc4, 0xf4, 0x28, 0xc9, 0x90, 0x15, 0x02,
24 0xe2, 0xba, 0xfd, 0xbb, 0xfa, 0xbc, 0x92, 0x76, 0x8a, 0x2c,
25 0x4b, 0xc7, 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9,
26 0x28, 0x70, 0xd2, 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b,
27 0xb7, 0xd5, 0xca, 0x1f, 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0,
28 0x56, 0x3a, 0x04, 0xd0
29 */
davidben 2016/01/11 20:18:57 Nit: I think // C++-style comments are more common
iclelland 2016/01/12 14:52:49 Switched. When this was a PEM-formatted RSA key, I
30 const uint8_t kTestPublicKey[] = {
31 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2,
32 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f,
33 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0,
34 };
35
36 // This is a good key, signed with the above test private key.
18 const char* kSampleAPIKey = 37 const char* kSampleAPIKey =
19 "Signature|https://valid.example.com|Frobulate|1458766277"; 38 "UsEO0cNxoUtBnHDJdGPWTlXuLENjXcEIPL7Bs7sbvicPCcvAtyqhQuTJ9h/u1R3VZpWigtI+S"
20 39 "dUwk7Dyk/qbDw==|https://valid.example.com|Frobulate|1458766277";
21 const char* kExpectedAPIKeySignature = "Signature"; 40 const char* kExpectedAPIKeySignature =
41 "UsEO0cNxoUtBnHDJdGPWTlXuLENjXcEIPL7Bs7sbvicPCcvAtyqhQuTJ9h/u1R3VZpWigtI+S"
42 "dUwk7Dyk/qbDw==";
22 const char* kExpectedAPIKeyData = 43 const char* kExpectedAPIKeyData =
23 "https://valid.example.com|Frobulate|1458766277"; 44 "https://valid.example.com|Frobulate|1458766277";
24 const char* kExpectedAPIName = "Frobulate"; 45 const char* kExpectedAPIName = "Frobulate";
25 const char* kExpectedOrigin = "https://valid.example.com"; 46 const char* kExpectedOrigin = "https://valid.example.com";
26 const uint64_t kExpectedExpiry = 1458766277; 47 const uint64_t kExpectedExpiry = 1458766277;
27 48
28 // The key should not be valid for this origin, or for this API. 49 // The key should not be valid for this origin, or for this API.
29 const char* kInvalidOrigin = "https://invalid.example.com"; 50 const char* kInvalidOrigin = "https://invalid.example.com";
30 const char* kInsecureOrigin = "http://valid.example.com"; 51 const char* kInsecureOrigin = "http://valid.example.com";
31 const char* kInvalidAPIName = "Grokalyze"; 52 const char* kInvalidAPIName = "Grokalyze";
32 53
33 // The key should be valid if the current time is kValidTimestamp or earlier. 54 // The key should be valid if the current time is kValidTimestamp or earlier.
34 double kValidTimestamp = 1458766276.0; 55 double kValidTimestamp = 1458766276.0;
35 56
36 // The key should be invalid if the current time is kInvalidTimestamp or later. 57 // The key should be invalid if the current time is kInvalidTimestamp or later.
37 double kInvalidTimestamp = 1458766278.0; 58 double kInvalidTimestamp = 1458766278.0;
38 59
60 // Well-formed API key with an invalid signature.
61 const char* kInvalidSignatureAPIKey =
62 "CO8hDne98QeFeOJ0DbRZCBN3uE0nyaPgaLlkYhSWnbRoDfEAg+TXELaYfQPfEvKYFauBg/hnx"
63 "mba765hz0mXMc==|https://valid.example.com|Frobulate|1458766277";
64
39 // Various ill-formed API keys. These should all fail to parse. 65 // Various ill-formed API keys. These should all fail to parse.
40 const char* kInvalidAPIKeys[] = { 66 const char* kInvalidAPIKeys[] = {
41 // Invalid - only one part 67 // Invalid - only one part
42 "abcde", 68 "abcde",
43 // Not enough parts 69 // Not enough parts
44 "https://valid.example.com|APIName|1458766277", 70 "https://valid.example.com|APIName|1458766277",
45 // Delimiter in API Name 71 // Delimiter in API Name
46 "Signature|https://valid.example.com|API|Name|1458766277", 72 "Signature|https://valid.example.com|API|Name|1458766277",
47 // Extra string field 73 // Extra string field
48 "Signature|https://valid.example.com|APIName|1458766277|SomethingElse", 74 "Signature|https://valid.example.com|APIName|1458766277|SomethingElse",
(...skipping 18 matching lines...) Expand all
67 return api_key->ValidateOrigin(origin); 93 return api_key->ValidateOrigin(origin);
68 } 94 }
69 95
70 bool ValidateApiName(ApiKey* api_key, const char* api_name) { 96 bool ValidateApiName(ApiKey* api_key, const char* api_name) {
71 return api_key->ValidateApiName(api_name); 97 return api_key->ValidateApiName(api_name);
72 } 98 }
73 99
74 bool ValidateDate(ApiKey* api_key, const base::Time& now) { 100 bool ValidateDate(ApiKey* api_key, const base::Time& now) {
75 return api_key->ValidateDate(now); 101 return api_key->ValidateDate(now);
76 } 102 }
103
104 bool ValidateSignature(ApiKey* api_key,
105 const uint8_t* public_key) {
106 return api_key->ValidateSignature(public_key);
107 }
77 }; 108 };
78 109
79 TEST_F(ApiKeyTest, ParseEmptyString) { 110 TEST_F(ApiKeyTest, ParseEmptyString) {
80 scoped_ptr<ApiKey> empty_key = ApiKey::Parse(""); 111 scoped_ptr<ApiKey> empty_key = ApiKey::Parse("");
81 EXPECT_FALSE(empty_key); 112 EXPECT_FALSE(empty_key);
82 } 113 }
83 114
84 TEST_F(ApiKeyTest, ParseInvalidStrings) { 115 TEST_F(ApiKeyTest, ParseInvalidStrings) {
85 for (size_t i = 0; i < kNumInvalidAPIKeys; ++i) { 116 for (size_t i = 0; i < kNumInvalidAPIKeys; ++i) {
86 scoped_ptr<ApiKey> empty_key = ApiKey::Parse(kInvalidAPIKeys[i]); 117 scoped_ptr<ApiKey> empty_key = ApiKey::Parse(kInvalidAPIKeys[i]);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 EXPECT_TRUE(key->IsAppropriate(kExpectedOrigin, kExpectedAPIName)); 150 EXPECT_TRUE(key->IsAppropriate(kExpectedOrigin, kExpectedAPIName));
120 EXPECT_TRUE(key->IsAppropriate(kExpectedOrigin, 151 EXPECT_TRUE(key->IsAppropriate(kExpectedOrigin,
121 base::ToUpperASCII(kExpectedAPIName))); 152 base::ToUpperASCII(kExpectedAPIName)));
122 EXPECT_TRUE(key->IsAppropriate(kExpectedOrigin, 153 EXPECT_TRUE(key->IsAppropriate(kExpectedOrigin,
123 base::ToLowerASCII(kExpectedAPIName))); 154 base::ToLowerASCII(kExpectedAPIName)));
124 EXPECT_FALSE(key->IsAppropriate(kInvalidOrigin, kExpectedAPIName)); 155 EXPECT_FALSE(key->IsAppropriate(kInvalidOrigin, kExpectedAPIName));
125 EXPECT_FALSE(key->IsAppropriate(kInsecureOrigin, kExpectedAPIName)); 156 EXPECT_FALSE(key->IsAppropriate(kInsecureOrigin, kExpectedAPIName));
126 EXPECT_FALSE(key->IsAppropriate(kExpectedOrigin, kInvalidAPIName)); 157 EXPECT_FALSE(key->IsAppropriate(kExpectedOrigin, kInvalidAPIName));
127 } 158 }
128 159
160 TEST_F(ApiKeyTest, ValidateValidSignature) {
161 scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey);
162 ASSERT_TRUE(key);
163 EXPECT_TRUE(
164 ValidateSignature(key.get(), kTestPublicKey));
165 }
166
167 TEST_F(ApiKeyTest, ValidateInvalidSignature) {
168 scoped_ptr<ApiKey> key = ApiKey::Parse(kInvalidSignatureAPIKey);
169 ASSERT_TRUE(key);
170 EXPECT_FALSE(
171 ValidateSignature(key.get(), kTestPublicKey));
172 }
173
174 TEST_F(ApiKeyTest, ValidateSignatureOnWrongKey) {
175 scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey);
176 ASSERT_TRUE(key);
177 // Signature will be invalid if tested against the real public key
178 EXPECT_FALSE(key->IsValid(base::Time::FromDoubleT(kValidTimestamp)));
179 }
180
181 TEST_F(ApiKeyTest, ValidateWhenNotExpired) {
182 scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey);
183 ASSERT_TRUE(key);
184 }
185
129 } // namespace content 186 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698