| 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 "components/gcm_driver/crypto/gcm_encryption_provider.h" | 5 #include "components/gcm_driver/crypto/gcm_encryption_provider.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 namespace gcm { | 25 namespace gcm { |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 const char kExampleAppId[] = "my-app-id"; | 28 const char kExampleAppId[] = "my-app-id"; |
| 29 const char kExampleMessage[] = "Hello, world, this is the GCM Driver!"; | 29 const char kExampleMessage[] = "Hello, world, this is the GCM Driver!"; |
| 30 | 30 |
| 31 const char kValidEncryptionHeader[] = | 31 const char kValidEncryptionHeader[] = |
| 32 "keyid=foo;salt=MTIzNDU2Nzg5MDEyMzQ1Ng;rs=1024"; | 32 "keyid=foo;salt=MTIzNDU2Nzg5MDEyMzQ1Ng;rs=1024"; |
| 33 const char kInvalidEncryptionHeader[] = "keyid"; | 33 const char kInvalidEncryptionHeader[] = "keyid"; |
| 34 | 34 |
| 35 const char kValidEncryptionKeyHeader[] = | 35 const char kValidCryptoKeyHeader[] = |
| 36 "keyid=foo;dh=BL_UGhfudEkXMUd4U4-D4nP5KHxKjQHsW6j88ybbehXM7fqi1OMFefDUEi0eJ" | 36 "keyid=foo;dh=BL_UGhfudEkXMUd4U4-D4nP5KHxKjQHsW6j88ybbehXM7fqi1OMFefDUEi0eJ" |
| 37 "vsKfyVBWYkQjH-lSPJKxjAyslg"; | 37 "vsKfyVBWYkQjH-lSPJKxjAyslg"; |
| 38 const char kInvalidEncryptionKeyHeader[] = "keyid"; | 38 const char kInvalidCryptoKeyHeader[] = "keyid"; |
| 39 | 39 |
| 40 // TODO(peter): Unify the Base64Url implementations. https://crbug.com/536745. | 40 // TODO(peter): Unify the Base64Url implementations. https://crbug.com/536745. |
| 41 void Base64UrlEncode(const std::string& decoded_input, | 41 void Base64UrlEncode(const std::string& decoded_input, |
| 42 std::string* encoded_output) { | 42 std::string* encoded_output) { |
| 43 base::Base64Encode(decoded_input, encoded_output); | 43 base::Base64Encode(decoded_input, encoded_output); |
| 44 base::ReplaceChars(*encoded_output, "+", "-", encoded_output); | 44 base::ReplaceChars(*encoded_output, "+", "-", encoded_output); |
| 45 base::ReplaceChars(*encoded_output, "/", "_", encoded_output); | 45 base::ReplaceChars(*encoded_output, "/", "_", encoded_output); |
| 46 } | 46 } |
| 47 | 47 |
| 48 } // namespace | 48 } // namespace |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 IncomingMessage empty_message; | 143 IncomingMessage empty_message; |
| 144 EXPECT_FALSE(encryption_provider()->IsEncryptedMessage(empty_message)); | 144 EXPECT_FALSE(encryption_provider()->IsEncryptedMessage(empty_message)); |
| 145 | 145 |
| 146 IncomingMessage single_header_message; | 146 IncomingMessage single_header_message; |
| 147 single_header_message.data["encryption"] = ""; | 147 single_header_message.data["encryption"] = ""; |
| 148 EXPECT_FALSE(encryption_provider()->IsEncryptedMessage( | 148 EXPECT_FALSE(encryption_provider()->IsEncryptedMessage( |
| 149 single_header_message)); | 149 single_header_message)); |
| 150 | 150 |
| 151 IncomingMessage double_header_message; | 151 IncomingMessage double_header_message; |
| 152 double_header_message.data["encryption"] = ""; | 152 double_header_message.data["encryption"] = ""; |
| 153 double_header_message.data["encryption_key"] = ""; | 153 double_header_message.data["crypto_key"] = ""; |
| 154 EXPECT_FALSE(encryption_provider()->IsEncryptedMessage( | 154 EXPECT_FALSE(encryption_provider()->IsEncryptedMessage( |
| 155 double_header_message)); | 155 double_header_message)); |
| 156 | 156 |
| 157 IncomingMessage double_header_with_data_message; | 157 IncomingMessage double_header_with_data_message; |
| 158 double_header_with_data_message.data["encryption"] = ""; | 158 double_header_with_data_message.data["encryption"] = ""; |
| 159 double_header_with_data_message.data["encryption_key"] = ""; | 159 double_header_with_data_message.data["crypto_key"] = ""; |
| 160 double_header_with_data_message.raw_data = "foo"; | 160 double_header_with_data_message.raw_data = "foo"; |
| 161 EXPECT_TRUE(encryption_provider()->IsEncryptedMessage( | 161 EXPECT_TRUE(encryption_provider()->IsEncryptedMessage( |
| 162 double_header_with_data_message)); | 162 double_header_with_data_message)); |
| 163 } | 163 } |
| 164 | 164 |
| 165 TEST_F(GCMEncryptionProviderTest, VerifiesEncryptionHeaderParsing) { | 165 TEST_F(GCMEncryptionProviderTest, VerifiesEncryptionHeaderParsing) { |
| 166 // The Encryption header must be parsable and contain valid values. | 166 // The Encryption header must be parsable and contain valid values. |
| 167 // Note that this is more extensively tested in EncryptionHeaderParsersTest. | 167 // Note that this is more extensively tested in EncryptionHeaderParsersTest. |
| 168 | 168 |
| 169 IncomingMessage invalid_message; | 169 IncomingMessage invalid_message; |
| 170 invalid_message.data["encryption"] = kInvalidEncryptionHeader; | 170 invalid_message.data["encryption"] = kInvalidEncryptionHeader; |
| 171 invalid_message.data["encryption_key"] = kValidEncryptionKeyHeader; | 171 invalid_message.data["crypto_key"] = kValidCryptoKeyHeader; |
| 172 | 172 |
| 173 ASSERT_NO_FATAL_FAILURE(Decrypt(invalid_message)); | 173 ASSERT_NO_FATAL_FAILURE(Decrypt(invalid_message)); |
| 174 ASSERT_EQ(DECRYPTION_FAILED, decryption_result()); | 174 ASSERT_EQ(DECRYPTION_FAILED, decryption_result()); |
| 175 EXPECT_EQ(GCMEncryptionProvider::DECRYPTION_FAILURE_INVALID_ENCRYPTION_HEADER, | 175 EXPECT_EQ(GCMEncryptionProvider::DECRYPTION_FAILURE_INVALID_ENCRYPTION_HEADER, |
| 176 failure_reason()); | 176 failure_reason()); |
| 177 | 177 |
| 178 IncomingMessage valid_message; | 178 IncomingMessage valid_message; |
| 179 valid_message.data["encryption"] = kValidEncryptionHeader; | 179 valid_message.data["encryption"] = kValidEncryptionHeader; |
| 180 valid_message.data["encryption_key"] = kInvalidEncryptionKeyHeader; | 180 valid_message.data["crypto_key"] = kInvalidCryptoKeyHeader; |
| 181 | 181 |
| 182 ASSERT_NO_FATAL_FAILURE(Decrypt(valid_message)); | 182 ASSERT_NO_FATAL_FAILURE(Decrypt(valid_message)); |
| 183 ASSERT_EQ(DECRYPTION_FAILED, decryption_result()); | 183 ASSERT_EQ(DECRYPTION_FAILED, decryption_result()); |
| 184 EXPECT_NE(GCMEncryptionProvider::DECRYPTION_FAILURE_INVALID_ENCRYPTION_HEADER, | 184 EXPECT_NE(GCMEncryptionProvider::DECRYPTION_FAILURE_INVALID_ENCRYPTION_HEADER, |
| 185 failure_reason()); | 185 failure_reason()); |
| 186 } | 186 } |
| 187 | 187 |
| 188 TEST_F(GCMEncryptionProviderTest, VerifiesEncryptionKeyHeaderParsing) { | 188 TEST_F(GCMEncryptionProviderTest, VerifiesCryptoKeyHeaderParsing) { |
| 189 // The Encryption-Key header must be parsable and contain valid values. | 189 // The Encryption-Key header must be parsable and contain valid values. |
| 190 // Note that this is more extensively tested in EncryptionHeaderParsersTest. | 190 // Note that this is more extensively tested in EncryptionHeaderParsersTest. |
| 191 | 191 |
| 192 IncomingMessage invalid_message; | 192 IncomingMessage invalid_message; |
| 193 invalid_message.data["encryption"] = kValidEncryptionHeader; | 193 invalid_message.data["encryption"] = kValidEncryptionHeader; |
| 194 invalid_message.data["encryption_key"] = kInvalidEncryptionKeyHeader; | 194 invalid_message.data["crypto_key"] = kInvalidCryptoKeyHeader; |
| 195 | 195 |
| 196 ASSERT_NO_FATAL_FAILURE(Decrypt(invalid_message)); | 196 ASSERT_NO_FATAL_FAILURE(Decrypt(invalid_message)); |
| 197 ASSERT_EQ(DECRYPTION_FAILED, decryption_result()); | 197 ASSERT_EQ(DECRYPTION_FAILED, decryption_result()); |
| 198 EXPECT_EQ( | 198 EXPECT_EQ(GCMEncryptionProvider::DECRYPTION_FAILURE_INVALID_CRYPTO_KEY_HEADER, |
| 199 GCMEncryptionProvider::DECRYPTION_FAILURE_INVALID_ENCRYPTION_KEY_HEADER, | 199 failure_reason()); |
| 200 failure_reason()); | |
| 201 | 200 |
| 202 IncomingMessage valid_message; | 201 IncomingMessage valid_message; |
| 203 valid_message.data["encryption"] = kInvalidEncryptionHeader; | 202 valid_message.data["encryption"] = kInvalidEncryptionHeader; |
| 204 valid_message.data["encryption_key"] = kValidEncryptionKeyHeader; | 203 valid_message.data["crypto_key"] = kValidCryptoKeyHeader; |
| 205 | 204 |
| 206 ASSERT_NO_FATAL_FAILURE(Decrypt(valid_message)); | 205 ASSERT_NO_FATAL_FAILURE(Decrypt(valid_message)); |
| 207 ASSERT_EQ(DECRYPTION_FAILED, decryption_result()); | 206 ASSERT_EQ(DECRYPTION_FAILED, decryption_result()); |
| 208 EXPECT_NE( | 207 EXPECT_NE(GCMEncryptionProvider::DECRYPTION_FAILURE_INVALID_CRYPTO_KEY_HEADER, |
| 209 GCMEncryptionProvider::DECRYPTION_FAILURE_INVALID_ENCRYPTION_KEY_HEADER, | 208 failure_reason()); |
| 210 failure_reason()); | |
| 211 } | 209 } |
| 212 | 210 |
| 213 TEST_F(GCMEncryptionProviderTest, VerifiesExistingKeys) { | 211 TEST_F(GCMEncryptionProviderTest, VerifiesExistingKeys) { |
| 214 // When both headers are valid, the encryption keys still must be known to | 212 // When both headers are valid, the encryption keys still must be known to |
| 215 // the GCM key store before the message can be decrypted. | 213 // the GCM key store before the message can be decrypted. |
| 216 | 214 |
| 217 IncomingMessage message; | 215 IncomingMessage message; |
| 218 message.data["encryption"] = kValidEncryptionHeader; | 216 message.data["encryption"] = kValidEncryptionHeader; |
| 219 message.data["encryption_key"] = kValidEncryptionKeyHeader; | 217 message.data["crypto_key"] = kValidCryptoKeyHeader; |
| 220 | 218 |
| 221 ASSERT_NO_FATAL_FAILURE(Decrypt(message)); | 219 ASSERT_NO_FATAL_FAILURE(Decrypt(message)); |
| 222 ASSERT_EQ(DECRYPTION_FAILED, decryption_result()); | 220 ASSERT_EQ(DECRYPTION_FAILED, decryption_result()); |
| 223 EXPECT_EQ(GCMEncryptionProvider::DECRYPTION_FAILURE_NO_KEYS, | 221 EXPECT_EQ(GCMEncryptionProvider::DECRYPTION_FAILURE_NO_KEYS, |
| 224 failure_reason()); | 222 failure_reason()); |
| 225 | 223 |
| 226 std::string public_key; | 224 std::string public_key; |
| 227 encryption_provider()->GetPublicKey( | 225 encryption_provider()->GetPublicKey( |
| 228 kExampleAppId, | 226 kExampleAppId, |
| 229 base::Bind(&GCMEncryptionProviderTest::DidGetPublicKey, | 227 base::Bind(&GCMEncryptionProviderTest::DidGetPublicKey, |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 | 292 |
| 295 // Compile the incoming GCM message, including the required headers. | 293 // Compile the incoming GCM message, including the required headers. |
| 296 Base64UrlEncode(salt, &encoded_salt); | 294 Base64UrlEncode(salt, &encoded_salt); |
| 297 Base64UrlEncode(server_pair.public_key(), &encoded_key); | 295 Base64UrlEncode(server_pair.public_key(), &encoded_key); |
| 298 | 296 |
| 299 std::stringstream encryption_header; | 297 std::stringstream encryption_header; |
| 300 encryption_header << "rs=" << base::SizeTToString(record_size) << ";"; | 298 encryption_header << "rs=" << base::SizeTToString(record_size) << ";"; |
| 301 encryption_header << "salt=" << encoded_salt; | 299 encryption_header << "salt=" << encoded_salt; |
| 302 | 300 |
| 303 message.data["encryption"] = encryption_header.str(); | 301 message.data["encryption"] = encryption_header.str(); |
| 304 message.data["encryption_key"] = "dh=" + encoded_key; | 302 message.data["crypto_key"] = "dh=" + encoded_key; |
| 305 | 303 |
| 306 ASSERT_TRUE(encryption_provider()->IsEncryptedMessage(message)); | 304 ASSERT_TRUE(encryption_provider()->IsEncryptedMessage(message)); |
| 307 | 305 |
| 308 // Decrypt the message, and expect everything to go wonderfully well. | 306 // Decrypt the message, and expect everything to go wonderfully well. |
| 309 ASSERT_NO_FATAL_FAILURE(Decrypt(message)); | 307 ASSERT_NO_FATAL_FAILURE(Decrypt(message)); |
| 310 ASSERT_EQ(DECRYPTION_SUCCEEDED, decryption_result()); | 308 ASSERT_EQ(DECRYPTION_SUCCEEDED, decryption_result()); |
| 311 | 309 |
| 312 EXPECT_TRUE(decrypted_message().decrypted); | 310 EXPECT_TRUE(decrypted_message().decrypted); |
| 313 EXPECT_EQ(kExampleMessage, decrypted_message().raw_data); | 311 EXPECT_EQ(kExampleMessage, decrypted_message().raw_data); |
| 314 } | 312 } |
| 315 | 313 |
| 316 } // namespace gcm | 314 } // namespace gcm |
| OLD | NEW |