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

Side by Side Diff: crypto/nss_key_util.cc

Issue 1106103003: Don't use RSAPrivateKey in NSS integration code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ocsp-refactor
Patch Set: sleevi comments Created 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "crypto/nss_key_util.h"
6
7 #include <cryptohi.h>
8 #include <keyhi.h>
9 #include <pk11pub.h>
10
11 #include "base/logging.h"
12 #include "crypto/nss_util.h"
13
14 #if defined(USE_NSS_CERTS)
15 #include <secmod.h>
16 #include "crypto/nss_util_internal.h"
17 #endif
18
19 namespace crypto {
20
21 namespace {
22
23 #if defined(USE_NSS_CERTS)
24
25 struct PublicKeyInfoDeleter {
26 inline void operator()(CERTSubjectPublicKeyInfo* spki) {
27 SECKEY_DestroySubjectPublicKeyInfo(spki);
28 }
29 };
30
31 typedef scoped_ptr<CERTSubjectPublicKeyInfo, PublicKeyInfoDeleter>
32 ScopedPublicKeyInfo;
33
34 // Decodes |input| as a SubjectPublicKeyInfo and returns a SECItem containing
35 // the CKA_ID of that public key or nullptr on error.
36 ScopedSECItem MakeIDFromSPKI(const std::vector<uint8_t> input) {
37 // First, decode and save the public key.
38 SECItem key_der;
39 key_der.type = siBuffer;
40 key_der.data = const_cast<unsigned char*>(&input[0]);
pneubeck (no reviews) 2015/04/28 09:56:26 note that this fails if size is null. probably (de
davidben 2015/04/28 16:27:46 Done.
41 key_der.len = input.size();
42
43 ScopedPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der));
44 if (!spki)
45 return nullptr;
46
47 ScopedSECKEYPublicKey result(SECKEY_ExtractPublicKey(spki.get()));
48 if (!result)
49 return nullptr;
50
51 // See pk11_MakeIDFromPublicKey from NSS.
52 SECItem* pub_key_index;
53 switch (SECKEY_GetPublicKeyType(result.get())) {
54 case rsaKey:
55 pub_key_index = &result->u.rsa.modulus;
56 break;
57 default:
58 // Unsupported key type.
59 return nullptr;
60 }
61
62 return ScopedSECItem(PK11_MakeIDFromPubKey(pub_key_index));
pneubeck (no reviews) 2015/04/28 09:56:26 you could move this to line 55 and remove the temp
davidben 2015/04/28 16:27:45 Done.
63 }
64
65 #endif // defined(USE_NSS_CERTS)
66
67 } // namespace
68
69 bool GenerateRSAKeyPairNSS(PK11SlotInfo* slot,
pneubeck (no reviews) 2015/04/28 09:56:26 it's unclear (or at least subtle) how PK11_Generat
davidben 2015/04/28 16:27:46 NSS generally checks for NULL inputs (and does her
pneubeck (no reviews) 2015/04/28 16:40:27 That's right. Usually we drop a DCHECK if we are c
70 uint16_t num_bits,
71 bool permanent,
72 ScopedSECKEYPublicKey* out_public_key,
73 ScopedSECKEYPrivateKey* out_private_key) {
74 PK11RSAGenParams param;
75 param.keySizeInBits = num_bits;
76 param.pe = 65537L;
77 SECKEYPublicKey* public_key_raw;
pneubeck (no reviews) 2015/04/28 09:56:27 should be intialized to nulltpr.
davidben 2015/04/28 16:27:46 Done.
78 ScopedSECKEYPrivateKey private_key(PK11_GenerateKeyPair(
pneubeck (no reviews) 2015/04/28 09:56:26 could directly assign to out_private_key and renam
davidben 2015/04/28 16:27:45 I prefer explicitly annotating output parameters i
79 slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &param, &public_key_raw, permanent,
80 permanent /* sensitive */, nullptr));
81 if (!private_key)
82 return false;
83
84 out_public_key->reset(public_key_raw);
85 *out_private_key = private_key.Pass();
86 return true;
87 }
88
89 ScopedSECKEYPrivateKey ImportNSSKeyFromPrivateKeyInfo(
pneubeck (no reviews) 2015/04/28 09:56:26 i think this function did an EnsureNSSInit before
davidben 2015/04/28 16:27:46 I didn't put in EnsureNSSInit for functions that t
pneubeck (no reviews) 2015/04/28 16:40:27 Acknowledged.
90 PK11SlotInfo* slot,
pneubeck (no reviews) 2015/04/28 09:56:26 ditto, add check for slot
davidben 2015/04/28 16:27:46 Added DCHECK.
91 const std::vector<uint8_t>& input,
92 bool permanent) {
93 ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
94 if (!arena) {
95 NOTREACHED();
pneubeck (no reviews) 2015/04/28 09:56:26 these NOTREACHED (which equals a DCHECK) + return
davidben 2015/04/28 16:27:45 This came from the old code. Invariant is really n
96 return nullptr;
97 }
98
99 // Excess data is illegal, but NSS silently accepts it, so first ensure that
100 // |input| consists of a single ASN.1 element.
101 SECItem input_item;
102 input_item.data = const_cast<unsigned char*>(&input.front());
pneubeck (no reviews) 2015/04/28 09:56:26 ditto, fails if input is empty.
davidben 2015/04/28 16:27:46 Done.
103 input_item.len = input.size();
104 SECItem der_private_key_info;
105 SECStatus rv =
106 SEC_QuickDERDecodeItem(arena.get(), &der_private_key_info,
107 SEC_ASN1_GET(SEC_AnyTemplate), &input_item);
108 if (rv != SECSuccess)
109 return nullptr;
110
111 // Allow the private key to be used for key unwrapping, data decryption,
112 // and signature generation.
113 const unsigned int key_usage =
114 KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | KU_DIGITAL_SIGNATURE;
115 SECKEYPrivateKey* key_raw;
pneubeck (no reviews) 2015/04/28 09:56:26 should be initialized to nullptr.
davidben 2015/04/28 16:27:45 Done.
116 rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
117 slot, &der_private_key_info, nullptr, nullptr, permanent,
118 permanent /* sensitive */, key_usage, &key_raw, nullptr);
119 if (rv != SECSuccess)
120 return nullptr;
121 return ScopedSECKEYPrivateKey(key_raw);
122 }
123
124 #if defined(USE_NSS_CERTS)
125
126 ScopedSECKEYPrivateKey FindNSSKeyFromPublicKeyInfo(
127 const std::vector<uint8_t>& input) {
128 EnsureNSSInit();
129
130 ScopedSECItem cka_id(MakeIDFromSPKI(input));
131 if (!cka_id) {
132 NOTREACHED();
pneubeck (no reviews) 2015/04/28 09:56:26 ditto, wrong NOTREACHED
davidben 2015/04/28 16:27:45 Removed the NOTREACHED. I probably got it from the
133 return nullptr;
134 }
135
136 // Search all slots in all modules for the key with the given ID.
137 AutoSECMODListReadLock auto_lock;
138 SECMODModuleList* head = SECMOD_GetDefaultModuleList();
pneubeck (no reviews) 2015/04/28 09:56:26 + const
davidben 2015/04/28 16:27:45 Done.
139 for (SECMODModuleList* item = head; item != nullptr; item = item->next) {
140 int slot_count = item->module->loaded ? item->module->slotCount : 0;
pneubeck (no reviews) 2015/04/28 09:56:26 + const
davidben 2015/04/28 16:27:46 I'm assume this meant to be the previous line? Don
pneubeck (no reviews) 2015/04/28 16:40:27 then both lines ;-)
davidben 2015/04/29 21:51:32 Do you mean the local variable? I didn't think we
pneubeck (no reviews) 2015/04/30 07:45:55 Yes.
141 for (int i = 0; i < slot_count; i++) {
142 // Look for the key in slot |i|.
143 ScopedSECKEYPrivateKey key(
144 PK11_FindKeyByKeyID(item->module->slots[i], cka_id.get(), nullptr));
145 if (key)
146 return key.Pass();
147 }
148 }
149
150 // The key wasn't found in any module.
151 return nullptr;
152 }
153
154 ScopedSECKEYPrivateKey FindNSSKeyFromPublicKeyInfoInSlot(
pneubeck (no reviews) 2015/04/28 09:56:26 i think this function did an EnsureNSSInit before
davidben 2015/04/28 16:27:46 Ditto about slot parameter.
155 const std::vector<uint8_t>& input,
156 PK11SlotInfo* slot) {
pneubeck (no reviews) 2015/04/28 09:56:26 ditto, add check for slot
davidben 2015/04/28 16:27:45 Done.
157 ScopedSECItem cka_id(MakeIDFromSPKI(input));
158 if (!cka_id) {
159 NOTREACHED();
pneubeck (no reviews) 2015/04/28 09:56:26 ditto, wrong NOTREACHED
davidben 2015/04/28 16:27:45 Done.
160 return nullptr;
161 }
162
163 return ScopedSECKEYPrivateKey(
164 PK11_FindKeyByKeyID(slot, cka_id.get(), nullptr));
165 }
166
167 #endif // defined(USE_NSS_CERTS)
168
169 } // namespace crypto
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698