Index: content/browser/experiments/api_key_unittest.cc |
diff --git a/content/browser/experiments/api_key_unittest.cc b/content/browser/experiments/api_key_unittest.cc |
index f236c0eac7ef4b719d080b87b206df4e9f2bbecd..3c390f7825e0473bfddb0d93c13d36290e3717f7 100644 |
--- a/content/browser/experiments/api_key_unittest.cc |
+++ b/content/browser/experiments/api_key_unittest.cc |
@@ -13,10 +13,63 @@ namespace content { |
namespace { |
+/* |
+This is a sample public key for testing the API. The corresponding private |
+key (use this to generate new samples for this test file) is |
+ |
+-----BEGIN RSA PRIVATE KEY----- |
+MIIEogIBAAKCAQEA6LVGtcy5JJnH7PHREKHTp3hnmg5cFTmQwG0BdgC81Ew9p4fl |
+ovmxRuV6iMNPOJoHLdflQnAJhEZAt0dQURSlC6X0nSqxdD0yrvB64sJKfZEsMWFH |
+8r3AMYVJN+v2yrYe7JxEKkESmPVIijXVafWz6gW1LnOTKYgtiJtaJ7DlkCucKdT2 |
+Jezlj9PuzXs0AEUG0m584G6g4q6kHw9XQGItMm7R1LlU7Gw0Zy72+L6uXOliLO1x |
+Q/mvAr1oNYCcYtPQdZyMW2ikBIKZO3ElSHR+LC3ZVVb8euwoSPJkpIMwc14/cGud |
+9nFckY3DQFhT9uf6ZTv49surG3P3uT1lNSSu5wIDAQABAoIBACWzyQMHai+t4qBX |
+BWJGdb46Wb6x+OVPcE5c2tG9iNp0h8Cu2duvzLMJ1vJ1gk5PVj5tLi23bTNLFo0b |
+Nr4MNDlQ5/LWye1lROLm/2HhzKPPc3OEqV2AtLTRPW2cA14QZ646GyklZdf2VYxe |
+8Ha8YivWROaDvyIJeCcb1F194ZObzhKoZQRSNd4GvbKGh7bIr0+dtvffe9K39YmI |
+nSvisgorLlQE8pte/aAfNdVhl9aAkZRBS6wF3F4qrIT3pFGRgp6RNnx/EN8Z6tcj |
+MwufnzvNWM62E+8kaEwF89iW6wVgqG63BjwmJ0n97BKmo2f9kCgg34ywM7nsS9CA |
+i08yJZECgYEA+ffw8KUOmteh7THUc0BpLQt0/H7XU7EbDO5lAzXaEpO0hs/egQ0a |
+8B58fnSs3KD5hz88IOpuHSqNKpwv2kK3EgmLSfzcJZMLGdPtay3fc2CiI8SiMhYk |
+OxbLplj5LO0DLoIPuJ3XyOhLb4ucaErK4K8GGCRXjm6aSgege6XSfsUCgYEA7lK3 |
+nmRK4PejYM/eP5WoG7wmCu1estYoGh6gnnsUkhafFcFQ5z/EZF8lxA/4O7gqfR7n |
+d3j+82SUeTUcQ5Ek43QHG48qVU66t7+D3gIFqdarqhZmINKeLnm0LP7BI3zQ30eU |
+Pf6QVQUWyGJ0HqAuEgEF6DXXSmJ+mORIlIGLEbsCgYBLu+M0Bc42+74Dr2U+xfUX |
+wLDhD00N/krD0DaqklZP6pB3h+NSFjZjKdluNstozRzM7Uu6bUyPaaT7k/armir9 |
+PAcHk6TffX2PhbYZEvzwaAa374t0wWCYxn9NFwfnpKeiH6XDuY73P+obEaGBt6dg |
+C6c9CUW90aTNaSImVEdCQQKBgFx9aZlk3tJ0CMnXoi8XC4jH+hOfj3LkPef1Huyi |
+Y5dWhCLTRWyZiMRTULrIX9P9Yy/vwHDTWk5nKF/pxrBKMgC71M5TP2CgD0KkZq7Q |
+JhaFo1V9H+F5G755qP0VWStGk2EzzEpK8wSr1u2pl9sS2w5Nq1c1HfpWQz9eyPQp |
+WillAoGAQ1DjFXgiTFeBILj8JIys/6noXVgGhkdhfXfbdgHYiGBv+ItSyIEfnPB2 |
+aY/BAXFmlXEtnCPOYMb15lz1ThEO09c98BfEES8cgpdr2rdTkYTjX2Uhte/iiDgx |
+KWOeBEhre0kx4HKyO5qvccclK9mRpCGiL/bQZKgSrrG9HbrSk9g= |
+-----END RSA PRIVATE KEY----- |
+*/ |
+const char* kTestPublicKeyPEM = |
+ "-----BEGIN PUBLIC KEY-----" |
+ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6LVGtcy5JJnH7PHREKHT" |
+ "p3hnmg5cFTmQwG0BdgC81Ew9p4flovmxRuV6iMNPOJoHLdflQnAJhEZAt0dQURSl" |
+ "C6X0nSqxdD0yrvB64sJKfZEsMWFH8r3AMYVJN+v2yrYe7JxEKkESmPVIijXVafWz" |
+ "6gW1LnOTKYgtiJtaJ7DlkCucKdT2Jezlj9PuzXs0AEUG0m584G6g4q6kHw9XQGIt" |
+ "Mm7R1LlU7Gw0Zy72+L6uXOliLO1xQ/mvAr1oNYCcYtPQdZyMW2ikBIKZO3ElSHR+" |
+ "LC3ZVVb8euwoSPJkpIMwc14/cGud9nFckY3DQFhT9uf6ZTv49surG3P3uT1lNSSu" |
+ "5wIDAQAB" |
+ "-----END PUBLIC KEY-----"; |
+ |
+// This is a good key, signed with the above test private key |
const char* kSampleAPIKey = |
- "Signature|https://valid.example.com|Frobulate|1458766277"; |
- |
-const char* kExpectedAPIKeySignature = "Signature"; |
+ "fsnbBl0XwKysvzH3d4TtIomsD9teP0PFfqxIYIAksfipEjB+cXAwI0tUzkYES4H0zZUZ2S982" |
+ "cZVEmrv0uX2LYKmsfXUhgZCwm46Xx6ZzX3BIg/U1noIlr50O+eB0iHAxe98Ph1NM1gPIlyaev" |
+ "Lw75PPmXT5kUh15lJy+UPkKB8q52p3TKa2024Q3D2kGUWZ8DBD2zR5G+oHRtnKqfAh5fcTQyL" |
+ "Oa37NL66h0kTZ8WfvzATfTuAaAYuw+H5sYYeYTLrrVxhDuYqu/+kRzlQ42jlpNA0xkKEqRiIz" |
+ "X0erG2umU/l8SQpvdXBC87JtOIseHS9dSUoKKRO1XWnmgXX9dA==|https://valid.exampl" |
+ "e.com|Frobulate|1458766277"; |
+const char* kExpectedAPIKeySignature = |
+ "fsnbBl0XwKysvzH3d4TtIomsD9teP0PFfqxIYIAksfipEjB+cXAwI0tUzkYES4H0zZUZ2S982" |
+ "cZVEmrv0uX2LYKmsfXUhgZCwm46Xx6ZzX3BIg/U1noIlr50O+eB0iHAxe98Ph1NM1gPIlyaev" |
+ "Lw75PPmXT5kUh15lJy+UPkKB8q52p3TKa2024Q3D2kGUWZ8DBD2zR5G+oHRtnKqfAh5fcTQyL" |
+ "Oa37NL66h0kTZ8WfvzATfTuAaAYuw+H5sYYeYTLrrVxhDuYqu/+kRzlQ42jlpNA0xkKEqRiIz" |
+ "X0erG2umU/l8SQpvdXBC87JtOIseHS9dSUoKKRO1XWnmgXX9dA=="; |
const char* kExpectedAPIKeyData = |
"https://valid.example.com|Frobulate|1458766277"; |
const char* kExpectedAPIName = "Frobulate"; |
@@ -26,9 +79,28 @@ const uint64_t kExpectedExpiry = 1458766277; |
double kValidTimestamp = 1458766276.0; |
double kInvalidTimestamp = 1458766278.0; |
+// Well-formed API key with an invalid signature |
+const char* kInvalidSignatureAPIKey = |
+ "CO8hDne98QeFeOJ0DbRZCBN3uE0nyaPgaLlkYhSWnbRoDfEAg+TXELaYfQPfEvKY" |
+ "FauBg/hnxmba765hz0mXMco40xqjzo2r0o29s7ri7OklUsHXEUGCmVt31y5Zq3Qp" |
+ "36aDM4D9JL6bkA4ESM2DR6KjVU76bFOZcT7nAFYFz5vpC3WuPu2qqvcW2o9v2JXu" |
+ "fDYeySNZ3HrV5xmr8roqRMTiqMk99wEiUN+Dy4ddaE6XT+yzK+7C0XZxCf01RIiO" |
+ "XKubdZbYvssq9CaYUJAS1N9BB9K2nxitL5VbDhNxbGVBK1EzzvtppNd9IQe34Bwp" |
+ "f8iGJciYrfSOdoS753X8aw==|https://valid.example.com|Frobulate|145" |
+ "8766277000"; |
+ |
} // namespace |
-class ApiKeyTest : public testing::Test {}; |
+class ApiKeyTest : public testing::Test { |
+ protected: |
+ bool ValidateDate(ApiKey* api_key, const base::Time& now) { |
+ return api_key->ValidateDate(now); |
+ } |
+ |
+ bool ValidateSignature(ApiKey* api_key, const char* publicKeyPEM) { |
+ return api_key->ValidateSignature(publicKeyPEM); |
+ } |
+}; |
TEST_F(ApiKeyTest, ParseNullString) { |
scoped_ptr<ApiKey> empty_key = ApiKey::Parse(std::string()); |
@@ -55,16 +127,39 @@ TEST_F(ApiKeyTest, ParseValidKeyString) { |
EXPECT_EQ(kExpectedExpiry, key->expiry_timestamp()); |
} |
+// Test internal validation methods |
+ |
+TEST_F(ApiKeyTest, ValidateValidSignature) { |
+ scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey); |
+ ASSERT_TRUE(key); |
+ EXPECT_TRUE(ValidateSignature(key.get(), kTestPublicKeyPEM)); |
+} |
+ |
+TEST_F(ApiKeyTest, ValidateInvalidSignature) { |
+ scoped_ptr<ApiKey> key = ApiKey::Parse(kInvalidSignatureAPIKey); |
+ ASSERT_TRUE(key); |
+ EXPECT_FALSE(ValidateSignature(key.get(), kTestPublicKeyPEM)); |
+} |
+ |
+TEST_F(ApiKeyTest, ValidateSignatureOnWrongKey) { |
+ scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey); |
+ ASSERT_TRUE(key); |
+ // Signature will be invalid if tested against the real public key |
+ EXPECT_FALSE(key->IsValidNow(base::Time::FromDoubleT(kInvalidTimestamp))); |
+} |
+ |
TEST_F(ApiKeyTest, ValidateWhenNotExpired) { |
scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey); |
ASSERT_TRUE(key); |
- EXPECT_TRUE(key->IsValidNow(base::Time::FromDoubleT(kValidTimestamp))); |
+ EXPECT_TRUE( |
+ ValidateDate(key.get(), base::Time::FromDoubleT(kValidTimestamp))); |
} |
TEST_F(ApiKeyTest, ValidateWhenExpired) { |
scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey); |
ASSERT_TRUE(key); |
- EXPECT_FALSE(key->IsValidNow(base::Time::FromDoubleT(kInvalidTimestamp))); |
+ EXPECT_FALSE( |
+ ValidateDate(key.get(), base::Time::FromDoubleT(kInvalidTimestamp))); |
} |
} // namespace content |