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

Side by Side Diff: content/child/webcrypto/platform_crypto_nss.cc

Issue 334983006: [webcrypto] Disable RSA key import for NSS versions less than 3.16.2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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
« no previous file with comments | « no previous file | content/child/webcrypto/shared_crypto_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 explicit PrivateKey(crypto::ScopedSECKEYPrivateKey key) : key_(key.Pass()) {} 270 explicit PrivateKey(crypto::ScopedSECKEYPrivateKey key) : key_(key.Pass()) {}
271 271
272 crypto::ScopedSECKEYPrivateKey key_; 272 crypto::ScopedSECKEYPrivateKey key_;
273 std::vector<uint8> serialized_key_; 273 std::vector<uint8> serialized_key_;
274 274
275 DISALLOW_COPY_AND_ASSIGN(PrivateKey); 275 DISALLOW_COPY_AND_ASSIGN(PrivateKey);
276 }; 276 };
277 277
278 namespace { 278 namespace {
279 279
280 Status NssSupportsKeyImport(blink::WebCryptoAlgorithmId algorithm) {
281 if (IsAlgorithmRsa(algorithm) && !NSS_VersionCheck("3.16.2")) {
Ryan Sleevi 2014/06/17 19:40:07 Sadly, this isn't sufficient -_- if (!IsAlgorithm
eroman 2014/06/17 20:00:16 Done.
282 // Prior to NSS 3.16.2 RSA key parameters were not validated. This is
283 // a security problem for RSA private key import from JWK which uses a
284 // CKA_ID based on the public modulus to retrieve the private key.
285 return Status::ErrorUnsupported(
286 "NSS version must be at least 3.16.2 for RSA key import. See "
287 "http://crbug.com/380424");
288 }
289 return Status::Success();
290 }
291
280 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so 292 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so
281 // |buffer| should outlive the SECItem. 293 // |buffer| should outlive the SECItem.
282 SECItem MakeSECItemForBuffer(const CryptoData& buffer) { 294 SECItem MakeSECItemForBuffer(const CryptoData& buffer) {
283 SECItem item = { 295 SECItem item = {
284 siBuffer, 296 siBuffer,
285 // NSS requires non-const data even though it is just for input. 297 // NSS requires non-const data even though it is just for input.
286 const_cast<unsigned char*>(buffer.bytes()), buffer.byte_length()}; 298 const_cast<unsigned char*>(buffer.bytes()), buffer.byte_length()};
287 return item; 299 return item;
288 } 300 }
289 301
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 return false; 975 return false;
964 } 976 }
965 977
966 } // namespace 978 } // namespace
967 979
968 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm, 980 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
969 const CryptoData& key_data, 981 const CryptoData& key_data,
970 bool extractable, 982 bool extractable,
971 blink::WebCryptoKeyUsageMask usage_mask, 983 blink::WebCryptoKeyUsageMask usage_mask,
972 blink::WebCryptoKey* key) { 984 blink::WebCryptoKey* key) {
985 Status status = NssSupportsKeyImport(algorithm.id());
986 if (status.IsError())
987 return status;
988
973 DCHECK(key); 989 DCHECK(key);
974 990
975 if (!key_data.byte_length()) 991 if (!key_data.byte_length())
976 return Status::ErrorImportEmptyKeyData(); 992 return Status::ErrorImportEmptyKeyData();
977 DCHECK(key_data.bytes()); 993 DCHECK(key_data.bytes());
978 994
979 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject 995 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject
980 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. 996 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo.
981 SECItem spki_item = MakeSECItemForBuffer(key_data); 997 SECItem spki_item = MakeSECItemForBuffer(key_data);
982 const ScopedCERTSubjectPublicKeyInfo spki( 998 const ScopedCERTSubjectPublicKeyInfo spki(
983 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); 999 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
984 if (!spki) 1000 if (!spki)
985 return Status::DataError(); 1001 return Status::DataError();
986 1002
987 crypto::ScopedSECKEYPublicKey sec_public_key( 1003 crypto::ScopedSECKEYPublicKey sec_public_key(
988 SECKEY_ExtractPublicKey(spki.get())); 1004 SECKEY_ExtractPublicKey(spki.get()));
989 if (!sec_public_key) 1005 if (!sec_public_key)
990 return Status::DataError(); 1006 return Status::DataError();
991 1007
992 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); 1008 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get());
993 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) 1009 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm))
994 return Status::DataError(); 1010 return Status::DataError();
995 1011
996 blink::WebCryptoKeyAlgorithm key_algorithm; 1012 blink::WebCryptoKeyAlgorithm key_algorithm;
997 if (!CreatePublicKeyAlgorithm( 1013 if (!CreatePublicKeyAlgorithm(
998 algorithm, sec_public_key.get(), &key_algorithm)) 1014 algorithm, sec_public_key.get(), &key_algorithm))
999 return Status::ErrorUnexpected(); 1015 return Status::ErrorUnexpected();
1000 1016
1001 scoped_ptr<PublicKey> key_handle; 1017 scoped_ptr<PublicKey> key_handle;
1002 Status status = PublicKey::Create(sec_public_key.Pass(), &key_handle); 1018 status = PublicKey::Create(sec_public_key.Pass(), &key_handle);
1003 if (status.IsError()) 1019 if (status.IsError())
1004 return status; 1020 return status;
1005 1021
1006 *key = blink::WebCryptoKey::create(key_handle.release(), 1022 *key = blink::WebCryptoKey::create(key_handle.release(),
1007 blink::WebCryptoKeyTypePublic, 1023 blink::WebCryptoKeyTypePublic,
1008 extractable, 1024 extractable,
1009 key_algorithm, 1025 key_algorithm,
1010 usage_mask); 1026 usage_mask);
1011 1027
1012 return Status::Success(); 1028 return Status::Success();
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 1148
1133 buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len); 1149 buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len);
1134 return Status::Success(); 1150 return Status::Success();
1135 } 1151 }
1136 1152
1137 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm, 1153 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
1138 const CryptoData& key_data, 1154 const CryptoData& key_data,
1139 bool extractable, 1155 bool extractable,
1140 blink::WebCryptoKeyUsageMask usage_mask, 1156 blink::WebCryptoKeyUsageMask usage_mask,
1141 blink::WebCryptoKey* key) { 1157 blink::WebCryptoKey* key) {
1158 Status status = NssSupportsKeyImport(algorithm.id());
1159 if (status.IsError())
1160 return status;
1161
1142 DCHECK(key); 1162 DCHECK(key);
1143 1163
1144 if (!key_data.byte_length()) 1164 if (!key_data.byte_length())
1145 return Status::ErrorImportEmptyKeyData(); 1165 return Status::ErrorImportEmptyKeyData();
1146 DCHECK(key_data.bytes()); 1166 DCHECK(key_data.bytes());
1147 1167
1148 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8 1168 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8
1149 // private key info object. 1169 // private key info object.
1150 SECItem pki_der = MakeSECItemForBuffer(key_data); 1170 SECItem pki_der = MakeSECItemForBuffer(key_data);
1151 1171
(...skipping 15 matching lines...) Expand all
1167 1187
1168 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); 1188 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get());
1169 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) 1189 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm))
1170 return Status::DataError(); 1190 return Status::DataError();
1171 1191
1172 blink::WebCryptoKeyAlgorithm key_algorithm; 1192 blink::WebCryptoKeyAlgorithm key_algorithm;
1173 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) 1193 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm))
1174 return Status::ErrorUnexpected(); 1194 return Status::ErrorUnexpected();
1175 1195
1176 scoped_ptr<PrivateKey> key_handle; 1196 scoped_ptr<PrivateKey> key_handle;
1177 Status status = 1197 status = PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
1178 PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
1179 if (status.IsError()) 1198 if (status.IsError())
1180 return status; 1199 return status;
1181 1200
1182 *key = blink::WebCryptoKey::create(key_handle.release(), 1201 *key = blink::WebCryptoKey::create(key_handle.release(),
1183 blink::WebCryptoKeyTypePrivate, 1202 blink::WebCryptoKeyTypePrivate,
1184 extractable, 1203 extractable,
1185 key_algorithm, 1204 key_algorithm,
1186 usage_mask); 1205 usage_mask);
1187 1206
1188 return Status::Success(); 1207 return Status::Success();
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 blink::WebCryptoKeyUsageMask usage_mask, 1681 blink::WebCryptoKeyUsageMask usage_mask,
1663 const CryptoData& modulus, 1682 const CryptoData& modulus,
1664 const CryptoData& public_exponent, 1683 const CryptoData& public_exponent,
1665 const CryptoData& private_exponent, 1684 const CryptoData& private_exponent,
1666 const CryptoData& prime1, 1685 const CryptoData& prime1,
1667 const CryptoData& prime2, 1686 const CryptoData& prime2,
1668 const CryptoData& exponent1, 1687 const CryptoData& exponent1,
1669 const CryptoData& exponent2, 1688 const CryptoData& exponent2,
1670 const CryptoData& coefficient, 1689 const CryptoData& coefficient,
1671 blink::WebCryptoKey* key) { 1690 blink::WebCryptoKey* key) {
1691 Status status = NssSupportsKeyImport(algorithm.id());
1692 if (status.IsError())
1693 return status;
1694
1672 CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY; 1695 CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY;
1673 CK_KEY_TYPE key_type = CKK_RSA; 1696 CK_KEY_TYPE key_type = CKK_RSA;
1674 CK_BBOOL ck_false = CK_FALSE; 1697 CK_BBOOL ck_false = CK_FALSE;
1675 1698
1676 std::vector<CK_ATTRIBUTE> key_template; 1699 std::vector<CK_ATTRIBUTE> key_template;
1677 1700
1678 AddAttribute(CKA_CLASS, &obj_class, sizeof(obj_class), &key_template); 1701 AddAttribute(CKA_CLASS, &obj_class, sizeof(obj_class), &key_template);
1679 AddAttribute(CKA_KEY_TYPE, &key_type, sizeof(key_type), &key_template); 1702 AddAttribute(CKA_KEY_TYPE, &key_type, sizeof(key_type), &key_template);
1680 AddAttribute(CKA_TOKEN, &ck_false, sizeof(ck_false), &key_template); 1703 AddAttribute(CKA_TOKEN, &ck_false, sizeof(ck_false), &key_template);
1681 AddAttribute(CKA_SENSITIVE, &ck_false, sizeof(ck_false), &key_template); 1704 AddAttribute(CKA_SENSITIVE, &ck_false, sizeof(ck_false), &key_template);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 SECKEY_CopyPrivateKey(private_key_tmp.get())); 1766 SECKEY_CopyPrivateKey(private_key_tmp.get()));
1744 1767
1745 if (!private_key) 1768 if (!private_key)
1746 return Status::OperationError(); 1769 return Status::OperationError();
1747 1770
1748 blink::WebCryptoKeyAlgorithm key_algorithm; 1771 blink::WebCryptoKeyAlgorithm key_algorithm;
1749 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) 1772 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm))
1750 return Status::ErrorUnexpected(); 1773 return Status::ErrorUnexpected();
1751 1774
1752 scoped_ptr<PrivateKey> key_handle; 1775 scoped_ptr<PrivateKey> key_handle;
1753 Status status = 1776 status = PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
1754 PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
1755 if (status.IsError()) 1777 if (status.IsError())
1756 return status; 1778 return status;
1757 1779
1758 *key = blink::WebCryptoKey::create(key_handle.release(), 1780 *key = blink::WebCryptoKey::create(key_handle.release(),
1759 blink::WebCryptoKeyTypePrivate, 1781 blink::WebCryptoKeyTypePrivate,
1760 extractable, 1782 extractable,
1761 key_algorithm, 1783 key_algorithm,
1762 usage_mask); 1784 usage_mask);
1763 return Status::Success(); 1785 return Status::Success();
1764 } 1786 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1848 std::vector<uint8>* buffer) { 1870 std::vector<uint8>* buffer) {
1849 return mode == ENCRYPT ? EncryptAesKw(wrapping_key, data, buffer) 1871 return mode == ENCRYPT ? EncryptAesKw(wrapping_key, data, buffer)
1850 : DecryptAesKw(wrapping_key, data, buffer); 1872 : DecryptAesKw(wrapping_key, data, buffer);
1851 } 1873 }
1852 1874
1853 } // namespace platform 1875 } // namespace platform
1854 1876
1855 } // namespace webcrypto 1877 } // namespace webcrypto
1856 1878
1857 } // namespace content 1879 } // namespace content
OLDNEW
« 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