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

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

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

Powered by Google App Engine
This is Rietveld 408576698