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

Side by Side Diff: nss/lib/cryptohi/seckey.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 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
« no previous file with comments | « nss/lib/cryptohi/sechash.c ('k') | nss/lib/cryptohi/secsign.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #include "cryptohi.h"
5 #include "keyhi.h"
6 #include "secoid.h"
7 #include "secitem.h"
8 #include "secder.h"
9 #include "base64.h"
10 #include "secasn1.h"
11 #include "cert.h"
12 #include "pk11func.h"
13 #include "secerr.h"
14 #include "secdig.h"
15 #include "prtime.h"
16 #include "keyi.h"
17
18 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
19 SEC_ASN1_MKSUB(SEC_IntegerTemplate)
20
21 const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[] = {
22 { SEC_ASN1_SEQUENCE,
23 0, NULL, sizeof(CERTSubjectPublicKeyInfo) },
24 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
25 offsetof(CERTSubjectPublicKeyInfo, algorithm),
26 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
27 { SEC_ASN1_BIT_STRING,
28 offsetof(CERTSubjectPublicKeyInfo, subjectPublicKey) },
29 { 0 }
30 };
31
32 const SEC_ASN1Template CERT_PublicKeyAndChallengeTemplate[] =
33 {
34 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPublicKeyAndChallenge) },
35 { SEC_ASN1_ANY, offsetof(CERTPublicKeyAndChallenge, spki) },
36 { SEC_ASN1_IA5_STRING, offsetof(CERTPublicKeyAndChallenge, challenge) },
37 { 0 }
38 };
39
40 const SEC_ASN1Template SECKEY_RSAPublicKeyTemplate[] = {
41 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPublicKey) },
42 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.rsa.modulus) },
43 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.rsa.publicExponent) },
44 { 0 }
45 };
46
47 static const SEC_ASN1Template seckey_PointerToAlgorithmIDTemplate[] = {
48 { SEC_ASN1_POINTER | SEC_ASN1_XTRN, 0,
49 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }
50 };
51
52 /* Parameters for SEC_OID_PKCS1_RSA_PSS_SIGNATURE */
53 const SEC_ASN1Template SECKEY_RSAPSSParamsTemplate[] =
54 {
55 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRSAPSSParams) },
56 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
57 SEC_ASN1_CONTEXT_SPECIFIC | 0,
58 offsetof(SECKEYRSAPSSParams, hashAlg),
59 seckey_PointerToAlgorithmIDTemplate },
60 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
61 SEC_ASN1_CONTEXT_SPECIFIC | 1,
62 offsetof(SECKEYRSAPSSParams, maskAlg),
63 seckey_PointerToAlgorithmIDTemplate },
64 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
65 SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 2,
66 offsetof(SECKEYRSAPSSParams, saltLength),
67 SEC_ASN1_SUB(SEC_IntegerTemplate) },
68 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
69 SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 3,
70 offsetof(SECKEYRSAPSSParams, trailerField),
71 SEC_ASN1_SUB(SEC_IntegerTemplate) },
72 { 0 }
73 };
74
75 const SEC_ASN1Template SECKEY_DSAPublicKeyTemplate[] = {
76 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dsa.publicValue) },
77 { 0 }
78 };
79
80 const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = {
81 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) },
82 { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, prime) },
83 { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, subPrime) },
84 { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, base) },
85 { 0 }
86 };
87
88 const SEC_ASN1Template SECKEY_DHPublicKeyTemplate[] = {
89 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dh.publicValue) },
90 { 0 }
91 };
92
93 const SEC_ASN1Template SECKEY_DHParamKeyTemplate[] = {
94 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPublicKey) },
95 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dh.prime) },
96 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dh.base) },
97 /* XXX chrisk: this needs to be expanded for decoding of j and validationPar ms (RFC2459 7.3.2) */
98 { SEC_ASN1_SKIP_REST },
99 { 0 }
100 };
101
102 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_DSAPublicKeyTemplate)
103 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPublicKeyTemplate)
104 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPSSParamsTemplate)
105 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SubjectPublicKeyInfoTemplate)
106
107 /*
108 * See bugzilla bug 125359
109 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
110 * all of the templates above that en/decode into integers must be converted
111 * from ASN.1's signed integer type. This is done by marking either the
112 * source or destination (encoding or decoding, respectively) type as
113 * siUnsignedInteger.
114 */
115 static void
116 prepare_rsa_pub_key_for_asn1(SECKEYPublicKey *pubk)
117 {
118 pubk->u.rsa.modulus.type = siUnsignedInteger;
119 pubk->u.rsa.publicExponent.type = siUnsignedInteger;
120 }
121
122 static void
123 prepare_dsa_pub_key_for_asn1(SECKEYPublicKey *pubk)
124 {
125 pubk->u.dsa.publicValue.type = siUnsignedInteger;
126 }
127
128 static void
129 prepare_pqg_params_for_asn1(SECKEYPQGParams *params)
130 {
131 params->prime.type = siUnsignedInteger;
132 params->subPrime.type = siUnsignedInteger;
133 params->base.type = siUnsignedInteger;
134 }
135
136 static void
137 prepare_dh_pub_key_for_asn1(SECKEYPublicKey *pubk)
138 {
139 pubk->u.dh.prime.type = siUnsignedInteger;
140 pubk->u.dh.base.type = siUnsignedInteger;
141 pubk->u.dh.publicValue.type = siUnsignedInteger;
142 }
143
144 /* Create an RSA key pair is any slot able to do so.
145 ** The created keys are "session" (temporary), not "token" (permanent),
146 ** and they are "sensitive", which makes them costly to move to another token.
147 */
148 SECKEYPrivateKey *
149 SECKEY_CreateRSAPrivateKey(int keySizeInBits, SECKEYPublicKey **pubk, void *cx)
150 {
151 SECKEYPrivateKey *privk;
152 PK11RSAGenParams param;
153 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, cx);
154 if (!slot) {
155 return NULL;
156 }
157
158 param.keySizeInBits = keySizeInBits;
159 param.pe = 65537L;
160
161 privk = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &param, pubk,
162 PR_FALSE, PR_TRUE, cx);
163 PK11_FreeSlot(slot);
164 return (privk);
165 }
166
167 /* Create a DH key pair in any slot able to do so,
168 ** This is a "session" (temporary), not "token" (permanent) key.
169 ** Because of the high probability that this key will need to be moved to
170 ** another token, and the high cost of moving "sensitive" keys, we attempt
171 ** to create this key pair without the "sensitive" attribute, but revert to
172 ** creating a "sensitive" key if necessary.
173 */
174 SECKEYPrivateKey *
175 SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *c x)
176 {
177 SECKEYPrivateKey *privk;
178 PK11SlotInfo *slot;
179
180 if (!param || !param->base.data || !param->prime.data ||
181 SECKEY_BigIntegerBitLength(&param->prime) < DH_MIN_P_BITS ||
182 param->base.len == 0 || param->base.len > param->prime.len + 1 ||
183 (param->base.len == 1 && param->base.data[0] == 0)) {
184 PORT_SetError(SEC_ERROR_INVALID_ARGS);
185 return NULL;
186 }
187
188 slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN, cx);
189 if (!slot) {
190 return NULL;
191 }
192
193 privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param,
194 pubk, PR_FALSE, PR_FALSE, cx);
195 if (!privk)
196 privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param,
197 pubk, PR_FALSE, PR_TRUE, cx);
198
199 PK11_FreeSlot(slot);
200 return (privk);
201 }
202
203 /* Create an EC key pair in any slot able to do so,
204 ** This is a "session" (temporary), not "token" (permanent) key.
205 ** Because of the high probability that this key will need to be moved to
206 ** another token, and the high cost of moving "sensitive" keys, we attempt
207 ** to create this key pair without the "sensitive" attribute, but revert to
208 ** creating a "sensitive" key if necessary.
209 */
210 SECKEYPrivateKey *
211 SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *c x)
212 {
213 SECKEYPrivateKey *privk;
214 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_KEY_PAIR_GEN, cx);
215 if (!slot) {
216 return NULL;
217 }
218
219 privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_KEY_PAIR_GEN,
220 param, pubk,
221 PK11_ATTR_SESSION |
222 PK11_ATTR_INSENSITIVE |
223 PK11_ATTR_PUBLIC,
224 CKF_DERIVE, CKF_DERIVE |
225 CKF_SIGN,
226 cx);
227 if (!privk)
228 privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_KEY_PAIR_GEN,
229 param, pubk,
230 PK11_ATTR_SESSION |
231 PK11_ATTR_SENSITIVE |
232 PK11_ATTR_PRIVATE,
233 CKF_DERIVE, CKF_DERIVE |
234 CKF_SIGN,
235 cx);
236
237 PK11_FreeSlot(slot);
238 return (privk);
239 }
240
241 void
242 SECKEY_DestroyPrivateKey(SECKEYPrivateKey *privk)
243 {
244 if (privk) {
245 if (privk->pkcs11Slot) {
246 if (privk->pkcs11IsTemp) {
247 PK11_DestroyObject(privk->pkcs11Slot, privk->pkcs11ID);
248 }
249 PK11_FreeSlot(privk->pkcs11Slot);
250 }
251 if (privk->arena) {
252 PORT_FreeArena(privk->arena, PR_TRUE);
253 }
254 }
255 }
256
257 void
258 SECKEY_DestroyPublicKey(SECKEYPublicKey *pubk)
259 {
260 if (pubk) {
261 if (pubk->pkcs11Slot) {
262 if (!PK11_IsPermObject(pubk->pkcs11Slot, pubk->pkcs11ID)) {
263 PK11_DestroyObject(pubk->pkcs11Slot, pubk->pkcs11ID);
264 }
265 PK11_FreeSlot(pubk->pkcs11Slot);
266 }
267 if (pubk->arena) {
268 PORT_FreeArena(pubk->arena, PR_FALSE);
269 }
270 }
271 }
272
273 SECStatus
274 SECKEY_CopySubjectPublicKeyInfo(PLArenaPool *arena,
275 CERTSubjectPublicKeyInfo *to,
276 CERTSubjectPublicKeyInfo *from)
277 {
278 SECStatus rv;
279 SECItem spk;
280
281 rv = SECOID_CopyAlgorithmID(arena, &to->algorithm, &from->algorithm);
282 if (rv == SECSuccess) {
283 /*
284 * subjectPublicKey is a bit string, whose length is in bits.
285 * Convert the length from bits to bytes for SECITEM_CopyItem.
286 */
287 spk = from->subjectPublicKey;
288 DER_ConvertBitString(&spk);
289 rv = SECITEM_CopyItem(arena, &to->subjectPublicKey, &spk);
290 /* Set the length back to bits. */
291 if (rv == SECSuccess) {
292 to->subjectPublicKey.len = from->subjectPublicKey.len;
293 }
294 }
295
296 return rv;
297 }
298
299 /* Procedure to update the pqg parameters for a cert's public key.
300 * pqg parameters only need to be updated for DSA certificates.
301 * The procedure uses calls to itself recursively to update a certificate
302 * issuer's pqg parameters. Some important rules are:
303 * - Do nothing if the cert already has PQG parameters.
304 * - If the cert does not have PQG parameters, obtain them from the issuer.
305 * - A valid cert chain cannot have a DSA cert without
306 * pqg parameters that has a parent that is not a DSA cert. */
307
308 static SECStatus
309 seckey_UpdateCertPQGChain(CERTCertificate *subjectCert, int count)
310 {
311 SECStatus rv;
312 SECOidData *oid = NULL;
313 int tag;
314 CERTSubjectPublicKeyInfo *subjectSpki = NULL;
315 CERTSubjectPublicKeyInfo *issuerSpki = NULL;
316 CERTCertificate *issuerCert = NULL;
317
318 rv = SECSuccess;
319
320 /* increment cert chain length counter*/
321 count++;
322
323 /* check if cert chain length exceeds the maximum length*/
324 if (count > CERT_MAX_CERT_CHAIN) {
325 return SECFailure;
326 }
327
328 oid = SECOID_FindOID(&subjectCert->subjectPublicKeyInfo.algorithm.algorithm) ;
329 if (oid != NULL) {
330 tag = oid->offset;
331
332 /* Check if cert has a DSA or EC public key. If not, return
333 * success since no PQG params need to be updated.
334 *
335 * Question: do we really need to do this for EC keys. They don't have
336 * PQG parameters, but they do have parameters. The question is does
337 * the child cert inherit thost parameters for EC from the parent, or
338 * do we always include those parameters in each cert.
339 */
340
341 if ((tag != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
342 (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
343 (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST) &&
344 (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST) &&
345 (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
346 (tag != SEC_OID_SDN702_DSA_SIGNATURE) &&
347 (tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) {
348
349 return SECSuccess;
350 }
351 } else {
352 return SECFailure; /* return failure if oid is NULL */
353 }
354
355 /* if cert has PQG parameters, return success */
356
357 subjectSpki = &subjectCert->subjectPublicKeyInfo;
358
359 if (subjectSpki->algorithm.parameters.len != 0) {
360 return SECSuccess;
361 }
362
363 /* check if the cert is self-signed */
364 if (subjectCert->isRoot) {
365 /* fail since cert is self-signed and has no pqg params. */
366 return SECFailure;
367 }
368
369 /* get issuer cert */
370 issuerCert = CERT_FindCertIssuer(subjectCert, PR_Now(), certUsageAnyCA);
371 if (!issuerCert) {
372 return SECFailure;
373 }
374
375 /* if parent is not DSA, return failure since
376 we don't allow this case. */
377
378 oid = SECOID_FindOID(&issuerCert->subjectPublicKeyInfo.algorithm.algorithm);
379 if (oid != NULL) {
380 tag = oid->offset;
381
382 /* Check if issuer cert has a DSA public key. If not,
383 * return failure. */
384
385 if ((tag != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
386 (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
387 (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST) &&
388 (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST) &&
389 (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
390 (tag != SEC_OID_SDN702_DSA_SIGNATURE) &&
391 (tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) {
392 rv = SECFailure;
393 goto loser;
394 }
395 } else {
396 rv = SECFailure; /* return failure if oid is NULL */
397 goto loser;
398 }
399
400 /* at this point the subject cert has no pqg parameters and the
401 * issuer cert has a DSA public key. Update the issuer's
402 * pqg parameters with a recursive call to this same function. */
403
404 rv = seckey_UpdateCertPQGChain(issuerCert, count);
405 if (rv != SECSuccess) {
406 rv = SECFailure;
407 goto loser;
408 }
409
410 /* ensure issuer has pqg parameters */
411
412 issuerSpki = &issuerCert->subjectPublicKeyInfo;
413 if (issuerSpki->algorithm.parameters.len == 0) {
414 rv = SECFailure;
415 }
416
417 /* if update was successful and pqg params present, then copy the
418 * parameters to the subject cert's key. */
419
420 if (rv == SECSuccess) {
421 rv = SECITEM_CopyItem(subjectCert->arena,
422 &subjectSpki->algorithm.parameters,
423 &issuerSpki->algorithm.parameters);
424 }
425
426 loser:
427 if (issuerCert) {
428 CERT_DestroyCertificate(issuerCert);
429 }
430 return rv;
431 }
432
433 SECStatus
434 SECKEY_UpdateCertPQG(CERTCertificate *subjectCert)
435 {
436 if (!subjectCert) {
437 PORT_SetError(SEC_ERROR_INVALID_ARGS);
438 return SECFailure;
439 }
440 return seckey_UpdateCertPQGChain(subjectCert, 0);
441 }
442
443 /* Decode the DSA PQG parameters. The params could be stored in two
444 * possible formats, the old fortezza-only wrapped format or
445 * the normal standard format. Store the decoded parameters in
446 * a V3 certificate data structure. */
447
448 static SECStatus
449 seckey_DSADecodePQG(PLArenaPool *arena, SECKEYPublicKey *pubk,
450 const SECItem *params)
451 {
452 SECStatus rv;
453 SECItem newparams;
454
455 if (params == NULL)
456 return SECFailure;
457
458 if (params->data == NULL)
459 return SECFailure;
460
461 PORT_Assert(arena);
462
463 /* make a copy of the data into the arena so QuickDER output is valid */
464 rv = SECITEM_CopyItem(arena, &newparams, params);
465
466 /* Check if params use the standard format.
467 * The value 0xa1 will appear in the first byte of the parameter data
468 * if the PQG parameters are not using the standard format. This
469 * code should be changed to use a better method to detect non-standard
470 * parameters. */
471
472 if ((newparams.data[0] != 0xa1) &&
473 (newparams.data[0] != 0xa0)) {
474
475 if (SECSuccess == rv) {
476 /* PQG params are in the standard format */
477 prepare_pqg_params_for_asn1(&pubk->u.dsa.params);
478 rv = SEC_QuickDERDecodeItem(arena, &pubk->u.dsa.params,
479 SECKEY_PQGParamsTemplate,
480 &newparams);
481 }
482 } else {
483
484 if (SECSuccess == rv) {
485 /* else the old fortezza-only wrapped format is used. */
486 PORT_SetError(SEC_ERROR_BAD_DER);
487 rv = SECFailure;
488 }
489 }
490 return rv;
491 }
492
493 /* Function used to make an oid tag to a key type */
494 KeyType
495 seckey_GetKeyType(SECOidTag tag)
496 {
497 KeyType keyType;
498
499 switch (tag) {
500 case SEC_OID_X500_RSA_ENCRYPTION:
501 case SEC_OID_PKCS1_RSA_ENCRYPTION:
502 keyType = rsaKey;
503 break;
504 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
505 keyType = rsaPssKey;
506 break;
507 case SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION:
508 keyType = rsaOaepKey;
509 break;
510 case SEC_OID_ANSIX9_DSA_SIGNATURE:
511 keyType = dsaKey;
512 break;
513 case SEC_OID_MISSI_KEA_DSS_OLD:
514 case SEC_OID_MISSI_KEA_DSS:
515 case SEC_OID_MISSI_DSS_OLD:
516 case SEC_OID_MISSI_DSS:
517 keyType = fortezzaKey;
518 break;
519 case SEC_OID_MISSI_KEA:
520 case SEC_OID_MISSI_ALT_KEA:
521 keyType = keaKey;
522 break;
523 case SEC_OID_X942_DIFFIE_HELMAN_KEY:
524 keyType = dhKey;
525 break;
526 case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
527 keyType = ecKey;
528 break;
529 /* accommodate applications that hand us a signature type when they
530 * should be handing us a cipher type */
531 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
532 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
533 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
534 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
535 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
536 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
537 keyType = rsaKey;
538 break;
539 default:
540 keyType = nullKey;
541 }
542 return keyType;
543 }
544
545 /* Function used to determine what kind of cert we are dealing with. */
546 KeyType
547 CERT_GetCertKeyType(const CERTSubjectPublicKeyInfo *spki)
548 {
549 return seckey_GetKeyType(SECOID_GetAlgorithmTag(&spki->algorithm));
550 }
551
552 static SECKEYPublicKey *
553 seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki)
554 {
555 SECKEYPublicKey *pubk;
556 SECItem os, newOs, newParms;
557 SECStatus rv;
558 PLArenaPool *arena;
559 SECOidTag tag;
560
561 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
562 if (arena == NULL)
563 return NULL;
564
565 pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
566 if (pubk == NULL) {
567 PORT_FreeArena(arena, PR_FALSE);
568 return NULL;
569 }
570
571 pubk->arena = arena;
572 pubk->pkcs11Slot = 0;
573 pubk->pkcs11ID = CK_INVALID_HANDLE;
574
575 /* Convert bit string length from bits to bytes */
576 os = spki->subjectPublicKey;
577 DER_ConvertBitString(&os);
578
579 tag = SECOID_GetAlgorithmTag(&spki->algorithm);
580
581 /* copy the DER into the arena, since Quick DER returns data that points
582 into the DER input, which may get freed by the caller */
583 rv = SECITEM_CopyItem(arena, &newOs, &os);
584 if (rv == SECSuccess)
585 switch (tag) {
586 case SEC_OID_X500_RSA_ENCRYPTION:
587 case SEC_OID_PKCS1_RSA_ENCRYPTION:
588 pubk->keyType = rsaKey;
589 prepare_rsa_pub_key_for_asn1(pubk);
590 rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemp late, &newOs);
591 if (rv == SECSuccess)
592 return pubk;
593 break;
594 case SEC_OID_ANSIX9_DSA_SIGNATURE:
595 case SEC_OID_SDN702_DSA_SIGNATURE:
596 pubk->keyType = dsaKey;
597 prepare_dsa_pub_key_for_asn1(pubk);
598 rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemp late, &newOs);
599 if (rv != SECSuccess)
600 break;
601
602 rv = seckey_DSADecodePQG(arena, pubk,
603 &spki->algorithm.parameters);
604
605 if (rv == SECSuccess)
606 return pubk;
607 break;
608 case SEC_OID_X942_DIFFIE_HELMAN_KEY:
609 pubk->keyType = dhKey;
610 prepare_dh_pub_key_for_asn1(pubk);
611 rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHPublicKeyTempl ate, &newOs);
612 if (rv != SECSuccess)
613 break;
614
615 /* copy the DER into the arena, since Quick DER returns data tha t points
616 into the DER input, which may get freed by the caller */
617 rv = SECITEM_CopyItem(arena, &newParms, &spki->algorithm.paramet ers);
618 if (rv != SECSuccess)
619 break;
620
621 rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHParamKeyTempla te,
622 &newParms);
623
624 if (rv == SECSuccess)
625 return pubk;
626 break;
627 case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
628 pubk->keyType = ecKey;
629 pubk->u.ec.size = 0;
630
631 /* Since PKCS#11 directly takes the DER encoding of EC params
632 * and public value, we don't need any decoding here.
633 */
634 rv = SECITEM_CopyItem(arena, &pubk->u.ec.DEREncodedParams,
635 &spki->algorithm.parameters);
636 if (rv != SECSuccess)
637 break;
638 rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &newOs);
639 if (rv == SECSuccess)
640 return pubk;
641 break;
642
643 default:
644 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
645 rv = SECFailure;
646 break;
647 }
648
649 SECKEY_DestroyPublicKey(pubk);
650 return NULL;
651 }
652
653 /* required for JSS */
654 SECKEYPublicKey *
655 SECKEY_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki)
656 {
657 return seckey_ExtractPublicKey(spki);
658 }
659
660 SECKEYPublicKey *
661 CERT_ExtractPublicKey(CERTCertificate *cert)
662 {
663 SECStatus rv;
664
665 if (!cert) {
666 PORT_SetError(SEC_ERROR_INVALID_ARGS);
667 return NULL;
668 }
669 rv = SECKEY_UpdateCertPQG(cert);
670 if (rv != SECSuccess)
671 return NULL;
672
673 return seckey_ExtractPublicKey(&cert->subjectPublicKeyInfo);
674 }
675
676 int
677 SECKEY_ECParamsToKeySize(const SECItem *encodedParams)
678 {
679 SECOidTag tag;
680 SECItem oid = { siBuffer, NULL, 0 };
681
682 /* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID),
683 * followed by the length of the curve oid and the curve oid.
684 */
685 oid.len = encodedParams->data[1];
686 oid.data = encodedParams->data + 2;
687 if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)
688 return 0;
689
690 switch (tag) {
691 case SEC_OID_SECG_EC_SECP112R1:
692 case SEC_OID_SECG_EC_SECP112R2:
693 return 112;
694
695 case SEC_OID_SECG_EC_SECT113R1:
696 case SEC_OID_SECG_EC_SECT113R2:
697 return 113;
698
699 case SEC_OID_SECG_EC_SECP128R1:
700 case SEC_OID_SECG_EC_SECP128R2:
701 return 128;
702
703 case SEC_OID_SECG_EC_SECT131R1:
704 case SEC_OID_SECG_EC_SECT131R2:
705 return 131;
706
707 case SEC_OID_SECG_EC_SECP160K1:
708 case SEC_OID_SECG_EC_SECP160R1:
709 case SEC_OID_SECG_EC_SECP160R2:
710 return 160;
711
712 case SEC_OID_SECG_EC_SECT163K1:
713 case SEC_OID_SECG_EC_SECT163R1:
714 case SEC_OID_SECG_EC_SECT163R2:
715 case SEC_OID_ANSIX962_EC_C2PNB163V1:
716 case SEC_OID_ANSIX962_EC_C2PNB163V2:
717 case SEC_OID_ANSIX962_EC_C2PNB163V3:
718 return 163;
719
720 case SEC_OID_ANSIX962_EC_C2PNB176V1:
721 return 176;
722
723 case SEC_OID_ANSIX962_EC_C2TNB191V1:
724 case SEC_OID_ANSIX962_EC_C2TNB191V2:
725 case SEC_OID_ANSIX962_EC_C2TNB191V3:
726 case SEC_OID_ANSIX962_EC_C2ONB191V4:
727 case SEC_OID_ANSIX962_EC_C2ONB191V5:
728 return 191;
729
730 case SEC_OID_SECG_EC_SECP192K1:
731 case SEC_OID_ANSIX962_EC_PRIME192V1:
732 case SEC_OID_ANSIX962_EC_PRIME192V2:
733 case SEC_OID_ANSIX962_EC_PRIME192V3:
734 return 192;
735
736 case SEC_OID_SECG_EC_SECT193R1:
737 case SEC_OID_SECG_EC_SECT193R2:
738 return 193;
739
740 case SEC_OID_ANSIX962_EC_C2PNB208W1:
741 return 208;
742
743 case SEC_OID_SECG_EC_SECP224K1:
744 case SEC_OID_SECG_EC_SECP224R1:
745 return 224;
746
747 case SEC_OID_SECG_EC_SECT233K1:
748 case SEC_OID_SECG_EC_SECT233R1:
749 return 233;
750
751 case SEC_OID_SECG_EC_SECT239K1:
752 case SEC_OID_ANSIX962_EC_C2TNB239V1:
753 case SEC_OID_ANSIX962_EC_C2TNB239V2:
754 case SEC_OID_ANSIX962_EC_C2TNB239V3:
755 case SEC_OID_ANSIX962_EC_C2ONB239V4:
756 case SEC_OID_ANSIX962_EC_C2ONB239V5:
757 case SEC_OID_ANSIX962_EC_PRIME239V1:
758 case SEC_OID_ANSIX962_EC_PRIME239V2:
759 case SEC_OID_ANSIX962_EC_PRIME239V3:
760 return 239;
761
762 case SEC_OID_SECG_EC_SECP256K1:
763 case SEC_OID_ANSIX962_EC_PRIME256V1:
764 return 256;
765
766 case SEC_OID_ANSIX962_EC_C2PNB272W1:
767 return 272;
768
769 case SEC_OID_SECG_EC_SECT283K1:
770 case SEC_OID_SECG_EC_SECT283R1:
771 return 283;
772
773 case SEC_OID_ANSIX962_EC_C2PNB304W1:
774 return 304;
775
776 case SEC_OID_ANSIX962_EC_C2TNB359V1:
777 return 359;
778
779 case SEC_OID_ANSIX962_EC_C2PNB368W1:
780 return 368;
781
782 case SEC_OID_SECG_EC_SECP384R1:
783 return 384;
784
785 case SEC_OID_SECG_EC_SECT409K1:
786 case SEC_OID_SECG_EC_SECT409R1:
787 return 409;
788
789 case SEC_OID_ANSIX962_EC_C2TNB431R1:
790 return 431;
791
792 case SEC_OID_SECG_EC_SECP521R1:
793 return 521;
794
795 case SEC_OID_SECG_EC_SECT571K1:
796 case SEC_OID_SECG_EC_SECT571R1:
797 return 571;
798
799 default:
800 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
801 return 0;
802 }
803 }
804
805 int
806 SECKEY_ECParamsToBasePointOrderLen(const SECItem *encodedParams)
807 {
808 SECOidTag tag;
809 SECItem oid = { siBuffer, NULL, 0 };
810
811 /* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID),
812 * followed by the length of the curve oid and the curve oid.
813 */
814 oid.len = encodedParams->data[1];
815 oid.data = encodedParams->data + 2;
816 if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)
817 return 0;
818
819 switch (tag) {
820 case SEC_OID_SECG_EC_SECP112R1:
821 return 112;
822 case SEC_OID_SECG_EC_SECP112R2:
823 return 110;
824
825 case SEC_OID_SECG_EC_SECT113R1:
826 case SEC_OID_SECG_EC_SECT113R2:
827 return 113;
828
829 case SEC_OID_SECG_EC_SECP128R1:
830 return 128;
831 case SEC_OID_SECG_EC_SECP128R2:
832 return 126;
833
834 case SEC_OID_SECG_EC_SECT131R1:
835 case SEC_OID_SECG_EC_SECT131R2:
836 return 131;
837
838 case SEC_OID_SECG_EC_SECP160K1:
839 case SEC_OID_SECG_EC_SECP160R1:
840 case SEC_OID_SECG_EC_SECP160R2:
841 return 161;
842
843 case SEC_OID_SECG_EC_SECT163K1:
844 return 163;
845 case SEC_OID_SECG_EC_SECT163R1:
846 return 162;
847 case SEC_OID_SECG_EC_SECT163R2:
848 case SEC_OID_ANSIX962_EC_C2PNB163V1:
849 return 163;
850 case SEC_OID_ANSIX962_EC_C2PNB163V2:
851 case SEC_OID_ANSIX962_EC_C2PNB163V3:
852 return 162;
853
854 case SEC_OID_ANSIX962_EC_C2PNB176V1:
855 return 161;
856
857 case SEC_OID_ANSIX962_EC_C2TNB191V1:
858 return 191;
859 case SEC_OID_ANSIX962_EC_C2TNB191V2:
860 return 190;
861 case SEC_OID_ANSIX962_EC_C2TNB191V3:
862 return 189;
863 case SEC_OID_ANSIX962_EC_C2ONB191V4:
864 return 191;
865 case SEC_OID_ANSIX962_EC_C2ONB191V5:
866 return 188;
867
868 case SEC_OID_SECG_EC_SECP192K1:
869 case SEC_OID_ANSIX962_EC_PRIME192V1:
870 case SEC_OID_ANSIX962_EC_PRIME192V2:
871 case SEC_OID_ANSIX962_EC_PRIME192V3:
872 return 192;
873
874 case SEC_OID_SECG_EC_SECT193R1:
875 case SEC_OID_SECG_EC_SECT193R2:
876 return 193;
877
878 case SEC_OID_ANSIX962_EC_C2PNB208W1:
879 return 193;
880
881 case SEC_OID_SECG_EC_SECP224K1:
882 return 225;
883 case SEC_OID_SECG_EC_SECP224R1:
884 return 224;
885
886 case SEC_OID_SECG_EC_SECT233K1:
887 return 232;
888 case SEC_OID_SECG_EC_SECT233R1:
889 return 233;
890
891 case SEC_OID_SECG_EC_SECT239K1:
892 case SEC_OID_ANSIX962_EC_C2TNB239V1:
893 return 238;
894 case SEC_OID_ANSIX962_EC_C2TNB239V2:
895 return 237;
896 case SEC_OID_ANSIX962_EC_C2TNB239V3:
897 return 236;
898 case SEC_OID_ANSIX962_EC_C2ONB239V4:
899 return 238;
900 case SEC_OID_ANSIX962_EC_C2ONB239V5:
901 return 237;
902 case SEC_OID_ANSIX962_EC_PRIME239V1:
903 case SEC_OID_ANSIX962_EC_PRIME239V2:
904 case SEC_OID_ANSIX962_EC_PRIME239V3:
905 return 239;
906
907 case SEC_OID_SECG_EC_SECP256K1:
908 case SEC_OID_ANSIX962_EC_PRIME256V1:
909 return 256;
910
911 case SEC_OID_ANSIX962_EC_C2PNB272W1:
912 return 257;
913
914 case SEC_OID_SECG_EC_SECT283K1:
915 return 281;
916 case SEC_OID_SECG_EC_SECT283R1:
917 return 282;
918
919 case SEC_OID_ANSIX962_EC_C2PNB304W1:
920 return 289;
921
922 case SEC_OID_ANSIX962_EC_C2TNB359V1:
923 return 353;
924
925 case SEC_OID_ANSIX962_EC_C2PNB368W1:
926 return 353;
927
928 case SEC_OID_SECG_EC_SECP384R1:
929 return 384;
930
931 case SEC_OID_SECG_EC_SECT409K1:
932 return 407;
933 case SEC_OID_SECG_EC_SECT409R1:
934 return 409;
935
936 case SEC_OID_ANSIX962_EC_C2TNB431R1:
937 return 418;
938
939 case SEC_OID_SECG_EC_SECP521R1:
940 return 521;
941
942 case SEC_OID_SECG_EC_SECT571K1:
943 case SEC_OID_SECG_EC_SECT571R1:
944 return 570;
945
946 default:
947 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
948 return 0;
949 }
950 }
951
952 /* The number of bits in the number from the first non-zero bit onward. */
953 unsigned
954 SECKEY_BigIntegerBitLength(const SECItem *number)
955 {
956 const unsigned char *p;
957 unsigned octets;
958 unsigned bits;
959
960 if (!number || !number->data) {
961 PORT_SetError(SEC_ERROR_INVALID_KEY);
962 return 0;
963 }
964
965 p = number->data;
966 octets = number->len;
967 while (octets > 0 && !*p) {
968 ++p;
969 --octets;
970 }
971 if (octets == 0) {
972 return 0;
973 }
974 /* bits = 7..1 because we know at least one bit is set already */
975 /* Note: This could do a binary search, but this is faster for keys if we
976 * assume that good keys will have the MSB set. */
977 for (bits = 7; bits > 0; --bits) {
978 if (*p & (1 << bits)) {
979 break;
980 }
981 }
982 return octets * 8 + bits - 7;
983 }
984
985 /* returns key strength in bytes (not bits) */
986 unsigned
987 SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk)
988 {
989 return (SECKEY_PublicKeyStrengthInBits(pubk) + 7) / 8;
990 }
991
992 /* returns key strength in bits */
993 unsigned
994 SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk)
995 {
996 unsigned bitSize = 0;
997
998 if (!pubk) {
999 PORT_SetError(SEC_ERROR_INVALID_KEY);
1000 return 0;
1001 }
1002
1003 /* interpret modulus length as key strength */
1004 switch (pubk->keyType) {
1005 case rsaKey:
1006 bitSize = SECKEY_BigIntegerBitLength(&pubk->u.rsa.modulus);
1007 break;
1008 case dsaKey:
1009 bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dsa.params.prime);
1010 break;
1011 case dhKey:
1012 bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dh.prime);
1013 break;
1014 case ecKey:
1015 bitSize = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
1016 break;
1017 default:
1018 PORT_SetError(SEC_ERROR_INVALID_KEY);
1019 break;
1020 }
1021 return bitSize;
1022 }
1023
1024 /* returns signature length in bytes (not bits) */
1025 unsigned
1026 SECKEY_SignatureLen(const SECKEYPublicKey *pubk)
1027 {
1028 unsigned char b0;
1029 unsigned size;
1030
1031 switch (pubk->keyType) {
1032 case rsaKey:
1033 b0 = pubk->u.rsa.modulus.data[0];
1034 return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
1035 case dsaKey:
1036 return pubk->u.dsa.params.subPrime.len * 2;
1037 case ecKey:
1038 /* Get the base point order length in bits and adjust */
1039 size = SECKEY_ECParamsToBasePointOrderLen(
1040 &pubk->u.ec.DEREncodedParams);
1041 return ((size + 7) / 8) * 2;
1042 default:
1043 break;
1044 }
1045 PORT_SetError(SEC_ERROR_INVALID_KEY);
1046 return 0;
1047 }
1048
1049 SECKEYPrivateKey *
1050 SECKEY_CopyPrivateKey(const SECKEYPrivateKey *privk)
1051 {
1052 SECKEYPrivateKey *copyk;
1053 PLArenaPool *arena;
1054
1055 if (!privk || !privk->pkcs11Slot) {
1056 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1057 return NULL;
1058 }
1059
1060 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1061 if (arena == NULL) {
1062 return NULL;
1063 }
1064
1065 copyk = (SECKEYPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey) );
1066 if (copyk) {
1067 copyk->arena = arena;
1068 copyk->keyType = privk->keyType;
1069
1070 /* copy the PKCS #11 parameters */
1071 copyk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot);
1072 /* if the key we're referencing was a temparary key we have just
1073 * created, that we want to go away when we're through, we need
1074 * to make a copy of it */
1075 if (privk->pkcs11IsTemp) {
1076 copyk->pkcs11ID =
1077 PK11_CopyKey(privk->pkcs11Slot, privk->pkcs11ID);
1078 if (copyk->pkcs11ID == CK_INVALID_HANDLE)
1079 goto fail;
1080 } else {
1081 copyk->pkcs11ID = privk->pkcs11ID;
1082 }
1083 copyk->pkcs11IsTemp = privk->pkcs11IsTemp;
1084 copyk->wincx = privk->wincx;
1085 copyk->staticflags = privk->staticflags;
1086 return copyk;
1087 } else {
1088 PORT_SetError(SEC_ERROR_NO_MEMORY);
1089 }
1090
1091 fail:
1092 PORT_FreeArena(arena, PR_FALSE);
1093 return NULL;
1094 }
1095
1096 SECKEYPublicKey *
1097 SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk)
1098 {
1099 SECKEYPublicKey *copyk;
1100 PLArenaPool *arena;
1101 SECStatus rv = SECSuccess;
1102
1103 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1104 if (arena == NULL) {
1105 PORT_SetError(SEC_ERROR_NO_MEMORY);
1106 return NULL;
1107 }
1108
1109 copyk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
1110 if (!copyk) {
1111 PORT_FreeArena(arena, PR_FALSE);
1112 PORT_SetError(SEC_ERROR_NO_MEMORY);
1113 return NULL;
1114 }
1115
1116 copyk->arena = arena;
1117 copyk->keyType = pubk->keyType;
1118 if (pubk->pkcs11Slot &&
1119 PK11_IsPermObject(pubk->pkcs11Slot, pubk->pkcs11ID)) {
1120 copyk->pkcs11Slot = PK11_ReferenceSlot(pubk->pkcs11Slot);
1121 copyk->pkcs11ID = pubk->pkcs11ID;
1122 } else {
1123 copyk->pkcs11Slot = NULL; /* go get own reference */
1124 copyk->pkcs11ID = CK_INVALID_HANDLE;
1125 }
1126 switch (pubk->keyType) {
1127 case rsaKey:
1128 rv = SECITEM_CopyItem(arena, &copyk->u.rsa.modulus,
1129 &pubk->u.rsa.modulus);
1130 if (rv == SECSuccess) {
1131 rv = SECITEM_CopyItem(arena, &copyk->u.rsa.publicExponent,
1132 &pubk->u.rsa.publicExponent);
1133 if (rv == SECSuccess)
1134 return copyk;
1135 }
1136 break;
1137 case dsaKey:
1138 rv = SECITEM_CopyItem(arena, &copyk->u.dsa.publicValue,
1139 &pubk->u.dsa.publicValue);
1140 if (rv != SECSuccess)
1141 break;
1142 rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.prime,
1143 &pubk->u.dsa.params.prime);
1144 if (rv != SECSuccess)
1145 break;
1146 rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.subPrime,
1147 &pubk->u.dsa.params.subPrime);
1148 if (rv != SECSuccess)
1149 break;
1150 rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.base,
1151 &pubk->u.dsa.params.base);
1152 break;
1153 case dhKey:
1154 rv = SECITEM_CopyItem(arena, &copyk->u.dh.prime, &pubk->u.dh.prime);
1155 if (rv != SECSuccess)
1156 break;
1157 rv = SECITEM_CopyItem(arena, &copyk->u.dh.base, &pubk->u.dh.base);
1158 if (rv != SECSuccess)
1159 break;
1160 rv = SECITEM_CopyItem(arena, &copyk->u.dh.publicValue,
1161 &pubk->u.dh.publicValue);
1162 break;
1163 case ecKey:
1164 copyk->u.ec.size = pubk->u.ec.size;
1165 rv = SECITEM_CopyItem(arena, &copyk->u.ec.DEREncodedParams,
1166 &pubk->u.ec.DEREncodedParams);
1167 if (rv != SECSuccess)
1168 break;
1169 rv = SECITEM_CopyItem(arena, &copyk->u.ec.publicValue,
1170 &pubk->u.ec.publicValue);
1171 break;
1172 case nullKey:
1173 return copyk;
1174 default:
1175 PORT_SetError(SEC_ERROR_INVALID_KEY);
1176 rv = SECFailure;
1177 break;
1178 }
1179 if (rv == SECSuccess)
1180 return copyk;
1181
1182 SECKEY_DestroyPublicKey(copyk);
1183 return NULL;
1184 }
1185
1186 SECKEYPublicKey *
1187 SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
1188 {
1189 SECKEYPublicKey *pubk;
1190 PLArenaPool *arena;
1191 CERTCertificate *cert;
1192 SECStatus rv;
1193
1194 /*
1195 * First try to look up the cert.
1196 */
1197 cert = PK11_GetCertFromPrivateKey(privk);
1198 if (cert) {
1199 pubk = CERT_ExtractPublicKey(cert);
1200 CERT_DestroyCertificate(cert);
1201 return pubk;
1202 }
1203
1204 /* couldn't find the cert, build pub key by hand */
1205 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1206 if (arena == NULL) {
1207 PORT_SetError(SEC_ERROR_NO_MEMORY);
1208 return NULL;
1209 }
1210 pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena,
1211 sizeof(SECKEYPublicKey));
1212 if (pubk == NULL) {
1213 PORT_FreeArena(arena, PR_FALSE);
1214 return NULL;
1215 }
1216 pubk->keyType = privk->keyType;
1217 pubk->pkcs11Slot = NULL;
1218 pubk->pkcs11ID = CK_INVALID_HANDLE;
1219 pubk->arena = arena;
1220
1221 switch (privk->keyType) {
1222 case nullKey:
1223 case dhKey:
1224 case dsaKey:
1225 /* Nothing to query, if the cert isn't there, we're done -- no way
1226 * to get the public key */
1227 break;
1228 case rsaKey:
1229 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1230 CKA_MODULUS, arena, &pubk->u.rsa.modulus);
1231 if (rv != SECSuccess)
1232 break;
1233 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1234 CKA_PUBLIC_EXPONENT, arena, &pubk->u.rsa.pub licExponent);
1235 if (rv != SECSuccess)
1236 break;
1237 return pubk;
1238 break;
1239 default:
1240 break;
1241 }
1242
1243 PORT_FreeArena(arena, PR_FALSE);
1244 return NULL;
1245 }
1246
1247 static CERTSubjectPublicKeyInfo *
1248 seckey_CreateSubjectPublicKeyInfo_helper(SECKEYPublicKey *pubk)
1249 {
1250 CERTSubjectPublicKeyInfo *spki;
1251 PLArenaPool *arena;
1252 SECItem params = { siBuffer, NULL, 0 };
1253
1254 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1255 if (arena == NULL) {
1256 PORT_SetError(SEC_ERROR_NO_MEMORY);
1257 return NULL;
1258 }
1259
1260 spki = (CERTSubjectPublicKeyInfo *)PORT_ArenaZAlloc(arena, sizeof(*spki));
1261 if (spki != NULL) {
1262 SECStatus rv;
1263 SECItem *rv_item;
1264
1265 spki->arena = arena;
1266 switch (pubk->keyType) {
1267 case rsaKey:
1268 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
1269 SEC_OID_PKCS1_RSA_ENCRYPTION, 0);
1270 if (rv == SECSuccess) {
1271 /*
1272 * DER encode the public key into the subjectPublicKeyInfo.
1273 */
1274 prepare_rsa_pub_key_for_asn1(pubk);
1275 rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
1276 pubk, SECKEY_RSAPublicKeyTempla te);
1277 if (rv_item != NULL) {
1278 /*
1279 * The stored value is supposed to be a BIT_STRING,
1280 * so convert the length.
1281 */
1282 spki->subjectPublicKey.len <<= 3;
1283 /*
1284 * We got a good one; return it.
1285 */
1286 return spki;
1287 }
1288 }
1289 break;
1290 case dsaKey:
1291 /* DER encode the params. */
1292 prepare_pqg_params_for_asn1(&pubk->u.dsa.params);
1293 rv_item = SEC_ASN1EncodeItem(arena, &params, &pubk->u.dsa.params ,
1294 SECKEY_PQGParamsTemplate);
1295 if (rv_item != NULL) {
1296 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
1297 SEC_OID_ANSIX9_DSA_SIGNATURE,
1298 &params);
1299 if (rv == SECSuccess) {
1300 /*
1301 * DER encode the public key into the subjectPublicKeyIn fo.
1302 */
1303 prepare_dsa_pub_key_for_asn1(pubk);
1304 rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublic Key,
1305 pubk,
1306 SECKEY_DSAPublicKeyTemplate );
1307 if (rv_item != NULL) {
1308 /*
1309 * The stored value is supposed to be a BIT_STRING,
1310 * so convert the length.
1311 */
1312 spki->subjectPublicKey.len <<= 3;
1313 /*
1314 * We got a good one; return it.
1315 */
1316 return spki;
1317 }
1318 }
1319 }
1320 SECITEM_FreeItem(&params, PR_FALSE);
1321 break;
1322 case ecKey:
1323 rv = SECITEM_CopyItem(arena, &params,
1324 &pubk->u.ec.DEREncodedParams);
1325 if (rv != SECSuccess)
1326 break;
1327
1328 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
1329 SEC_OID_ANSIX962_EC_PUBLIC_KEY,
1330 &params);
1331 if (rv != SECSuccess)
1332 break;
1333
1334 rv = SECITEM_CopyItem(arena, &spki->subjectPublicKey,
1335 &pubk->u.ec.publicValue);
1336
1337 if (rv == SECSuccess) {
1338 /*
1339 * The stored value is supposed to be a BIT_STRING,
1340 * so convert the length.
1341 */
1342 spki->subjectPublicKey.len <<= 3;
1343 /*
1344 * We got a good one; return it.
1345 */
1346 return spki;
1347 }
1348 break;
1349 case dhKey: /* later... */
1350
1351 break;
1352 default:
1353 break;
1354 }
1355 } else {
1356 PORT_SetError(SEC_ERROR_NO_MEMORY);
1357 }
1358
1359 PORT_FreeArena(arena, PR_FALSE);
1360 return NULL;
1361 }
1362
1363 CERTSubjectPublicKeyInfo *
1364 SECKEY_CreateSubjectPublicKeyInfo(const SECKEYPublicKey *pubk)
1365 {
1366 CERTSubjectPublicKeyInfo *spki;
1367 SECKEYPublicKey *tempKey;
1368
1369 if (!pubk) {
1370 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1371 return NULL;
1372 }
1373
1374 tempKey = SECKEY_CopyPublicKey(pubk);
1375 if (!tempKey) {
1376 return NULL;
1377 }
1378 spki = seckey_CreateSubjectPublicKeyInfo_helper(tempKey);
1379 SECKEY_DestroyPublicKey(tempKey);
1380 return spki;
1381 }
1382
1383 void
1384 SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki)
1385 {
1386 if (spki && spki->arena) {
1387 PORT_FreeArena(spki->arena, PR_FALSE);
1388 }
1389 }
1390
1391 SECItem *
1392 SECKEY_EncodeDERSubjectPublicKeyInfo(const SECKEYPublicKey *pubk)
1393 {
1394 CERTSubjectPublicKeyInfo *spki = NULL;
1395 SECItem *spkiDER = NULL;
1396
1397 /* get the subjectpublickeyinfo */
1398 spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);
1399 if (spki == NULL) {
1400 goto finish;
1401 }
1402
1403 /* DER-encode the subjectpublickeyinfo */
1404 spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL /*dest*/, spki,
1405 CERT_SubjectPublicKeyInfoTemplate);
1406
1407 SECKEY_DestroySubjectPublicKeyInfo(spki);
1408
1409 finish:
1410 return spkiDER;
1411 }
1412
1413 CERTSubjectPublicKeyInfo *
1414 SECKEY_DecodeDERSubjectPublicKeyInfo(const SECItem *spkider)
1415 {
1416 PLArenaPool *arena;
1417 CERTSubjectPublicKeyInfo *spki;
1418 SECStatus rv;
1419 SECItem newSpkider;
1420
1421 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1422 if (arena == NULL) {
1423 PORT_SetError(SEC_ERROR_NO_MEMORY);
1424 return NULL;
1425 }
1426
1427 spki = (CERTSubjectPublicKeyInfo *)
1428 PORT_ArenaZAlloc(arena, sizeof(CERTSubjectPublicKeyInfo));
1429 if (spki != NULL) {
1430 spki->arena = arena;
1431
1432 /* copy the DER into the arena, since Quick DER returns data that points
1433 into the DER input, which may get freed by the caller */
1434 rv = SECITEM_CopyItem(arena, &newSpkider, spkider);
1435 if (rv == SECSuccess) {
1436 rv = SEC_QuickDERDecodeItem(arena, spki,
1437 CERT_SubjectPublicKeyInfoTemplate, &newS pkider);
1438 }
1439 if (rv == SECSuccess)
1440 return spki;
1441 } else {
1442 PORT_SetError(SEC_ERROR_NO_MEMORY);
1443 }
1444
1445 PORT_FreeArena(arena, PR_FALSE);
1446 return NULL;
1447 }
1448
1449 /*
1450 * Decode a base64 ascii encoded DER encoded subject public key info.
1451 */
1452 CERTSubjectPublicKeyInfo *
1453 SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(const char *spkistr)
1454 {
1455 CERTSubjectPublicKeyInfo *spki;
1456 SECStatus rv;
1457 SECItem der;
1458
1459 rv = ATOB_ConvertAsciiToItem(&der, spkistr);
1460 if (rv != SECSuccess)
1461 return NULL;
1462
1463 spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
1464
1465 PORT_Free(der.data);
1466 return spki;
1467 }
1468
1469 /*
1470 * Decode a base64 ascii encoded DER encoded public key and challenge
1471 * Verify digital signature and make sure challenge matches
1472 */
1473 CERTSubjectPublicKeyInfo *
1474 SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,
1475 void *wincx)
1476 {
1477 CERTSubjectPublicKeyInfo *spki = NULL;
1478 CERTPublicKeyAndChallenge pkac;
1479 SECStatus rv;
1480 SECItem signedItem;
1481 PLArenaPool *arena = NULL;
1482 CERTSignedData sd;
1483 SECItem sig;
1484 SECKEYPublicKey *pubKey = NULL;
1485 unsigned int len;
1486
1487 signedItem.data = NULL;
1488
1489 /* convert the base64 encoded data to binary */
1490 rv = ATOB_ConvertAsciiToItem(&signedItem, pkacstr);
1491 if (rv != SECSuccess) {
1492 goto loser;
1493 }
1494
1495 /* create an arena */
1496 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1497 if (arena == NULL) {
1498 goto loser;
1499 }
1500
1501 /* decode the outer wrapping of signed data */
1502 PORT_Memset(&sd, 0, sizeof(CERTSignedData));
1503 rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, &signedItem );
1504 if (rv) {
1505 goto loser;
1506 }
1507
1508 /* decode the public key and challenge wrapper */
1509 PORT_Memset(&pkac, 0, sizeof(CERTPublicKeyAndChallenge));
1510 rv = SEC_QuickDERDecodeItem(arena, &pkac, CERT_PublicKeyAndChallengeTemplate ,
1511 &sd.data);
1512 if (rv) {
1513 goto loser;
1514 }
1515
1516 /* decode the subject public key info */
1517 spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&pkac.spki);
1518 if (spki == NULL) {
1519 goto loser;
1520 }
1521
1522 /* get the public key */
1523 pubKey = seckey_ExtractPublicKey(spki);
1524 if (pubKey == NULL) {
1525 goto loser;
1526 }
1527
1528 /* check the signature */
1529 sig = sd.signature;
1530 DER_ConvertBitString(&sig);
1531 rv = VFY_VerifyDataWithAlgorithmID(sd.data.data, sd.data.len, pubKey, &sig,
1532 &(sd.signatureAlgorithm), NULL, wincx);
1533 if (rv != SECSuccess) {
1534 goto loser;
1535 }
1536
1537 /* check the challenge */
1538 if (challenge) {
1539 len = PORT_Strlen(challenge);
1540 /* length is right */
1541 if (len != pkac.challenge.len) {
1542 goto loser;
1543 }
1544 /* actual data is right */
1545 if (PORT_Memcmp(challenge, pkac.challenge.data, len) != 0) {
1546 goto loser;
1547 }
1548 }
1549 goto done;
1550
1551 loser:
1552 /* make sure that we return null if we got an error */
1553 if (spki) {
1554 SECKEY_DestroySubjectPublicKeyInfo(spki);
1555 }
1556 spki = NULL;
1557
1558 done:
1559 if (signedItem.data) {
1560 PORT_Free(signedItem.data);
1561 }
1562 if (arena) {
1563 PORT_FreeArena(arena, PR_FALSE);
1564 }
1565 if (pubKey) {
1566 SECKEY_DestroyPublicKey(pubKey);
1567 }
1568
1569 return spki;
1570 }
1571
1572 void
1573 SECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo *pvk,
1574 PRBool freeit)
1575 {
1576 PLArenaPool *poolp;
1577
1578 if (pvk != NULL) {
1579 if (pvk->arena) {
1580 poolp = pvk->arena;
1581 /* zero structure since PORT_FreeArena does not support
1582 * this yet.
1583 */
1584 PORT_Memset(pvk->privateKey.data, 0, pvk->privateKey.len);
1585 PORT_Memset(pvk, 0, sizeof(*pvk));
1586 if (freeit == PR_TRUE) {
1587 PORT_FreeArena(poolp, PR_TRUE);
1588 } else {
1589 pvk->arena = poolp;
1590 }
1591 } else {
1592 SECITEM_ZfreeItem(&pvk->version, PR_FALSE);
1593 SECITEM_ZfreeItem(&pvk->privateKey, PR_FALSE);
1594 SECOID_DestroyAlgorithmID(&pvk->algorithm, PR_FALSE);
1595 PORT_Memset(pvk, 0, sizeof(*pvk));
1596 if (freeit == PR_TRUE) {
1597 PORT_Free(pvk);
1598 }
1599 }
1600 }
1601 }
1602
1603 void
1604 SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki,
1605 PRBool freeit)
1606 {
1607 PLArenaPool *poolp;
1608
1609 if (epki != NULL) {
1610 if (epki->arena) {
1611 poolp = epki->arena;
1612 /* zero structure since PORT_FreeArena does not support
1613 * this yet.
1614 */
1615 PORT_Memset(epki->encryptedData.data, 0, epki->encryptedData.len);
1616 PORT_Memset(epki, 0, sizeof(*epki));
1617 if (freeit == PR_TRUE) {
1618 PORT_FreeArena(poolp, PR_TRUE);
1619 } else {
1620 epki->arena = poolp;
1621 }
1622 } else {
1623 SECITEM_ZfreeItem(&epki->encryptedData, PR_FALSE);
1624 SECOID_DestroyAlgorithmID(&epki->algorithm, PR_FALSE);
1625 PORT_Memset(epki, 0, sizeof(*epki));
1626 if (freeit == PR_TRUE) {
1627 PORT_Free(epki);
1628 }
1629 }
1630 }
1631 }
1632
1633 SECStatus
1634 SECKEY_CopyPrivateKeyInfo(PLArenaPool *poolp,
1635 SECKEYPrivateKeyInfo *to,
1636 const SECKEYPrivateKeyInfo *from)
1637 {
1638 SECStatus rv = SECFailure;
1639
1640 if ((to == NULL) || (from == NULL)) {
1641 return SECFailure;
1642 }
1643
1644 rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);
1645 if (rv != SECSuccess) {
1646 return SECFailure;
1647 }
1648 rv = SECITEM_CopyItem(poolp, &to->privateKey, &from->privateKey);
1649 if (rv != SECSuccess) {
1650 return SECFailure;
1651 }
1652 rv = SECITEM_CopyItem(poolp, &to->version, &from->version);
1653
1654 return rv;
1655 }
1656
1657 SECStatus
1658 SECKEY_CopyEncryptedPrivateKeyInfo(PLArenaPool *poolp,
1659 SECKEYEncryptedPrivateKeyInfo *to,
1660 const SECKEYEncryptedPrivateKeyInfo *from)
1661 {
1662 SECStatus rv = SECFailure;
1663
1664 if ((to == NULL) || (from == NULL)) {
1665 return SECFailure;
1666 }
1667
1668 rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);
1669 if (rv != SECSuccess) {
1670 return SECFailure;
1671 }
1672 rv = SECITEM_CopyItem(poolp, &to->encryptedData, &from->encryptedData);
1673
1674 return rv;
1675 }
1676
1677 KeyType
1678 SECKEY_GetPrivateKeyType(const SECKEYPrivateKey *privKey)
1679 {
1680 return privKey->keyType;
1681 }
1682
1683 KeyType
1684 SECKEY_GetPublicKeyType(const SECKEYPublicKey *pubKey)
1685 {
1686 return pubKey->keyType;
1687 }
1688
1689 SECKEYPublicKey *
1690 SECKEY_ImportDERPublicKey(const SECItem *derKey, CK_KEY_TYPE type)
1691 {
1692 SECKEYPublicKey *pubk = NULL;
1693 SECStatus rv = SECFailure;
1694 SECItem newDerKey;
1695 PLArenaPool *arena = NULL;
1696
1697 if (!derKey) {
1698 return NULL;
1699 }
1700
1701 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1702 if (arena == NULL) {
1703 PORT_SetError(SEC_ERROR_NO_MEMORY);
1704 goto finish;
1705 }
1706
1707 pubk = PORT_ArenaZNew(arena, SECKEYPublicKey);
1708 if (pubk == NULL) {
1709 goto finish;
1710 }
1711 pubk->arena = arena;
1712
1713 rv = SECITEM_CopyItem(pubk->arena, &newDerKey, derKey);
1714 if (SECSuccess != rv) {
1715 goto finish;
1716 }
1717
1718 pubk->pkcs11Slot = NULL;
1719 pubk->pkcs11ID = CK_INVALID_HANDLE;
1720
1721 switch (type) {
1722 case CKK_RSA:
1723 prepare_rsa_pub_key_for_asn1(pubk);
1724 rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_RSAPublicKeyTe mplate, &newDerKey);
1725 pubk->keyType = rsaKey;
1726 break;
1727 case CKK_DSA:
1728 prepare_dsa_pub_key_for_asn1(pubk);
1729 rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_DSAPublicKeyTe mplate, &newDerKey);
1730 pubk->keyType = dsaKey;
1731 break;
1732 case CKK_DH:
1733 prepare_dh_pub_key_for_asn1(pubk);
1734 rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_DHPublicKeyTem plate, &newDerKey);
1735 pubk->keyType = dhKey;
1736 break;
1737 default:
1738 rv = SECFailure;
1739 break;
1740 }
1741
1742 finish:
1743 if (rv != SECSuccess) {
1744 if (arena != NULL) {
1745 PORT_FreeArena(arena, PR_FALSE);
1746 }
1747 pubk = NULL;
1748 }
1749 return pubk;
1750 }
1751
1752 SECKEYPrivateKeyList *
1753 SECKEY_NewPrivateKeyList(void)
1754 {
1755 PLArenaPool *arena = NULL;
1756 SECKEYPrivateKeyList *ret = NULL;
1757
1758 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1759 if (arena == NULL) {
1760 goto loser;
1761 }
1762
1763 ret = (SECKEYPrivateKeyList *)PORT_ArenaZAlloc(arena,
1764 sizeof(SECKEYPrivateKeyList)) ;
1765 if (ret == NULL) {
1766 goto loser;
1767 }
1768
1769 ret->arena = arena;
1770
1771 PR_INIT_CLIST(&ret->list);
1772
1773 return (ret);
1774
1775 loser:
1776 if (arena != NULL) {
1777 PORT_FreeArena(arena, PR_FALSE);
1778 }
1779
1780 return (NULL);
1781 }
1782
1783 void
1784 SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys)
1785 {
1786 while (!PR_CLIST_IS_EMPTY(&keys->list)) {
1787 SECKEY_RemovePrivateKeyListNode(
1788 (SECKEYPrivateKeyListNode *)(PR_LIST_HEAD(&keys->list)));
1789 }
1790
1791 PORT_FreeArena(keys->arena, PR_FALSE);
1792
1793 return;
1794 }
1795
1796 void
1797 SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node)
1798 {
1799 PR_ASSERT(node->key);
1800 SECKEY_DestroyPrivateKey(node->key);
1801 node->key = NULL;
1802 PR_REMOVE_LINK(&node->links);
1803 return;
1804 }
1805
1806 SECStatus
1807 SECKEY_AddPrivateKeyToListTail(SECKEYPrivateKeyList *list,
1808 SECKEYPrivateKey *key)
1809 {
1810 SECKEYPrivateKeyListNode *node;
1811
1812 node = (SECKEYPrivateKeyListNode *)PORT_ArenaZAlloc(list->arena,
1813 sizeof(SECKEYPrivateKeyL istNode));
1814 if (node == NULL) {
1815 goto loser;
1816 }
1817
1818 PR_INSERT_BEFORE(&node->links, &list->list);
1819 node->key = key;
1820 return (SECSuccess);
1821
1822 loser:
1823 return (SECFailure);
1824 }
1825
1826 SECKEYPublicKeyList *
1827 SECKEY_NewPublicKeyList(void)
1828 {
1829 PLArenaPool *arena = NULL;
1830 SECKEYPublicKeyList *ret = NULL;
1831
1832 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1833 if (arena == NULL) {
1834 goto loser;
1835 }
1836
1837 ret = (SECKEYPublicKeyList *)PORT_ArenaZAlloc(arena,
1838 sizeof(SECKEYPublicKeyList));
1839 if (ret == NULL) {
1840 goto loser;
1841 }
1842
1843 ret->arena = arena;
1844
1845 PR_INIT_CLIST(&ret->list);
1846
1847 return (ret);
1848
1849 loser:
1850 if (arena != NULL) {
1851 PORT_FreeArena(arena, PR_FALSE);
1852 }
1853
1854 return (NULL);
1855 }
1856
1857 void
1858 SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys)
1859 {
1860 while (!PR_CLIST_IS_EMPTY(&keys->list)) {
1861 SECKEY_RemovePublicKeyListNode(
1862 (SECKEYPublicKeyListNode *)(PR_LIST_HEAD(&keys->list)));
1863 }
1864
1865 PORT_FreeArena(keys->arena, PR_FALSE);
1866
1867 return;
1868 }
1869
1870 void
1871 SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node)
1872 {
1873 PR_ASSERT(node->key);
1874 SECKEY_DestroyPublicKey(node->key);
1875 node->key = NULL;
1876 PR_REMOVE_LINK(&node->links);
1877 return;
1878 }
1879
1880 SECStatus
1881 SECKEY_AddPublicKeyToListTail(SECKEYPublicKeyList *list,
1882 SECKEYPublicKey *key)
1883 {
1884 SECKEYPublicKeyListNode *node;
1885
1886 node = (SECKEYPublicKeyListNode *)PORT_ArenaZAlloc(list->arena,
1887 sizeof(SECKEYPublicKeyLis tNode));
1888 if (node == NULL) {
1889 goto loser;
1890 }
1891
1892 PR_INSERT_BEFORE(&node->links, &list->list);
1893 node->key = key;
1894 return (SECSuccess);
1895
1896 loser:
1897 return (SECFailure);
1898 }
1899
1900 #define SECKEY_CacheAttribute(key, attribute) \
1901 if (CK_TRUE == PK11_HasAttributeSet(key->pkcs11Slot, key->pkcs11ID, attribut e, PR_FALSE)) { \
1902 key->staticflags |= SECKEY_##attribute; \
1903 } else { \
1904 key->staticflags &= (~SECKEY_##attribute); \
1905 }
1906
1907 SECStatus
1908 SECKEY_CacheStaticFlags(SECKEYPrivateKey *key)
1909 {
1910 SECStatus rv = SECFailure;
1911 if (key && key->pkcs11Slot && key->pkcs11ID) {
1912 key->staticflags |= SECKEY_Attributes_Cached;
1913 SECKEY_CacheAttribute(key, CKA_PRIVATE);
1914 SECKEY_CacheAttribute(key, CKA_ALWAYS_AUTHENTICATE);
1915 rv = SECSuccess;
1916 }
1917 return rv;
1918 }
1919
1920 SECOidTag
1921 SECKEY_GetECCOid(const SECKEYECParams *params)
1922 {
1923 SECItem oid = { siBuffer, NULL, 0 };
1924 SECOidData *oidData = NULL;
1925
1926 /*
1927 * params->data needs to contain the ASN encoding of an object ID (OID)
1928 * representing a named curve. Here, we strip away everything
1929 * before the actual OID and use the OID to look up a named curve.
1930 */
1931 if (params->data[0] != SEC_ASN1_OBJECT_ID)
1932 return 0;
1933 oid.len = params->len - 2;
1934 oid.data = params->data + 2;
1935 if ((oidData = SECOID_FindOID(&oid)) == NULL)
1936 return 0;
1937
1938 return oidData->offset;
1939 }
OLDNEW
« no previous file with comments | « nss/lib/cryptohi/sechash.c ('k') | nss/lib/cryptohi/secsign.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698