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 |