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

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: rebase onto master 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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 } 285 }
286 286
287 Status NssSupportsRsaOaep() { 287 Status NssSupportsRsaOaep() {
288 if (g_nss_runtime_support.Get().IsRsaOaepSupported()) 288 if (g_nss_runtime_support.Get().IsRsaOaepSupported())
289 return Status::Success(); 289 return Status::Success();
290 return Status::ErrorUnsupported( 290 return Status::ErrorUnsupported(
291 "NSS version doesn't support RSA-OAEP. Try using version 3.16.2 or " 291 "NSS version doesn't support RSA-OAEP. Try using version 3.16.2 or "
292 "later"); 292 "later");
293 } 293 }
294 294
295 #if defined(USE_NSS) && !defined(OS_CHROMEOS)
296 Status ErrorRsaKeyImportNotSupported() {
297 return Status::ErrorUnsupported(
298 "NSS version must be at least 3.16.2 for RSA key import. See "
299 "http://crbug.com/380424");
300 }
301
302 Status NssSupportsKeyImport(blink::WebCryptoAlgorithmId algorithm) {
303 // Prior to NSS 3.16.2 RSA key parameters were not validated. This is
304 // a security problem for RSA private key import from JWK which uses a
305 // CKA_ID based on the public modulus to retrieve the private key.
306
307 if (!IsAlgorithmRsa(algorithm))
308 return Status::Success();
309
310 if (!NSS_VersionCheck("3.16.2"))
311 return ErrorRsaKeyImportNotSupported();
312
313 // Also ensure that the version of Softoken is 3.16.2 or later.
314 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
315 CK_SLOT_INFO info = {};
316 if (PK11_GetSlotInfo(slot.get(), &info) != SECSuccess)
317 return ErrorRsaKeyImportNotSupported();
318
319 // CK_SLOT_INFO.hardwareVersion contains the major.minor
320 // version info for Softoken in the corresponding .major/.minor
321 // fields, and .firmwareVersion contains the patch.build
322 // version info (in the .major/.minor fields)
323 if ((info.hardwareVersion.major > 3) ||
324 (info.hardwareVersion.major == 3 &&
325 (info.hardwareVersion.minor > 16 ||
326 (info.hardwareVersion.minor == 16 &&
327 info.firmwareVersion.major >= 2)))) {
328 return Status::Success();
329 }
330
331 return ErrorRsaKeyImportNotSupported();
332 }
333 #else
334 Status NssSupportsKeyImport(blink::WebCryptoAlgorithmId) {
335 return Status::Success();
336 }
337 #endif
338
295 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so 339 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so
296 // |buffer| should outlive the SECItem. 340 // |buffer| should outlive the SECItem.
297 SECItem MakeSECItemForBuffer(const CryptoData& buffer) { 341 SECItem MakeSECItemForBuffer(const CryptoData& buffer) {
298 SECItem item = { 342 SECItem item = {
299 siBuffer, 343 siBuffer,
300 // NSS requires non-const data even though it is just for input. 344 // NSS requires non-const data even though it is just for input.
301 const_cast<unsigned char*>(buffer.bytes()), buffer.byte_length()}; 345 const_cast<unsigned char*>(buffer.bytes()), buffer.byte_length()};
302 return item; 346 return item;
303 } 347 }
304 348
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 return false; 1024 return false;
981 } 1025 }
982 1026
983 } // namespace 1027 } // namespace
984 1028
985 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm, 1029 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
986 const CryptoData& key_data, 1030 const CryptoData& key_data,
987 bool extractable, 1031 bool extractable,
988 blink::WebCryptoKeyUsageMask usage_mask, 1032 blink::WebCryptoKeyUsageMask usage_mask,
989 blink::WebCryptoKey* key) { 1033 blink::WebCryptoKey* key) {
1034 Status status = NssSupportsKeyImport(algorithm.id());
1035 if (status.IsError())
1036 return status;
1037
990 DCHECK(key); 1038 DCHECK(key);
991 1039
992 if (!key_data.byte_length()) 1040 if (!key_data.byte_length())
993 return Status::ErrorImportEmptyKeyData(); 1041 return Status::ErrorImportEmptyKeyData();
994 DCHECK(key_data.bytes()); 1042 DCHECK(key_data.bytes());
995 1043
996 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject 1044 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject
997 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. 1045 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo.
998 SECItem spki_item = MakeSECItemForBuffer(key_data); 1046 SECItem spki_item = MakeSECItemForBuffer(key_data);
999 const ScopedCERTSubjectPublicKeyInfo spki( 1047 const ScopedCERTSubjectPublicKeyInfo spki(
1000 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); 1048 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
1001 if (!spki) 1049 if (!spki)
1002 return Status::DataError(); 1050 return Status::DataError();
1003 1051
1004 crypto::ScopedSECKEYPublicKey sec_public_key( 1052 crypto::ScopedSECKEYPublicKey sec_public_key(
1005 SECKEY_ExtractPublicKey(spki.get())); 1053 SECKEY_ExtractPublicKey(spki.get()));
1006 if (!sec_public_key) 1054 if (!sec_public_key)
1007 return Status::DataError(); 1055 return Status::DataError();
1008 1056
1009 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); 1057 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get());
1010 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) 1058 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm))
1011 return Status::DataError(); 1059 return Status::DataError();
1012 1060
1013 blink::WebCryptoKeyAlgorithm key_algorithm; 1061 blink::WebCryptoKeyAlgorithm key_algorithm;
1014 if (!CreatePublicKeyAlgorithm( 1062 if (!CreatePublicKeyAlgorithm(
1015 algorithm, sec_public_key.get(), &key_algorithm)) 1063 algorithm, sec_public_key.get(), &key_algorithm))
1016 return Status::ErrorUnexpected(); 1064 return Status::ErrorUnexpected();
1017 1065
1018 scoped_ptr<PublicKey> key_handle; 1066 scoped_ptr<PublicKey> key_handle;
1019 Status status = PublicKey::Create(sec_public_key.Pass(), &key_handle); 1067 status = PublicKey::Create(sec_public_key.Pass(), &key_handle);
1020 if (status.IsError()) 1068 if (status.IsError())
1021 return status; 1069 return status;
1022 1070
1023 *key = blink::WebCryptoKey::create(key_handle.release(), 1071 *key = blink::WebCryptoKey::create(key_handle.release(),
1024 blink::WebCryptoKeyTypePublic, 1072 blink::WebCryptoKeyTypePublic,
1025 extractable, 1073 extractable,
1026 key_algorithm, 1074 key_algorithm,
1027 usage_mask); 1075 usage_mask);
1028 1076
1029 return Status::Success(); 1077 return Status::Success();
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 1197
1150 buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len); 1198 buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len);
1151 return Status::Success(); 1199 return Status::Success();
1152 } 1200 }
1153 1201
1154 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm, 1202 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
1155 const CryptoData& key_data, 1203 const CryptoData& key_data,
1156 bool extractable, 1204 bool extractable,
1157 blink::WebCryptoKeyUsageMask usage_mask, 1205 blink::WebCryptoKeyUsageMask usage_mask,
1158 blink::WebCryptoKey* key) { 1206 blink::WebCryptoKey* key) {
1207 Status status = NssSupportsKeyImport(algorithm.id());
1208 if (status.IsError())
1209 return status;
1210
1159 DCHECK(key); 1211 DCHECK(key);
1160 1212
1161 if (!key_data.byte_length()) 1213 if (!key_data.byte_length())
1162 return Status::ErrorImportEmptyKeyData(); 1214 return Status::ErrorImportEmptyKeyData();
1163 DCHECK(key_data.bytes()); 1215 DCHECK(key_data.bytes());
1164 1216
1165 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8 1217 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8
1166 // private key info object. 1218 // private key info object.
1167 SECItem pki_der = MakeSECItemForBuffer(key_data); 1219 SECItem pki_der = MakeSECItemForBuffer(key_data);
1168 1220
(...skipping 15 matching lines...) Expand all
1184 1236
1185 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); 1237 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get());
1186 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) 1238 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm))
1187 return Status::DataError(); 1239 return Status::DataError();
1188 1240
1189 blink::WebCryptoKeyAlgorithm key_algorithm; 1241 blink::WebCryptoKeyAlgorithm key_algorithm;
1190 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) 1242 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm))
1191 return Status::ErrorUnexpected(); 1243 return Status::ErrorUnexpected();
1192 1244
1193 scoped_ptr<PrivateKey> key_handle; 1245 scoped_ptr<PrivateKey> key_handle;
1194 Status status = 1246 status = PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
1195 PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
1196 if (status.IsError()) 1247 if (status.IsError())
1197 return status; 1248 return status;
1198 1249
1199 *key = blink::WebCryptoKey::create(key_handle.release(), 1250 *key = blink::WebCryptoKey::create(key_handle.release(),
1200 blink::WebCryptoKeyTypePrivate, 1251 blink::WebCryptoKeyTypePrivate,
1201 extractable, 1252 extractable,
1202 key_algorithm, 1253 key_algorithm,
1203 usage_mask); 1254 usage_mask);
1204 1255
1205 return Status::Success(); 1256 return Status::Success();
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 blink::WebCryptoKeyUsageMask usage_mask, 1733 blink::WebCryptoKeyUsageMask usage_mask,
1683 const CryptoData& modulus, 1734 const CryptoData& modulus,
1684 const CryptoData& public_exponent, 1735 const CryptoData& public_exponent,
1685 const CryptoData& private_exponent, 1736 const CryptoData& private_exponent,
1686 const CryptoData& prime1, 1737 const CryptoData& prime1,
1687 const CryptoData& prime2, 1738 const CryptoData& prime2,
1688 const CryptoData& exponent1, 1739 const CryptoData& exponent1,
1689 const CryptoData& exponent2, 1740 const CryptoData& exponent2,
1690 const CryptoData& coefficient, 1741 const CryptoData& coefficient,
1691 blink::WebCryptoKey* key) { 1742 blink::WebCryptoKey* key) {
1743 Status status = NssSupportsKeyImport(algorithm.id());
1744 if (status.IsError())
1745 return status;
1746
1692 CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY; 1747 CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY;
1693 CK_KEY_TYPE key_type = CKK_RSA; 1748 CK_KEY_TYPE key_type = CKK_RSA;
1694 CK_BBOOL ck_false = CK_FALSE; 1749 CK_BBOOL ck_false = CK_FALSE;
1695 1750
1696 std::vector<CK_ATTRIBUTE> key_template; 1751 std::vector<CK_ATTRIBUTE> key_template;
1697 1752
1698 AddAttribute(CKA_CLASS, &obj_class, sizeof(obj_class), &key_template); 1753 AddAttribute(CKA_CLASS, &obj_class, sizeof(obj_class), &key_template);
1699 AddAttribute(CKA_KEY_TYPE, &key_type, sizeof(key_type), &key_template); 1754 AddAttribute(CKA_KEY_TYPE, &key_type, sizeof(key_type), &key_template);
1700 AddAttribute(CKA_TOKEN, &ck_false, sizeof(ck_false), &key_template); 1755 AddAttribute(CKA_TOKEN, &ck_false, sizeof(ck_false), &key_template);
1701 AddAttribute(CKA_SENSITIVE, &ck_false, sizeof(ck_false), &key_template); 1756 AddAttribute(CKA_SENSITIVE, &ck_false, sizeof(ck_false), &key_template);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 SECKEY_CopyPrivateKey(private_key_tmp.get())); 1818 SECKEY_CopyPrivateKey(private_key_tmp.get()));
1764 1819
1765 if (!private_key) 1820 if (!private_key)
1766 return Status::OperationError(); 1821 return Status::OperationError();
1767 1822
1768 blink::WebCryptoKeyAlgorithm key_algorithm; 1823 blink::WebCryptoKeyAlgorithm key_algorithm;
1769 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) 1824 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm))
1770 return Status::ErrorUnexpected(); 1825 return Status::ErrorUnexpected();
1771 1826
1772 scoped_ptr<PrivateKey> key_handle; 1827 scoped_ptr<PrivateKey> key_handle;
1773 Status status = 1828 status = PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
1774 PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
1775 if (status.IsError()) 1829 if (status.IsError())
1776 return status; 1830 return status;
1777 1831
1778 *key = blink::WebCryptoKey::create(key_handle.release(), 1832 *key = blink::WebCryptoKey::create(key_handle.release(),
1779 blink::WebCryptoKeyTypePrivate, 1833 blink::WebCryptoKeyTypePrivate,
1780 extractable, 1834 extractable,
1781 key_algorithm, 1835 key_algorithm,
1782 usage_mask); 1836 usage_mask);
1783 return Status::Success(); 1837 return Status::Success();
1784 } 1838 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1868 std::vector<uint8>* buffer) { 1922 std::vector<uint8>* buffer) {
1869 return mode == ENCRYPT ? EncryptAesKw(wrapping_key, data, buffer) 1923 return mode == ENCRYPT ? EncryptAesKw(wrapping_key, data, buffer)
1870 : DecryptAesKw(wrapping_key, data, buffer); 1924 : DecryptAesKw(wrapping_key, data, buffer);
1871 } 1925 }
1872 1926
1873 } // namespace platform 1927 } // namespace platform
1874 1928
1875 } // namespace webcrypto 1929 } // namespace webcrypto
1876 1930
1877 } // namespace content 1931 } // 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