Chromium Code Reviews| 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 6995b48c4b07868b63f7df252dc5f99df9611e5d..556e721d9a3b19a2517cbed583080db5108fa506 100644 |
| --- a/content/child/webcrypto/shared_crypto_unittest.cc |
| +++ b/content/child/webcrypto/shared_crypto_unittest.cc |
| @@ -542,23 +542,20 @@ scoped_ptr<base::DictionaryValue> GetJwkDictionary( |
| // Verifies that the JSON in the input ArrayBuffer contains the provided |
|
eroman
2014/03/24 22:05:51
This comment needs to be updated as well (no longe
padolph
2014/03/25 01:10:28
Done.
|
| // expected values. Exact matches are required on the fields examined. |
| -::testing::AssertionResult VerifySymmetricJwk( |
| - const blink::WebArrayBuffer& json, |
| +::testing::AssertionResult VerifyJwk( |
| + const scoped_ptr<base::DictionaryValue>& dict, |
| + const std::string& kty_expected, |
| const std::string& alg_expected, |
| - const std::string& k_expected_hex, |
| blink::WebCryptoKeyUsageMask use_mask_expected) { |
| - scoped_ptr<base::DictionaryValue> dict = GetJwkDictionary(json); |
| - if (!dict.get() || dict->empty()) |
| - return ::testing::AssertionFailure() << "JSON parsing failed"; |
| - |
| // ---- kty |
| std::string value_string; |
| if (!dict->GetString("kty", &value_string)) |
| return ::testing::AssertionFailure() << "Missing 'kty'"; |
| - if (value_string != "oct") |
| - return ::testing::AssertionFailure() |
| - << "Expected 'kty' to be 'oct' but found " << value_string; |
| + if (value_string != kty_expected) |
| + return ::testing::AssertionFailure() << "Expected 'kty' to be " |
| + << kty_expected << "but found " |
| + << value_string; |
| // ---- alg |
| if (!dict->GetString("alg", &value_string)) |
| @@ -568,18 +565,6 @@ scoped_ptr<base::DictionaryValue> GetJwkDictionary( |
| << alg_expected << " but found " |
| << value_string; |
| - // ---- k |
| - if (!dict->GetString("k", &value_string)) |
| - return ::testing::AssertionFailure() << "Missing 'k'"; |
| - std::string k_value; |
| - if (!webcrypto::Base64DecodeUrlSafe(value_string, &k_value)) |
| - return ::testing::AssertionFailure() << "Base64DecodeUrlSafe(k) failed"; |
| - if (!LowerCaseEqualsASCII(base::HexEncode(k_value.data(), k_value.size()), |
| - k_expected_hex.c_str())) { |
| - return ::testing::AssertionFailure() << "Expected 'k' to be " |
| - << k_expected_hex |
| - << " but found something different"; |
| - } |
| // ---- ext |
| // always expect ext == true in this case |
| bool ext_value; |
| @@ -605,6 +590,75 @@ scoped_ptr<base::DictionaryValue> GetJwkDictionary( |
| return ::testing::AssertionSuccess(); |
| } |
| +// Verifies that the JSON in the input ArrayBuffer contains the provided |
| +// expected values. Exact matches are required on the fields examined. |
| +::testing::AssertionResult VerifySecretJwk( |
| + const blink::WebArrayBuffer& json, |
| + const std::string& alg_expected, |
| + const std::string& k_expected_hex, |
| + blink::WebCryptoKeyUsageMask use_mask_expected) { |
| + scoped_ptr<base::DictionaryValue> dict = GetJwkDictionary(json); |
| + if (!dict.get() || dict->empty()) |
| + return ::testing::AssertionFailure() << "JSON parsing failed"; |
| + |
| + // ---- k |
| + std::string value_string; |
| + if (!dict->GetString("k", &value_string)) |
| + return ::testing::AssertionFailure() << "Missing 'k'"; |
| + std::string k_value; |
| + if (!webcrypto::Base64DecodeUrlSafe(value_string, &k_value)) |
| + return ::testing::AssertionFailure() << "Base64DecodeUrlSafe(k) failed"; |
| + if (!LowerCaseEqualsASCII(base::HexEncode(k_value.data(), k_value.size()), |
| + k_expected_hex.c_str())) { |
| + return ::testing::AssertionFailure() << "Expected 'k' to be " |
| + << k_expected_hex |
| + << " but found something different"; |
| + } |
| + |
| + return VerifyJwk(dict, "oct", alg_expected, use_mask_expected); |
| +} |
| + |
| +// Verifies that the JSON in the input ArrayBuffer contains the provided |
| +// expected values. Exact matches are required on the fields examined. |
| +::testing::AssertionResult VerifyPublicJwk( |
| + const blink::WebArrayBuffer& json, |
| + const std::string& alg_expected, |
| + const std::string& n_expected_hex, |
| + const std::string& e_expected_hex, |
| + blink::WebCryptoKeyUsageMask use_mask_expected) { |
| + scoped_ptr<base::DictionaryValue> dict = GetJwkDictionary(json); |
| + if (!dict.get() || dict->empty()) |
| + return ::testing::AssertionFailure() << "JSON parsing failed"; |
| + |
| + // ---- n |
| + std::string value_string; |
| + if (!dict->GetString("n", &value_string)) |
| + return ::testing::AssertionFailure() << "Missing 'n'"; |
| + std::string n_value; |
| + if (!webcrypto::Base64DecodeUrlSafe(value_string, &n_value)) |
| + return ::testing::AssertionFailure() << "Base64DecodeUrlSafe(n) failed"; |
| + if (base::HexEncode(n_value.data(), n_value.size()) != n_expected_hex) { |
| + return ::testing::AssertionFailure() << "'n' does not match the expected " |
| + "value"; |
| + } |
| + // TODO(padolph): LowerCaseEqualsASCII() does not work for above! |
|
eroman
2014/03/24 22:05:51
Not sure I follow, can you explain this comment? S
padolph
2014/03/25 01:10:28
LowerCaseEqual() did not behave properly in this c
eroman
2014/03/25 01:21:12
I would be very surprised if LowerCaseEqual() was
|
| + |
| + // ---- e |
| + if (!dict->GetString("e", &value_string)) |
| + return ::testing::AssertionFailure() << "Missing 'e'"; |
| + std::string e_value; |
| + if (!webcrypto::Base64DecodeUrlSafe(value_string, &e_value)) |
| + return ::testing::AssertionFailure() << "Base64DecodeUrlSafe(e) failed"; |
| + if (!LowerCaseEqualsASCII(base::HexEncode(e_value.data(), e_value.size()), |
| + e_expected_hex.c_str())) { |
| + return ::testing::AssertionFailure() << "Expected 'e' to be " |
| + << e_expected_hex |
| + << " but found something different"; |
| + } |
| + |
| + return VerifyJwk(dict, "RSA", alg_expected, use_mask_expected); |
| +} |
| + |
| } // namespace |
| TEST_F(SharedCryptoTest, CheckAesGcm) { |
| @@ -1270,6 +1324,77 @@ TEST_F(SharedCryptoTest, ImportJwkOctFailures) { |
| RestoreJwkOctDictionary(&dict); |
| } |
| +TEST_F(SharedCryptoTest, MAYBE(ImportExportJwkRsaPublicKey)) { |
| + // This test uses kPublicKeySpkiDerHex as the RSA key. The data below |
| + // represents the modulus and public exponent extracted from this SPKI blob. |
| + // These values appear explicitly in the JWK rendering of the key. |
| + const std::string n_hex = |
| + "A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056" |
| + "FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B" |
| + "8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E138" |
| + "6B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137"; |
| + const std::string e_hex = "010001"; |
| + |
| + struct TestCase { |
| + const blink::WebCryptoAlgorithm algorithm; |
| + const blink::WebCryptoKeyUsageMask usage; |
| + const char* const jwk_alg; |
| + }; |
| + const TestCase kTests[] = { |
| + // RSAES-PKCS1-v1_5 |
| + {CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), |
| + blink::WebCryptoKeyUsageEncrypt, "RSA1_5"}, |
| + // RSASSA-PKCS1-v1_5 SHA-1 |
| + {CreateRsaSsaImportAlgorithm(blink::WebCryptoAlgorithmIdSha1), |
| + blink::WebCryptoKeyUsageSign, "RS1"}, |
| + // RSASSA-PKCS1-v1_5 SHA-256 |
| + {CreateRsaSsaImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
| + blink::WebCryptoKeyUsageSign, "RS256"}, |
| + // RSASSA-PKCS1-v1_5 SHA-384 |
| + {CreateRsaSsaImportAlgorithm(blink::WebCryptoAlgorithmIdSha384), |
| + blink::WebCryptoKeyUsageSign, "RS384"}, |
| + // RSASSA-PKCS1-v1_5 SHA-512 |
| + {CreateRsaSsaImportAlgorithm(blink::WebCryptoAlgorithmIdSha512), |
| + blink::WebCryptoKeyUsageSign, "RS512"}}; |
| + |
| + for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); |
| + ++test_index) { |
| + SCOPED_TRACE(test_index); |
| + const TestCase& test = kTests[test_index]; |
| + |
| + // Import the spki to create a public key |
| + blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| + ASSERT_STATUS_SUCCESS( |
| + ImportKey(blink::WebCryptoKeyFormatSpki, |
| + CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), |
| + test.algorithm, |
| + true, |
| + test.usage, |
| + &public_key)); |
| + |
| + // Export the public key as JWK and verify its contents |
| + blink::WebArrayBuffer jwk; |
| + ASSERT_STATUS_SUCCESS( |
| + ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &jwk)); |
| + EXPECT_TRUE(VerifyPublicJwk(jwk, test.jwk_alg, n_hex, e_hex, test.usage)); |
| + |
| + // Import the JWK back in to create a new key |
| + blink::WebCryptoKey public_key2 = blink::WebCryptoKey::createNull(); |
| + EXPECT_STATUS_SUCCESS(ImportKeyJwk( |
| + CryptoData(jwk), test.algorithm, true, test.usage, &public_key2)); |
| + EXPECT_TRUE(public_key2.handle()); |
| + EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key2.type()); |
| + EXPECT_EQ(true, public_key2.extractable()); |
| + EXPECT_EQ(test.algorithm.id(), public_key2.algorithm().id()); |
| + |
| + // Export the new key as spki and compare to the original. |
| + blink::WebArrayBuffer spki; |
| + ASSERT_STATUS_SUCCESS( |
| + ExportKey(blink::WebCryptoKeyFormatSpki, public_key2, &spki)); |
| + ExpectCryptoDataMatchesHex(kPublicKeySpkiDerHex, CryptoData(spki)); |
| + } |
| +} |
| + |
| TEST_F(SharedCryptoTest, MAYBE(ImportJwkRsaFailures)) { |
| base::DictionaryValue dict; |
| RestoreJwkRsaDictionary(&dict); |
| @@ -1588,8 +1713,7 @@ TEST_F(SharedCryptoTest, MAYBE(ImportExportJwkSymmetricKey)) { |
| // Export the key in JWK format and validate. |
| ASSERT_STATUS_SUCCESS(ExportKeyJwk(key, &json)); |
| - EXPECT_TRUE( |
| - VerifySymmetricJwk(json, test.jwk_alg, test.key_hex, test.usage)); |
| + EXPECT_TRUE(VerifySecretJwk(json, test.jwk_alg, test.key_hex, test.usage)); |
| // Import the JWK-formatted key. |
| ASSERT_STATUS_SUCCESS( |