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