OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/child/webcrypto/shared_crypto.h" | 5 #include "content/child/webcrypto/shared_crypto.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); | 998 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); |
999 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha512, | 999 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha512, |
1000 key.algorithm().hmacParams()->hash().id()); | 1000 key.algorithm().hmacParams()->hash().id()); |
1001 #if defined(WEBCRYPTO_HMAC_KEY_HAS_LENGTH) | 1001 #if defined(WEBCRYPTO_HMAC_KEY_HAS_LENGTH) |
1002 EXPECT_EQ(1024u, key.algorithm().hmacParams()->lengthBits()); | 1002 EXPECT_EQ(1024u, key.algorithm().hmacParams()->lengthBits()); |
1003 #endif | 1003 #endif |
1004 ASSERT_STATUS_SUCCESS(ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key)); | 1004 ASSERT_STATUS_SUCCESS(ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key)); |
1005 EXPECT_EQ(128U, raw_key.byteLength()); | 1005 EXPECT_EQ(128U, raw_key.byteLength()); |
1006 } | 1006 } |
1007 | 1007 |
1008 TEST_F(SharedCryptoTest, MAYBE(ImportSecretKeyNoAlgorithm)) { | |
1009 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | |
1010 | |
1011 // This fails because the algorithm is null. | |
1012 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), | |
1013 ImportKey(blink::WebCryptoKeyFormatRaw, | |
1014 CryptoData(HexStringToBytes("00000000000000000000")), | |
1015 blink::WebCryptoAlgorithm::createNull(), | |
1016 true, | |
1017 blink::WebCryptoKeyUsageEncrypt, | |
1018 &key)); | |
1019 } | |
1020 | |
1021 TEST_F(SharedCryptoTest, ImportJwkKeyUsage) { | 1008 TEST_F(SharedCryptoTest, ImportJwkKeyUsage) { |
1022 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1009 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1023 base::DictionaryValue dict; | 1010 base::DictionaryValue dict; |
1024 dict.SetString("kty", "oct"); | 1011 dict.SetString("kty", "oct"); |
1025 dict.SetBoolean("ext", false); | 1012 dict.SetBoolean("ext", false); |
1026 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); | 1013 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); |
1027 const blink::WebCryptoAlgorithm aes_cbc_algorithm = | 1014 const blink::WebCryptoAlgorithm aes_cbc_algorithm = |
1028 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 1015 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
1029 const blink::WebCryptoAlgorithm hmac_algorithm = | 1016 const blink::WebCryptoAlgorithm hmac_algorithm = |
1030 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | 1017 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1181 Status::ErrorJwkNotDictionary(), | 1168 Status::ErrorJwkNotDictionary(), |
1182 ImportKeyJwk( | 1169 ImportKeyJwk( |
1183 CryptoData(bad_json_vec), algorithm, false, usage_mask, &key)); | 1170 CryptoData(bad_json_vec), algorithm, false, usage_mask, &key)); |
1184 | 1171 |
1185 // Fail on JWK alg present but unrecognized. | 1172 // Fail on JWK alg present but unrecognized. |
1186 dict.SetString("alg", "A127CBC"); | 1173 dict.SetString("alg", "A127CBC"); |
1187 EXPECT_STATUS(Status::ErrorJwkUnrecognizedAlgorithm(), | 1174 EXPECT_STATUS(Status::ErrorJwkUnrecognizedAlgorithm(), |
1188 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1175 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1189 RestoreJwkOctDictionary(&dict); | 1176 RestoreJwkOctDictionary(&dict); |
1190 | 1177 |
1191 // Fail on both JWK and input algorithm missing. | |
1192 dict.Remove("alg", NULL); | |
1193 EXPECT_STATUS(Status::ErrorJwkAlgorithmMissing(), | |
1194 ImportKeyJwkFromDict(dict, | |
1195 blink::WebCryptoAlgorithm::createNull(), | |
1196 false, | |
1197 usage_mask, | |
1198 &key)); | |
1199 RestoreJwkOctDictionary(&dict); | |
1200 | |
1201 // Fail on invalid kty. | 1178 // Fail on invalid kty. |
1202 dict.SetString("kty", "foo"); | 1179 dict.SetString("kty", "foo"); |
1203 EXPECT_STATUS(Status::ErrorJwkUnrecognizedKty(), | 1180 EXPECT_STATUS(Status::ErrorJwkUnrecognizedKty(), |
1204 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1181 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1205 RestoreJwkOctDictionary(&dict); | 1182 RestoreJwkOctDictionary(&dict); |
1206 | 1183 |
1207 // Fail on missing kty. | 1184 // Fail on missing kty. |
1208 dict.Remove("kty", NULL); | 1185 dict.Remove("kty", NULL); |
1209 EXPECT_STATUS(Status::ErrorJwkPropertyMissing("kty"), | 1186 EXPECT_STATUS(Status::ErrorJwkPropertyMissing("kty"), |
1210 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1187 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 // Fail: Input algorithm (HMAC SHA1) is inconsistent with JWK value | 1405 // Fail: Input algorithm (HMAC SHA1) is inconsistent with JWK value |
1429 // (HMAC SHA256). | 1406 // (HMAC SHA256). |
1430 EXPECT_STATUS( | 1407 EXPECT_STATUS( |
1431 Status::ErrorJwkAlgorithmInconsistent(), | 1408 Status::ErrorJwkAlgorithmInconsistent(), |
1432 ImportKeyJwk(CryptoData(json_vec), | 1409 ImportKeyJwk(CryptoData(json_vec), |
1433 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1), | 1410 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1), |
1434 extractable, | 1411 extractable, |
1435 usage_mask, | 1412 usage_mask, |
1436 &key)); | 1413 &key)); |
1437 | 1414 |
1438 // Pass: JWK alg valid but input algorithm isNull: use JWK algorithm value. | |
1439 EXPECT_STATUS_SUCCESS(ImportKeyJwk(CryptoData(json_vec), | |
1440 blink::WebCryptoAlgorithm::createNull(), | |
1441 extractable, | |
1442 usage_mask, | |
1443 &key)); | |
1444 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); | |
1445 | |
1446 // Pass: JWK alg missing but input algorithm specified: use input value | 1415 // Pass: JWK alg missing but input algorithm specified: use input value |
1447 dict.Remove("alg", NULL); | 1416 dict.Remove("alg", NULL); |
1448 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( | 1417 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( |
1449 dict, | 1418 dict, |
1450 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), | 1419 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
1451 extractable, | 1420 extractable, |
1452 usage_mask, | 1421 usage_mask, |
1453 &key)); | 1422 &key)); |
1454 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); | 1423 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); |
1455 dict.SetString("alg", "HS256"); | 1424 dict.SetString("alg", "HS256"); |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1662 EXPECT_TRUE(key.handle()); | 1631 EXPECT_TRUE(key.handle()); |
1663 EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type()); | 1632 EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type()); |
1664 EXPECT_TRUE(key.extractable()); | 1633 EXPECT_TRUE(key.extractable()); |
1665 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages()); | 1634 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages()); |
1666 EXPECT_EQ(kModulusLengthBits, | 1635 EXPECT_EQ(kModulusLengthBits, |
1667 key.algorithm().rsaParams()->modulusLengthBits()); | 1636 key.algorithm().rsaParams()->modulusLengthBits()); |
1668 ExpectCryptoDataMatchesHex( | 1637 ExpectCryptoDataMatchesHex( |
1669 "010001", CryptoData(key.algorithm().rsaParams()->publicExponent())); | 1638 "010001", CryptoData(key.algorithm().rsaParams()->publicExponent())); |
1670 | 1639 |
1671 // Failing case: Empty SPKI data | 1640 // Failing case: Empty SPKI data |
1672 EXPECT_STATUS(Status::ErrorImportEmptyKeyData(), | 1641 EXPECT_STATUS( |
1673 ImportKey(blink::WebCryptoKeyFormatSpki, | 1642 Status::ErrorImportEmptyKeyData(), |
1674 CryptoData(std::vector<uint8>()), | 1643 ImportKey(blink::WebCryptoKeyFormatSpki, |
1675 blink::WebCryptoAlgorithm::createNull(), | 1644 CryptoData(std::vector<uint8>()), |
1676 true, | 1645 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), |
1677 blink::WebCryptoKeyUsageEncrypt, | 1646 true, |
1678 &key)); | 1647 blink::WebCryptoKeyUsageEncrypt, |
1679 | 1648 &key)); |
1680 // Failing case: Import RSA key with NULL input algorithm. This is not | |
1681 // allowed because the SPKI ASN.1 format for RSA keys is not specific enough | |
1682 // to map to a Web Crypto algorithm. | |
1683 EXPECT_STATUS(Status::Error(), | |
1684 ImportKey(blink::WebCryptoKeyFormatSpki, | |
1685 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), | |
1686 blink::WebCryptoAlgorithm::createNull(), | |
1687 true, | |
1688 blink::WebCryptoKeyUsageEncrypt, | |
1689 &key)); | |
1690 | 1649 |
1691 // Failing case: Bad DER encoding. | 1650 // Failing case: Bad DER encoding. |
1692 EXPECT_STATUS( | 1651 EXPECT_STATUS( |
1693 Status::Error(), | 1652 Status::Error(), |
1694 ImportKey(blink::WebCryptoKeyFormatSpki, | 1653 ImportKey(blink::WebCryptoKeyFormatSpki, |
1695 CryptoData(HexStringToBytes("618333c4cb")), | 1654 CryptoData(HexStringToBytes("618333c4cb")), |
1696 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), | 1655 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), |
1697 true, | 1656 true, |
1698 blink::WebCryptoKeyUsageEncrypt, | 1657 blink::WebCryptoKeyUsageEncrypt, |
1699 &key)); | 1658 &key)); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1752 EXPECT_EQ(kModulusLengthBits, | 1711 EXPECT_EQ(kModulusLengthBits, |
1753 key.algorithm().rsaHashedParams()->modulusLengthBits()); | 1712 key.algorithm().rsaHashedParams()->modulusLengthBits()); |
1754 ExpectCryptoDataMatchesHex( | 1713 ExpectCryptoDataMatchesHex( |
1755 "010001", | 1714 "010001", |
1756 CryptoData(key.algorithm().rsaHashedParams()->publicExponent())); | 1715 CryptoData(key.algorithm().rsaHashedParams()->publicExponent())); |
1757 | 1716 |
1758 // Failing case: Empty PKCS#8 data | 1717 // Failing case: Empty PKCS#8 data |
1759 EXPECT_STATUS(Status::ErrorImportEmptyKeyData(), | 1718 EXPECT_STATUS(Status::ErrorImportEmptyKeyData(), |
1760 ImportKey(blink::WebCryptoKeyFormatPkcs8, | 1719 ImportKey(blink::WebCryptoKeyFormatPkcs8, |
1761 CryptoData(std::vector<uint8>()), | 1720 CryptoData(std::vector<uint8>()), |
1762 blink::WebCryptoAlgorithm::createNull(), | 1721 CreateRsaHashedImportAlgorithm( |
| 1722 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
| 1723 blink::WebCryptoAlgorithmIdSha1), |
1763 true, | 1724 true, |
1764 blink::WebCryptoKeyUsageSign, | 1725 blink::WebCryptoKeyUsageSign, |
1765 &key)); | 1726 &key)); |
1766 | |
1767 // Failing case: Import RSA key with NULL input algorithm. This is not | |
1768 // allowed because the PKCS#8 ASN.1 format for RSA keys is not specific enough | |
1769 // to map to a Web Crypto algorithm. | |
1770 EXPECT_STATUS(Status::Error(), | |
1771 ImportKey(blink::WebCryptoKeyFormatPkcs8, | |
1772 CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)), | |
1773 blink::WebCryptoAlgorithm::createNull(), | |
1774 true, | |
1775 blink::WebCryptoKeyUsageSign, | |
1776 &key)); | |
1777 | 1727 |
1778 // Failing case: Bad DER encoding. | 1728 // Failing case: Bad DER encoding. |
1779 EXPECT_STATUS( | 1729 EXPECT_STATUS( |
1780 Status::Error(), | 1730 Status::Error(), |
1781 ImportKey(blink::WebCryptoKeyFormatPkcs8, | 1731 ImportKey(blink::WebCryptoKeyFormatPkcs8, |
1782 CryptoData(HexStringToBytes("618333c4cb")), | 1732 CryptoData(HexStringToBytes("618333c4cb")), |
1783 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5), | 1733 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5), |
1784 true, | 1734 true, |
1785 blink::WebCryptoKeyUsageSign, | 1735 blink::WebCryptoKeyUsageSign, |
1786 &key)); | 1736 &key)); |
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2516 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( | 2466 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( |
2517 test_kek, | 2467 test_kek, |
2518 wrapping_algorithm, | 2468 wrapping_algorithm, |
2519 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey); | 2469 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey); |
2520 // Import the key to be wrapped. | 2470 // Import the key to be wrapped. |
2521 blink::WebCryptoKey key = ImportSecretKeyFromRaw( | 2471 blink::WebCryptoKey key = ImportSecretKeyFromRaw( |
2522 test_key, | 2472 test_key, |
2523 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), | 2473 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
2524 blink::WebCryptoKeyUsageEncrypt); | 2474 blink::WebCryptoKeyUsageEncrypt); |
2525 | 2475 |
2526 // Unwrap with null algorithm must fail. | |
2527 blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull(); | |
2528 EXPECT_STATUS(Status::ErrorMissingAlgorithmUnwrapRawKey(), | |
2529 UnwrapKey(blink::WebCryptoKeyFormatRaw, | |
2530 CryptoData(test_ciphertext), | |
2531 wrapping_key, | |
2532 wrapping_algorithm, | |
2533 blink::WebCryptoAlgorithm::createNull(), | |
2534 true, | |
2535 blink::WebCryptoKeyUsageEncrypt, | |
2536 &unwrapped_key)); | |
2537 | |
2538 // Unwrap with wrapped data too small must fail. | 2476 // Unwrap with wrapped data too small must fail. |
2539 const std::vector<uint8> small_data(test_ciphertext.begin(), | 2477 const std::vector<uint8> small_data(test_ciphertext.begin(), |
2540 test_ciphertext.begin() + 23); | 2478 test_ciphertext.begin() + 23); |
| 2479 blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull(); |
2541 EXPECT_STATUS(Status::ErrorDataTooSmall(), | 2480 EXPECT_STATUS(Status::ErrorDataTooSmall(), |
2542 UnwrapKey(blink::WebCryptoKeyFormatRaw, | 2481 UnwrapKey(blink::WebCryptoKeyFormatRaw, |
2543 CryptoData(small_data), | 2482 CryptoData(small_data), |
2544 wrapping_key, | 2483 wrapping_key, |
2545 wrapping_algorithm, | 2484 wrapping_algorithm, |
2546 key_algorithm, | 2485 key_algorithm, |
2547 true, | 2486 true, |
2548 blink::WebCryptoKeyUsageEncrypt, | 2487 blink::WebCryptoKeyUsageEncrypt, |
2549 &unwrapped_key)); | 2488 &unwrapped_key)); |
2550 | 2489 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2615 HexStringToBytes("000102030405060708090A0B0C0D0E0F"); | 2554 HexStringToBytes("000102030405060708090A0B0C0D0E0F"); |
2616 const blink::WebCryptoAlgorithm wrapping_algorithm = | 2555 const blink::WebCryptoAlgorithm wrapping_algorithm = |
2617 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | 2556 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); |
2618 | 2557 |
2619 // Import the wrapping key. | 2558 // Import the wrapping key. |
2620 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( | 2559 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( |
2621 wrapping_key_data, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey); | 2560 wrapping_key_data, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey); |
2622 | 2561 |
2623 // Unwrap the known wrapped key data to produce a new key | 2562 // Unwrap the known wrapped key data to produce a new key |
2624 blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull(); | 2563 blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull(); |
2625 ASSERT_STATUS_SUCCESS(UnwrapKey(blink::WebCryptoKeyFormatJwk, | 2564 ASSERT_STATUS_SUCCESS( |
2626 CryptoData(wrapped_key_data), | 2565 UnwrapKey(blink::WebCryptoKeyFormatJwk, |
2627 wrapping_key, | 2566 CryptoData(wrapped_key_data), |
2628 wrapping_algorithm, | 2567 wrapping_key, |
2629 blink::WebCryptoAlgorithm::createNull(), | 2568 wrapping_algorithm, |
2630 true, | 2569 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
2631 blink::WebCryptoKeyUsageVerify, | 2570 true, |
2632 &unwrapped_key)); | 2571 blink::WebCryptoKeyUsageVerify, |
| 2572 &unwrapped_key)); |
2633 | 2573 |
2634 // Validate the new key's attributes. | 2574 // Validate the new key's attributes. |
2635 EXPECT_FALSE(unwrapped_key.isNull()); | 2575 EXPECT_FALSE(unwrapped_key.isNull()); |
2636 EXPECT_TRUE(unwrapped_key.handle()); | 2576 EXPECT_TRUE(unwrapped_key.handle()); |
2637 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, unwrapped_key.type()); | 2577 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, unwrapped_key.type()); |
2638 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, unwrapped_key.algorithm().id()); | 2578 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, unwrapped_key.algorithm().id()); |
2639 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, | 2579 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, |
2640 unwrapped_key.algorithm().hmacParams()->hash().id()); | 2580 unwrapped_key.algorithm().hmacParams()->hash().id()); |
2641 #if defined(WEBCRYPTO_HMAC_KEY_HAS_LENGTH) | 2581 #if defined(WEBCRYPTO_HMAC_KEY_HAS_LENGTH) |
2642 EXPECT_EQ(256u, unwrapped_key.algorithm().hmacParams()->lengthBits()); | 2582 EXPECT_EQ(256u, unwrapped_key.algorithm().hmacParams()->lengthBits()); |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3114 algorithm, | 3054 algorithm, |
3115 CreateAesCbcAlgorithm(std::vector<uint8>(0, 16)), | 3055 CreateAesCbcAlgorithm(std::vector<uint8>(0, 16)), |
3116 true, | 3056 true, |
3117 blink::WebCryptoKeyUsageEncrypt, | 3057 blink::WebCryptoKeyUsageEncrypt, |
3118 &unwrapped_key)); | 3058 &unwrapped_key)); |
3119 } | 3059 } |
3120 | 3060 |
3121 } // namespace webcrypto | 3061 } // namespace webcrypto |
3122 | 3062 |
3123 } // namespace content | 3063 } // namespace content |
OLD | NEW |