Index: content/renderer/webcrypto/shared_crypto_unittest.cc |
diff --git a/content/renderer/webcrypto/shared_crypto_unittest.cc b/content/renderer/webcrypto/shared_crypto_unittest.cc |
index c02b8aa783158c7379972499a251f49444e24376..9cb03463207025e413c56bd23bc90f08c240a667 100644 |
--- a/content/renderer/webcrypto/shared_crypto_unittest.cc |
+++ b/content/renderer/webcrypto/shared_crypto_unittest.cc |
@@ -145,6 +145,13 @@ void ExpectArrayBufferMatches(const std::vector<uint8>& expected, |
base::HexEncode(actual.data(), actual.byteLength())); |
} |
+void ExpectArrayBufferNotMatch(const std::vector<uint8>& expected, |
eroman
2014/03/04 03:16:26
For a future change, the right fix is to change th
padolph
2014/03/04 17:20:07
Done.
|
+ const blink::WebArrayBuffer& actual) { |
+ EXPECT_NE( |
+ base::HexEncode(webcrypto::Uint8VectorStart(expected), expected.size()), |
+ base::HexEncode(actual.data(), actual.byteLength())); |
+} |
+ |
void ExpectCryptoDataMatchesHex(const std::string& expected_hex, |
const CryptoData& actual) { |
EXPECT_STRCASEEQ( |
@@ -2020,6 +2027,174 @@ TEST_F(SharedCryptoTest, MAYBE(AesKwKeyImport)) { |
&key)); |
} |
+TEST_F(SharedCryptoTest, MAYBE(AesKwRawSymkeyWrapUnwrapKnownAnswer)) { |
+ scoped_ptr<base::ListValue> tests; |
+ ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests)); |
+ |
+ for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { |
+ SCOPED_TRACE(test_index); |
+ base::DictionaryValue* test; |
+ ASSERT_TRUE(tests->GetDictionary(test_index, &test)); |
+ const std::vector<uint8> test_kek = GetBytesFromHexString(test, "kek"); |
+ const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); |
+ const std::vector<uint8> test_ciphertext = |
+ GetBytesFromHexString(test, "ciphertext"); |
+ const blink::WebCryptoAlgorithm wrapping_algorithm = |
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); |
+ |
+ // Import the wrapping key. |
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( |
+ test_kek, |
+ wrapping_algorithm, |
+ blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey); |
+ |
+ // Import the key to be wrapped. |
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw( |
+ test_key, |
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
+ blink::WebCryptoKeyUsageEncrypt); |
+ |
+ // Wrap the key and verify the ciphertext result against the known answer. |
+ blink::WebArrayBuffer wrapped_key; |
+ ASSERT_STATUS_SUCCESS(WrapKey(blink::WebCryptoKeyFormatRaw, |
+ wrapping_key, |
+ key, |
+ wrapping_algorithm, |
+ &wrapped_key)); |
+ ExpectArrayBufferMatches(test_ciphertext, wrapped_key); |
+ |
+ // Unwrap the known ciphertext to get a new test_key. |
+ blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull(); |
+ ASSERT_STATUS_SUCCESS( |
+ UnwrapKey(blink::WebCryptoKeyFormatRaw, |
+ CryptoData(test_ciphertext), |
+ wrapping_key, |
+ wrapping_algorithm, |
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
+ true, |
+ blink::WebCryptoKeyUsageEncrypt, |
+ &unwrapped_key)); |
+ EXPECT_FALSE(key.isNull()); |
+ EXPECT_TRUE(key.handle()); |
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); |
+ EXPECT_EQ( |
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc).id(), |
+ key.algorithm().id()); |
+ EXPECT_EQ(true, key.extractable()); |
+ EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages()); |
+ |
+ // Export the new key and compare its raw bytes with the original known key. |
+ blink::WebArrayBuffer raw_key; |
+ EXPECT_STATUS_SUCCESS( |
+ ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key)); |
+ ExpectArrayBufferMatches(test_key, raw_key); |
+ } |
+} |
+ |
+TEST_F(SharedCryptoTest, MAYBE(AesKwRawSymkeyWrapUnwrapErrors)) { |
+ scoped_ptr<base::ListValue> tests; |
+ ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests)); |
+ base::DictionaryValue* test; |
+ // Use 256 bits of data with a 256-bit KEK |
+ ASSERT_TRUE(tests->GetDictionary(5, &test)); |
+ const std::vector<uint8> test_kek = GetBytesFromHexString(test, "kek"); |
+ const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); |
+ const std::vector<uint8> test_ciphertext = |
+ GetBytesFromHexString(test, "ciphertext"); |
+ const blink::WebCryptoAlgorithm wrapping_algorithm = |
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); |
+ const blink::WebCryptoAlgorithm key_algorithm = |
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
+ // Import the wrapping key. |
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( |
+ test_kek, |
+ wrapping_algorithm, |
+ blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey); |
+ // Import the key to be wrapped. |
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw( |
+ test_key, |
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
+ blink::WebCryptoKeyUsageEncrypt); |
+ |
+ // Unwrap with null algorithm must fail. |
+ blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull(); |
+ EXPECT_STATUS(Status::ErrorMissingAlgorithmUnwrapRawKey(), |
+ UnwrapKey(blink::WebCryptoKeyFormatRaw, |
+ CryptoData(test_ciphertext), |
+ wrapping_key, |
+ wrapping_algorithm, |
+ blink::WebCryptoAlgorithm::createNull(), |
+ true, |
+ blink::WebCryptoKeyUsageEncrypt, |
+ &unwrapped_key)); |
+ |
+ // Unwrap with wrapped data too small must fail. |
+ const std::vector<uint8> small_data(test_ciphertext.begin(), |
+ test_ciphertext.begin() + 23); |
+ EXPECT_STATUS(Status::ErrorDataTooSmall(), |
+ UnwrapKey(blink::WebCryptoKeyFormatRaw, |
+ CryptoData(small_data), |
+ wrapping_key, |
+ wrapping_algorithm, |
+ key_algorithm, |
+ true, |
+ blink::WebCryptoKeyUsageEncrypt, |
+ &unwrapped_key)); |
+ |
+ // Unwrap with wrapped data size not a multiple of 8 bytes must fail. |
+ const std::vector<uint8> unaligned_data(test_ciphertext.begin(), |
+ test_ciphertext.end() - 2); |
+ EXPECT_STATUS(Status::ErrorInvalidAesKwDataLength(), |
+ UnwrapKey(blink::WebCryptoKeyFormatRaw, |
+ CryptoData(unaligned_data), |
+ wrapping_key, |
+ wrapping_algorithm, |
+ key_algorithm, |
+ true, |
+ blink::WebCryptoKeyUsageEncrypt, |
+ &unwrapped_key)); |
+} |
+ |
+TEST_F(SharedCryptoTest, MAYBE(AesKwRawSymkeyUnwrapCorruptData)) { |
+ scoped_ptr<base::ListValue> tests; |
+ ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests)); |
+ base::DictionaryValue* test; |
+ // Use 256 bits of data with a 256-bit KEK |
+ ASSERT_TRUE(tests->GetDictionary(5, &test)); |
+ const std::vector<uint8> test_kek = GetBytesFromHexString(test, "kek"); |
+ const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); |
+ const std::vector<uint8> test_ciphertext = |
+ GetBytesFromHexString(test, "ciphertext"); |
+ const blink::WebCryptoAlgorithm wrapping_algorithm = |
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); |
+ |
+ // Import the wrapping key. |
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw( |
+ test_kek, |
+ wrapping_algorithm, |
+ blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey); |
+ |
+ // Unwrap a corrupted version of the known ciphertext. Unwrap should pass but |
+ // will produce a key that is different than the known original. |
+ blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull(); |
+ ASSERT_STATUS_SUCCESS( |
+ UnwrapKey(blink::WebCryptoKeyFormatRaw, |
+ CryptoData(Corrupted(test_ciphertext)), |
+ wrapping_key, |
+ wrapping_algorithm, |
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
+ true, |
+ blink::WebCryptoKeyUsageEncrypt, |
+ &unwrapped_key)); |
+ |
+ // Export the new key and compare its raw bytes with the original known key. |
+ // The comparison should fail. |
+ blink::WebArrayBuffer raw_key; |
+ EXPECT_STATUS_SUCCESS( |
+ ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key)); |
+ ExpectArrayBufferNotMatch(test_key, raw_key); |
+} |
+ |
// TODO(eroman): |
// * Test decryption when the tag length exceeds input size |
// * Test decryption with empty input |