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

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: Address sleevi comments 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
« 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..80fa2663c73e1ca2d0d05ece371b9d65d0be9492 100644
--- a/content/child/webcrypto/platform_crypto_nss.cc
+++ b/content/child/webcrypto/platform_crypto_nss.cc
@@ -18,6 +18,7 @@
#include "content/child/webcrypto/status.h"
#include "content/child/webcrypto/webcrypto_util.h"
#include "crypto/nss_util.h"
+#include "crypto/random.h"
#include "crypto/scoped_nss_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -1717,6 +1718,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.
+ //
+ // A randomly generated value is used for the ID.
+ //
+ // NSS assigns the CKA_ID to PK11_MakeIDFromPubKey() for the other key
+ // creation paths. However it is incorrect to try and use that as the CKA_ID
+ // here because:
+ //
+ // (1) CreateGenericObject does not validate its parameters. It is therefore
+ // possible to construct a key using the known public modulus, and 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.
+ // NSS 3.16.2 does validate parameters.
+ //
+ // (2) The ID space is shared by different key types. So even if parameters
+ // were validated by NSS, FindKeyByKeyID() could still return the wrong
+ // key. For instance it might return a DH key that happens to have same
+ // values for its public data.
+ // Ryan says this isn't possible in practice, because matching values for
Ryan Sleevi 2014/06/02 23:55:57 We don't do this in comments :) But I'm glad Rya
+ // valid keys can't be easily guessed.
+ //
+ // (3) Even if the above two problems were non-issues, there is no guarantee
+ // that FindKeyByKeyID() returns the object just created. If the same
+ // private key were imported multiple times, with different flags, using
+ // the wrong one could lead to problems.
+ std::vector<uint8> cka_id(20);
+ crypto::RandBytes(&cka_id[0], cka_id.size());
+ AddOptionalAttribute(CKA_ID, CryptoData(cka_id), &key_template);
+ SECItem object_id = MakeSECItemForBuffer(CryptoData(cka_id));
+
// 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,18 +1766,9 @@ 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(
PK11_FindKeyByKeyID(slot.get(), &object_id, NULL));
- SECITEM_FreeItem(&object_id, PR_FALSE);
-
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