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

Unified Diff: content/renderer/webcrypto/webcrypto_impl_unittest.cc

Issue 100593002: [webcrypto] Add symmetric key export for NSS and OpenSSL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 7 years 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
Index: content/renderer/webcrypto/webcrypto_impl_unittest.cc
diff --git a/content/renderer/webcrypto/webcrypto_impl_unittest.cc b/content/renderer/webcrypto/webcrypto_impl_unittest.cc
index 48552b76e62bb32a1fe5d0f2b6609a5f9fc13d5f..9cb33249b4ea55d4c6b25f4db4599b20695f572e 100644
--- a/content/renderer/webcrypto/webcrypto_impl_unittest.cc
+++ b/content/renderer/webcrypto/webcrypto_impl_unittest.cc
@@ -94,6 +94,43 @@ blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm(
#endif // #if !defined(USE_OPENSSL)
+// Determines if two ArrayBuffers have identical content.
+bool ArrayBuffersEqual(
+ const blink::WebArrayBuffer& a,
+ const blink::WebArrayBuffer& b) {
+ if (a.byteLength() != b.byteLength())
+ return false;
+ const uint8* a_begin = static_cast<uint8*>(a.data());
+ const uint8* const a_end = a_begin + a.byteLength();
+ const uint8* b_begin = static_cast<uint8*>(b.data());
+ return std::equal(a_begin, a_end, b_begin);
eroman 2013/12/05 01:47:53 [no change necessary] My inclination would have be
padolph 2013/12/05 02:45:57 I'm sure std::equal optimizes down to memcmp in th
+}
+
+// Adapts ArrayBufferEqual() into a unary predicate for use with std::count_if
+// in CopiesExist().
+class ArrayBufferEqualTo {
+ public:
+ ArrayBufferEqualTo(const blink::WebArrayBuffer& b) : b_(b) {}
+ bool operator()(const blink::WebArrayBuffer& a) const {
+ return ArrayBuffersEqual(a, b_);
+ }
+
+ private:
+ const blink::WebArrayBuffer& b_;
+};
+
+// Given a vector of WebArrayBuffers, determines if there are any copies. Not
+// the most efficient implementation, but the vector is expected to be small.
+bool CopiesExist(std::vector<blink::WebArrayBuffer> bufs) {
+ for (std::vector<blink::WebArrayBuffer>::const_iterator it = bufs.begin();
eroman 2013/12/05 01:47:53 I much prefer the old-fashioned double-for-loop he
padolph 2013/12/05 02:45:57 I can't argue with that. 1/3 the lines and faster.
+ it != bufs.end();
+ ++it) {
+ if (std::count_if(bufs.begin(), bufs.end(), ArrayBufferEqualTo(*it)) != 1)
+ return true;
+ }
+ return false;
+}
+
} // namespace
class WebCryptoImplTest : public testing::Test {
@@ -432,6 +469,11 @@ TEST_F(WebCryptoImplTest, HMACSampleSets) {
blink::WebCryptoKey key = ImportSecretKeyFromRawHexString(
test.key, algorithm, blink::WebCryptoKeyUsageSign);
+ // Verify exported raw key is identical to the imported data
+ blink::WebArrayBuffer raw_key;
+ EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ ExpectArrayBufferMatchesHex(test.key, raw_key);
+
std::vector<uint8> message_raw = HexStringToBytes(test.message);
blink::WebArrayBuffer output;
@@ -476,11 +518,17 @@ TEST_F(WebCryptoImplTest, HMACSampleSets) {
#if !defined(USE_OPENSSL)
TEST_F(WebCryptoImplTest, AesCbcFailures) {
+ const std::string key_hex = "2b7e151628aed2a6abf7158809cf4f3c";
blink::WebCryptoKey key = ImportSecretKeyFromRawHexString(
- "2b7e151628aed2a6abf7158809cf4f3c",
+ key_hex,
webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
+ // Verify exported raw key is identical to the imported data
+ blink::WebArrayBuffer raw_key;
+ EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ ExpectArrayBufferMatchesHex(key_hex, raw_key);
+
blink::WebArrayBuffer output;
// Use an invalid |iv| (fewer than 16 bytes)
@@ -534,9 +582,10 @@ TEST_F(WebCryptoImplTest, AesCbcFailures) {
&key));
}
- // Fail exporting the key in SPKI format (SPKI export not allowed for secret
- // keys)
+ // Fail exporting the key in SPKI and PKCS#8 formats (not allowed for secret
+ // keys).
EXPECT_FALSE(ExportKeyInternal(blink::WebCryptoKeyFormatSpki, key, &output));
+ EXPECT_FALSE(ExportKeyInternal(blink::WebCryptoKeyFormatPkcs8, key, &output));
}
TEST_F(WebCryptoImplTest, AesCbcSampleSets) {
@@ -626,6 +675,11 @@ TEST_F(WebCryptoImplTest, AesCbcSampleSets) {
webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
+ // Verify exported raw key is identical to the imported data
+ blink::WebArrayBuffer raw_key;
+ EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ ExpectArrayBufferMatchesHex(test.key, raw_key);
+
std::vector<uint8> plain_text = HexStringToBytes(test.plain_text);
std::vector<uint8> iv = HexStringToBytes(test.iv);
@@ -670,14 +724,23 @@ TEST_F(WebCryptoImplTest, AesCbcSampleSets) {
}
}
-// TODO(padolph): Add test to verify generated symmetric keys appear random.
-
TEST_F(WebCryptoImplTest, GenerateKeyAes) {
- blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
- ASSERT_TRUE(
- GenerateKeyInternal(webcrypto::CreateAesCbcKeyGenAlgorithm(128), &key));
- EXPECT_TRUE(key.handle());
- EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ // Generate a small sample of AES keys.
+ std::vector<blink::WebArrayBuffer> keys;
+ blink::WebArrayBuffer key_bytes;
+ for (int i = 0; i < 16; ++i) {
+ blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+ ASSERT_TRUE(
+ GenerateKeyInternal(webcrypto::CreateAesCbcKeyGenAlgorithm(128), &key));
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ ASSERT_TRUE(
+ ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &key_bytes));
+ keys.push_back(key_bytes);
+ }
+ // Ensure all entries in the key sample set are unique. This is a simplistic
+ // estimate of whether the generated keys appear random.
+ EXPECT_FALSE(CopiesExist(keys));
}
TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) {
@@ -691,13 +754,21 @@ TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) {
}
TEST_F(WebCryptoImplTest, GenerateKeyHmac) {
- blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
- blink::WebCryptoAlgorithm algorithm = webcrypto::CreateHmacKeyGenAlgorithm(
- blink::WebCryptoAlgorithmIdSha1, 128);
- ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
- EXPECT_FALSE(key.isNull());
- EXPECT_TRUE(key.handle());
- EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ // Generate a small sample of HMAC keys.
+ std::vector<blink::WebArrayBuffer> keys;
+ for (int i = 0; i < 16; ++i) {
+ blink::WebArrayBuffer key_bytes;
+ blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+ blink::WebCryptoAlgorithm algorithm = webcrypto::CreateHmacKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdSha1, 128);
+ ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
+ EXPECT_FALSE(key.isNull());
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ }
+ // Ensure all entries in the key sample set are unique. This is a simplistic
+ // estimate of whether the generated keys appear random.
+ EXPECT_FALSE(CopiesExist(keys));
}
TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) {
@@ -1119,6 +1190,10 @@ TEST_F(WebCryptoImplTest, ImportExportSpki) {
ASSERT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatSpki, key, &output));
ExpectArrayBufferMatchesHex(hex_rsa_spki_der, output);
+ // Failing case: Try to export a previously imported RSA public key in raw
+ // format (not allowed for a public key).
+ EXPECT_FALSE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &output));
+
// Failing case: Try to export a non-extractable key
ASSERT_TRUE(ImportKeyInternal(
blink::WebCryptoKeyFormatSpki,

Powered by Google App Engine
This is Rietveld 408576698