Chromium Code Reviews| 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 { |
| +/* |
|
davidben
2015/12/18 22:23:17
Nit: I think // is more common, though I don't ter
iclelland
2015/12/22 05:45:28
Ack. I deliberately chose /* */ here so that anyon
|
| +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"; |
|
davidben
2015/12/18 22:23:17
FWIW, there's much much smaller signature schemes
iclelland
2015/12/22 05:45:28
That's a great idea, and I appreciate you enabling
|
| +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 |