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

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

Issue 308523003: [webcrypto] Fix a bug with JWK private key import. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 6 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
« no previous file with comments | « no previous file | content/child/webcrypto/shared_crypto_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/child/webcrypto/platform_crypto_nss.cc
diff --git a/content/child/webcrypto/platform_crypto_nss.cc b/content/child/webcrypto/platform_crypto_nss.cc
index 3d0e9923a69f4185b2bdb2e4919fa2ff61e25204..dab8582753cf2329dedec349bba9e40e92c160f3 100644
--- a/content/child/webcrypto/platform_crypto_nss.cc
+++ b/content/child/webcrypto/platform_crypto_nss.cc
@@ -1717,6 +1717,39 @@ Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm,
AddOptionalAttribute(CKA_PUBLIC_EXPONENT, public_exponent, &key_template);
AddOptionalAttribute(CKA_PRIVATE_EXPONENT, private_exponent, &key_template);
+ // Manufacture a CKA_ID so the created key can be retrieved later as a
+ // SECKEYPrivateKey using FindKeyByKeyID(). Unfortunately there isn't a more
+ // direct way to do this in NSS.
+ //
+ // For consistency with other NSS key creation methods, set the CKA_ID to
+ // PK11_MakeIDFromPubKey(). There are some problems with
+ // this approach:
+ //
+ // (1) Prior to NSS 3.16.2, there is no parameter validation when creating
+ // private keys. It is therefore possible to construct a key using the
+ // known public modulus, and where all the other parameters are bogus.
+ // FindKeyByKeyID() returns the first key matching the ID. So this would
+ // effectively allow an attacker to retrieve a private key of their
+ // choice.
+ // TODO(eroman): Once NSS rolls and this is fixed, disallow RSA key
+ // import on older versions of NSS.
+ // http://crbug.com/378315
+ //
+ // (2) The ID space is shared by different key types. So theoretically
+ // possible to retrieve a key of the wrong type which has a matching
+ // CKA_ID. In practice I am told this is not likely except for small key
+ // sizes, since would require constructing keys with the same public
+ // data.
+ //
+ // (3) FindKeyByKeyID() doesn't necessarily return the object that was just
+ // created by CreateGenericObject. If the pre-existing key was
+ // provisioned with flags incompatible with WebCrypto (for instance
+ // marked sensitive) then this will break things.
+ SECItem modulus_item = MakeSECItemForBuffer(CryptoData(modulus));
+ crypto::ScopedSECItem object_id(PK11_MakeIDFromPubKey(&modulus_item));
+ AddOptionalAttribute(
+ CKA_ID, CryptoData(object_id->data, object_id->len), &key_template);
+
// Optional properties (all of these will have been specified or none).
AddOptionalAttribute(CKA_PRIME_1, prime1, &key_template);
AddOptionalAttribute(CKA_PRIME_2, prime2, &key_template);
@@ -1732,17 +1765,13 @@ Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm,
if (!key_object)
return Status::OperationError();
- // The ID isn't guaranteed to be set by PKCS#11. However it is by softtoken so
- // this should work.
- SECItem object_id = {};
- if (PK11_ReadRawAttribute(
- PK11_TypeGeneric, key_object.get(), CKA_ID, &object_id) != SECSuccess)
- return Status::OperationError();
+ crypto::ScopedSECKEYPrivateKey private_key_tmp(
+ PK11_FindKeyByKeyID(slot.get(), object_id.get(), NULL));
+ // PK11_FindKeyByKeyID() may return a handle to an existing key, rather than
+ // the object created by PK11_CreateGenericObject().
crypto::ScopedSECKEYPrivateKey private_key(
- PK11_FindKeyByKeyID(slot.get(), &object_id, NULL));
-
- SECITEM_FreeItem(&object_id, PR_FALSE);
+ SECKEY_CopyPrivateKey(private_key_tmp.get()));
if (!private_key)
return Status::OperationError();
« no previous file with comments | « no previous file | content/child/webcrypto/shared_crypto_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698