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