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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/child/webcrypto/shared_crypto.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/child/webcrypto/shared_crypto_unittest.cc
diff --git a/content/child/webcrypto/shared_crypto_unittest.cc b/content/child/webcrypto/shared_crypto_unittest.cc
index a71b52fc187973fbabcc1f9839237b49335ce506..67825683798e6fa9d45d318b15930eb2fc976365 100644
--- a/content/child/webcrypto/shared_crypto_unittest.cc
+++ b/content/child/webcrypto/shared_crypto_unittest.cc
@@ -2380,6 +2380,51 @@ TEST_F(SharedCryptoTest, MAYBE(AesKwKeyImport)) {
&key));
}
+TEST_F(SharedCryptoTest, MAYBE(UnwrapFailures)) {
+ // This test exercises the code path common to all unwrap operations.
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
+ base::DictionaryValue* test;
+ ASSERT_TRUE(tests->GetDictionary(0, &test));
+ const std::vector<uint8> test_kek = GetBytesFromHexString(test, "kek");
+ const std::vector<uint8> test_ciphertext =
+ GetBytesFromHexString(test, "ciphertext");
+
+ // Using a key that does not have unwrapKey usage should fail.
+ blink::WebCryptoKey bad_wrapping_key = ImportSecretKeyFromRaw(
+ test_kek,
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
+ blink::WebCryptoKeyUsageDecrypt); // <-- should be UnwrapKey
+ blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+ EXPECT_STATUS(
+ Status::ErrorUnexpected(),
+ UnwrapKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(test_ciphertext),
+ bad_wrapping_key,
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
+ true,
+ blink::WebCryptoKeyUsageEncrypt,
+ &unwrapped_key));
+
+ // Using a wrapping algorithm that does not match the wrapping key algorithm
+ // should fail.
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+ test_kek,
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
+ blink::WebCryptoKeyUsageUnwrapKey);
+ EXPECT_STATUS(
+ Status::ErrorUnexpected(),
+ UnwrapKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(test_ciphertext),
+ wrapping_key,
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
+ true,
+ blink::WebCryptoKeyUsageEncrypt,
+ &unwrapped_key));
+}
+
TEST_F(SharedCryptoTest, MAYBE(AesKwRawSymkeyWrapUnwrapKnownAnswer)) {
scoped_ptr<base::ListValue> tests;
ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
@@ -2542,6 +2587,114 @@ TEST_F(SharedCryptoTest, MAYBE(AesKwRawSymkeyUnwrapCorruptData)) {
&unwrapped_key));
}
+TEST_F(SharedCryptoTest, MAYBE(AesKwJwkSymkeyUnwrapKnownData)) {
+ // The following data lists a known HMAC SHA-256 key, then a JWK
+ // representation of this key which was encrypted ("wrapped") using AES-KW and
+ // the following wrapping key.
+ // For reference, the intermediate clear JWK is
+ // {"alg":"HS256","ext":true,"k":<b64urlKey>,"key_ops":["verify"],"kty":"oct"}
+ // (Not shown is space padding to ensure the cleartext meets the size
+ // requirements of the AES-KW algorithm.)
+ const std::vector<uint8> key_data = HexStringToBytes(
+ "000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F");
+ const std::vector<uint8> wrapped_key_data = HexStringToBytes(
+ "14E6380B35FDC5B72E1994764B6CB7BFDD64E7832894356AAEE6C3768FC3D0F115E6B0"
+ "6729756225F999AA99FDF81FD6A359F1576D3D23DE6CB69C3937054EB497AC1E8C38D5"
+ "5E01B9783A20C8D930020932CF25926103002213D0FC37279888154FEBCEDF31832158"
+ "97938C5CFE5B10B4254D0C399F39D0");
+ const std::vector<uint8> wrapping_key_data =
+ HexStringToBytes("000102030405060708090A0B0C0D0E0F");
+ const blink::WebCryptoAlgorithm wrapping_algorithm =
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ // Import the wrapping key.
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+ wrapping_key_data, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey);
+
+ // Unwrap the known wrapped key data to produce a new key
+ blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+ ASSERT_STATUS_SUCCESS(UnwrapKey(blink::WebCryptoKeyFormatJwk,
+ CryptoData(wrapped_key_data),
+ wrapping_key,
+ wrapping_algorithm,
+ blink::WebCryptoAlgorithm::createNull(),
+ true,
+ blink::WebCryptoKeyUsageVerify,
+ &unwrapped_key));
+
+ // Validate the new key's attributes.
+ EXPECT_FALSE(unwrapped_key.isNull());
+ EXPECT_TRUE(unwrapped_key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, unwrapped_key.type());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, unwrapped_key.algorithm().id());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256,
+ unwrapped_key.algorithm().hmacParams()->hash().id());
+ EXPECT_EQ(true, unwrapped_key.extractable());
+ EXPECT_EQ(blink::WebCryptoKeyUsageVerify, unwrapped_key.usages());
+
+ // Export the new key's raw data and compare to the known original.
+ blink::WebArrayBuffer raw_key;
+ EXPECT_STATUS_SUCCESS(
+ ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key));
+ EXPECT_TRUE(ArrayBufferMatches(key_data, raw_key));
+}
+
+TEST_F(SharedCryptoTest, MAYBE(AesKwJwkSymkeyUnwrapErrors)) {
+ // Unwrap data that can be successfully decrypted, but contains an error in
+ // the plaintext JWK, and ensure that a generic error is returned instead of
+ // some other more specific error, to show that information about the
+ // plaintext JWK inside the encrypted data is not leaked.
+ // Specifically, wrapped_key_data below is an AES-KW encrypted version of the
+ // plaintext JWK
+ // {
+ // "alg":"HS256",
+ // "ext":true,
+ // "k":"AAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8",
+ // "key_ops":["verify"],
+ // "kty":"foo" <-- Invalid kty value
+ // }
+ // Recall that unwrapKey = decrypt followed by import. The wrapped_key_data
+ // will decrypt successfully, but the import step will fail because of the bad
+ // kty value. But unlike the standalone ImportKey() method which returns
+ // ErrorJwkUnrecognizedKty in this case, the error returned must be just
+ // Error::Status().
+ // Note that it is sufficient to consider just one JWK import failure mode
+ // here; others are validated in the ImportJwkFailures Test.
+ const std::vector<uint8> wrapped_key_data = HexStringToBytes(
+ "8d5ad45f5be6195a7a5944f0cf521bbae255daea140d4712985bb63ca1de1a318fbc49ff"
+ "307bd91bfafd7e9ea2057a2ddabb42ba94e319465972d165e5cc42785ad5cfa36159d5cc"
+ "50084133eae85a22bf8f7cb35f3c07b7c06480dec745d9ce4d4bfce45a6cbc2d39263ab7"
+ "073fc346724841f872f7148d");
+ const std::vector<uint8> wrapping_key_data =
+ HexStringToBytes("000102030405060708090A0B0C0D0E0F");
+ const blink::WebCryptoAlgorithm wrapping_algorithm =
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ // Import the wrapping key.
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+ wrapping_key_data, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey);
+
+ // Unwrap and ensure a generic error is received.
+ blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+ EXPECT_STATUS(Status::Error(),
+ UnwrapKey(blink::WebCryptoKeyFormatJwk,
+ CryptoData(wrapped_key_data),
+ wrapping_key,
+ wrapping_algorithm,
+ blink::WebCryptoAlgorithm::createNull(),
+ true,
+ blink::WebCryptoKeyUsageVerify,
+ &unwrapped_key));
+
+ // FIXME(padolph): The check above can fail if the AES-KW decryption step
+ // failed, which masks the test result desired here. For now we have to just
+ // trust the result because I say so.
+ // Once RSA-ES unwrapping is implemented, port this test to use that wrapping
+ // algorithm instead of AES-KW. Unlike AES-KW, RSA-ES supports both the
+ // decrypt and unwrapKey usages, so we can validate successful decryption of
+ // wrapped_key_data prior to seeing the unwrapKey (import) failure.
+}
+
// TODO(eroman):
// * Test decryption when the tag length exceeds input size
// * Test decryption with empty input
@@ -2824,7 +2977,7 @@ TEST_F(SharedCryptoTest, MAYBE(RsaEsRawSymkeyWrapUnwrapErrors)) {
blink::WebCryptoKeyUsageSign,
&unwrapped_key));
- // Unwapping data too large for the wrapping key should fail.
+ // Unwrapping data too large for the wrapping key should fail.
EXPECT_STATUS(Status::ErrorDataTooLarge(),
UnwrapKey(blink::WebCryptoKeyFormatRaw,
CryptoData(big_data),
« 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