OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 "base/stl_util.h" | |
6 #include "content/child/webcrypto/algorithm_dispatch.h" | |
7 #include "content/child/webcrypto/crypto_data.h" | |
8 #include "content/child/webcrypto/status.h" | |
9 #include "content/child/webcrypto/test/test_helpers.h" | |
10 #include "content/child/webcrypto/webcrypto_util.h" | |
11 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | |
12 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | |
13 | |
14 namespace content { | |
15 | |
16 namespace webcrypto { | |
17 | |
18 namespace { | |
19 | |
20 blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm( | |
21 unsigned short key_length_bits) { | |
22 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesKw, | |
23 key_length_bits); | |
24 } | |
25 | |
26 TEST(WebCryptoAesKwTest, GenerateKeyBadLength) { | |
27 const unsigned short kKeyLen[] = {0, 127, 257}; | |
28 blink::WebCryptoKey key; | |
29 for (size_t i = 0; i < arraysize(kKeyLen); ++i) { | |
30 SCOPED_TRACE(i); | |
31 EXPECT_EQ(Status::ErrorGenerateAesKeyLength(), | |
32 GenerateSecretKey(CreateAesKwKeyGenAlgorithm(kKeyLen[i]), true, | |
33 blink::WebCryptoKeyUsageWrapKey, &key)); | |
34 } | |
35 } | |
36 | |
37 TEST(WebCryptoAesKwTest, GenerateKeyEmptyUsage) { | |
38 blink::WebCryptoKey key; | |
39 EXPECT_EQ(Status::ErrorCreateKeyEmptyUsages(), | |
40 GenerateSecretKey(CreateAesKwKeyGenAlgorithm(256), true, 0, &key)); | |
41 } | |
42 | |
43 TEST(WebCryptoAesKwTest, ImportKeyEmptyUsage) { | |
44 blink::WebCryptoKey key; | |
45 EXPECT_EQ(Status::ErrorCreateKeyEmptyUsages(), | |
46 ImportKey(blink::WebCryptoKeyFormatRaw, | |
47 CryptoData(std::vector<uint8_t>(16)), | |
48 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw), | |
49 true, 0, &key)); | |
50 } | |
51 | |
52 TEST(WebCryptoAesKwTest, ImportKeyJwkKeyOpsWrapUnwrap) { | |
53 blink::WebCryptoKey key; | |
54 base::DictionaryValue dict; | |
55 dict.SetString("kty", "oct"); | |
56 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg"); | |
57 base::ListValue* key_ops = new base::ListValue; | |
58 dict.Set("key_ops", key_ops); // Takes ownership. | |
59 | |
60 key_ops->AppendString("wrapKey"); | |
61 | |
62 EXPECT_EQ(Status::Success(), | |
63 ImportKeyJwkFromDict( | |
64 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw), false, | |
65 blink::WebCryptoKeyUsageWrapKey, &key)); | |
66 | |
67 EXPECT_EQ(blink::WebCryptoKeyUsageWrapKey, key.usages()); | |
68 | |
69 key_ops->AppendString("unwrapKey"); | |
70 | |
71 EXPECT_EQ(Status::Success(), | |
72 ImportKeyJwkFromDict( | |
73 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw), false, | |
74 blink::WebCryptoKeyUsageUnwrapKey, &key)); | |
75 | |
76 EXPECT_EQ(blink::WebCryptoKeyUsageUnwrapKey, key.usages()); | |
77 } | |
78 | |
79 TEST(WebCryptoAesKwTest, ImportExportJwk) { | |
80 const blink::WebCryptoAlgorithm algorithm = | |
81 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
82 | |
83 // AES-KW 128 | |
84 ImportExportJwkSymmetricKey( | |
85 128, algorithm, | |
86 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, | |
87 "A128KW"); | |
88 | |
89 // AES-KW 256 | |
90 ImportExportJwkSymmetricKey( | |
91 256, algorithm, | |
92 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, | |
93 "A256KW"); | |
94 } | |
95 | |
96 TEST(WebCryptoAesKwTest, AesKwKeyImport) { | |
97 blink::WebCryptoKey key; | |
98 blink::WebCryptoAlgorithm algorithm = | |
99 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
100 | |
101 // Import a 128-bit Key Encryption Key (KEK) | |
102 std::string key_raw_hex_in = "025a8cf3f08b4f6c5f33bbc76a471939"; | |
103 ASSERT_EQ(Status::Success(), | |
104 ImportKey(blink::WebCryptoKeyFormatRaw, | |
105 CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm, | |
106 true, blink::WebCryptoKeyUsageWrapKey, &key)); | |
107 std::vector<uint8_t> key_raw_out; | |
108 EXPECT_EQ(Status::Success(), | |
109 ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_raw_out)); | |
110 EXPECT_BYTES_EQ_HEX(key_raw_hex_in, key_raw_out); | |
111 | |
112 // Import a 192-bit KEK | |
113 key_raw_hex_in = "c0192c6466b2370decbb62b2cfef4384544ffeb4d2fbc103"; | |
114 ASSERT_EQ(Status::ErrorAes192BitUnsupported(), | |
115 ImportKey(blink::WebCryptoKeyFormatRaw, | |
116 CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm, | |
117 true, blink::WebCryptoKeyUsageWrapKey, &key)); | |
118 | |
119 // Import a 256-bit Key Encryption Key (KEK) | |
120 key_raw_hex_in = | |
121 "e11fe66380d90fa9ebefb74e0478e78f95664d0c67ca20ce4a0b5842863ac46f"; | |
122 ASSERT_EQ(Status::Success(), | |
123 ImportKey(blink::WebCryptoKeyFormatRaw, | |
124 CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm, | |
125 true, blink::WebCryptoKeyUsageWrapKey, &key)); | |
126 EXPECT_EQ(Status::Success(), | |
127 ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_raw_out)); | |
128 EXPECT_BYTES_EQ_HEX(key_raw_hex_in, key_raw_out); | |
129 | |
130 // Fail import of 0 length key | |
131 EXPECT_EQ( | |
132 Status::ErrorImportAesKeyLength(), | |
133 ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(HexStringToBytes("")), | |
134 algorithm, true, blink::WebCryptoKeyUsageWrapKey, &key)); | |
135 | |
136 // Fail import of 124-bit KEK | |
137 key_raw_hex_in = "3e4566a2bdaa10cb68134fa66c15ddb"; | |
138 EXPECT_EQ(Status::ErrorImportAesKeyLength(), | |
139 ImportKey(blink::WebCryptoKeyFormatRaw, | |
140 CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm, | |
141 true, blink::WebCryptoKeyUsageWrapKey, &key)); | |
142 | |
143 // Fail import of 200-bit KEK | |
144 key_raw_hex_in = "0a1d88608a5ad9fec64f1ada269ebab4baa2feeb8d95638c0e"; | |
145 EXPECT_EQ(Status::ErrorImportAesKeyLength(), | |
146 ImportKey(blink::WebCryptoKeyFormatRaw, | |
147 CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm, | |
148 true, blink::WebCryptoKeyUsageWrapKey, &key)); | |
149 | |
150 // Fail import of 260-bit KEK | |
151 key_raw_hex_in = | |
152 "72d4e475ff34215416c9ad9c8281247a4d730c5f275ac23f376e73e3bce8d7d5a"; | |
153 EXPECT_EQ(Status::ErrorImportAesKeyLength(), | |
154 ImportKey(blink::WebCryptoKeyFormatRaw, | |
155 CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm, | |
156 true, blink::WebCryptoKeyUsageWrapKey, &key)); | |
157 } | |
158 | |
159 TEST(WebCryptoAesKwTest, UnwrapFailures) { | |
160 // This test exercises the code path common to all unwrap operations. | |
161 scoped_ptr<base::ListValue> tests; | |
162 ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests)); | |
163 base::DictionaryValue* test; | |
164 ASSERT_TRUE(tests->GetDictionary(0, &test)); | |
165 const std::vector<uint8_t> test_kek = GetBytesFromHexString(test, "kek"); | |
166 const std::vector<uint8_t> test_ciphertext = | |
167 GetBytesFromHexString(test, "ciphertext"); | |
168 | |
169 blink::WebCryptoKey unwrapped_key; | |
170 | |
171 // Using a wrapping algorithm that does not match the wrapping key algorithm | |
172 // should fail. | |
173 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( | |
174 test_kek, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw), | |
175 blink::WebCryptoKeyUsageUnwrapKey); | |
176 EXPECT_EQ(Status::ErrorUnexpected(), | |
177 UnwrapKey(blink::WebCryptoKeyFormatRaw, CryptoData(test_ciphertext), | |
178 wrapping_key, | |
179 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), | |
180 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true, | |
181 blink::WebCryptoKeyUsageEncrypt, &unwrapped_key)); | |
182 } | |
183 | |
184 TEST(WebCryptoAesKwTest, AesKwRawSymkeyWrapUnwrapKnownAnswer) { | |
185 scoped_ptr<base::ListValue> tests; | |
186 ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests)); | |
187 | |
188 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { | |
189 SCOPED_TRACE(test_index); | |
190 base::DictionaryValue* test; | |
191 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); | |
192 const std::vector<uint8_t> test_kek = GetBytesFromHexString(test, "kek"); | |
193 const std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key"); | |
194 const std::vector<uint8_t> test_ciphertext = | |
195 GetBytesFromHexString(test, "ciphertext"); | |
196 const blink::WebCryptoAlgorithm wrapping_algorithm = | |
197 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
198 | |
199 // Import the wrapping key. | |
200 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( | |
201 test_kek, wrapping_algorithm, | |
202 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey); | |
203 | |
204 // Import the key to be wrapped. | |
205 blink::WebCryptoKey key = ImportSecretKeyFromRaw( | |
206 test_key, | |
207 CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha1), | |
208 blink::WebCryptoKeyUsageSign); | |
209 | |
210 // Wrap the key and verify the ciphertext result against the known answer. | |
211 std::vector<uint8_t> wrapped_key; | |
212 ASSERT_EQ(Status::Success(), | |
213 WrapKey(blink::WebCryptoKeyFormatRaw, key, wrapping_key, | |
214 wrapping_algorithm, &wrapped_key)); | |
215 EXPECT_BYTES_EQ(test_ciphertext, wrapped_key); | |
216 | |
217 // Unwrap the known ciphertext to get a new test_key. | |
218 blink::WebCryptoKey unwrapped_key; | |
219 ASSERT_EQ( | |
220 Status::Success(), | |
221 UnwrapKey( | |
222 blink::WebCryptoKeyFormatRaw, CryptoData(test_ciphertext), | |
223 wrapping_key, wrapping_algorithm, | |
224 CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha1), | |
225 true, blink::WebCryptoKeyUsageSign, &unwrapped_key)); | |
226 EXPECT_FALSE(key.isNull()); | |
227 EXPECT_TRUE(key.handle()); | |
228 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); | |
229 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); | |
230 EXPECT_EQ(true, key.extractable()); | |
231 EXPECT_EQ(blink::WebCryptoKeyUsageSign, key.usages()); | |
232 | |
233 // Export the new key and compare its raw bytes with the original known key. | |
234 std::vector<uint8_t> raw_key; | |
235 EXPECT_EQ(Status::Success(), | |
236 ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key)); | |
237 EXPECT_BYTES_EQ(test_key, raw_key); | |
238 } | |
239 } | |
240 | |
241 // Unwrap a HMAC key using AES-KW, and then try doing a sign/verify with the | |
242 // unwrapped key | |
243 TEST(WebCryptoAesKwTest, AesKwRawSymkeyUnwrapSignVerifyHmac) { | |
244 scoped_ptr<base::ListValue> tests; | |
245 ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests)); | |
246 | |
247 base::DictionaryValue* test; | |
248 ASSERT_TRUE(tests->GetDictionary(0, &test)); | |
249 const std::vector<uint8_t> test_kek = GetBytesFromHexString(test, "kek"); | |
250 const std::vector<uint8_t> test_ciphertext = | |
251 GetBytesFromHexString(test, "ciphertext"); | |
252 const blink::WebCryptoAlgorithm wrapping_algorithm = | |
253 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
254 | |
255 // Import the wrapping key. | |
256 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( | |
257 test_kek, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey); | |
258 | |
259 // Unwrap the known ciphertext. | |
260 blink::WebCryptoKey key; | |
261 ASSERT_EQ( | |
262 Status::Success(), | |
263 UnwrapKey( | |
264 blink::WebCryptoKeyFormatRaw, CryptoData(test_ciphertext), | |
265 wrapping_key, wrapping_algorithm, | |
266 CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha1), | |
267 false, blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, | |
268 &key)); | |
269 | |
270 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); | |
271 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); | |
272 EXPECT_FALSE(key.extractable()); | |
273 EXPECT_EQ(blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, | |
274 key.usages()); | |
275 | |
276 // Sign an empty message and ensure it is verified. | |
277 std::vector<uint8_t> test_message; | |
278 std::vector<uint8_t> signature; | |
279 | |
280 ASSERT_EQ(Status::Success(), | |
281 Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), key, | |
282 CryptoData(test_message), &signature)); | |
283 | |
284 EXPECT_GT(signature.size(), 0u); | |
285 | |
286 bool verify_result; | |
287 ASSERT_EQ( | |
288 Status::Success(), | |
289 Verify(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), key, | |
290 CryptoData(signature), CryptoData(test_message), &verify_result)); | |
291 } | |
292 | |
293 TEST(WebCryptoAesKwTest, AesKwRawSymkeyWrapUnwrapErrors) { | |
294 scoped_ptr<base::ListValue> tests; | |
295 ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests)); | |
296 base::DictionaryValue* test; | |
297 // Use 256 bits of data with a 256-bit KEK | |
298 ASSERT_TRUE(tests->GetDictionary(3, &test)); | |
299 const std::vector<uint8_t> test_kek = GetBytesFromHexString(test, "kek"); | |
300 const std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key"); | |
301 const std::vector<uint8_t> test_ciphertext = | |
302 GetBytesFromHexString(test, "ciphertext"); | |
303 const blink::WebCryptoAlgorithm wrapping_algorithm = | |
304 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
305 const blink::WebCryptoAlgorithm key_algorithm = | |
306 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | |
307 // Import the wrapping key. | |
308 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( | |
309 test_kek, wrapping_algorithm, | |
310 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey); | |
311 // Import the key to be wrapped. | |
312 blink::WebCryptoKey key = ImportSecretKeyFromRaw( | |
313 test_key, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), | |
314 blink::WebCryptoKeyUsageEncrypt); | |
315 | |
316 // Unwrap with wrapped data too small must fail. | |
317 const std::vector<uint8_t> small_data(test_ciphertext.begin(), | |
318 test_ciphertext.begin() + 23); | |
319 blink::WebCryptoKey unwrapped_key; | |
320 EXPECT_EQ(Status::ErrorDataTooSmall(), | |
321 UnwrapKey(blink::WebCryptoKeyFormatRaw, CryptoData(small_data), | |
322 wrapping_key, wrapping_algorithm, key_algorithm, true, | |
323 blink::WebCryptoKeyUsageEncrypt, &unwrapped_key)); | |
324 | |
325 // Unwrap with wrapped data size not a multiple of 8 bytes must fail. | |
326 const std::vector<uint8_t> unaligned_data(test_ciphertext.begin(), | |
327 test_ciphertext.end() - 2); | |
328 EXPECT_EQ(Status::ErrorInvalidAesKwDataLength(), | |
329 UnwrapKey(blink::WebCryptoKeyFormatRaw, CryptoData(unaligned_data), | |
330 wrapping_key, wrapping_algorithm, key_algorithm, true, | |
331 blink::WebCryptoKeyUsageEncrypt, &unwrapped_key)); | |
332 } | |
333 | |
334 TEST(WebCryptoAesKwTest, AesKwRawSymkeyUnwrapCorruptData) { | |
335 scoped_ptr<base::ListValue> tests; | |
336 ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests)); | |
337 base::DictionaryValue* test; | |
338 // Use 256 bits of data with a 256-bit KEK | |
339 ASSERT_TRUE(tests->GetDictionary(3, &test)); | |
340 const std::vector<uint8_t> test_kek = GetBytesFromHexString(test, "kek"); | |
341 const std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key"); | |
342 const std::vector<uint8_t> test_ciphertext = | |
343 GetBytesFromHexString(test, "ciphertext"); | |
344 const blink::WebCryptoAlgorithm wrapping_algorithm = | |
345 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
346 | |
347 // Import the wrapping key. | |
348 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( | |
349 test_kek, wrapping_algorithm, | |
350 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey); | |
351 | |
352 // Unwrap of a corrupted version of the known ciphertext should fail, due to | |
353 // AES-KW's built-in integrity check. | |
354 blink::WebCryptoKey unwrapped_key; | |
355 EXPECT_EQ(Status::OperationError(), | |
356 UnwrapKey(blink::WebCryptoKeyFormatRaw, | |
357 CryptoData(Corrupted(test_ciphertext)), wrapping_key, | |
358 wrapping_algorithm, | |
359 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true, | |
360 blink::WebCryptoKeyUsageEncrypt, &unwrapped_key)); | |
361 } | |
362 | |
363 TEST(WebCryptoAesKwTest, AesKwJwkSymkeyUnwrapKnownData) { | |
364 // The following data lists a known HMAC SHA-256 key, then a JWK | |
365 // representation of this key which was encrypted ("wrapped") using AES-KW and | |
366 // the following wrapping key. | |
367 // For reference, the intermediate clear JWK is | |
368 // {"alg":"HS256","ext":true,"k":<b64urlKey>,"key_ops":["verify"],"kty":"oct"} | |
369 // (Not shown is space padding to ensure the cleartext meets the size | |
370 // requirements of the AES-KW algorithm.) | |
371 const std::vector<uint8_t> key_data = HexStringToBytes( | |
372 "000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F"); | |
373 const std::vector<uint8_t> wrapped_key_data = HexStringToBytes( | |
374 "14E6380B35FDC5B72E1994764B6CB7BFDD64E7832894356AAEE6C3768FC3D0F115E6B0" | |
375 "6729756225F999AA99FDF81FD6A359F1576D3D23DE6CB69C3937054EB497AC1E8C38D5" | |
376 "5E01B9783A20C8D930020932CF25926103002213D0FC37279888154FEBCEDF31832158" | |
377 "97938C5CFE5B10B4254D0C399F39D0"); | |
378 const std::vector<uint8_t> wrapping_key_data = | |
379 HexStringToBytes("000102030405060708090A0B0C0D0E0F"); | |
380 const blink::WebCryptoAlgorithm wrapping_algorithm = | |
381 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
382 | |
383 // Import the wrapping key. | |
384 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( | |
385 wrapping_key_data, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey); | |
386 | |
387 // Unwrap the known wrapped key data to produce a new key | |
388 blink::WebCryptoKey unwrapped_key; | |
389 ASSERT_EQ( | |
390 Status::Success(), | |
391 UnwrapKey( | |
392 blink::WebCryptoKeyFormatJwk, CryptoData(wrapped_key_data), | |
393 wrapping_key, wrapping_algorithm, | |
394 CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha256), | |
395 true, blink::WebCryptoKeyUsageVerify, &unwrapped_key)); | |
396 | |
397 // Validate the new key's attributes. | |
398 EXPECT_FALSE(unwrapped_key.isNull()); | |
399 EXPECT_TRUE(unwrapped_key.handle()); | |
400 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, unwrapped_key.type()); | |
401 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, unwrapped_key.algorithm().id()); | |
402 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, | |
403 unwrapped_key.algorithm().hmacParams()->hash().id()); | |
404 EXPECT_EQ(256u, unwrapped_key.algorithm().hmacParams()->lengthBits()); | |
405 EXPECT_EQ(true, unwrapped_key.extractable()); | |
406 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, unwrapped_key.usages()); | |
407 | |
408 // Export the new key's raw data and compare to the known original. | |
409 std::vector<uint8_t> raw_key; | |
410 EXPECT_EQ(Status::Success(), | |
411 ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key)); | |
412 EXPECT_BYTES_EQ(key_data, raw_key); | |
413 } | |
414 | |
415 // Try importing an AES-KW key with unsupported key usages using raw | |
416 // format. AES-KW keys support the following usages: | |
417 // 'wrapKey', 'unwrapKey' | |
418 TEST(WebCryptoAesKwTest, ImportKeyBadUsage_Raw) { | |
419 const blink::WebCryptoAlgorithm algorithm = | |
420 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
421 | |
422 blink::WebCryptoKeyUsageMask bad_usages[] = { | |
423 blink::WebCryptoKeyUsageEncrypt, | |
424 blink::WebCryptoKeyUsageDecrypt, | |
425 blink::WebCryptoKeyUsageSign, | |
426 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageUnwrapKey, | |
427 blink::WebCryptoKeyUsageDeriveBits, | |
428 blink::WebCryptoKeyUsageUnwrapKey | blink::WebCryptoKeyUsageVerify, | |
429 }; | |
430 | |
431 std::vector<uint8_t> key_bytes(16); | |
432 | |
433 for (size_t i = 0; i < arraysize(bad_usages); ++i) { | |
434 SCOPED_TRACE(i); | |
435 | |
436 blink::WebCryptoKey key; | |
437 ASSERT_EQ(Status::ErrorCreateKeyBadUsages(), | |
438 ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(key_bytes), | |
439 algorithm, true, bad_usages[i], &key)); | |
440 } | |
441 } | |
442 | |
443 // Try unwrapping an HMAC key with unsupported usages using JWK format and | |
444 // AES-KW. HMAC keys support the following usages: | |
445 // 'sign', 'verify' | |
446 TEST(WebCryptoAesKwTest, UnwrapHmacKeyBadUsage_JWK) { | |
447 const blink::WebCryptoAlgorithm unwrap_algorithm = | |
448 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
449 | |
450 blink::WebCryptoKeyUsageMask bad_usages[] = { | |
451 blink::WebCryptoKeyUsageEncrypt, | |
452 blink::WebCryptoKeyUsageDecrypt, | |
453 blink::WebCryptoKeyUsageWrapKey, | |
454 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageWrapKey, | |
455 blink::WebCryptoKeyUsageVerify | blink::WebCryptoKeyUsageDeriveKey, | |
456 }; | |
457 | |
458 // Import the wrapping key. | |
459 blink::WebCryptoKey wrapping_key; | |
460 ASSERT_EQ(Status::Success(), | |
461 ImportKey(blink::WebCryptoKeyFormatRaw, | |
462 CryptoData(std::vector<uint8_t>(16)), unwrap_algorithm, | |
463 true, blink::WebCryptoKeyUsageUnwrapKey, &wrapping_key)); | |
464 | |
465 // The JWK plain text is: | |
466 // {"kty":"oct","alg":"HS256","k":"GADWrMRHwQfoNaXU5fZvTg"} | |
467 const char* kWrappedJwk = | |
468 "C2B7F19A32EE31372CD40C9C969B8CD67553E5AEA7FD1144874584E46ABCD79FDC308848" | |
469 "B2DD8BD36A2D61062B9C5B8B499B8D6EF8EB320D87A614952B4EE771"; | |
470 | |
471 for (size_t i = 0; i < arraysize(bad_usages); ++i) { | |
472 SCOPED_TRACE(i); | |
473 | |
474 blink::WebCryptoKey key; | |
475 | |
476 ASSERT_EQ( | |
477 Status::ErrorCreateKeyBadUsages(), | |
478 UnwrapKey(blink::WebCryptoKeyFormatJwk, | |
479 CryptoData(HexStringToBytes(kWrappedJwk)), wrapping_key, | |
480 unwrap_algorithm, CreateHmacImportAlgorithmNoLength( | |
481 blink::WebCryptoAlgorithmIdSha256), | |
482 true, bad_usages[i], &key)); | |
483 } | |
484 } | |
485 | |
486 // Try unwrapping an RSA-SSA public key with unsupported usages using JWK format | |
487 // and AES-KW. RSA-SSA public keys support the following usages: | |
488 // 'verify' | |
489 TEST(WebCryptoAesKwTest, UnwrapRsaSsaPublicKeyBadUsage_JWK) { | |
490 const blink::WebCryptoAlgorithm unwrap_algorithm = | |
491 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
492 | |
493 blink::WebCryptoKeyUsageMask bad_usages[] = { | |
494 blink::WebCryptoKeyUsageEncrypt, | |
495 blink::WebCryptoKeyUsageSign, | |
496 blink::WebCryptoKeyUsageDecrypt, | |
497 blink::WebCryptoKeyUsageWrapKey, | |
498 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageWrapKey, | |
499 }; | |
500 | |
501 // Import the wrapping key. | |
502 blink::WebCryptoKey wrapping_key; | |
503 ASSERT_EQ(Status::Success(), | |
504 ImportKey(blink::WebCryptoKeyFormatRaw, | |
505 CryptoData(std::vector<uint8_t>(16)), unwrap_algorithm, | |
506 true, blink::WebCryptoKeyUsageUnwrapKey, &wrapping_key)); | |
507 | |
508 // The JWK plaintext is: | |
509 // { "kty": "RSA","alg": "RS256","n": "...","e": "AQAB"} | |
510 | |
511 const char* kWrappedJwk = | |
512 "CE8DAEF99E977EE58958B8C4494755C846E883B2ECA575C5366622839AF71AB30875F152" | |
513 "E8E33E15A7817A3A2874EB53EFE05C774D98BC936BA9BA29BEB8BB3F3C3CE2323CB3359D" | |
514 "E3F426605CF95CCF0E01E870ABD7E35F62E030B5FB6E520A5885514D1D850FB64B57806D" | |
515 "1ADA57C6E27DF345D8292D80F6B074F1BE51C4CF3D76ECC8886218551308681B44FAC60B" | |
516 "8CF6EA439BC63239103D0AE81ADB96F908680586C6169284E32EB7DD09D31103EBDAC0C2" | |
517 "40C72DCF0AEA454113CC47457B13305B25507CBEAB9BDC8D8E0F867F9167F9DCEF0D9F9B" | |
518 "30F2EE83CEDFD51136852C8A5939B768"; | |
519 | |
520 for (size_t i = 0; i < arraysize(bad_usages); ++i) { | |
521 SCOPED_TRACE(i); | |
522 | |
523 blink::WebCryptoKey key; | |
524 | |
525 ASSERT_EQ(Status::ErrorCreateKeyBadUsages(), | |
526 UnwrapKey(blink::WebCryptoKeyFormatJwk, | |
527 CryptoData(HexStringToBytes(kWrappedJwk)), wrapping_key, | |
528 unwrap_algorithm, | |
529 CreateRsaHashedImportAlgorithm( | |
530 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | |
531 blink::WebCryptoAlgorithmIdSha256), | |
532 true, bad_usages[i], &key)); | |
533 } | |
534 } | |
535 | |
536 } // namespace | |
537 | |
538 } // namespace webcrypto | |
539 | |
540 } // namespace content | |
OLD | NEW |