| 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..7a528b9526fd246e9b4ed3362cb0c19616016c7f 100644
|
| --- a/content/renderer/webcrypto/shared_crypto_unittest.cc
|
| +++ b/content/renderer/webcrypto/shared_crypto_unittest.cc
|
| @@ -138,11 +138,13 @@ std::vector<uint8> HexStringToBytes(const std::string& hex) {
|
| return bytes;
|
| }
|
|
|
| -void ExpectArrayBufferMatches(const std::vector<uint8>& expected,
|
| - const blink::WebArrayBuffer& actual) {
|
| - EXPECT_EQ(
|
| - base::HexEncode(webcrypto::Uint8VectorStart(expected), expected.size()),
|
| - base::HexEncode(actual.data(), actual.byteLength()));
|
| +::testing::AssertionResult ArrayBufferMatches(
|
| + const std::vector<uint8>& expected,
|
| + const blink::WebArrayBuffer& actual) {
|
| + if (base::HexEncode(webcrypto::Uint8VectorStart(expected), expected.size()) ==
|
| + base::HexEncode(actual.data(), actual.byteLength()))
|
| + return ::testing::AssertionSuccess();
|
| + return ::testing::AssertionFailure();
|
| }
|
|
|
| void ExpectCryptoDataMatchesHex(const std::string& expected_hex,
|
| @@ -566,7 +568,7 @@ TEST_F(SharedCryptoTest, DigestSampleSets) {
|
| blink::WebArrayBuffer output;
|
| ASSERT_STATUS_SUCCESS(
|
| Digest(test_algorithm, CryptoData(test_input), &output));
|
| - ExpectArrayBufferMatches(test_output, output);
|
| + EXPECT_TRUE(ArrayBufferMatches(test_output, output));
|
| }
|
| }
|
|
|
| @@ -602,14 +604,14 @@ TEST_F(SharedCryptoTest, HMACSampleSets) {
|
| blink::WebArrayBuffer raw_key;
|
| EXPECT_STATUS_SUCCESS(
|
| ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
|
| - ExpectArrayBufferMatches(test_key, raw_key);
|
| + EXPECT_TRUE(ArrayBufferMatches(test_key, raw_key));
|
|
|
| blink::WebArrayBuffer output;
|
|
|
| ASSERT_STATUS_SUCCESS(
|
| Sign(algorithm, key, CryptoData(test_message), &output));
|
|
|
| - ExpectArrayBufferMatches(test_mac, output);
|
| + EXPECT_TRUE(ArrayBufferMatches(test_mac, output));
|
|
|
| bool signature_match = false;
|
| EXPECT_STATUS_SUCCESS(VerifySignature(algorithm,
|
| @@ -761,7 +763,7 @@ TEST_F(SharedCryptoTest, MAYBE(AesCbcSampleSets)) {
|
| blink::WebArrayBuffer raw_key;
|
| EXPECT_STATUS_SUCCESS(
|
| ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
|
| - ExpectArrayBufferMatches(test_key, raw_key);
|
| + EXPECT_TRUE(ArrayBufferMatches(test_key, raw_key));
|
|
|
| blink::WebArrayBuffer output;
|
|
|
| @@ -771,7 +773,7 @@ TEST_F(SharedCryptoTest, MAYBE(AesCbcSampleSets)) {
|
| key,
|
| CryptoData(test_plain_text),
|
| &output));
|
| - ExpectArrayBufferMatches(test_cipher_text, output);
|
| + EXPECT_TRUE(ArrayBufferMatches(test_cipher_text, output));
|
|
|
| // Test decryption.
|
| EXPECT_STATUS(Status::Success(),
|
| @@ -779,7 +781,7 @@ TEST_F(SharedCryptoTest, MAYBE(AesCbcSampleSets)) {
|
| key,
|
| CryptoData(test_cipher_text),
|
| &output));
|
| - ExpectArrayBufferMatches(test_plain_text, output);
|
| + EXPECT_TRUE(ArrayBufferMatches(test_plain_text, output));
|
|
|
| const unsigned int kAesCbcBlockSize = 16;
|
|
|
| @@ -1660,7 +1662,7 @@ TEST_F(SharedCryptoTest, MAYBE(RsaEsKnownAnswer)) {
|
| ASSERT_STATUS_SUCCESS(
|
| Decrypt(algorithm, private_key, CryptoData(ciphertext), &decrypted_data));
|
| EXPECT_FALSE(decrypted_data.isNull());
|
| - ExpectArrayBufferMatches(cleartext, decrypted_data);
|
| + EXPECT_TRUE(ArrayBufferMatches(cleartext, decrypted_data));
|
|
|
| // Encrypt this decrypted data with the public key.
|
| blink::WebArrayBuffer encrypted_data;
|
| @@ -1674,7 +1676,7 @@ TEST_F(SharedCryptoTest, MAYBE(RsaEsKnownAnswer)) {
|
| ASSERT_STATUS_SUCCESS(Decrypt(
|
| algorithm, private_key, CryptoData(encrypted_data), &decrypted_data));
|
| EXPECT_FALSE(decrypted_data.isNull());
|
| - ExpectArrayBufferMatches(cleartext, decrypted_data);
|
| + EXPECT_TRUE(ArrayBufferMatches(cleartext, decrypted_data));
|
| }
|
|
|
| TEST_F(SharedCryptoTest, MAYBE(RsaEsFailures)) {
|
| @@ -1924,7 +1926,7 @@ TEST_F(SharedCryptoTest, MAYBE(RsaSignVerifyKnownAnswer)) {
|
| signature.reset();
|
| ASSERT_STATUS_SUCCESS(
|
| Sign(algorithm, private_key, CryptoData(test_message), &signature));
|
| - ExpectArrayBufferMatches(test_signature, signature);
|
| + EXPECT_TRUE(ArrayBufferMatches(test_signature, signature));
|
|
|
| bool is_match = false;
|
| ASSERT_STATUS_SUCCESS(VerifySignature(algorithm,
|
| @@ -2020,6 +2022,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));
|
| + EXPECT_TRUE(ArrayBufferMatches(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));
|
| + EXPECT_TRUE(ArrayBufferMatches(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));
|
| + EXPECT_FALSE(ArrayBufferMatches(test_key, raw_key));
|
| +}
|
| +
|
| // TODO(eroman):
|
| // * Test decryption when the tag length exceeds input size
|
| // * Test decryption with empty input
|
| @@ -2062,7 +2232,7 @@ TEST_F(SharedCryptoTest, MAYBE(AesGcmSampleSets)) {
|
| EXPECT_STATUS_SUCCESS(
|
| ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
|
|
|
| - ExpectArrayBufferMatches(test_key, raw_key);
|
| + EXPECT_TRUE(ArrayBufferMatches(test_key, raw_key));
|
|
|
| // Test encryption.
|
| std::vector<uint8> cipher_text;
|
| @@ -2087,7 +2257,7 @@ TEST_F(SharedCryptoTest, MAYBE(AesGcmSampleSets)) {
|
| test_cipher_text,
|
| test_authentication_tag,
|
| &plain_text));
|
| - ExpectArrayBufferMatches(test_plain_text, plain_text);
|
| + EXPECT_TRUE(ArrayBufferMatches(test_plain_text, plain_text));
|
|
|
| // Decryption should fail if any of the inputs are tampered with.
|
| EXPECT_STATUS(Status::Error(),
|
|
|