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

Side by Side Diff: crypto/ec_private_key_nss.cc

Issue 66213002: NSS: {EC,RSA}PrivateKey shouldn't call crypto::GetPublicNSSKeySlot or GetPrivateNSSKeySlot. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove the checks again Created 7 years, 1 month 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/ec_private_key.h ('k') | crypto/ec_private_key_openssl.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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/ec_private_key.h" 5 #include "crypto/ec_private_key.h"
6 6
7 extern "C" { 7 extern "C" {
8 // Work around NSS missing SEC_BEGIN_PROTOS in secmodt.h. This must come before 8 // Work around NSS missing SEC_BEGIN_PROTOS in secmodt.h. This must come before
9 // other NSS headers. 9 // other NSS headers.
10 #include <secmodt.h> 10 #include <secmodt.h>
11 } 11 }
12 12
13 #include <cryptohi.h> 13 #include <cryptohi.h>
14 #include <keyhi.h> 14 #include <keyhi.h>
15 #include <pk11pub.h> 15 #include <pk11pub.h>
16 #include <secmod.h> 16 #include <secmod.h>
17 17
18 #include "base/lazy_instance.h" 18 #include "base/lazy_instance.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h" 20 #include "base/memory/scoped_ptr.h"
21 #include "crypto/nss_util.h" 21 #include "crypto/nss_util.h"
22 #include "crypto/nss_util_internal.h" 22 #include "crypto/nss_util_internal.h"
23 #include "crypto/scoped_nss_types.h" 23 #include "crypto/scoped_nss_types.h"
24 #include "crypto/third_party/nss/chromium-nss.h" 24 #include "crypto/third_party/nss/chromium-nss.h"
25 25
26 namespace { 26 namespace {
27 27
28 PK11SlotInfo* GetKeySlot() { 28 PK11SlotInfo* GetTempKeySlot() {
29 return crypto::GetPublicNSSKeySlot(); 29 return PK11_GetInternalSlot();
30 } 30 }
31 31
32 class EllipticCurveSupportChecker { 32 class EllipticCurveSupportChecker {
33 public: 33 public:
34 EllipticCurveSupportChecker() { 34 EllipticCurveSupportChecker() {
35 // NOTE: we can do this check here only because we use the NSS internal 35 // NOTE: we can do this check here only because we use the NSS internal
36 // slot. If we support other slots in the future, checking whether they 36 // slot. If we support other slots in the future, checking whether they
37 // support ECDSA may block NSS, and the value may also change as devices are 37 // support ECDSA may block NSS, and the value may also change as devices are
38 // inserted/removed, so we would need to re-check on every use. 38 // inserted/removed, so we would need to re-check on every use.
39 crypto::EnsureNSSInit(); 39 crypto::EnsureNSSInit();
40 crypto::ScopedPK11Slot slot(GetKeySlot()); 40 crypto::ScopedPK11Slot slot(GetTempKeySlot());
41 supported_ = PK11_DoesMechanism(slot.get(), CKM_EC_KEY_PAIR_GEN) && 41 supported_ = PK11_DoesMechanism(slot.get(), CKM_EC_KEY_PAIR_GEN) &&
42 PK11_DoesMechanism(slot.get(), CKM_ECDSA); 42 PK11_DoesMechanism(slot.get(), CKM_ECDSA);
43 } 43 }
44 44
45 bool Supported() { 45 bool Supported() {
46 return supported_; 46 return supported_;
47 } 47 }
48 48
49 private: 49 private:
50 bool supported_; 50 bool supported_;
(...skipping 30 matching lines...) Expand all
81 SECKEY_DestroyPublicKey(public_key_); 81 SECKEY_DestroyPublicKey(public_key_);
82 } 82 }
83 83
84 // static 84 // static
85 bool ECPrivateKey::IsSupported() { 85 bool ECPrivateKey::IsSupported() {
86 return g_elliptic_curve_supported.Get().Supported(); 86 return g_elliptic_curve_supported.Get().Supported();
87 } 87 }
88 88
89 // static 89 // static
90 ECPrivateKey* ECPrivateKey::Create() { 90 ECPrivateKey* ECPrivateKey::Create() {
91 return CreateWithParams(PR_FALSE /* not permanent */, 91 EnsureNSSInit();
92 PR_FALSE /* not sensitive */); 92
93 ScopedPK11Slot slot(GetTempKeySlot());
94 return CreateWithParams(slot.get(),
95 false /* not permanent */,
96 false /* not sensitive */);
93 } 97 }
94 98
99 #if defined(USE_NSS)
95 // static 100 // static
96 ECPrivateKey* ECPrivateKey::CreateSensitive() { 101 ECPrivateKey* ECPrivateKey::CreateSensitive(PK11SlotInfo* slot) {
97 #if defined(USE_NSS) 102 return CreateWithParams(
98 return CreateWithParams(PR_TRUE /* permanent */, 103 slot, true /* permanent */, true /* sensitive */);
99 PR_TRUE /* sensitive */); 104 }
100 #else
101 // If USE_NSS is not defined, we initialize NSS with no databases, so we can't
102 // create permanent keys.
103 NOTREACHED();
104 return NULL;
105 #endif 105 #endif
106 }
107 106
108 // static 107 // static
109 ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( 108 ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
110 const std::string& password, 109 const std::string& password,
111 const std::vector<uint8>& encrypted_private_key_info, 110 const std::vector<uint8>& encrypted_private_key_info,
112 const std::vector<uint8>& subject_public_key_info) { 111 const std::vector<uint8>& subject_public_key_info) {
112 EnsureNSSInit();
113
114 ScopedPK11Slot slot(GetTempKeySlot());
113 return CreateFromEncryptedPrivateKeyInfoWithParams( 115 return CreateFromEncryptedPrivateKeyInfoWithParams(
116 slot.get(),
114 password, 117 password,
115 encrypted_private_key_info, 118 encrypted_private_key_info,
116 subject_public_key_info, 119 subject_public_key_info,
117 PR_FALSE /* not permanent */, 120 false /* not permanent */,
118 PR_FALSE /* not sensitive */); 121 false /* not sensitive */);
119 } 122 }
120 123
124 #if defined(USE_NSS)
121 // static 125 // static
122 ECPrivateKey* ECPrivateKey::CreateSensitiveFromEncryptedPrivateKeyInfo( 126 ECPrivateKey* ECPrivateKey::CreateSensitiveFromEncryptedPrivateKeyInfo(
127 PK11SlotInfo* slot,
123 const std::string& password, 128 const std::string& password,
124 const std::vector<uint8>& encrypted_private_key_info, 129 const std::vector<uint8>& encrypted_private_key_info,
125 const std::vector<uint8>& subject_public_key_info) { 130 const std::vector<uint8>& subject_public_key_info) {
126 #if defined(USE_NSS)
127 return CreateFromEncryptedPrivateKeyInfoWithParams( 131 return CreateFromEncryptedPrivateKeyInfoWithParams(
132 slot,
128 password, 133 password,
129 encrypted_private_key_info, 134 encrypted_private_key_info,
130 subject_public_key_info, 135 subject_public_key_info,
131 PR_TRUE /* permanent */, 136 true /* permanent */,
132 PR_TRUE /* sensitive */); 137 true /* sensitive */);
133 #else 138 }
134 // If USE_NSS is not defined, we initialize NSS with no databases, so we can't
135 // create permanent keys.
136 NOTREACHED();
137 return NULL;
138 #endif 139 #endif
139 }
140 140
141 // static 141 // static
142 bool ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( 142 bool ECPrivateKey::ImportFromEncryptedPrivateKeyInfo(
143 PK11SlotInfo* slot,
143 const std::string& password, 144 const std::string& password,
144 const uint8* encrypted_private_key_info, 145 const uint8* encrypted_private_key_info,
145 size_t encrypted_private_key_info_len, 146 size_t encrypted_private_key_info_len,
146 CERTSubjectPublicKeyInfo* decoded_spki, 147 CERTSubjectPublicKeyInfo* decoded_spki,
147 bool permanent, 148 bool permanent,
148 bool sensitive, 149 bool sensitive,
149 SECKEYPrivateKey** key, 150 SECKEYPrivateKey** key,
150 SECKEYPublicKey** public_key) { 151 SECKEYPublicKey** public_key) {
151 ScopedPK11Slot slot(GetKeySlot()); 152 if (!slot)
152 if (!slot.get())
153 return false; 153 return false;
154 154
155 *public_key = SECKEY_ExtractPublicKey(decoded_spki); 155 *public_key = SECKEY_ExtractPublicKey(decoded_spki);
156 156
157 if (!*public_key) { 157 if (!*public_key) {
158 DLOG(ERROR) << "SECKEY_ExtractPublicKey: " << PORT_GetError(); 158 DLOG(ERROR) << "SECKEY_ExtractPublicKey: " << PORT_GetError();
159 return false; 159 return false;
160 } 160 }
161 161
162 SECItem encoded_epki = { 162 SECItem encoded_epki = {
(...skipping 18 matching lines...) Expand all
181 return false; 181 return false;
182 } 182 }
183 183
184 SECItem password_item = { 184 SECItem password_item = {
185 siBuffer, 185 siBuffer,
186 reinterpret_cast<unsigned char*>(const_cast<char*>(password.data())), 186 reinterpret_cast<unsigned char*>(const_cast<char*>(password.data())),
187 static_cast<unsigned>(password.size()) 187 static_cast<unsigned>(password.size())
188 }; 188 };
189 189
190 rv = ImportEncryptedECPrivateKeyInfoAndReturnKey( 190 rv = ImportEncryptedECPrivateKeyInfoAndReturnKey(
191 slot.get(), 191 slot,
192 &epki, 192 &epki,
193 &password_item, 193 &password_item,
194 NULL, // nickname 194 NULL, // nickname
195 &(*public_key)->u.ec.publicValue, 195 &(*public_key)->u.ec.publicValue,
196 permanent, 196 permanent,
197 sensitive, 197 sensitive,
198 key, 198 key,
199 NULL); // wincx 199 NULL); // wincx
200 if (rv != SECSuccess) { 200 if (rv != SECSuccess) {
201 DLOG(ERROR) << "ImportEncryptedECPrivateKeyInfoAndReturnKey: " 201 DLOG(ERROR) << "ImportEncryptedECPrivateKeyInfoAndReturnKey: "
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 return ReadAttribute(key_, CKA_VALUE, output); 268 return ReadAttribute(key_, CKA_VALUE, output);
269 } 269 }
270 270
271 bool ECPrivateKey::ExportECParams(std::vector<uint8>* output) { 271 bool ECPrivateKey::ExportECParams(std::vector<uint8>* output) {
272 return ReadAttribute(key_, CKA_EC_PARAMS, output); 272 return ReadAttribute(key_, CKA_EC_PARAMS, output);
273 } 273 }
274 274
275 ECPrivateKey::ECPrivateKey() : key_(NULL), public_key_(NULL) {} 275 ECPrivateKey::ECPrivateKey() : key_(NULL), public_key_(NULL) {}
276 276
277 // static 277 // static
278 ECPrivateKey* ECPrivateKey::CreateWithParams(bool permanent, 278 ECPrivateKey* ECPrivateKey::CreateWithParams(PK11SlotInfo* slot,
279 bool permanent,
279 bool sensitive) { 280 bool sensitive) {
280 EnsureNSSInit(); 281 if (!slot)
282 return NULL;
281 283
282 scoped_ptr<ECPrivateKey> result(new ECPrivateKey); 284 scoped_ptr<ECPrivateKey> result(new ECPrivateKey);
283 285
284 ScopedPK11Slot slot(GetKeySlot());
285 if (!slot.get())
286 return NULL;
287
288 SECOidData* oid_data = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1); 286 SECOidData* oid_data = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1);
289 if (!oid_data) { 287 if (!oid_data) {
290 DLOG(ERROR) << "SECOID_FindOIDByTag: " << PORT_GetError(); 288 DLOG(ERROR) << "SECOID_FindOIDByTag: " << PORT_GetError();
291 return NULL; 289 return NULL;
292 } 290 }
293 291
294 // SECKEYECParams is a SECItem containing the DER encoded ASN.1 ECParameters 292 // SECKEYECParams is a SECItem containing the DER encoded ASN.1 ECParameters
295 // value. For a named curve, that is just the OBJECT IDENTIFIER of the curve. 293 // value. For a named curve, that is just the OBJECT IDENTIFIER of the curve.
296 // In addition to the oid data, the encoding requires one byte for the ASN.1 294 // In addition to the oid data, the encoding requires one byte for the ASN.1
297 // tag and one byte for the length (assuming the length is <= 127). 295 // tag and one byte for the length (assuming the length is <= 127).
298 DCHECK_LE(oid_data->oid.len, 127U); 296 DCHECK_LE(oid_data->oid.len, 127U);
299 std::vector<unsigned char> parameters_buf(2 + oid_data->oid.len); 297 std::vector<unsigned char> parameters_buf(2 + oid_data->oid.len);
300 SECKEYECParams ec_parameters = { 298 SECKEYECParams ec_parameters = {
301 siDEROID, &parameters_buf[0], 299 siDEROID, &parameters_buf[0],
302 static_cast<unsigned>(parameters_buf.size()) 300 static_cast<unsigned>(parameters_buf.size())
303 }; 301 };
304 302
305 ec_parameters.data[0] = SEC_ASN1_OBJECT_ID; 303 ec_parameters.data[0] = SEC_ASN1_OBJECT_ID;
306 ec_parameters.data[1] = oid_data->oid.len; 304 ec_parameters.data[1] = oid_data->oid.len;
307 memcpy(ec_parameters.data + 2, oid_data->oid.data, oid_data->oid.len); 305 memcpy(ec_parameters.data + 2, oid_data->oid.data, oid_data->oid.len);
308 306
309 result->key_ = PK11_GenerateKeyPair(slot.get(), 307 result->key_ = PK11_GenerateKeyPair(slot,
310 CKM_EC_KEY_PAIR_GEN, 308 CKM_EC_KEY_PAIR_GEN,
311 &ec_parameters, 309 &ec_parameters,
312 &result->public_key_, 310 &result->public_key_,
313 permanent, 311 permanent,
314 sensitive, 312 sensitive,
315 NULL); 313 NULL);
316 if (!result->key_) { 314 if (!result->key_) {
317 DLOG(ERROR) << "PK11_GenerateKeyPair: " << PORT_GetError(); 315 DLOG(ERROR) << "PK11_GenerateKeyPair: " << PORT_GetError();
318 return NULL; 316 return NULL;
319 } 317 }
320 318
321 return result.release(); 319 return result.release();
322 } 320 }
323 321
324 // static 322 // static
325 ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfoWithParams( 323 ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfoWithParams(
324 PK11SlotInfo* slot,
326 const std::string& password, 325 const std::string& password,
327 const std::vector<uint8>& encrypted_private_key_info, 326 const std::vector<uint8>& encrypted_private_key_info,
328 const std::vector<uint8>& subject_public_key_info, 327 const std::vector<uint8>& subject_public_key_info,
329 bool permanent, 328 bool permanent,
330 bool sensitive) { 329 bool sensitive) {
331 EnsureNSSInit();
332
333 scoped_ptr<ECPrivateKey> result(new ECPrivateKey); 330 scoped_ptr<ECPrivateKey> result(new ECPrivateKey);
334 331
335 SECItem encoded_spki = { 332 SECItem encoded_spki = {
336 siBuffer, 333 siBuffer,
337 const_cast<unsigned char*>(&subject_public_key_info[0]), 334 const_cast<unsigned char*>(&subject_public_key_info[0]),
338 static_cast<unsigned>(subject_public_key_info.size()) 335 static_cast<unsigned>(subject_public_key_info.size())
339 }; 336 };
340 CERTSubjectPublicKeyInfo* decoded_spki = SECKEY_DecodeDERSubjectPublicKeyInfo( 337 CERTSubjectPublicKeyInfo* decoded_spki = SECKEY_DecodeDERSubjectPublicKeyInfo(
341 &encoded_spki); 338 &encoded_spki);
342 if (!decoded_spki) { 339 if (!decoded_spki) {
343 DLOG(ERROR) << "SECKEY_DecodeDERSubjectPublicKeyInfo: " << PORT_GetError(); 340 DLOG(ERROR) << "SECKEY_DecodeDERSubjectPublicKeyInfo: " << PORT_GetError();
344 return NULL; 341 return NULL;
345 } 342 }
346 343
347 bool success = ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( 344 bool success = ImportFromEncryptedPrivateKeyInfo(
345 slot,
348 password, 346 password,
349 &encrypted_private_key_info[0], 347 &encrypted_private_key_info[0],
350 encrypted_private_key_info.size(), 348 encrypted_private_key_info.size(),
351 decoded_spki, 349 decoded_spki,
352 permanent, 350 permanent,
353 sensitive, 351 sensitive,
354 &result->key_, 352 &result->key_,
355 &result->public_key_); 353 &result->public_key_);
356 354
357 SECKEY_DestroySubjectPublicKeyInfo(decoded_spki); 355 SECKEY_DestroySubjectPublicKeyInfo(decoded_spki);
358 356
359 if (success) 357 if (success)
360 return result.release(); 358 return result.release();
361 359
362 return NULL; 360 return NULL;
363 } 361 }
364 362
365 } // namespace crypto 363 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/ec_private_key.h ('k') | crypto/ec_private_key_openssl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698