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 7613194c61ffae55c300d7809718b11436e44a81..68de63b85a50b167586bfe632eec83c0772fb3be 100644 |
| --- a/content/child/webcrypto/shared_crypto_unittest.cc |
| +++ b/content/child/webcrypto/shared_crypto_unittest.cc |
| @@ -29,6 +29,13 @@ |
| #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
| #include "third_party/re2/re2/re2.h" |
| +#if defined(USE_NSS) |
| +#include <nss.h> |
| +#include <pk11pub.h> |
| + |
| +#include "crypto/scoped_nss_types.h" |
| +#endif |
| + |
| // The OpenSSL implementation of WebCrypto is less complete, so don't run all of |
| // the tests: http://crbug.com/267888 |
| #if defined(USE_OPENSSL) |
| @@ -106,6 +113,17 @@ bool SupportsAesGcm() { |
| return status.IsSuccess(); |
| } |
| +bool SupportsRsaOaep() { |
| +#if defined(USE_OPENSSL) |
| + return false; |
| +#else |
| + if (!NSS_VersionCheck("3.16.2")) |
|
eroman
2014/05/16 20:29:51
I prefer to not have this sort of knowledge in uni
Ryan Sleevi
2014/05/16 22:43:05
I strongly disagree with this.
1) Performance - t
|
| + return false; |
| + crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
| + return !!PK11_DoesMechanism(slot.get(), CKM_RSA_PKCS_OAEP); |
|
eroman
2014/05/16 20:29:51
Same question as earlier, why the !! rather than i
Ryan Sleevi
2014/05/16 22:43:05
Because PR_Boolean is an int, and bool is a narrow
|
| +#endif |
| +} |
| + |
| blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm( |
| blink::WebCryptoAlgorithmId algorithm_id, |
| unsigned int modulus_length, |
| @@ -136,6 +154,15 @@ blink::WebCryptoAlgorithm CreateRsaHashedKeyGenAlgorithm( |
| public_exponent.size())); |
| } |
| +// Creates an RSA-OAEP algorithm |
|
eroman
2014/05/16 20:29:51
Might want to mention "for encryption/decryption/w
|
| +blink::WebCryptoAlgorithm CreateRsaOaepAlgorithm( |
| + const std::vector<uint8>& label) { |
| + return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
| + blink::WebCryptoAlgorithmIdRsaOaep, |
| + new blink::WebCryptoRsaOaepParams( |
| + !label.empty(), Uint8VectorStart(label), label.size())); |
| +} |
| + |
| // Creates an AES-CBC algorithm. |
| blink::WebCryptoAlgorithm CreateAesCbcAlgorithm(const std::vector<uint8>& iv) { |
| return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
| @@ -403,6 +430,13 @@ const char* const kPrivateKeyPkcs8DerHex = |
| "156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319" |
| "584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24" |
| "a79f4d"; |
| +// The modulus and exponent (in hex) of kPublicKeySpkiDerHex |
| +const char* const kPublicKeyModulusHex = |
| + "A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056" |
|
eroman
2014/05/16 20:29:51
[optional] OCD nit: The hex string above uses lowe
Ryan Sleevi
2014/05/16 22:43:05
This was your string - from 1445.
|
| + "FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B" |
| + "8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E138" |
| + "6B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137"; |
| +const char* const kPublicKeyExponentHex = "010001"; |
|
eroman
2014/05/16 20:29:51
Consider adding a TODO to replace the existing usa
Ryan Sleevi
2014/05/16 22:43:05
I already fixed the existing usages. I'm not sure
eroman
2014/05/19 19:04:33
There are other occurrences of "010001" in the fil
|
| class SharedCryptoTest : public testing::Test { |
| protected: |
| @@ -439,7 +473,7 @@ void ImportRsaKeyPair(const std::vector<uint8>& spki_der, |
| blink::WebCryptoKeyUsageMask usage_mask, |
| blink::WebCryptoKey* public_key, |
| blink::WebCryptoKey* private_key) { |
| - EXPECT_EQ(Status::Success(), |
| + ASSERT_EQ(Status::Success(), |
|
Ryan Sleevi
2014/05/16 05:17:22
Ran into CHECK failures here when testing and I di
|
| ImportKey(blink::WebCryptoKeyFormatSpki, |
| CryptoData(spki_der), |
| algorithm, |
| @@ -453,7 +487,7 @@ void ImportRsaKeyPair(const std::vector<uint8>& spki_der, |
| EXPECT_EQ(extractable, extractable); |
| EXPECT_EQ(usage_mask, public_key->usages()); |
| - EXPECT_EQ(Status::Success(), |
| + ASSERT_EQ(Status::Success(), |
| ImportKey(blink::WebCryptoKeyFormatPkcs8, |
| CryptoData(pkcs8_der), |
| algorithm, |
| @@ -1439,15 +1473,11 @@ TEST_F(SharedCryptoTest, ImportJwkOctFailures) { |
| } |
| 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"; |
| + const bool supports_rsa_oaep = SupportsRsaOaep(); |
| + if (!supports_rsa_oaep) { |
| + LOG(WARNING) << "RSA-OAEP not supported on this platform. Skipping some" |
|
eroman
2014/05/16 20:29:51
sometests --> some tests
|
| + << "tests."; |
| + } |
| struct TestCase { |
| const blink::WebCryptoAlgorithm algorithm; |
| @@ -1477,12 +1507,32 @@ TEST_F(SharedCryptoTest, MAYBE(ImportExportJwkRsaPublicKey)) { |
| {CreateRsaHashedImportAlgorithm( |
| blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
| blink::WebCryptoAlgorithmIdSha512), |
| - blink::WebCryptoKeyUsageSign, "RS512"}}; |
| + blink::WebCryptoKeyUsageSign, "RS512"}, |
| + // RSA-OAEP with SHA-1 and MGF-1 / SHA-1 |
| + {CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaOaep, |
| + blink::WebCryptoAlgorithmIdSha1), |
| + blink::WebCryptoKeyUsageEncrypt, "RSA-OAEP"}, |
| + // RSA-OAEP with SHA-256 and MGF-1 / SHA-256 |
| + {CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaOaep, |
| + blink::WebCryptoAlgorithmIdSha256), |
| + blink::WebCryptoKeyUsageEncrypt, "RSA-OAEP-256"}, |
| + // RSA-OAEP with SHA-384 and MGF-1 / SHA-384 |
| + {CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaOaep, |
| + blink::WebCryptoAlgorithmIdSha384), |
| + blink::WebCryptoKeyUsageEncrypt, "RSA-OAEP-384"}, |
| + // RSA-OAEP with SHA-512 and MGF-1 / SHA-512 |
| + {CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaOaep, |
| + blink::WebCryptoAlgorithmIdSha512), |
| + blink::WebCryptoKeyUsageEncrypt, "RSA-OAEP-512"}}; |
| for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); |
| ++test_index) { |
| SCOPED_TRACE(test_index); |
| const TestCase& test = kTests[test_index]; |
| + if (!supports_rsa_oaep && |
| + test.algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep) { |
| + continue; |
|
eroman
2014/05/16 20:29:51
Consider adding the skip warning here. The outter
Ryan Sleevi
2014/05/16 22:43:05
I generally oppose logging skipped tests on princi
|
| + } |
| // Import the spki to create a public key |
| blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| @@ -1498,24 +1548,33 @@ TEST_F(SharedCryptoTest, MAYBE(ImportExportJwkRsaPublicKey)) { |
| std::vector<uint8> jwk; |
| ASSERT_EQ(Status::Success(), |
| ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &jwk)); |
| - EXPECT_TRUE(VerifyPublicJwk(jwk, test.jwk_alg, n_hex, e_hex, test.usage)); |
| + EXPECT_TRUE(VerifyPublicJwk(jwk, |
| + test.jwk_alg, |
| + kPublicKeyModulusHex, |
| + kPublicKeyExponentHex, |
| + test.usage)); |
| // Import the JWK back in to create a new key |
| blink::WebCryptoKey public_key2 = blink::WebCryptoKey::createNull(); |
| - EXPECT_EQ( |
| + ASSERT_EQ( |
| Status::Success(), |
| ImportKeyJwk( |
| CryptoData(jwk), test.algorithm, true, test.usage, &public_key2)); |
| - EXPECT_TRUE(public_key2.handle()); |
| + ASSERT_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. |
| - std::vector<uint8> spki; |
| - ASSERT_EQ(Status::Success(), |
| - ExportKey(blink::WebCryptoKeyFormatSpki, public_key2, &spki)); |
| - EXPECT_BYTES_EQ_HEX(kPublicKeySpkiDerHex, CryptoData(spki)); |
| + // Only perform SPKI consistency test for RSA-ES and RSA-SSA, as their |
| + // export format is the same as kPublicKeySpkiDerHex |
|
Ryan Sleevi
2014/05/16 05:17:22
These should probably be moved into the JSON prope
eroman
2014/05/16 20:29:51
What is the difference in format, just the OID? Fe
Ryan Sleevi
2014/05/16 22:43:05
You already filed the bug - https://code.google.co
|
| + if (test.algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 || |
| + test.algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5) { |
| + // Export the new key as spki and compare to the original. |
| + std::vector<uint8> spki; |
| + ASSERT_EQ(Status::Success(), |
| + ExportKey(blink::WebCryptoKeyFormatSpki, public_key2, &spki)); |
| + EXPECT_BYTES_EQ_HEX(kPublicKeySpkiDerHex, CryptoData(spki)); |
| + } |
| } |
| } |
| @@ -1980,6 +2039,13 @@ TEST_F(SharedCryptoTest, MAYBE(ImportExportSpki)) { |
| EXPECT_FALSE(key.extractable()); |
| EXPECT_EQ(Status::ErrorKeyNotExtractable(), |
| ExportKey(blink::WebCryptoKeyFormatSpki, key, &output)); |
| + |
| + // TODO(eroman): Failing test: Import a SPKI with an unrecognized hash OID |
| + // TODO(eroman): Failing test: Import a SPKI with invalid algorithm params |
| + // TODO(eroman): Failing test: Import a SPKI with inconsistent parameters |
| + // (e.g. SHA-1 in OID, SHA-256 in params) |
| + // TODO(eroman): Failing test: Import a SPKI for RSA-SSA, but with params |
| + // as OAEP/PSS |
|
Ryan Sleevi
2014/05/16 05:17:22
Just documenting various SPKI failures.
eroman
2014/05/16 20:29:51
why TODO(eroman) and not TODO(rsleevi)?
FYI TODO
Ryan Sleevi
2014/05/16 22:43:05
Because you filed the bug on Import/Export SPKI an
|
| } |
| TEST_F(SharedCryptoTest, MAYBE(ImportExportPkcs8)) { |
| @@ -2234,14 +2300,14 @@ TEST_F(SharedCryptoTest, MAYBE(RsaEsRoundTrip)) { |
| CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
| blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| - ImportRsaKeyPair( |
| + ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair( |
|
Ryan Sleevi
2014/05/16 05:17:22
*slightly* unrelated, but the OAEP correction (to
|
| HexStringToBytes(kPublicKeySpkiDerHex), |
| HexStringToBytes(kPrivateKeyPkcs8DerHex), |
| algorithm, |
| false, |
| blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, |
| &public_key, |
| - &private_key); |
| + &private_key)); |
| // Make a maximum-length data message. RSAES can operate on messages up to |
| // length of k - 11 bytes, where k is the octet length of the RSA modulus. |
| @@ -2302,14 +2368,14 @@ TEST_F(SharedCryptoTest, MAYBE(RsaEsKnownAnswer)) { |
| CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
| blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| - ImportRsaKeyPair( |
| + ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair( |
| rsa_spki_der, |
| rsa_pkcs8_der, |
| algorithm, |
| false, |
| blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, |
| &public_key, |
| - &private_key); |
| + &private_key)); |
| // Decrypt the known-good ciphertext with the private key. As a check we must |
| // get the known original cleartext. |
| @@ -2343,14 +2409,14 @@ TEST_F(SharedCryptoTest, MAYBE(RsaEsFailures)) { |
| CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
| blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| - ImportRsaKeyPair( |
| + ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair( |
| HexStringToBytes(kPublicKeySpkiDerHex), |
| HexStringToBytes(kPrivateKeyPkcs8DerHex), |
| algorithm, |
| false, |
| blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, |
| &public_key, |
| - &private_key); |
| + &private_key)); |
| // Fail encrypt with a private key. |
| std::vector<uint8> encrypted_data; |
| @@ -2416,13 +2482,14 @@ TEST_F(SharedCryptoTest, MAYBE(RsaSsaSignVerifyFailures)) { |
| blink::WebCryptoAlgorithmIdSha1); |
| blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| - ImportRsaKeyPair(HexStringToBytes(kPublicKeySpkiDerHex), |
| - HexStringToBytes(kPrivateKeyPkcs8DerHex), |
| - importAlgorithm, |
| - false, |
| - usage_mask, |
| - &public_key, |
| - &private_key); |
| + ASSERT_NO_FATAL_FAILURE( |
| + ImportRsaKeyPair(HexStringToBytes(kPublicKeySpkiDerHex), |
| + HexStringToBytes(kPrivateKeyPkcs8DerHex), |
| + importAlgorithm, |
| + false, |
| + usage_mask, |
| + &public_key, |
| + &private_key)); |
| blink::WebCryptoAlgorithm algorithm = |
| CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5); |
| @@ -2559,14 +2626,14 @@ TEST_F(SharedCryptoTest, MAYBE(RsaSignVerifyKnownAnswer)) { |
| blink::WebCryptoAlgorithmIdSha1); |
| blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| - ImportRsaKeyPair( |
| + ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair( |
| HexStringToBytes(kPublicKeySpkiDerHex), |
| HexStringToBytes(kPrivateKeyPkcs8DerHex), |
| importAlgorithm, |
| false, |
| blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, |
| &public_key, |
| - &private_key); |
| + &private_key)); |
| blink::WebCryptoAlgorithm algorithm = |
| CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5); |
| @@ -3140,14 +3207,14 @@ TEST_F(SharedCryptoTest, MAYBE(RsaEsRawSymkeyWrapUnwrapKnownAnswer)) { |
| CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
| blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| - ImportRsaKeyPair( |
| + ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair( |
| rsa_spki_der, |
| rsa_pkcs8_der, |
| algorithm, |
| false, |
| blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| &public_key, |
| - &private_key); |
| + &private_key)); |
| // Import the symmetric key. |
| blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| @@ -3217,14 +3284,14 @@ TEST_F(SharedCryptoTest, MAYBE(RsaEsRawSymkeyWrapUnwrapErrors)) { |
| CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
| blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| - ImportRsaKeyPair( |
| + ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair( |
| HexStringToBytes(kPublicKeySpkiDerHex), |
| HexStringToBytes(kPrivateKeyPkcs8DerHex), |
| wrapping_algorithm, |
| false, |
| blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| &public_key, |
| - &private_key); |
| + &private_key)); |
| // Import the symmetric key. |
| blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| @@ -3370,14 +3437,14 @@ TEST_F(SharedCryptoTest, MAYBE(RsaEsJwkSymkeyWrapUnwrapRoundTrip)) { |
| CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
| blink::WebCryptoKey public_wrapping_key = blink::WebCryptoKey::createNull(); |
| blink::WebCryptoKey private_wrapping_key = blink::WebCryptoKey::createNull(); |
| - ImportRsaKeyPair( |
| + ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair( |
| HexStringToBytes(kPublicKeySpkiDerHex), |
| HexStringToBytes(kPrivateKeyPkcs8DerHex), |
| wrapping_algorithm, |
| false, |
| blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| &public_wrapping_key, |
| - &private_wrapping_key); |
| + &private_wrapping_key)); |
| // Wrap the symkey in JWK format, using the public wrapping key. |
| std::vector<uint8> wrapped_data; |
| @@ -3479,6 +3546,308 @@ TEST_F(SharedCryptoTest, MAYBE(RsaEsJwkSymkeyWrapUnwrapErrors)) { |
| &unwrapped_key)); |
| } |
| +class SharedCryptoRsaOaepTest : public ::testing::Test { |
| + public: |
| + SharedCryptoRsaOaepTest() { Init(); } |
|
eroman
2014/05/16 20:29:51
Would inheriting from SharedCryptoTest instead wor
|
| + |
| + scoped_ptr<base::DictionaryValue> CreatePublicKeyJwkDict() { |
|
eroman
2014/05/16 20:29:51
why introduce a new test fixture, can't this be a
Ryan Sleevi
2014/05/16 22:43:05
It can. A new fixture was created, because in my i
eroman
2014/05/19 19:04:33
Ok
|
| + scoped_ptr<base::DictionaryValue> jwk(new base::DictionaryValue()); |
| + jwk->SetString("kty", "RSA"); |
| + jwk->SetString("n", |
| + Base64EncodeUrlSafe(HexStringToBytes(kPublicKeyModulusHex))); |
| + jwk->SetString( |
| + "e", Base64EncodeUrlSafe(HexStringToBytes(kPublicKeyExponentHex))); |
| + return jwk.Pass(); |
| + } |
| +}; |
| + |
| +// Import a PKCS#8 private key that uses RSAPrivateKey with the |
| +// id-rsaEncryption OID. |
| +TEST_F(SharedCryptoRsaOaepTest, ImportPkcs8WithRsaEncryption) { |
|
Ryan Sleevi
2014/05/16 05:17:22
More tests needed: Variations of SPKI param handli
eroman
2014/05/16 20:29:51
These tests are going to fail when run on Android
Ryan Sleevi
2014/05/16 22:43:05
No. Because SupportsRsaOaep().
|
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| + ASSERT_EQ(Status::Success(), |
| + ImportKey(blink::WebCryptoKeyFormatPkcs8, |
| + CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)), |
| + CreateRsaHashedImportAlgorithm( |
| + blink::WebCryptoAlgorithmIdRsaOaep, |
| + blink::WebCryptoAlgorithmIdSha1), |
| + true, |
| + blink::WebCryptoKeyUsageDecrypt, |
| + &private_key)); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, ImportJwkWithNoAlg) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict()); |
| + |
| + blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| + ASSERT_EQ(Status::Success(), |
| + ImportKeyJwkFromDict(*jwk.get(), |
| + CreateRsaHashedImportAlgorithm( |
| + blink::WebCryptoAlgorithmIdRsaOaep, |
| + blink::WebCryptoAlgorithmIdSha1), |
| + true, |
| + blink::WebCryptoKeyUsageEncrypt, |
| + &public_key)); |
|
eroman
2014/05/16 20:29:51
Assert that the resulting key.algorithm() matches?
|
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, ImportJwkWithMatchingAlg) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict()); |
| + jwk->SetString("alg", "RSA-OAEP"); |
| + |
| + blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| + ASSERT_EQ(Status::Success(), |
| + ImportKeyJwkFromDict(*jwk.get(), |
| + CreateRsaHashedImportAlgorithm( |
| + blink::WebCryptoAlgorithmIdRsaOaep, |
| + blink::WebCryptoAlgorithmIdSha1), |
| + true, |
| + blink::WebCryptoKeyUsageEncrypt, |
| + &public_key)); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, ImportJwkWithMismatchedAlgFails) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict()); |
| + jwk->SetString("alg", "RSA-OAEP-512"); |
| + |
| + blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| + ASSERT_EQ(Status::ErrorJwkAlgorithmInconsistent(), |
| + ImportKeyJwkFromDict(*jwk.get(), |
| + CreateRsaHashedImportAlgorithm( |
| + blink::WebCryptoAlgorithmIdRsaOaep, |
| + blink::WebCryptoAlgorithmIdSha1), |
| + true, |
| + blink::WebCryptoKeyUsageEncrypt, |
| + &public_key)); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, ImportJwkWithMismatchedTypFails) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict()); |
| + jwk->SetString("kty", "oct"); |
| + jwk->SetString("alg", "RSA-OAEP"); |
| + |
| + blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| + ASSERT_EQ(Status::ErrorJwkPropertyMissing("k"), |
| + ImportKeyJwkFromDict(*jwk.get(), |
| + CreateRsaHashedImportAlgorithm( |
| + blink::WebCryptoAlgorithmIdRsaOaep, |
| + blink::WebCryptoAlgorithmIdSha1), |
| + true, |
| + blink::WebCryptoKeyUsageEncrypt, |
| + &public_key)); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, ExportJwk) { |
|
eroman
2014/05/16 20:29:51
Include "Public" somewhere in the name.
|
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + struct TestData { |
| + blink::WebCryptoAlgorithmId hash_alg; |
| + const char* expected_jwk_alg; |
| + } kTestData[] = {{blink::WebCryptoAlgorithmIdSha1, "RSA-OAEP"}, |
| + {blink::WebCryptoAlgorithmIdSha256, "RSA-OAEP-256"}, |
| + {blink::WebCryptoAlgorithmIdSha384, "RSA-OAEP-384"}, |
| + {blink::WebCryptoAlgorithmIdSha512, "RSA-OAEP-512"}}; |
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestData); ++i) { |
| + const TestData& test_data = kTestData[i]; |
| + SCOPED_TRACE(test_data.expected_jwk_alg); |
| + |
| + scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict()); |
| + jwk->SetString("alg", test_data.expected_jwk_alg); |
| + |
| + // Import the key in a known-good format |
| + blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| + ASSERT_EQ(Status::Success(), |
| + ImportKeyJwkFromDict( |
| + *jwk.get(), |
| + CreateRsaHashedImportAlgorithm( |
| + blink::WebCryptoAlgorithmIdRsaOaep, test_data.hash_alg), |
| + true, |
| + blink::WebCryptoKeyUsageEncrypt, |
| + &public_key)); |
| + |
| + // Now export the key as JWK and verify its contents |
| + std::vector<uint8> jwk_data; |
| + ASSERT_EQ(Status::Success(), |
| + ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &jwk_data)); |
| + EXPECT_TRUE(VerifyPublicJwk(jwk_data, |
| + test_data.expected_jwk_alg, |
| + kPublicKeyModulusHex, |
| + kPublicKeyExponentHex, |
| + blink::WebCryptoKeyUsageEncrypt)); |
| + } |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, EncryptDecryptKnownAnswerTest) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + scoped_ptr<base::ListValue> tests; |
| + ASSERT_TRUE(ReadJsonTestFileToList("rsa_oaep.json", &tests)); |
| + |
| + for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { |
| + SCOPED_TRACE(test_index); |
| + |
| + base::DictionaryValue* test = NULL; |
| + ASSERT_TRUE(tests->GetDictionary(test_index, &test)); |
| + |
| + blink::WebCryptoAlgorithm digest_algorithm = |
| + GetDigestAlgorithm(test, "hash"); |
| + ASSERT_FALSE(digest_algorithm.isNull()); |
| + std::vector<uint8> public_key_der = |
| + GetBytesFromHexString(test, "public_key"); |
| + std::vector<uint8> private_key_der = |
| + GetBytesFromHexString(test, "private_key"); |
| + std::vector<uint8> ciphertext = GetBytesFromHexString(test, "ciphertext"); |
| + std::vector<uint8> plaintext = GetBytesFromHexString(test, "plaintext"); |
| + std::vector<uint8> label = GetBytesFromHexString(test, "label"); |
| + |
| + blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm( |
| + blink::WebCryptoAlgorithmIdRsaOaep, digest_algorithm.id()); |
| + blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| + blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| + |
| + ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair( |
| + public_key_der, |
| + private_key_der, |
| + import_algorithm, |
| + false, |
| + blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, |
| + &public_key, |
| + &private_key)); |
| + |
| + blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label); |
| + std::vector<uint8> decrypted_data; |
| + ASSERT_EQ(Status::Success(), |
| + Decrypt(op_algorithm, |
| + private_key, |
| + CryptoData(ciphertext), |
| + &decrypted_data)); |
| + EXPECT_BYTES_EQ(plaintext, decrypted_data); |
| + std::vector<uint8> encrypted_data; |
| + ASSERT_EQ( |
| + Status::Success(), |
| + Encrypt( |
| + op_algorithm, public_key, CryptoData(plaintext), &encrypted_data)); |
| + std::vector<uint8> redecrypted_data; |
| + ASSERT_EQ(Status::Success(), |
| + Decrypt(op_algorithm, |
| + private_key, |
| + CryptoData(encrypted_data), |
| + &redecrypted_data)); |
| + EXPECT_BYTES_EQ(plaintext, redecrypted_data); |
| + } |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, EncryptWithLargeMessageFails) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + FAIL(); |
|
eroman
2014/05/16 20:29:51
Wut? Either fill these out, make them into TODOs,
|
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, DecryptWithLargeMessageFails) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + FAIL(); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, DecryptWithCorruptedHashFails) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + FAIL(); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, DecryptWithCorruptedPaddingFails) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + FAIL(); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, WrapUnwrapRawKey) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + FAIL(); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, WrapUnwrapJwkSymKey) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + FAIL(); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, WrapWithLargeKeyFails) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + FAIL(); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, UnwrapWithCorruptedKeyFails) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + FAIL(); |
| +} |
| + |
| +TEST_F(SharedCryptoRsaOaepTest, UnwrapWithInvalidKeyFails) { |
| + if (!SupportsRsaOaep()) { |
| + LOG(WARNING) << "RSA-OAEP support not present; skipping."; |
| + return; |
| + } |
| + |
| + FAIL(); |
| +} |
| + |
| } // namespace webcrypto |
| } // namespace content |