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

Side by Side Diff: crypto/rsa_private_key_nss.cc

Issue 7066032: Fixing FindFromPublicKeyInfo so that it searches the "Public" NSS database (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review changes Created 9 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 | Annotate | Revision Log
« no previous file with comments | « crypto/nss_util.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "crypto/rsa_private_key.h" 5 #include "crypto/rsa_private_key.h"
6 6
7 #include <cryptohi.h> 7 #include <cryptohi.h>
8 #include <keyhi.h> 8 #include <keyhi.h>
9 #include <pk11pub.h> 9 #include <pk11pub.h>
10 10
11 #include <list> 11 #include <list>
12 12
13 #include "base/debug/leak_annotations.h" 13 #include "base/debug/leak_annotations.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
16 #include "base/string_util.h" 16 #include "base/string_util.h"
17 #include "crypto/nss_util.h" 17 #include "crypto/nss_util.h"
18 #include "crypto/nss_util_internal.h" 18 #include "crypto/nss_util_internal.h"
19 #include "crypto/scoped_nss_types.h"
19 20
20 // TODO(rafaelw): Consider refactoring common functions and definitions from 21 // TODO(rafaelw): Consider refactoring common functions and definitions from
21 // rsa_private_key_win.cc or using NSS's ASN.1 encoder. 22 // rsa_private_key_win.cc or using NSS's ASN.1 encoder.
22 namespace { 23 namespace {
23 24
24 static bool ReadAttribute(SECKEYPrivateKey* key, 25 static bool ReadAttribute(SECKEYPrivateKey* key,
25 CK_ATTRIBUTE_TYPE type, 26 CK_ATTRIBUTE_TYPE type,
26 std::vector<uint8>* output) { 27 std::vector<uint8>* output) {
27 SECItem item; 28 SECItem item;
28 SECStatus rv; 29 SECStatus rv;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 EnsureNSSInit(); 85 EnsureNSSInit();
85 86
86 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); 87 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
87 88
88 // First, decode and save the public key. 89 // First, decode and save the public key.
89 SECItem key_der; 90 SECItem key_der;
90 key_der.type = siBuffer; 91 key_der.type = siBuffer;
91 key_der.data = const_cast<unsigned char*>(&input[0]); 92 key_der.data = const_cast<unsigned char*>(&input[0]);
92 key_der.len = input.size(); 93 key_der.len = input.size();
93 94
94 CERTSubjectPublicKeyInfo *spki = 95 CERTSubjectPublicKeyInfo* spki =
95 SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der); 96 SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der);
96 if (!spki) { 97 if (!spki) {
97 NOTREACHED(); 98 NOTREACHED();
98 return NULL; 99 return NULL;
99 } 100 }
100 101
101 result->public_key_ = SECKEY_ExtractPublicKey(spki); 102 result->public_key_ = SECKEY_ExtractPublicKey(spki);
102 SECKEY_DestroySubjectPublicKeyInfo(spki); 103 SECKEY_DestroySubjectPublicKeyInfo(spki);
103 if (!result->public_key_) { 104 if (!result->public_key_) {
104 NOTREACHED(); 105 NOTREACHED();
105 return NULL; 106 return NULL;
106 } 107 }
107 108
108 // Now, look for the associated private key in the user's
109 // hardware-backed NSS DB. If it's not there, consider that an
110 // error.
111 PK11SlotInfo *slot = GetPrivateNSSKeySlot();
112 if (!slot) {
113 NOTREACHED();
114 return NULL;
115 }
116
117 // Make sure the key is an RSA key. If not, that's an error 109 // Make sure the key is an RSA key. If not, that's an error
118 if (result->public_key_->keyType != rsaKey) { 110 if (result->public_key_->keyType != rsaKey) {
119 PK11_FreeSlot(slot);
120 NOTREACHED(); 111 NOTREACHED();
121 return NULL; 112 return NULL;
122 } 113 }
123 114
124 SECItem *ck_id = PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus)); 115 ScopedSECItem ck_id(
125 if (!ck_id) { 116 PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus)));
126 PK11_FreeSlot(slot); 117 if (!ck_id.get()) {
118 NOTREACHED();
119 return NULL;
120 }
121
122 ScopedPK11Slot slot(GetPrivateNSSKeySlot());
123 if (!slot.get()) {
127 NOTREACHED(); 124 NOTREACHED();
128 return NULL; 125 return NULL;
129 } 126 }
130 127
131 // Finally...Look for the key! 128 // Finally...Look for the key!
132 result->key_ = PK11_FindKeyByKeyID(slot, ck_id, NULL); 129 result->key_ = PK11_FindKeyByKeyID(slot.get(), ck_id.get(), NULL);
133 130
134 // Cleanup... 131 // If we don't find the matching key in the private slot, then we
135 PK11_FreeSlot(slot); 132 // look in the public slot.
136 SECITEM_FreeItem(ck_id, PR_TRUE); 133 if (!result->key_) {
134 slot.reset(GetPublicNSSKeySlot());
wtc 2011/05/25 23:34:01 If the computer doesn't have a TPM, GetPrivateNSSK
135 if (!slot.get()) {
136 NOTREACHED();
137 return NULL;
138 }
139 result->key_ = PK11_FindKeyByKeyID(slot.get(), ck_id.get(), NULL);
140 }
137 141
138 // If we didn't find it, that's ok. 142 // If we didn't find it, that's ok.
139 if (!result->key_) 143 if (!result->key_)
140 return NULL; 144 return NULL;
141 145
142 return result.release(); 146 return result.release();
143 } 147 }
144 148
145 149
146 bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { 150 bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) {
(...skipping 12 matching lines...) Expand all
159 !ReadAttribute(key_, CKA_EXPONENT_2, private_key_info.exponent2()) || 163 !ReadAttribute(key_, CKA_EXPONENT_2, private_key_info.exponent2()) ||
160 !ReadAttribute(key_, CKA_COEFFICIENT, private_key_info.coefficient())) { 164 !ReadAttribute(key_, CKA_COEFFICIENT, private_key_info.coefficient())) {
161 NOTREACHED(); 165 NOTREACHED();
162 return false; 166 return false;
163 } 167 }
164 168
165 return private_key_info.Export(output); 169 return private_key_info.Export(output);
166 } 170 }
167 171
168 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { 172 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) {
169 SECItem* der_pubkey = SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_); 173 ScopedSECItem der_pubkey(SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_));
170 if (!der_pubkey) { 174 if (!der_pubkey.get()) {
171 NOTREACHED(); 175 NOTREACHED();
172 return false; 176 return false;
173 } 177 }
174 178
175 for (size_t i = 0; i < der_pubkey->len; ++i) 179 for (size_t i = 0; i < der_pubkey->len; ++i)
176 output->push_back(der_pubkey->data[i]); 180 output->push_back(der_pubkey->data[i]);
177 181
178 SECITEM_FreeItem(der_pubkey, PR_TRUE);
179 return true; 182 return true;
180 } 183 }
181 184
182 RSAPrivateKey::RSAPrivateKey() : key_(NULL), public_key_(NULL) { 185 RSAPrivateKey::RSAPrivateKey() : key_(NULL), public_key_(NULL) {
183 EnsureNSSInit(); 186 EnsureNSSInit();
184 } 187 }
185 188
186 // static 189 // static
187 RSAPrivateKey* RSAPrivateKey::CreateWithParams(uint16 num_bits, 190 RSAPrivateKey* RSAPrivateKey::CreateWithParams(uint16 num_bits,
188 bool permanent, 191 bool permanent,
189 bool sensitive) { 192 bool sensitive) {
190 EnsureNSSInit(); 193 EnsureNSSInit();
191 194
192 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); 195 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
193 196
194 PK11SlotInfo *slot = GetPrivateNSSKeySlot(); 197 ScopedPK11Slot slot(GetPrivateNSSKeySlot());
195 if (!slot) 198 if (!slot.get())
196 return NULL; 199 return NULL;
197 200
198 PK11RSAGenParams param; 201 PK11RSAGenParams param;
199 param.keySizeInBits = num_bits; 202 param.keySizeInBits = num_bits;
200 param.pe = 65537L; 203 param.pe = 65537L;
201 result->key_ = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &param, 204 result->key_ = PK11_GenerateKeyPair(slot.get(),
202 &result->public_key_, permanent, sensitive, NULL); 205 CKM_RSA_PKCS_KEY_PAIR_GEN,
203 PK11_FreeSlot(slot); 206 &param,
207 &result->public_key_,
208 permanent,
209 sensitive,
210 NULL);
204 if (!result->key_) 211 if (!result->key_)
205 return NULL; 212 return NULL;
206 213
207 return result.release(); 214 return result.release();
208 } 215 }
209 216
210 // static 217 // static
211 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams( 218 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams(
212 const std::vector<uint8>& input, bool permanent, bool sensitive) { 219 const std::vector<uint8>& input, bool permanent, bool sensitive) {
213 // This method currently leaks some memory. 220 // This method currently leaks some memory.
214 // See http://crbug.com/34742. 221 // See http://crbug.com/34742.
215 ANNOTATE_SCOPED_MEMORY_LEAK; 222 ANNOTATE_SCOPED_MEMORY_LEAK;
216 EnsureNSSInit(); 223 EnsureNSSInit();
217 224
218 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); 225 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
219 226
220 PK11SlotInfo *slot = GetPrivateNSSKeySlot(); 227 ScopedPK11Slot slot(GetPrivateNSSKeySlot());
221 if (!slot) 228 if (!slot.get())
222 return NULL; 229 return NULL;
223 230
224 SECItem der_private_key_info; 231 SECItem der_private_key_info;
225 der_private_key_info.data = const_cast<unsigned char*>(&input.front()); 232 der_private_key_info.data = const_cast<unsigned char*>(&input.front());
226 der_private_key_info.len = input.size(); 233 der_private_key_info.len = input.size();
227 // Allow the private key to be used for key unwrapping, data decryption, 234 // Allow the private key to be used for key unwrapping, data decryption,
228 // and signature generation. 235 // and signature generation.
229 const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | 236 const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT |
230 KU_DIGITAL_SIGNATURE; 237 KU_DIGITAL_SIGNATURE;
231 SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( 238 SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
232 slot, &der_private_key_info, NULL, NULL, permanent, sensitive, 239 slot.get(), &der_private_key_info, NULL, NULL, permanent, sensitive,
233 key_usage, &result->key_, NULL); 240 key_usage, &result->key_, NULL);
234 PK11_FreeSlot(slot);
235 if (rv != SECSuccess) { 241 if (rv != SECSuccess) {
236 NOTREACHED(); 242 NOTREACHED();
237 return NULL; 243 return NULL;
238 } 244 }
239 245
240 result->public_key_ = SECKEY_ConvertToPublicKey(result->key_); 246 result->public_key_ = SECKEY_ConvertToPublicKey(result->key_);
241 if (!result->public_key_) { 247 if (!result->public_key_) {
242 NOTREACHED(); 248 NOTREACHED();
243 return NULL; 249 return NULL;
244 } 250 }
245 251
246 return result.release(); 252 return result.release();
247 } 253 }
248 254
249 } // namespace crypto 255 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/nss_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698