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