| 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_message_cryptographer.h" | 5 #include "components/gcm_driver/crypto/gcm_message_cryptographer.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/base64url.h" | 9 #include "base/base64url.h" |
| 10 #include "base/big_endian.h" | 10 #include "base/big_endian.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/strings/string_piece.h" | 12 #include "base/strings/string_piece.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #include "components/gcm_driver/crypto/message_payload_parser.h" |
| 14 #include "components/gcm_driver/crypto/p256_key_util.h" | 15 #include "components/gcm_driver/crypto/p256_key_util.h" |
| 15 #include "crypto/random.h" | 16 #include "crypto/random.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 18 |
| 18 namespace gcm { | 19 namespace gcm { |
| 19 | 20 |
| 20 namespace { | 21 namespace { |
| 21 | 22 |
| 22 // Example plaintext data to use in the tests. | 23 // Example plaintext data to use in the tests. |
| 23 const char kExamplePlaintext[] = "Example plaintext"; | 24 const char kExamplePlaintext[] = "Example plaintext"; |
| 24 | 25 |
| 25 // Expected sizes of the different input given to the cryptographer. | 26 // Expected sizes of the different input given to the cryptographer. |
| 26 constexpr size_t kUncompressedPointSize = 65; | |
| 27 constexpr size_t kEcdhSharedSecretSize = 32; | 27 constexpr size_t kEcdhSharedSecretSize = 32; |
| 28 constexpr size_t kAuthSecretSize = 16; | 28 constexpr size_t kAuthSecretSize = 16; |
| 29 constexpr size_t kSaltSize = 16; | 29 constexpr size_t kSaltSize = 16; |
| 30 | 30 |
| 31 // Keying material for both parties as P-256 EC points. Used to make sure that | 31 // Keying material for both parties as P-256 EC points. Used to make sure that |
| 32 // the test vectors are reproducible. | 32 // the test vectors are reproducible. |
| 33 const unsigned char kCommonSenderPublicKey[] = { | 33 const unsigned char kCommonSenderPublicKey[] = { |
| 34 0x04, 0x05, 0x3C, 0xA1, 0xB9, 0xA5, 0xAB, 0xB8, 0x2D, 0x88, 0x48, | 34 0x04, 0x05, 0x3C, 0xA1, 0xB9, 0xA5, 0xAB, 0xB8, 0x2D, 0x88, 0x48, |
| 35 0x82, 0xC9, 0x49, 0x19, 0x91, 0xD5, 0xFD, 0xD1, 0x92, 0xDB, 0xA7, | 35 0x82, 0xC9, 0x49, 0x19, 0x91, 0xD5, 0xFD, 0xD1, 0x92, 0xDB, 0xA7, |
| 36 0x7E, 0x70, 0x48, 0x37, 0x41, 0xCD, 0x90, 0x05, 0x80, 0xDF, 0x65, | 36 0x7E, 0x70, 0x48, 0x37, 0x41, 0xCD, 0x90, 0x05, 0x80, 0xDF, 0x65, |
| (...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 859 "DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_" | 859 "DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_" |
| 860 "c7VJSPQTBtkgcy27mlmlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_" | 860 "c7VJSPQTBtkgcy27mlmlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_" |
| 861 "yl95bQpu6cVPTpK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_" | 861 "yl95bQpu6cVPTpK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_" |
| 862 "Qulcy4a-fN"; | 862 "Qulcy4a-fN"; |
| 863 | 863 |
| 864 std::string message; | 864 std::string message; |
| 865 ASSERT_TRUE(base::Base64UrlDecode(kReferenceMessage, | 865 ASSERT_TRUE(base::Base64UrlDecode(kReferenceMessage, |
| 866 base::Base64UrlDecodePolicy::IGNORE_PADDING, | 866 base::Base64UrlDecodePolicy::IGNORE_PADDING, |
| 867 &message)); | 867 &message)); |
| 868 | 868 |
| 869 // TODO(peter): Break out the following in a separate message parser class so | 869 MessagePayloadParser message_parser(message); |
| 870 // that it can be reused by the GCMEncryptionProvider (on the receiving path) | 870 ASSERT_TRUE(message_parser.IsValid()); |
| 871 // and the gcm_crypto_test_helpers.cc file (on the sending path) too. | |
| 872 // | |
| 873 // The message contains a binary header in the following format: | |
| 874 // [ salt(16) | record_size(4) | sender_public_key_len(1) | | |
| 875 // sender_public_key(sender_public_key_len) ] | |
| 876 // | |
| 877 // For Web Push Encryption, which uses a P-256 sender key as uncompressed | |
| 878 // P-256 EC points, the length of the sender key is 65 bytes, making the | |
| 879 // total, fixed length of the header 86 bytes. | |
| 880 // | |
| 881 // The regular AEAD_AES_128_GCM ciphertext follows immediately after this. The | |
| 882 // minimum overhead for a single record is 18 bytes. This means that an | |
| 883 // incoming message must be at least 104 bytes in size. | |
| 884 ASSERT_GE(message.size(), 104u); | |
| 885 | 871 |
| 886 const char* current = &message.front(); | 872 base::StringPiece salt = message_parser.salt(); |
| 887 | 873 uint32_t record_size = message_parser.record_size(); |
| 888 uint32_t record_size; | 874 base::StringPiece sender_public_key = message_parser.public_key(); |
| 889 uint8_t sender_public_key_length; | 875 base::StringPiece ciphertext = message_parser.ciphertext(); |
| 890 | |
| 891 base::StringPiece salt(current, kSaltSize); | |
| 892 current += kSaltSize; | |
| 893 | |
| 894 base::ReadBigEndian(current, &record_size); | |
| 895 current += sizeof(record_size); | |
| 896 | |
| 897 base::ReadBigEndian(current, &sender_public_key_length); | |
| 898 current += sizeof(sender_public_key_length); | |
| 899 | |
| 900 ASSERT_EQ(sender_public_key_length, kUncompressedPointSize); | |
| 901 | |
| 902 base::StringPiece sender_public_key(current, sender_public_key_length); | |
| 903 current += sender_public_key_length; | |
| 904 | |
| 905 base::StringPiece ciphertext( | |
| 906 current, message.size() - kSaltSize - sizeof(record_size) - | |
| 907 sizeof(sender_public_key_length) - sender_public_key_length); | |
| 908 | 876 |
| 909 std::string sender_shared_secret, receiver_shared_secret; | 877 std::string sender_shared_secret, receiver_shared_secret; |
| 910 | 878 |
| 911 // Compute the shared secrets between the sender and receiver's keys. | 879 // Compute the shared secrets between the sender and receiver's keys. |
| 912 ASSERT_NO_FATAL_FAILURE(ComputeSharedSecret(kSenderPrivate, kSenderPublicX509, | 880 ASSERT_NO_FATAL_FAILURE(ComputeSharedSecret(kSenderPrivate, kSenderPublicX509, |
| 913 kRecipientPublicKeyUncompressed, | 881 kRecipientPublicKeyUncompressed, |
| 914 &sender_shared_secret)); | 882 &sender_shared_secret)); |
| 915 | 883 |
| 916 // Compute the shared secret based on the sender's public key, which isn't a | 884 // Compute the shared secret based on the sender's public key, which isn't a |
| 917 // constant but instead is included in the message's binary header. | 885 // constant but instead is included in the message's binary header. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 | 923 |
| 956 ASSERT_TRUE(cryptographer.Encrypt(recipient_public_key, sender_public_key, | 924 ASSERT_TRUE(cryptographer.Encrypt(recipient_public_key, sender_public_key, |
| 957 sender_shared_secret, auth_secret, salt, | 925 sender_shared_secret, auth_secret, salt, |
| 958 kPlaintext, &record_size2, &ciphertext2)); | 926 kPlaintext, &record_size2, &ciphertext2)); |
| 959 | 927 |
| 960 EXPECT_GE(record_size2, record_size); | 928 EXPECT_GE(record_size2, record_size); |
| 961 EXPECT_EQ(ciphertext2, ciphertext); | 929 EXPECT_EQ(ciphertext2, ciphertext); |
| 962 } | 930 } |
| 963 | 931 |
| 964 } // namespace gcm | 932 } // namespace gcm |
| OLD | NEW |