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

Side by Side Diff: content/child/webcrypto/nss/rsa_key_nss.cc

Issue 500653002: [webcrypto] Don't disallow RSA public key import using SPKI format when on Linux. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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/nss/rsa_key_nss.h" 5 #include "content/child/webcrypto/nss/rsa_key_nss.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "content/child/webcrypto/crypto_data.h" 8 #include "content/child/webcrypto/crypto_data.h"
9 #include "content/child/webcrypto/jwk.h" 9 #include "content/child/webcrypto/jwk.h"
10 #include "content/child/webcrypto/nss/key_nss.h" 10 #include "content/child/webcrypto/nss/key_nss.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 } 48 }
49 49
50 bool CreatePrivateKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, 50 bool CreatePrivateKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm,
51 SECKEYPrivateKey* key, 51 SECKEYPrivateKey* key,
52 blink::WebCryptoKeyAlgorithm* key_algorithm) { 52 blink::WebCryptoKeyAlgorithm* key_algorithm) {
53 crypto::ScopedSECKEYPublicKey public_key(SECKEY_ConvertToPublicKey(key)); 53 crypto::ScopedSECKEYPublicKey public_key(SECKEY_ConvertToPublicKey(key));
54 return CreatePublicKeyAlgorithm(algorithm, public_key.get(), key_algorithm); 54 return CreatePublicKeyAlgorithm(algorithm, public_key.get(), key_algorithm);
55 } 55 }
56 56
57 #if defined(USE_NSS) && !defined(OS_CHROMEOS) 57 #if defined(USE_NSS) && !defined(OS_CHROMEOS)
58 Status ErrorRsaKeyImportNotSupported() { 58 Status ErrorRsaPrivateKeyImportNotSupported() {
59 return Status::ErrorUnsupported( 59 return Status::ErrorUnsupported(
60 "NSS version must be at least 3.16.2 for RSA key import. See " 60 "NSS version must be at least 3.16.2 for RSA private key import. See "
61 "http://crbug.com/380424"); 61 "http://crbug.com/380424");
62 } 62 }
63 63
64 // Prior to NSS 3.16.2 RSA key parameters were not validated. This is 64 // Prior to NSS 3.16.2 RSA key parameters were not validated. This is
65 // a security problem for RSA private key import from JWK which uses a 65 // a security problem for RSA private key import from JWK which uses a
66 // CKA_ID based on the public modulus to retrieve the private key. 66 // CKA_ID based on the public modulus to retrieve the private key.
67 Status NssSupportsRsaKeyImport() { 67 Status NssSupportsRsaPrivateKeyImport() {
68 if (!NSS_VersionCheck("3.16.2")) 68 if (!NSS_VersionCheck("3.16.2"))
69 return ErrorRsaKeyImportNotSupported(); 69 return ErrorRsaPrivateKeyImportNotSupported();
70 70
71 // Also ensure that the version of Softoken is 3.16.2 or later. 71 // Also ensure that the version of Softoken is 3.16.2 or later.
72 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); 72 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
73 CK_SLOT_INFO info = {}; 73 CK_SLOT_INFO info = {};
74 if (PK11_GetSlotInfo(slot.get(), &info) != SECSuccess) 74 if (PK11_GetSlotInfo(slot.get(), &info) != SECSuccess)
75 return ErrorRsaKeyImportNotSupported(); 75 return ErrorRsaPrivateKeyImportNotSupported();
76 76
77 // CK_SLOT_INFO.hardwareVersion contains the major.minor 77 // CK_SLOT_INFO.hardwareVersion contains the major.minor
78 // version info for Softoken in the corresponding .major/.minor 78 // version info for Softoken in the corresponding .major/.minor
79 // fields, and .firmwareVersion contains the patch.build 79 // fields, and .firmwareVersion contains the patch.build
80 // version info (in the .major/.minor fields) 80 // version info (in the .major/.minor fields)
81 if ((info.hardwareVersion.major > 3) || 81 if ((info.hardwareVersion.major > 3) ||
82 (info.hardwareVersion.major == 3 && 82 (info.hardwareVersion.major == 3 &&
83 (info.hardwareVersion.minor > 16 || 83 (info.hardwareVersion.minor > 16 ||
84 (info.hardwareVersion.minor == 16 && 84 (info.hardwareVersion.minor == 16 &&
85 info.firmwareVersion.major >= 2)))) { 85 info.firmwareVersion.major >= 2)))) {
86 return Status::Success(); 86 return Status::Success();
87 } 87 }
88 88
89 return ErrorRsaKeyImportNotSupported(); 89 return ErrorRsaPrivateKeyImportNotSupported();
90 } 90 }
91 #else 91 #else
92 Status NssSupportsRsaKeyImport() { 92 Status NssSupportsRsaPrivateKeyImport() {
93 return Status::Success(); 93 return Status::Success();
94 } 94 }
95 #endif 95 #endif
96 96
97 bool CreateRsaHashedPublicKeyAlgorithm( 97 bool CreateRsaHashedPublicKeyAlgorithm(
98 const blink::WebCryptoAlgorithm& algorithm, 98 const blink::WebCryptoAlgorithm& algorithm,
99 SECKEYPublicKey* key, 99 SECKEYPublicKey* key,
100 blink::WebCryptoKeyAlgorithm* key_algorithm) { 100 blink::WebCryptoKeyAlgorithm* key_algorithm) {
101 // TODO(eroman): What about other key types rsaPss, rsaOaep. 101 // TODO(eroman): What about other key types rsaPss, rsaOaep.
102 if (!key || key->keyType != rsaKey) 102 if (!key || key->keyType != rsaKey)
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 339
340 buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len); 340 buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len);
341 return Status::Success(); 341 return Status::Success();
342 } 342 }
343 343
344 Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm, 344 Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm,
345 bool extractable, 345 bool extractable,
346 blink::WebCryptoKeyUsageMask usage_mask, 346 blink::WebCryptoKeyUsageMask usage_mask,
347 const JwkRsaInfo& params, 347 const JwkRsaInfo& params,
348 blink::WebCryptoKey* key) { 348 blink::WebCryptoKey* key) {
349 Status status = NssSupportsRsaKeyImport(); 349 Status status = NssSupportsRsaPrivateKeyImport();
350 if (status.IsError()) 350 if (status.IsError())
351 return status; 351 return status;
352 352
353 CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY; 353 CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY;
354 CK_KEY_TYPE key_type = CKK_RSA; 354 CK_KEY_TYPE key_type = CKK_RSA;
355 CK_BBOOL ck_false = CK_FALSE; 355 CK_BBOOL ck_false = CK_FALSE;
356 356
357 std::vector<CK_ATTRIBUTE> key_template; 357 std::vector<CK_ATTRIBUTE> key_template;
358 358
359 AddAttribute(CKA_CLASS, &obj_class, sizeof(obj_class), &key_template); 359 AddAttribute(CKA_CLASS, &obj_class, sizeof(obj_class), &key_template);
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 return Status::ErrorUnsupportedImportKeyFormat(); 642 return Status::ErrorUnsupportedImportKeyFormat();
643 } 643 }
644 } 644 }
645 645
646 Status RsaHashedAlgorithm::ImportKeyPkcs8( 646 Status RsaHashedAlgorithm::ImportKeyPkcs8(
647 const CryptoData& key_data, 647 const CryptoData& key_data,
648 const blink::WebCryptoAlgorithm& algorithm, 648 const blink::WebCryptoAlgorithm& algorithm,
649 bool extractable, 649 bool extractable,
650 blink::WebCryptoKeyUsageMask usage_mask, 650 blink::WebCryptoKeyUsageMask usage_mask,
651 blink::WebCryptoKey* key) const { 651 blink::WebCryptoKey* key) const {
652 Status status = NssSupportsRsaKeyImport(); 652 Status status = NssSupportsRsaPrivateKeyImport();
653 if (status.IsError()) 653 if (status.IsError())
654 return status; 654 return status;
655 655
656 if (!key_data.byte_length()) 656 if (!key_data.byte_length())
657 return Status::ErrorImportEmptyKeyData(); 657 return Status::ErrorImportEmptyKeyData();
658 658
659 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8 659 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8
660 // private key info object. 660 // private key info object.
661 SECItem pki_der = MakeSECItemForBuffer(key_data); 661 SECItem pki_der = MakeSECItemForBuffer(key_data);
662 662
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 702
703 return Status::Success(); 703 return Status::Success();
704 } 704 }
705 705
706 Status RsaHashedAlgorithm::ImportKeySpki( 706 Status RsaHashedAlgorithm::ImportKeySpki(
707 const CryptoData& key_data, 707 const CryptoData& key_data,
708 const blink::WebCryptoAlgorithm& algorithm, 708 const blink::WebCryptoAlgorithm& algorithm,
709 bool extractable, 709 bool extractable,
710 blink::WebCryptoKeyUsageMask usage_mask, 710 blink::WebCryptoKeyUsageMask usage_mask,
711 blink::WebCryptoKey* key) const { 711 blink::WebCryptoKey* key) const {
712 Status status = NssSupportsRsaKeyImport();
713 if (status.IsError())
714 return status;
715
716 if (!key_data.byte_length()) 712 if (!key_data.byte_length())
717 return Status::ErrorImportEmptyKeyData(); 713 return Status::ErrorImportEmptyKeyData();
718 714
719 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject 715 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject
720 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. 716 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo.
721 SECItem spki_item = MakeSECItemForBuffer(key_data); 717 SECItem spki_item = MakeSECItemForBuffer(key_data);
722 const ScopedCERTSubjectPublicKeyInfo spki( 718 const ScopedCERTSubjectPublicKeyInfo spki(
723 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); 719 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
724 if (!spki) 720 if (!spki)
725 return Status::DataError(); 721 return Status::DataError();
726 722
727 crypto::ScopedSECKEYPublicKey sec_public_key( 723 crypto::ScopedSECKEYPublicKey sec_public_key(
728 SECKEY_ExtractPublicKey(spki.get())); 724 SECKEY_ExtractPublicKey(spki.get()));
729 if (!sec_public_key) 725 if (!sec_public_key)
730 return Status::DataError(); 726 return Status::DataError();
731 727
732 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); 728 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get());
733 if (sec_key_type != rsaKey) 729 if (sec_key_type != rsaKey)
734 return Status::DataError(); 730 return Status::DataError();
735 731
736 blink::WebCryptoKeyAlgorithm key_algorithm; 732 blink::WebCryptoKeyAlgorithm key_algorithm;
737 if (!CreateRsaHashedPublicKeyAlgorithm( 733 if (!CreateRsaHashedPublicKeyAlgorithm(
738 algorithm, sec_public_key.get(), &key_algorithm)) 734 algorithm, sec_public_key.get(), &key_algorithm))
739 return Status::ErrorUnexpected(); 735 return Status::ErrorUnexpected();
740 736
741 // TODO(eroman): This is probably going to be the same as the input. 737 // TODO(eroman): This is probably going to be the same as the input.
742 std::vector<uint8_t> spki_data; 738 std::vector<uint8_t> spki_data;
743 status = ExportKeySpkiNss(sec_public_key.get(), &spki_data); 739 Status status = ExportKeySpkiNss(sec_public_key.get(), &spki_data);
744 if (status.IsError()) 740 if (status.IsError())
745 return status; 741 return status;
746 742
747 scoped_ptr<PublicKeyNss> key_handle( 743 scoped_ptr<PublicKeyNss> key_handle(
748 new PublicKeyNss(sec_public_key.Pass(), CryptoData(spki_data))); 744 new PublicKeyNss(sec_public_key.Pass(), CryptoData(spki_data)));
749 745
750 *key = blink::WebCryptoKey::create(key_handle.release(), 746 *key = blink::WebCryptoKey::create(key_handle.release(),
751 blink::WebCryptoKeyTypePublic, 747 blink::WebCryptoKeyTypePublic,
752 extractable, 748 extractable,
753 key_algorithm, 749 key_algorithm,
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 return Status::Success(); 851 return Status::Success();
856 } 852 }
857 default: 853 default:
858 return Status::ErrorUnexpected(); 854 return Status::ErrorUnexpected();
859 } 855 }
860 } 856 }
861 857
862 } // namespace webcrypto 858 } // namespace webcrypto
863 859
864 } // namespace content 860 } // 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