Home | History | Annotate | Download | only in test
      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 = blink::WebCryptoKey::createNull();
     29   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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 = blink::WebCryptoKey::createNull();
     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 = blink::WebCryptoKey::createNull();
     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 = blink::WebCryptoKey::createNull();
    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 = blink::WebCryptoKey::createNull();
    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 = blink::WebCryptoKey::createNull();
    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 = blink::WebCryptoKey::createNull();
    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 = blink::WebCryptoKey::createNull();
    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 = blink::WebCryptoKey::createNull();
    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 = blink::WebCryptoKey::createNull();
    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 = blink::WebCryptoKey::createNull();
    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 = blink::WebCryptoKey::createNull();
    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 = blink::WebCryptoKey::createNull();
    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 = blink::WebCryptoKey::createNull();
    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
    608