1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/nearby_sharing/certificates/test_util.h"
6 
7 #include <set>
8 
9 #include "base/no_destructor.h"
10 #include "chrome/browser/nearby_sharing/certificates/constants.h"
11 #include "chrome/browser/nearby_sharing/proto/timestamp.pb.h"
12 #include "device/bluetooth/public/cpp/bluetooth_address.h"
13 
14 namespace {
15 
16 // Sample P-256 public and private keys from RFC 6979 A.2.5 in their respective
17 // ASN.1 formats: SubjectPublicKeyInfo (RFC 5280) and PKCS #8 PrivateKeyInfo
18 // (RFC 5208).
19 const uint8_t kTestPublicKeyBytes[] = {
20     0x30, 0x59,
21     // Begin AlgorithmIdentifier: ecPublicKey, prime256v1
22     0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06,
23     0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
24     // End AlgorithmIdentifier
25     0x03, 0x42, 0x00, 0x04,
26     // Public key bytes (Ux):
27     0x60, 0xfe, 0xd4, 0xba, 0x25, 0x5a, 0x9d, 0x31, 0xc9, 0x61, 0xeb, 0x74,
28     0xc6, 0x35, 0x6d, 0x68, 0xc0, 0x49, 0xb8, 0x92, 0x3b, 0x61, 0xfa, 0x6c,
29     0xe6, 0x69, 0x62, 0x2e, 0x60, 0xf2, 0x9f, 0xb6,
30     // Public key bytes (Uy):
31     0x79, 0x03, 0xfe, 0x10, 0x08, 0xb8, 0xbc, 0x99, 0xa4, 0x1a, 0xe9, 0xe9,
32     0x56, 0x28, 0xbc, 0x64, 0xf2, 0xf1, 0xb2, 0x0c, 0x2d, 0x7e, 0x9f, 0x51,
33     0x77, 0xa3, 0xc2, 0x94, 0xd4, 0x46, 0x22, 0x99};
34 const uint8_t kTestPrivateKeyBytes[] = {
35     0x30, 0x81, 0x87, 0x02, 0x01, 0x00,
36     // Begin AlgorithmIdentifier: ecPublicKey, prime256v1
37     0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06,
38     0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
39     // End AlgorithmIdentifier
40     0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
41     // Begin private key bytes
42     0xc9, 0xaf, 0xa9, 0xd8, 0x45, 0xba, 0x75, 0x16, 0x6b, 0x5c, 0x21, 0x57,
43     0x67, 0xb1, 0xd6, 0x93, 0x4e, 0x50, 0xc3, 0xdb, 0x36, 0xe8, 0x9b, 0x12,
44     0x7b, 0x8a, 0x62, 0x2b, 0x12, 0x0f, 0x67, 0x21,
45     // End private key bytes
46     0xa1, 0x44, 0x03, 0x42, 0x00, 0x04,
47     // Public key:
48     0x60, 0xfe, 0xd4, 0xba, 0x25, 0x5a, 0x9d, 0x31, 0xc9, 0x61, 0xeb, 0x74,
49     0xc6, 0x35, 0x6d, 0x68, 0xc0, 0x49, 0xb8, 0x92, 0x3b, 0x61, 0xfa, 0x6c,
50     0xe6, 0x69, 0x62, 0x2e, 0x60, 0xf2, 0x9f, 0xb6, 0x79, 0x03, 0xfe, 0x10,
51     0x08, 0xb8, 0xbc, 0x99, 0xa4, 0x1a, 0xe9, 0xe9, 0x56, 0x28, 0xbc, 0x64,
52     0xf2, 0xf1, 0xb2, 0x0c, 0x2d, 0x7e, 0x9f, 0x51, 0x77, 0xa3, 0xc2, 0x94,
53     0xd4, 0x46, 0x22, 0x99};
54 
55 const uint8_t kTestSecretKey[] = {
56     0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae,
57     0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
58     0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4};
59 
60 const uint8_t kTestCertificateId[] = {
61     0xb9, 0x3c, 0x72, 0xb7, 0x4b, 0xc8, 0x48, 0x7d, 0x29, 0x82, 0x70,
62     0x05, 0xf8, 0x0d, 0x63, 0x59, 0x18, 0xf9, 0x1b, 0xc2, 0x2b, 0x14,
63     0xd7, 0xed, 0x05, 0x71, 0x4d, 0x58, 0xf9, 0x67, 0x02, 0xdd};
64 
65 const uint8_t kTestMetadataEncryptionKey[] = {0x60, 0x1e, 0xc3, 0x13, 0x77,
66                                               0x57, 0x89, 0xa5, 0xb7, 0xa7,
67                                               0xf5, 0x04, 0xbb, 0xf3};
68 
69 const uint8_t kTestMetadataEncryptionKeyTag[] = {
70     0x51, 0x9b, 0x16, 0xd8, 0x91, 0xb4, 0x0d, 0x81, 0x11, 0x21, 0xe3,
71     0x70, 0x42, 0x80, 0x8f, 0x87, 0x23, 0x6a, 0x84, 0x9b, 0xcd, 0xac,
72     0xbc, 0xe3, 0x54, 0xd7, 0xff, 0x53, 0xdf, 0x5d, 0x8a, 0xda};
73 
74 const uint8_t kTestSalt[] = {0xf0, 0xf1};
75 
76 const uint8_t kTestEncryptedMetadataKey[] = {0x52, 0x0e, 0x7e, 0x6b, 0x8e,
77                                              0xb5, 0x40, 0xe8, 0xe2, 0xbd,
78                                              0xa0, 0xee, 0x9d, 0x7b};
79 
80 const uint8_t kTestEncryptedMetadata[] = {
81     0x4d, 0x59, 0x5d, 0xb6, 0xac, 0x70, 0x00, 0x8f, 0x32, 0x9d, 0x0d, 0xcf,
82     0xc3, 0x8b, 0x01, 0x19, 0x1d, 0xad, 0x2e, 0xb4, 0x62, 0xec, 0xf3, 0xa5,
83     0xe4, 0x89, 0x51, 0x37, 0x0d, 0x78, 0xad, 0x9d, 0x2e, 0xe5, 0x99, 0xd5,
84     0xf7, 0x1d, 0x71, 0x47, 0xef, 0x33,
85     // tag
86     0x63, 0x47, 0xae, 0xb0, 0xdf, 0x67, 0x07, 0x16, 0x70, 0x97, 0x3d, 0x8f,
87     0xc8, 0xe6, 0x61, 0xc0};
88 
89 // Plaintext "sample" (from RFC 6979 A.2.5).
90 const uint8_t kTestPayloadToSign[] = {0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65};
91 
92 // One possible signature (from RFC 6979 A.2.5).
93 const uint8_t kTestSampleSignature[] = {
94     0x30,
95     0x46,  // length of remaining data
96     0x02,
97     0x21,  // length of r
98     // begin r (note 0x00 padding since leading bit of 0xEF is 1)
99     0x00, 0xEF, 0xD4, 0x8B, 0x2A, 0xAC, 0xB6, 0xA8, 0xFD, 0x11, 0x40, 0xDD,
100     0x9C, 0xD4, 0x5E, 0x81, 0xD6, 0x9D, 0x2C, 0x87, 0x7B, 0x56, 0xAA, 0xF9,
101     0x91, 0xC3, 0x4D, 0x0E, 0xA8, 0x4E, 0xAF, 0x37, 0x16,
102     // end r
103     0x02,
104     0x21,  // length of s
105     // begin s (note 0x00 padding since leading bit of 0xF7 is 1)
106     0x00, 0xF7, 0xCB, 0x1C, 0x94, 0x2D, 0x65, 0x7C, 0x41, 0xD4, 0x36, 0xC7,
107     0xA1, 0xB6, 0xE2, 0x9F, 0x65, 0xF3, 0xE9, 0x00, 0xDB, 0xB9, 0xAF, 0xF4,
108     0x06, 0x4D, 0xC4, 0xAB, 0x2F, 0x84, 0x3A, 0xCD, 0xA8
109     // end s
110 };
111 
112 // The result of HKDF of kTestPayloadToSign, using kTestSecretKey as salt. A
113 // trivial info parameter is used, and the output length is fixed to be
114 // kNearbyShareNumBytesAuthenticationTokenHash.
115 const uint8_t kTestPayloadHashUsingSecretKey[] = {0xE2, 0xCB, 0x90,
116                                                   0x58, 0xDE, 0x3A};
117 
118 const int64_t kTestNotBeforeMillis = 1881702000000;
119 
120 const int64_t kTestValidityOffsetMillis = 1800000;  // 30 minutes
121 
122 }  // namespace
123 
124 // Do not change. Values align with kTestEncryptedMetadata.
125 const char kTestDeviceName[] = "device_name";
126 const char kTestMetadataFullName[] = "full_name";
127 const char kTestMetadataIconUrl[] = "icon_url";
128 const char kTestUnparsedBluetoothMacAddress[] = "4E:65:61:72:62:79";
129 
GetNearbyShareTestP256KeyPair()130 std::unique_ptr<crypto::ECPrivateKey> GetNearbyShareTestP256KeyPair() {
131   return crypto::ECPrivateKey::CreateFromPrivateKeyInfo(kTestPrivateKeyBytes);
132 }
133 
GetNearbyShareTestP256PublicKey()134 const std::vector<uint8_t>& GetNearbyShareTestP256PublicKey() {
135   static const base::NoDestructor<std::vector<uint8_t>> public_key(
136       std::begin(kTestPublicKeyBytes), std::end(kTestPublicKeyBytes));
137   return *public_key;
138 }
139 
GetNearbyShareTestSecretKey()140 std::unique_ptr<crypto::SymmetricKey> GetNearbyShareTestSecretKey() {
141   return crypto::SymmetricKey::Import(
142       crypto::SymmetricKey::Algorithm::AES,
143       std::string(reinterpret_cast<const char*>(kTestSecretKey),
144                   kNearbyShareNumBytesSecretKey));
145 }
146 
GetNearbyShareTestCertificateId()147 const std::vector<uint8_t>& GetNearbyShareTestCertificateId() {
148   static const base::NoDestructor<std::vector<uint8_t>> id(
149       std::begin(kTestCertificateId), std::end(kTestCertificateId));
150   return *id;
151 }
152 
GetNearbyShareTestMetadataEncryptionKey()153 const std::vector<uint8_t>& GetNearbyShareTestMetadataEncryptionKey() {
154   static const base::NoDestructor<std::vector<uint8_t>> metadata_encryption_key(
155       kTestMetadataEncryptionKey,
156       kTestMetadataEncryptionKey + kNearbyShareNumBytesMetadataEncryptionKey);
157   return *metadata_encryption_key;
158 }
159 
GetNearbyShareTestMetadataEncryptionKeyTag()160 const std::vector<uint8_t>& GetNearbyShareTestMetadataEncryptionKeyTag() {
161   static const base::NoDestructor<std::vector<uint8_t>> tag(
162       std::begin(kTestMetadataEncryptionKeyTag),
163       std::end(kTestMetadataEncryptionKeyTag));
164   return *tag;
165 }
166 
GetNearbyShareTestSalt()167 const std::vector<uint8_t>& GetNearbyShareTestSalt() {
168   static const base::NoDestructor<std::vector<uint8_t>> salt(
169       std::begin(kTestSalt), std::end(kTestSalt));
170   return *salt;
171 }
172 
173 const NearbyShareEncryptedMetadataKey&
GetNearbyShareTestEncryptedMetadataKey()174 GetNearbyShareTestEncryptedMetadataKey() {
175   static const base::NoDestructor<NearbyShareEncryptedMetadataKey>
176       encrypted_metadata_key(
177           GetNearbyShareTestSalt(),
178           std::vector<uint8_t>(std::begin(kTestEncryptedMetadataKey),
179                                std::end(kTestEncryptedMetadataKey)));
180   return *encrypted_metadata_key;
181 }
182 
GetNearbyShareTestNotBefore()183 base::Time GetNearbyShareTestNotBefore() {
184   static const base::NoDestructor<base::Time> not_before(
185       base::Time::FromJavaTime(kTestNotBeforeMillis));
186   return *not_before;
187 }
188 
GetNearbyShareTestValidityOffset()189 base::TimeDelta GetNearbyShareTestValidityOffset() {
190   static const base::NoDestructor<base::TimeDelta> offset(
191       base::TimeDelta::FromMilliseconds(kTestValidityOffsetMillis));
192   return *offset;
193 }
194 
GetNearbyShareTestMetadata()195 const nearbyshare::proto::EncryptedMetadata& GetNearbyShareTestMetadata() {
196   static const base::NoDestructor<nearbyshare::proto::EncryptedMetadata>
197       metadata([] {
198         std::array<uint8_t, 6> bytes;
199         device::ParseBluetoothAddress(kTestUnparsedBluetoothMacAddress, bytes);
200 
201         nearbyshare::proto::EncryptedMetadata metadata;
202         metadata.set_device_name(kTestDeviceName);
203         metadata.set_full_name(kTestMetadataFullName);
204         metadata.set_icon_url(kTestMetadataIconUrl);
205         metadata.set_bluetooth_mac_address(bytes.data(), 6u);
206         return metadata;
207       }());
208   return *metadata;
209 }
210 
GetNearbyShareTestEncryptedMetadata()211 const std::vector<uint8_t>& GetNearbyShareTestEncryptedMetadata() {
212   static const base::NoDestructor<std::vector<uint8_t>> bytes(
213       std::begin(kTestEncryptedMetadata), std::end(kTestEncryptedMetadata));
214   return *bytes;
215 }
216 
GetNearbyShareTestPayloadToSign()217 const std::vector<uint8_t>& GetNearbyShareTestPayloadToSign() {
218   static const base::NoDestructor<std::vector<uint8_t>> payload(
219       std::begin(kTestPayloadToSign), std::end(kTestPayloadToSign));
220   return *payload;
221 }
222 
GetNearbyShareTestSampleSignature()223 const std::vector<uint8_t>& GetNearbyShareTestSampleSignature() {
224   static const base::NoDestructor<std::vector<uint8_t>> signature(
225       std::begin(kTestSampleSignature), std::end(kTestSampleSignature));
226   return *signature;
227 }
228 
GetNearbyShareTestPayloadHashUsingSecretKey()229 const std::vector<uint8_t>& GetNearbyShareTestPayloadHashUsingSecretKey() {
230   static const base::NoDestructor<std::vector<uint8_t>> hash(
231       std::begin(kTestPayloadHashUsingSecretKey),
232       std::end(kTestPayloadHashUsingSecretKey));
233   return *hash;
234 }
235 
GetNearbyShareTestPrivateCertificate(nearby_share::mojom::Visibility visibility,base::Time not_before)236 NearbySharePrivateCertificate GetNearbyShareTestPrivateCertificate(
237     nearby_share::mojom::Visibility visibility,
238     base::Time not_before) {
239   NearbySharePrivateCertificate cert(
240       visibility, not_before,
241       not_before + kNearbyShareCertificateValidityPeriod,
242       GetNearbyShareTestP256KeyPair(), GetNearbyShareTestSecretKey(),
243       GetNearbyShareTestMetadataEncryptionKey(),
244       GetNearbyShareTestCertificateId(), GetNearbyShareTestMetadata(),
245       /*consumed_salts=*/std::set<std::vector<uint8_t>>());
246   cert.next_salts_for_testing().push(GetNearbyShareTestSalt());
247   return cert;
248 }
249 
GetNearbyShareTestPublicCertificate(nearby_share::mojom::Visibility visibility,base::Time not_before)250 nearbyshare::proto::PublicCertificate GetNearbyShareTestPublicCertificate(
251     nearby_share::mojom::Visibility visibility,
252     base::Time not_before) {
253   nearbyshare::proto::PublicCertificate cert;
254   cert.set_secret_id(std::string(GetNearbyShareTestCertificateId().begin(),
255                                  GetNearbyShareTestCertificateId().end()));
256   cert.set_secret_key(GetNearbyShareTestSecretKey()->key());
257   cert.set_public_key(std::string(GetNearbyShareTestP256PublicKey().begin(),
258                                   GetNearbyShareTestP256PublicKey().end()));
259   cert.mutable_start_time()->set_seconds(
260       (not_before - GetNearbyShareTestValidityOffset()).ToJavaTime() / 1000);
261   cert.mutable_end_time()->set_seconds((not_before +
262                                         kNearbyShareCertificateValidityPeriod +
263                                         GetNearbyShareTestValidityOffset())
264                                            .ToJavaTime() /
265                                        1000);
266   cert.set_for_selected_contacts(
267       visibility == nearby_share::mojom::Visibility::kSelectedContacts);
268   cert.set_metadata_encryption_key(
269       std::string(GetNearbyShareTestMetadataEncryptionKey().begin(),
270                   GetNearbyShareTestMetadataEncryptionKey().end()));
271   cert.set_encrypted_metadata_bytes(
272       std::string(GetNearbyShareTestEncryptedMetadata().begin(),
273                   GetNearbyShareTestEncryptedMetadata().end()));
274   cert.set_metadata_encryption_key_tag(
275       std::string(GetNearbyShareTestMetadataEncryptionKeyTag().begin(),
276                   GetNearbyShareTestMetadataEncryptionKeyTag().end()));
277   return cert;
278 }
279 
280 std::vector<NearbySharePrivateCertificate>
GetNearbyShareTestPrivateCertificateList(nearby_share::mojom::Visibility visibility)281 GetNearbyShareTestPrivateCertificateList(
282     nearby_share::mojom::Visibility visibility) {
283   std::vector<NearbySharePrivateCertificate> list;
284   for (size_t i = 0; i < kNearbyShareNumPrivateCertificates; ++i) {
285     list.push_back(GetNearbyShareTestPrivateCertificate(
286         visibility, GetNearbyShareTestNotBefore() +
287                         i * kNearbyShareCertificateValidityPeriod));
288   }
289   return list;
290 }
291 
292 std::vector<nearbyshare::proto::PublicCertificate>
GetNearbyShareTestPublicCertificateList(nearby_share::mojom::Visibility visibility)293 GetNearbyShareTestPublicCertificateList(
294     nearby_share::mojom::Visibility visibility) {
295   std::vector<nearbyshare::proto::PublicCertificate> list;
296   for (size_t i = 0; i < kNearbyShareNumPrivateCertificates; ++i) {
297     list.push_back(GetNearbyShareTestPublicCertificate(
298         visibility, GetNearbyShareTestNotBefore() +
299                         i * kNearbyShareCertificateValidityPeriod));
300   }
301   return list;
302 }
303 
304 const NearbyShareDecryptedPublicCertificate&
GetNearbyShareTestDecryptedPublicCertificate()305 GetNearbyShareTestDecryptedPublicCertificate() {
306   static const base::NoDestructor<NearbyShareDecryptedPublicCertificate> cert(
307       *NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
308           GetNearbyShareTestPublicCertificate(
309               nearby_share::mojom::Visibility::kAllContacts),
310           GetNearbyShareTestEncryptedMetadataKey()));
311   return *cert;
312 }
313