Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: content/child/webcrypto/shared_crypto_unittest.cc

Issue 195983010: [webcrypto] Add JWK symmetric key AES-KW unwrap for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: added missing openssl stub Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/child/webcrypto/shared_crypto.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2362 matching lines...) Expand 10 before | Expand all | Expand 10 after
2373 "72d4e475ff34215416c9ad9c8281247a4d730c5f275ac23f376e73e3bce8d7d5a"; 2373 "72d4e475ff34215416c9ad9c8281247a4d730c5f275ac23f376e73e3bce8d7d5a";
2374 EXPECT_STATUS(Status::Error(), 2374 EXPECT_STATUS(Status::Error(),
2375 ImportKey(blink::WebCryptoKeyFormatRaw, 2375 ImportKey(blink::WebCryptoKeyFormatRaw,
2376 CryptoData(HexStringToBytes(key_raw_hex_in)), 2376 CryptoData(HexStringToBytes(key_raw_hex_in)),
2377 algorithm, 2377 algorithm,
2378 true, 2378 true,
2379 blink::WebCryptoKeyUsageWrapKey, 2379 blink::WebCryptoKeyUsageWrapKey,
2380 &key)); 2380 &key));
2381 } 2381 }
2382 2382
2383 TEST_F(SharedCryptoTest, MAYBE(UnwrapFailures)) {
2384 // This test exercises the code path common to all unwrap operations.
2385 scoped_ptr<base::ListValue> tests;
2386 ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
2387 base::DictionaryValue* test;
2388 ASSERT_TRUE(tests->GetDictionary(0, &test));
2389 const std::vector<uint8> test_kek = GetBytesFromHexString(test, "kek");
2390 const std::vector<uint8> test_ciphertext =
2391 GetBytesFromHexString(test, "ciphertext");
2392
2393 // Using a key that does not have unwrapKey usage should fail.
2394 blink::WebCryptoKey bad_wrapping_key = ImportSecretKeyFromRaw(
2395 test_kek,
2396 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
2397 blink::WebCryptoKeyUsageDecrypt); // <-- should be UnwrapKey
2398 blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
2399 EXPECT_STATUS(
2400 Status::ErrorUnexpected(),
2401 UnwrapKey(blink::WebCryptoKeyFormatRaw,
2402 CryptoData(test_ciphertext),
2403 bad_wrapping_key,
2404 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
2405 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
2406 true,
2407 blink::WebCryptoKeyUsageEncrypt,
2408 &unwrapped_key));
2409
2410 // Using a wrapping algorithm that does not match the wrapping key algorithm
2411 // should fail.
2412 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
2413 test_kek,
2414 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
2415 blink::WebCryptoKeyUsageUnwrapKey);
2416 EXPECT_STATUS(
2417 Status::ErrorUnexpected(),
2418 UnwrapKey(blink::WebCryptoKeyFormatRaw,
2419 CryptoData(test_ciphertext),
2420 wrapping_key,
2421 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
2422 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
2423 true,
2424 blink::WebCryptoKeyUsageEncrypt,
2425 &unwrapped_key));
2426 }
2427
2383 TEST_F(SharedCryptoTest, MAYBE(AesKwRawSymkeyWrapUnwrapKnownAnswer)) { 2428 TEST_F(SharedCryptoTest, MAYBE(AesKwRawSymkeyWrapUnwrapKnownAnswer)) {
2384 scoped_ptr<base::ListValue> tests; 2429 scoped_ptr<base::ListValue> tests;
2385 ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests)); 2430 ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
2386 2431
2387 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { 2432 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
2388 SCOPED_TRACE(test_index); 2433 SCOPED_TRACE(test_index);
2389 base::DictionaryValue* test; 2434 base::DictionaryValue* test;
2390 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); 2435 ASSERT_TRUE(tests->GetDictionary(test_index, &test));
2391 const std::vector<uint8> test_kek = GetBytesFromHexString(test, "kek"); 2436 const std::vector<uint8> test_kek = GetBytesFromHexString(test, "kek");
2392 const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); 2437 const std::vector<uint8> test_key = GetBytesFromHexString(test, "key");
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
2535 UnwrapKey(blink::WebCryptoKeyFormatRaw, 2580 UnwrapKey(blink::WebCryptoKeyFormatRaw,
2536 CryptoData(Corrupted(test_ciphertext)), 2581 CryptoData(Corrupted(test_ciphertext)),
2537 wrapping_key, 2582 wrapping_key,
2538 wrapping_algorithm, 2583 wrapping_algorithm,
2539 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), 2584 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
2540 true, 2585 true,
2541 blink::WebCryptoKeyUsageEncrypt, 2586 blink::WebCryptoKeyUsageEncrypt,
2542 &unwrapped_key)); 2587 &unwrapped_key));
2543 } 2588 }
2544 2589
2590 TEST_F(SharedCryptoTest, MAYBE(AesKwJwkSymkeyUnwrapKnownData)) {
2591 // The following data lists a known HMAC SHA-256 key, then a JWK
2592 // representation of this key which was encrypted ("wrapped") using AES-KW and
2593 // the following wrapping key.
2594 // For reference, the intermediate clear JWK is
2595 // {"alg":"HS256","ext":true,"k":<b64urlKey>,"key_ops":["verify"],"kty":"oct"}
2596 // (Not shown is space padding to ensure the cleartext meets the size
2597 // requirements of the AES-KW algorithm.)
2598 const std::vector<uint8> key_data = HexStringToBytes(
2599 "000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F");
2600 const std::vector<uint8> wrapped_key_data = HexStringToBytes(
2601 "14E6380B35FDC5B72E1994764B6CB7BFDD64E7832894356AAEE6C3768FC3D0F115E6B0"
2602 "6729756225F999AA99FDF81FD6A359F1576D3D23DE6CB69C3937054EB497AC1E8C38D5"
2603 "5E01B9783A20C8D930020932CF25926103002213D0FC37279888154FEBCEDF31832158"
2604 "97938C5CFE5B10B4254D0C399F39D0");
2605 const std::vector<uint8> wrapping_key_data =
2606 HexStringToBytes("000102030405060708090A0B0C0D0E0F");
2607 const blink::WebCryptoAlgorithm wrapping_algorithm =
2608 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
2609
2610 // Import the wrapping key.
2611 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
2612 wrapping_key_data, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey);
2613
2614 // Unwrap the known wrapped key data to produce a new key
2615 blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
2616 ASSERT_STATUS_SUCCESS(UnwrapKey(blink::WebCryptoKeyFormatJwk,
2617 CryptoData(wrapped_key_data),
2618 wrapping_key,
2619 wrapping_algorithm,
2620 blink::WebCryptoAlgorithm::createNull(),
2621 true,
2622 blink::WebCryptoKeyUsageVerify,
2623 &unwrapped_key));
2624
2625 // Validate the new key's attributes.
2626 EXPECT_FALSE(unwrapped_key.isNull());
2627 EXPECT_TRUE(unwrapped_key.handle());
2628 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, unwrapped_key.type());
2629 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, unwrapped_key.algorithm().id());
2630 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256,
2631 unwrapped_key.algorithm().hmacParams()->hash().id());
2632 EXPECT_EQ(true, unwrapped_key.extractable());
2633 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, unwrapped_key.usages());
2634
2635 // Export the new key's raw data and compare to the known original.
2636 blink::WebArrayBuffer raw_key;
2637 EXPECT_STATUS_SUCCESS(
2638 ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key));
2639 EXPECT_TRUE(ArrayBufferMatches(key_data, raw_key));
2640 }
2641
2642 TEST_F(SharedCryptoTest, MAYBE(AesKwJwkSymkeyUnwrapErrors)) {
2643 // Unwrap data that can be successfully decrypted, but contains an error in
2644 // the plaintext JWK, and ensure that a generic error is returned instead of
2645 // some other more specific error, to show that information about the
2646 // plaintext JWK inside the encrypted data is not leaked.
2647 // Specifically, wrapped_key_data below is an AES-KW encrypted version of the
2648 // plaintext JWK
2649 // {
2650 // "alg":"HS256",
2651 // "ext":true,
2652 // "k":"AAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8",
2653 // "key_ops":["verify"],
2654 // "kty":"foo" <-- Invalid kty value
2655 // }
2656 // Recall that unwrapKey = decrypt followed by import. The wrapped_key_data
2657 // will decrypt successfully, but the import step will fail because of the bad
2658 // kty value. But unlike the standalone ImportKey() method which returns
2659 // ErrorJwkUnrecognizedKty in this case, the error returned must be just
2660 // Error::Status().
2661 // Note that it is sufficient to consider just one JWK import failure mode
2662 // here; others are validated in the ImportJwkFailures Test.
2663 const std::vector<uint8> wrapped_key_data = HexStringToBytes(
2664 "8d5ad45f5be6195a7a5944f0cf521bbae255daea140d4712985bb63ca1de1a318fbc49ff"
2665 "307bd91bfafd7e9ea2057a2ddabb42ba94e319465972d165e5cc42785ad5cfa36159d5cc"
2666 "50084133eae85a22bf8f7cb35f3c07b7c06480dec745d9ce4d4bfce45a6cbc2d39263ab7"
2667 "073fc346724841f872f7148d");
2668 const std::vector<uint8> wrapping_key_data =
2669 HexStringToBytes("000102030405060708090A0B0C0D0E0F");
2670 const blink::WebCryptoAlgorithm wrapping_algorithm =
2671 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
2672
2673 // Import the wrapping key.
2674 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
2675 wrapping_key_data, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey);
2676
2677 // Unwrap and ensure a generic error is received.
2678 blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
2679 EXPECT_STATUS(Status::Error(),
2680 UnwrapKey(blink::WebCryptoKeyFormatJwk,
2681 CryptoData(wrapped_key_data),
2682 wrapping_key,
2683 wrapping_algorithm,
2684 blink::WebCryptoAlgorithm::createNull(),
2685 true,
2686 blink::WebCryptoKeyUsageVerify,
2687 &unwrapped_key));
2688
2689 // FIXME(padolph): The check above can fail if the AES-KW decryption step
2690 // failed, which masks the test result desired here. For now we have to just
2691 // trust the result because I say so.
2692 // Once RSA-ES unwrapping is implemented, port this test to use that wrapping
2693 // algorithm instead of AES-KW. Unlike AES-KW, RSA-ES supports both the
2694 // decrypt and unwrapKey usages, so we can validate successful decryption of
2695 // wrapped_key_data prior to seeing the unwrapKey (import) failure.
2696 }
2697
2545 // TODO(eroman): 2698 // TODO(eroman):
2546 // * Test decryption when the tag length exceeds input size 2699 // * Test decryption when the tag length exceeds input size
2547 // * Test decryption with empty input 2700 // * Test decryption with empty input
2548 // * Test decryption with tag length of 0. 2701 // * Test decryption with tag length of 0.
2549 TEST_F(SharedCryptoTest, MAYBE(AesGcmSampleSets)) { 2702 TEST_F(SharedCryptoTest, MAYBE(AesGcmSampleSets)) {
2550 // Some Linux test runners may not have a new enough version of NSS. 2703 // Some Linux test runners may not have a new enough version of NSS.
2551 if (!SupportsAesGcm()) { 2704 if (!SupportsAesGcm()) {
2552 LOG(WARNING) << "AES GCM not supported, skipping tests"; 2705 LOG(WARNING) << "AES GCM not supported, skipping tests";
2553 return; 2706 return;
2554 } 2707 }
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
2817 EXPECT_STATUS(Status::ErrorDataTooSmall(), 2970 EXPECT_STATUS(Status::ErrorDataTooSmall(),
2818 UnwrapKey(blink::WebCryptoKeyFormatRaw, 2971 UnwrapKey(blink::WebCryptoKeyFormatRaw,
2819 CryptoData(emtpy_data), 2972 CryptoData(emtpy_data),
2820 private_key, 2973 private_key,
2821 wrapping_algorithm, 2974 wrapping_algorithm,
2822 key_algorithm, 2975 key_algorithm,
2823 true, 2976 true,
2824 blink::WebCryptoKeyUsageSign, 2977 blink::WebCryptoKeyUsageSign,
2825 &unwrapped_key)); 2978 &unwrapped_key));
2826 2979
2827 // Unwapping data too large for the wrapping key should fail. 2980 // Unwrapping data too large for the wrapping key should fail.
2828 EXPECT_STATUS(Status::ErrorDataTooLarge(), 2981 EXPECT_STATUS(Status::ErrorDataTooLarge(),
2829 UnwrapKey(blink::WebCryptoKeyFormatRaw, 2982 UnwrapKey(blink::WebCryptoKeyFormatRaw,
2830 CryptoData(big_data), 2983 CryptoData(big_data),
2831 private_key, 2984 private_key,
2832 wrapping_algorithm, 2985 wrapping_algorithm,
2833 key_algorithm, 2986 key_algorithm,
2834 true, 2987 true,
2835 blink::WebCryptoKeyUsageSign, 2988 blink::WebCryptoKeyUsageSign,
2836 &unwrapped_key)); 2989 &unwrapped_key));
2837 } 2990 }
2838 2991
2839 } // namespace webcrypto 2992 } // namespace webcrypto
2840 2993
2841 } // namespace content 2994 } // namespace content
OLDNEW
« no previous file with comments | « content/child/webcrypto/shared_crypto.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698