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

Unified Diff: content/child/webcrypto/shared_crypto_unittest.cc

Issue 275943004: Add support for RSA-OAEP when using NSS 3.16.2 or later (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Unit tests Created 6 years, 7 months 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/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

Powered by Google App Engine
This is Rietveld 408576698