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

Side by Side 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: Switch over to PK11_MakeIDFromPubKey() and mark consistency test DISABLED 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/child/webcrypto/platform_crypto.h" 5 #include "content/child/webcrypto/platform_crypto.h"
6 6
7 #include <cryptohi.h> 7 #include <cryptohi.h>
8 #include <pk11pub.h> 8 #include <pk11pub.h>
9 #include <secerr.h> 9 #include <secerr.h>
10 #include <sechash.h> 10 #include <sechash.h>
(...skipping 1699 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 AddAttribute(CKA_KEY_TYPE, &key_type, sizeof(key_type), &key_template); 1710 AddAttribute(CKA_KEY_TYPE, &key_type, sizeof(key_type), &key_template);
1711 AddAttribute(CKA_TOKEN, &ck_false, sizeof(ck_false), &key_template); 1711 AddAttribute(CKA_TOKEN, &ck_false, sizeof(ck_false), &key_template);
1712 AddAttribute(CKA_SENSITIVE, &ck_false, sizeof(ck_false), &key_template); 1712 AddAttribute(CKA_SENSITIVE, &ck_false, sizeof(ck_false), &key_template);
1713 AddAttribute(CKA_PRIVATE, &ck_false, sizeof(ck_false), &key_template); 1713 AddAttribute(CKA_PRIVATE, &ck_false, sizeof(ck_false), &key_template);
1714 1714
1715 // Required properties. 1715 // Required properties.
1716 AddOptionalAttribute(CKA_MODULUS, modulus, &key_template); 1716 AddOptionalAttribute(CKA_MODULUS, modulus, &key_template);
1717 AddOptionalAttribute(CKA_PUBLIC_EXPONENT, public_exponent, &key_template); 1717 AddOptionalAttribute(CKA_PUBLIC_EXPONENT, public_exponent, &key_template);
1718 AddOptionalAttribute(CKA_PRIVATE_EXPONENT, private_exponent, &key_template); 1718 AddOptionalAttribute(CKA_PRIVATE_EXPONENT, private_exponent, &key_template);
1719 1719
1720 // Manufacture a CKA_ID so the created key can be retrieved later as a
1721 // SECKEYPrivateKey using FindKeyByKeyID(). Unfortunately there isn't a more
1722 // direct way to do this in NSS.
1723 //
1724 // For consistency with other NSS key creation methods, set the CKA_ID to
1725 // PK11_MakeIDFromPubKey(). There are some problems with
1726 // this approach:
1727 //
1728 // (1) Prior to NSS 3.16.2, there is no parameter validation when creating
1729 // private keys. It is therefore possible to construct a key using the
1730 // known public modulus, and where all the other parameters are bogus.
1731 // FindKeyByKeyID() returns the first key matching the ID. So this would
1732 // effectively allow an attacker to retrieve a private key of their
1733 // choice.
1734 // TODO(eroman): Once NSS rolls and this is fixed, disallow RSA key
1735 // import on older versions of NSS.
1736 // http://crbug.com/378315
1737 //
1738 // (2) The ID space is shared by different key types. So theoretically
1739 // possible to retrieve a key of the wrong type which has a matching
1740 // CKA_ID. In practice I am told this is not likely except for small key
1741 // sizes, since would require constructing keys with the same public
1742 // data.
1743 //
1744 // (3) FindKeyByKeyID() doesn't necessarily return the object that was just
1745 // created by CreateGenericObject. If the pre-existing key was
1746 // provisioned with flags incompatible with WebCrypto (for instance
1747 // marked sensitive) then this will break things.
1748 SECItem modulus_item = MakeSECItemForBuffer(CryptoData(modulus));
1749 crypto::ScopedSECItem object_id(PK11_MakeIDFromPubKey(&modulus_item));
1750 AddOptionalAttribute(
1751 CKA_ID, CryptoData(object_id->data, object_id->len), &key_template);
1752
1720 // Optional properties (all of these will have been specified or none). 1753 // Optional properties (all of these will have been specified or none).
1721 AddOptionalAttribute(CKA_PRIME_1, prime1, &key_template); 1754 AddOptionalAttribute(CKA_PRIME_1, prime1, &key_template);
1722 AddOptionalAttribute(CKA_PRIME_2, prime2, &key_template); 1755 AddOptionalAttribute(CKA_PRIME_2, prime2, &key_template);
1723 AddOptionalAttribute(CKA_EXPONENT_1, exponent1, &key_template); 1756 AddOptionalAttribute(CKA_EXPONENT_1, exponent1, &key_template);
1724 AddOptionalAttribute(CKA_EXPONENT_2, exponent2, &key_template); 1757 AddOptionalAttribute(CKA_EXPONENT_2, exponent2, &key_template);
1725 AddOptionalAttribute(CKA_COEFFICIENT, coefficient, &key_template); 1758 AddOptionalAttribute(CKA_COEFFICIENT, coefficient, &key_template);
1726 1759
1727 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); 1760 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
1728 1761
1729 ScopedPK11GenericObject key_object(PK11_CreateGenericObject( 1762 ScopedPK11GenericObject key_object(PK11_CreateGenericObject(
1730 slot.get(), &key_template[0], key_template.size(), PR_FALSE)); 1763 slot.get(), &key_template[0], key_template.size(), PR_FALSE));
1731 1764
1732 if (!key_object) 1765 if (!key_object)
1733 return Status::OperationError(); 1766 return Status::OperationError();
1734 1767
1735 // The ID isn't guaranteed to be set by PKCS#11. However it is by softtoken so 1768 crypto::ScopedSECKEYPrivateKey private_key_tmp(
1736 // this should work. 1769 PK11_FindKeyByKeyID(slot.get(), object_id.get(), NULL));
1737 SECItem object_id = {};
1738 if (PK11_ReadRawAttribute(
1739 PK11_TypeGeneric, key_object.get(), CKA_ID, &object_id) != SECSuccess)
1740 return Status::OperationError();
1741 1770
1771 // PK11_FindKeyByKeyID() may return a handle to an existing key, rather than
1772 // the object created by PK11_CreateGenericObject().
1742 crypto::ScopedSECKEYPrivateKey private_key( 1773 crypto::ScopedSECKEYPrivateKey private_key(
1743 PK11_FindKeyByKeyID(slot.get(), &object_id, NULL)); 1774 SECKEY_CopyPrivateKey(private_key_tmp.get()));
1744
1745 SECITEM_FreeItem(&object_id, PR_FALSE);
1746 1775
1747 if (!private_key) 1776 if (!private_key)
1748 return Status::OperationError(); 1777 return Status::OperationError();
1749 1778
1750 blink::WebCryptoKeyAlgorithm key_algorithm; 1779 blink::WebCryptoKeyAlgorithm key_algorithm;
1751 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) 1780 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm))
1752 return Status::ErrorUnexpected(); 1781 return Status::ErrorUnexpected();
1753 1782
1754 scoped_ptr<PrivateKey> key_handle; 1783 scoped_ptr<PrivateKey> key_handle;
1755 Status status = 1784 Status status =
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 buffer->assign(key_data->data, key_data->data + key_data->len); 1892 buffer->assign(key_data->data, key_data->data + key_data->len);
1864 1893
1865 return Status::Success(); 1894 return Status::Success();
1866 } 1895 }
1867 1896
1868 } // namespace platform 1897 } // namespace platform
1869 1898
1870 } // namespace webcrypto 1899 } // namespace webcrypto
1871 1900
1872 } // namespace content 1901 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/child/webcrypto/shared_crypto_unittest.cc » ('j') | content/child/webcrypto/shared_crypto_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698