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 /*
1215 * Use the private key to find a public key handle. The handle will be on
1216 * the same slot as the private key.
1217 */
1218 static CK_OBJECT_HANDLE
seckey_FindPublicKeyHandle(SECKEYPrivateKey * privk,SECKEYPublicKey * pubk)1219 seckey_FindPublicKeyHandle(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk)
1220 {
1221 CK_OBJECT_HANDLE keyID;
1222
1223 /* this helper function is only used below. If we want to make this more
1224 * general, we would need to free up any already cached handles if the
1225 * slot doesn't match up with the private key slot */
1226 PORT_Assert(pubk->pkcs11ID == CK_INVALID_HANDLE);
1227
1228 /* first look for a matching public key */
1229 keyID = PK11_MatchItem(privk->pkcs11Slot, privk->pkcs11ID, CKO_PUBLIC_KEY);
1230 if (keyID != CK_INVALID_HANDLE) {
1231 return keyID;
1232 }
1233
1234 /* none found, create a temp one, make the pubk the owner */
1235 pubk->pkcs11ID = PK11_DerivePubKeyFromPrivKey(privk);
1236 if (pubk->pkcs11ID == CK_INVALID_HANDLE) {
1237 /* end of the road. Token doesn't have matching public key, nor can
1238 * token regenerate a new public key from and existing private key. */
1239 return CK_INVALID_HANDLE;
1240 }
1241 pubk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot);
1242 return pubk->pkcs11ID;
1243 }
1244
1245 SECKEYPublicKey *
SECKEY_ConvertToPublicKey(SECKEYPrivateKey * privk)1246 SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
1247 {
1248 SECKEYPublicKey *pubk;
1249 PLArenaPool *arena;
1250 CERTCertificate *cert;
1251 SECStatus rv;
1252 CK_OBJECT_HANDLE pubKeyHandle;
1253 SECItem decodedPoint;
1254
1255 /*
1256 * First try to look up the cert.
1257 */
1258 cert = PK11_GetCertFromPrivateKey(privk);
1259 if (cert) {
1260 pubk = CERT_ExtractPublicKey(cert);
1261 CERT_DestroyCertificate(cert);
1262 return pubk;
1263 }
1264
1265 /* couldn't find the cert, build pub key by hand */
1266 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1267 if (arena == NULL) {
1268 PORT_SetError(SEC_ERROR_NO_MEMORY);
1269 return NULL;
1270 }
1271 pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena,
1272 sizeof(SECKEYPublicKey));
1273 if (pubk == NULL) {
1274 PORT_FreeArena(arena, PR_FALSE);
1275 return NULL;
1276 }
1277 pubk->keyType = privk->keyType;
1278 pubk->pkcs11Slot = NULL;
1279 pubk->pkcs11ID = CK_INVALID_HANDLE;
1280 pubk->arena = arena;
1281
1282 switch (privk->keyType) {
1283 case nullKey:
1284 /* Nothing to query, if the cert isn't there, we're done -- no way
1285 * to get the public key */
1286 break;
1287 case dsaKey:
1288 pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
1289 if (pubKeyHandle == CK_INVALID_HANDLE)
1290 break;
1291 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1292 CKA_BASE, arena, &pubk->u.dsa.params.base);
1293 if (rv != SECSuccess)
1294 break;
1295 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1296 CKA_PRIME, arena, &pubk->u.dsa.params.prime);
1297 if (rv != SECSuccess)
1298 break;
1299 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1300 CKA_SUBPRIME, arena, &pubk->u.dsa.params.subPrime);
1301 if (rv != SECSuccess)
1302 break;
1303 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1304 CKA_VALUE, arena, &pubk->u.dsa.publicValue);
1305 if (rv != SECSuccess)
1306 break;
1307 return pubk;
1308 case dhKey:
1309 pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
1310 if (pubKeyHandle == CK_INVALID_HANDLE)
1311 break;
1312 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1313 CKA_BASE, arena, &pubk->u.dh.base);
1314 if (rv != SECSuccess)
1315 break;
1316 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1317 CKA_PRIME, arena, &pubk->u.dh.prime);
1318 if (rv != SECSuccess)
1319 break;
1320 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1321 CKA_VALUE, arena, &pubk->u.dh.publicValue);
1322 if (rv != SECSuccess)
1323 break;
1324 return pubk;
1325 case rsaKey:
1326 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1327 CKA_MODULUS, arena, &pubk->u.rsa.modulus);
1328 if (rv != SECSuccess)
1329 break;
1330 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1331 CKA_PUBLIC_EXPONENT, arena, &pubk->u.rsa.publicExponent);
1332 if (rv != SECSuccess)
1333 break;
1334 return pubk;
1335 case ecKey:
1336 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1337 CKA_EC_PARAMS, arena, &pubk->u.ec.DEREncodedParams);
1338 if (rv != SECSuccess) {
1339 break;
1340 }
1341 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1342 CKA_EC_POINT, arena, &pubk->u.ec.publicValue);
1343 if (rv != SECSuccess || pubk->u.ec.publicValue.len == 0) {
1344 pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
1345 if (pubKeyHandle == CK_INVALID_HANDLE)
1346 break;
1347 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1348 CKA_EC_POINT, arena, &pubk->u.ec.publicValue);
1349 if (rv != SECSuccess)
1350 break;
1351 }
1352 /* ec.publicValue should be decoded, PKCS #11 defines CKA_EC_POINT
1353 * as encoded, but it's not always. try do decoded it and if it
1354 * succeeds store the decoded value */
1355 rv = SEC_QuickDERDecodeItem(arena, &decodedPoint,
1356 SEC_ASN1_GET(SEC_OctetStringTemplate), &pubk->u.ec.publicValue);
1357 if (rv == SECSuccess) {
1358 /* both values are in the public key arena, so it's safe to
1359 * overwrite the old value */
1360 pubk->u.ec.publicValue = decodedPoint;
1361 }
1362 pubk->u.ec.encoding = ECPoint_Undefined;
1363 return pubk;
1364 default:
1365 break;
1366 }
1367
1368 /* must use Destroy public key here, because some paths create temporary
1369 * PKCS #11 objects which need to be freed */
1370 SECKEY_DestroyPublicKey(pubk);
1371 return NULL;
1372 }
1373
1374 static CERTSubjectPublicKeyInfo *
seckey_CreateSubjectPublicKeyInfo_helper(SECKEYPublicKey * pubk)1375 seckey_CreateSubjectPublicKeyInfo_helper(SECKEYPublicKey *pubk)
1376 {
1377 CERTSubjectPublicKeyInfo *spki;
1378 PLArenaPool *arena;
1379 SECItem params = { siBuffer, NULL, 0 };
1380
1381 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1382 if (arena == NULL) {
1383 PORT_SetError(SEC_ERROR_NO_MEMORY);
1384 return NULL;
1385 }
1386
1387 spki = (CERTSubjectPublicKeyInfo *)PORT_ArenaZAlloc(arena, sizeof(*spki));
1388 if (spki != NULL) {
1389 SECStatus rv;
1390 SECItem *rv_item;
1391
1392 spki->arena = arena;
1393 switch (pubk->keyType) {
1394 case rsaKey:
1395 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
1396 SEC_OID_PKCS1_RSA_ENCRYPTION, 0);
1397 if (rv == SECSuccess) {
1398 /*
1399 * DER encode the public key into the subjectPublicKeyInfo.
1400 */
1401 prepare_rsa_pub_key_for_asn1(pubk);
1402 rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
1403 pubk, SECKEY_RSAPublicKeyTemplate);
1404 if (rv_item != NULL) {
1405 /*
1406 * The stored value is supposed to be a BIT_STRING,
1407 * so convert the length.
1408 */
1409 spki->subjectPublicKey.len <<= 3;
1410 /*
1411 * We got a good one; return it.
1412 */
1413 return spki;
1414 }
1415 }
1416 break;
1417 case dsaKey:
1418 /* DER encode the params. */
1419 prepare_pqg_params_for_asn1(&pubk->u.dsa.params);
1420 rv_item = SEC_ASN1EncodeItem(arena, ¶ms, &pubk->u.dsa.params,
1421 SECKEY_PQGParamsTemplate);
1422 if (rv_item != NULL) {
1423 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
1424 SEC_OID_ANSIX9_DSA_SIGNATURE,
1425 ¶ms);
1426 if (rv == SECSuccess) {
1427 /*
1428 * DER encode the public key into the subjectPublicKeyInfo.
1429 */
1430 prepare_dsa_pub_key_for_asn1(pubk);
1431 rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
1432 pubk,
1433 SECKEY_DSAPublicKeyTemplate);
1434 if (rv_item != NULL) {
1435 /*
1436 * The stored value is supposed to be a BIT_STRING,
1437 * so convert the length.
1438 */
1439 spki->subjectPublicKey.len <<= 3;
1440 /*
1441 * We got a good one; return it.
1442 */
1443 return spki;
1444 }
1445 }
1446 }
1447 SECITEM_FreeItem(¶ms, PR_FALSE);
1448 break;
1449 case ecKey:
1450 rv = SECITEM_CopyItem(arena, ¶ms,
1451 &pubk->u.ec.DEREncodedParams);
1452 if (rv != SECSuccess)
1453 break;
1454
1455 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
1456 SEC_OID_ANSIX962_EC_PUBLIC_KEY,
1457 ¶ms);
1458 if (rv != SECSuccess)
1459 break;
1460
1461 rv = SECITEM_CopyItem(arena, &spki->subjectPublicKey,
1462 &pubk->u.ec.publicValue);
1463
1464 if (rv == SECSuccess) {
1465 /*
1466 * The stored value is supposed to be a BIT_STRING,
1467 * so convert the length.
1468 */
1469 spki->subjectPublicKey.len <<= 3;
1470 /*
1471 * We got a good one; return it.
1472 */
1473 return spki;
1474 }
1475 break;
1476 case dhKey: /* later... */
1477
1478 break;
1479 default:
1480 break;
1481 }
1482 } else {
1483 PORT_SetError(SEC_ERROR_NO_MEMORY);
1484 }
1485
1486 PORT_FreeArena(arena, PR_FALSE);
1487 return NULL;
1488 }
1489
1490 CERTSubjectPublicKeyInfo *
SECKEY_CreateSubjectPublicKeyInfo(const SECKEYPublicKey * pubk)1491 SECKEY_CreateSubjectPublicKeyInfo(const SECKEYPublicKey *pubk)
1492 {
1493 CERTSubjectPublicKeyInfo *spki;
1494 SECKEYPublicKey *tempKey;
1495
1496 if (!pubk) {
1497 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1498 return NULL;
1499 }
1500
1501 tempKey = SECKEY_CopyPublicKey(pubk);
1502 if (!tempKey) {
1503 return NULL;
1504 }
1505 spki = seckey_CreateSubjectPublicKeyInfo_helper(tempKey);
1506 SECKEY_DestroyPublicKey(tempKey);
1507 return spki;
1508 }
1509
1510 void
SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo * spki)1511 SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki)
1512 {
1513 if (spki && spki->arena) {
1514 PORT_FreeArena(spki->arena, PR_FALSE);
1515 }
1516 }
1517
1518 SECItem *
SECKEY_EncodeDERSubjectPublicKeyInfo(const SECKEYPublicKey * pubk)1519 SECKEY_EncodeDERSubjectPublicKeyInfo(const SECKEYPublicKey *pubk)
1520 {
1521 CERTSubjectPublicKeyInfo *spki = NULL;
1522 SECItem *spkiDER = NULL;
1523
1524 /* get the subjectpublickeyinfo */
1525 spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);
1526 if (spki == NULL) {
1527 goto finish;
1528 }
1529
1530 /* DER-encode the subjectpublickeyinfo */
1531 spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL /*dest*/, spki,
1532 CERT_SubjectPublicKeyInfoTemplate);
1533
1534 SECKEY_DestroySubjectPublicKeyInfo(spki);
1535
1536 finish:
1537 return spkiDER;
1538 }
1539
1540 CERTSubjectPublicKeyInfo *
SECKEY_DecodeDERSubjectPublicKeyInfo(const SECItem * spkider)1541 SECKEY_DecodeDERSubjectPublicKeyInfo(const SECItem *spkider)
1542 {
1543 PLArenaPool *arena;
1544 CERTSubjectPublicKeyInfo *spki;
1545 SECStatus rv;
1546 SECItem newSpkider;
1547
1548 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1549 if (arena == NULL) {
1550 PORT_SetError(SEC_ERROR_NO_MEMORY);
1551 return NULL;
1552 }
1553
1554 spki = (CERTSubjectPublicKeyInfo *)
1555 PORT_ArenaZAlloc(arena, sizeof(CERTSubjectPublicKeyInfo));
1556 if (spki != NULL) {
1557 spki->arena = arena;
1558
1559 /* copy the DER into the arena, since Quick DER returns data that points
1560 into the DER input, which may get freed by the caller */
1561 rv = SECITEM_CopyItem(arena, &newSpkider, spkider);
1562 if (rv == SECSuccess) {
1563 rv = SEC_QuickDERDecodeItem(arena, spki,
1564 CERT_SubjectPublicKeyInfoTemplate, &newSpkider);
1565 }
1566 if (rv == SECSuccess)
1567 return spki;
1568 } else {
1569 PORT_SetError(SEC_ERROR_NO_MEMORY);
1570 }
1571
1572 PORT_FreeArena(arena, PR_FALSE);
1573 return NULL;
1574 }
1575
1576 /*
1577 * Decode a base64 ascii encoded DER encoded subject public key info.
1578 */
1579 CERTSubjectPublicKeyInfo *
SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(const char * spkistr)1580 SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(const char *spkistr)
1581 {
1582 CERTSubjectPublicKeyInfo *spki;
1583 SECStatus rv;
1584 SECItem der;
1585
1586 rv = ATOB_ConvertAsciiToItem(&der, spkistr);
1587 if (rv != SECSuccess)
1588 return NULL;
1589
1590 spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
1591
1592 PORT_Free(der.data);
1593 return spki;
1594 }
1595
1596 /*
1597 * Decode a base64 ascii encoded DER encoded public key and challenge
1598 * Verify digital signature and make sure challenge matches
1599 */
1600 CERTSubjectPublicKeyInfo *
SECKEY_ConvertAndDecodePublicKeyAndChallenge(char * pkacstr,char * challenge,void * wincx)1601 SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,
1602 void *wincx)
1603 {
1604 CERTSubjectPublicKeyInfo *spki = NULL;
1605 CERTPublicKeyAndChallenge pkac;
1606 SECStatus rv;
1607 SECItem signedItem;
1608 PLArenaPool *arena = NULL;
1609 CERTSignedData sd;
1610 SECItem sig;
1611 SECKEYPublicKey *pubKey = NULL;
1612 unsigned int len;
1613
1614 signedItem.data = NULL;
1615
1616 /* convert the base64 encoded data to binary */
1617 rv = ATOB_ConvertAsciiToItem(&signedItem, pkacstr);
1618 if (rv != SECSuccess) {
1619 goto loser;
1620 }
1621
1622 /* create an arena */
1623 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1624 if (arena == NULL) {
1625 goto loser;
1626 }
1627
1628 /* decode the outer wrapping of signed data */
1629 PORT_Memset(&sd, 0, sizeof(CERTSignedData));
1630 rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, &signedItem);
1631 if (rv) {
1632 goto loser;
1633 }
1634
1635 /* decode the public key and challenge wrapper */
1636 PORT_Memset(&pkac, 0, sizeof(CERTPublicKeyAndChallenge));
1637 rv = SEC_QuickDERDecodeItem(arena, &pkac, CERT_PublicKeyAndChallengeTemplate,
1638 &sd.data);
1639 if (rv) {
1640 goto loser;
1641 }
1642
1643 /* decode the subject public key info */
1644 spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&pkac.spki);
1645 if (spki == NULL) {
1646 goto loser;
1647 }
1648
1649 /* get the public key */
1650 pubKey = seckey_ExtractPublicKey(spki);
1651 if (pubKey == NULL) {
1652 goto loser;
1653 }
1654
1655 /* check the signature */
1656 sig = sd.signature;
1657 DER_ConvertBitString(&sig);
1658 rv = VFY_VerifyDataWithAlgorithmID(sd.data.data, sd.data.len, pubKey, &sig,
1659 &(sd.signatureAlgorithm), NULL, wincx);
1660 if (rv != SECSuccess) {
1661 goto loser;
1662 }
1663
1664 /* check the challenge */
1665 if (challenge) {
1666 len = PORT_Strlen(challenge);
1667 /* length is right */
1668 if (len != pkac.challenge.len) {
1669 goto loser;
1670 }
1671 /* actual data is right */
1672 if (PORT_Memcmp(challenge, pkac.challenge.data, len) != 0) {
1673 goto loser;
1674 }
1675 }
1676 goto done;
1677
1678 loser:
1679 /* make sure that we return null if we got an error */
1680 if (spki) {
1681 SECKEY_DestroySubjectPublicKeyInfo(spki);
1682 }
1683 spki = NULL;
1684
1685 done:
1686 if (signedItem.data) {
1687 PORT_Free(signedItem.data);
1688 }
1689 if (arena) {
1690 PORT_FreeArena(arena, PR_FALSE);
1691 }
1692 if (pubKey) {
1693 SECKEY_DestroyPublicKey(pubKey);
1694 }
1695
1696 return spki;
1697 }
1698
1699 void
SECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo * pvk,PRBool freeit)1700 SECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo *pvk,
1701 PRBool freeit)
1702 {
1703 PLArenaPool *poolp;
1704
1705 if (pvk != NULL) {
1706 if (pvk->arena) {
1707 poolp = pvk->arena;
1708 /* zero structure since PORT_FreeArena does not support
1709 * this yet.
1710 */
1711 PORT_Memset(pvk->privateKey.data, 0, pvk->privateKey.len);
1712 PORT_Memset(pvk, 0, sizeof(*pvk));
1713 if (freeit == PR_TRUE) {
1714 PORT_FreeArena(poolp, PR_TRUE);
1715 } else {
1716 pvk->arena = poolp;
1717 }
1718 } else {
1719 SECITEM_ZfreeItem(&pvk->version, PR_FALSE);
1720 SECITEM_ZfreeItem(&pvk->privateKey, PR_FALSE);
1721 SECOID_DestroyAlgorithmID(&pvk->algorithm, PR_FALSE);
1722 PORT_Memset(pvk, 0, sizeof(*pvk));
1723 if (freeit == PR_TRUE) {
1724 PORT_Free(pvk);
1725 }
1726 }
1727 }
1728 }
1729
1730 void
SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo * epki,PRBool freeit)1731 SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki,
1732 PRBool freeit)
1733 {
1734 PLArenaPool *poolp;
1735
1736 if (epki != NULL) {
1737 if (epki->arena) {
1738 poolp = epki->arena;
1739 /* zero structure since PORT_FreeArena does not support
1740 * this yet.
1741 */
1742 PORT_Memset(epki->encryptedData.data, 0, epki->encryptedData.len);
1743 PORT_Memset(epki, 0, sizeof(*epki));
1744 if (freeit == PR_TRUE) {
1745 PORT_FreeArena(poolp, PR_TRUE);
1746 } else {
1747 epki->arena = poolp;
1748 }
1749 } else {
1750 SECITEM_ZfreeItem(&epki->encryptedData, PR_FALSE);
1751 SECOID_DestroyAlgorithmID(&epki->algorithm, PR_FALSE);
1752 PORT_Memset(epki, 0, sizeof(*epki));
1753 if (freeit == PR_TRUE) {
1754 PORT_Free(epki);
1755 }
1756 }
1757 }
1758 }
1759
1760 SECStatus
SECKEY_CopyPrivateKeyInfo(PLArenaPool * poolp,SECKEYPrivateKeyInfo * to,const SECKEYPrivateKeyInfo * from)1761 SECKEY_CopyPrivateKeyInfo(PLArenaPool *poolp,
1762 SECKEYPrivateKeyInfo *to,
1763 const SECKEYPrivateKeyInfo *from)
1764 {
1765 SECStatus rv = SECFailure;
1766
1767 if ((to == NULL) || (from == NULL)) {
1768 return SECFailure;
1769 }
1770
1771 rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);
1772 if (rv != SECSuccess) {
1773 return SECFailure;
1774 }
1775 rv = SECITEM_CopyItem(poolp, &to->privateKey, &from->privateKey);
1776 if (rv != SECSuccess) {
1777 return SECFailure;
1778 }
1779 rv = SECITEM_CopyItem(poolp, &to->version, &from->version);
1780
1781 return rv;
1782 }
1783
1784 SECStatus
SECKEY_CopyEncryptedPrivateKeyInfo(PLArenaPool * poolp,SECKEYEncryptedPrivateKeyInfo * to,const SECKEYEncryptedPrivateKeyInfo * from)1785 SECKEY_CopyEncryptedPrivateKeyInfo(PLArenaPool *poolp,
1786 SECKEYEncryptedPrivateKeyInfo *to,
1787 const SECKEYEncryptedPrivateKeyInfo *from)
1788 {
1789 SECStatus rv = SECFailure;
1790
1791 if ((to == NULL) || (from == NULL)) {
1792 return SECFailure;
1793 }
1794
1795 rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);
1796 if (rv != SECSuccess) {
1797 return SECFailure;
1798 }
1799 rv = SECITEM_CopyItem(poolp, &to->encryptedData, &from->encryptedData);
1800
1801 return rv;
1802 }
1803
1804 KeyType
SECKEY_GetPrivateKeyType(const SECKEYPrivateKey * privKey)1805 SECKEY_GetPrivateKeyType(const SECKEYPrivateKey *privKey)
1806 {
1807 return privKey->keyType;
1808 }
1809
1810 KeyType
SECKEY_GetPublicKeyType(const SECKEYPublicKey * pubKey)1811 SECKEY_GetPublicKeyType(const SECKEYPublicKey *pubKey)
1812 {
1813 return pubKey->keyType;
1814 }
1815
1816 SECKEYPublicKey *
SECKEY_ImportDERPublicKey(const SECItem * derKey,CK_KEY_TYPE type)1817 SECKEY_ImportDERPublicKey(const SECItem *derKey, CK_KEY_TYPE type)
1818 {
1819 SECKEYPublicKey *pubk = NULL;
1820 SECStatus rv = SECFailure;
1821 SECItem newDerKey;
1822 PLArenaPool *arena = NULL;
1823
1824 if (!derKey) {
1825 return NULL;
1826 }
1827
1828 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1829 if (arena == NULL) {
1830 PORT_SetError(SEC_ERROR_NO_MEMORY);
1831 goto finish;
1832 }
1833
1834 pubk = PORT_ArenaZNew(arena, SECKEYPublicKey);
1835 if (pubk == NULL) {
1836 goto finish;
1837 }
1838 pubk->arena = arena;
1839
1840 rv = SECITEM_CopyItem(pubk->arena, &newDerKey, derKey);
1841 if (SECSuccess != rv) {
1842 goto finish;
1843 }
1844
1845 pubk->pkcs11Slot = NULL;
1846 pubk->pkcs11ID = CK_INVALID_HANDLE;
1847
1848 switch (type) {
1849 case CKK_RSA:
1850 prepare_rsa_pub_key_for_asn1(pubk);
1851 rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_RSAPublicKeyTemplate, &newDerKey);
1852 pubk->keyType = rsaKey;
1853 break;
1854 case CKK_DSA:
1855 prepare_dsa_pub_key_for_asn1(pubk);
1856 rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_DSAPublicKeyTemplate, &newDerKey);
1857 pubk->keyType = dsaKey;
1858 break;
1859 case CKK_DH:
1860 prepare_dh_pub_key_for_asn1(pubk);
1861 rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_DHPublicKeyTemplate, &newDerKey);
1862 pubk->keyType = dhKey;
1863 break;
1864 default:
1865 rv = SECFailure;
1866 break;
1867 }
1868
1869 finish:
1870 if (rv != SECSuccess) {
1871 if (arena != NULL) {
1872 PORT_FreeArena(arena, PR_FALSE);
1873 }
1874 pubk = NULL;
1875 }
1876 return pubk;
1877 }
1878
1879 SECKEYPrivateKeyList *
SECKEY_NewPrivateKeyList(void)1880 SECKEY_NewPrivateKeyList(void)
1881 {
1882 PLArenaPool *arena = NULL;
1883 SECKEYPrivateKeyList *ret = NULL;
1884
1885 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1886 if (arena == NULL) {
1887 goto loser;
1888 }
1889
1890 ret = (SECKEYPrivateKeyList *)PORT_ArenaZAlloc(arena,
1891 sizeof(SECKEYPrivateKeyList));
1892 if (ret == NULL) {
1893 goto loser;
1894 }
1895
1896 ret->arena = arena;
1897
1898 PR_INIT_CLIST(&ret->list);
1899
1900 return (ret);
1901
1902 loser:
1903 if (arena != NULL) {
1904 PORT_FreeArena(arena, PR_FALSE);
1905 }
1906
1907 return (NULL);
1908 }
1909
1910 void
SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList * keys)1911 SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys)
1912 {
1913 while (!PR_CLIST_IS_EMPTY(&keys->list)) {
1914 SECKEY_RemovePrivateKeyListNode(
1915 (SECKEYPrivateKeyListNode *)(PR_LIST_HEAD(&keys->list)));
1916 }
1917
1918 PORT_FreeArena(keys->arena, PR_FALSE);
1919
1920 return;
1921 }
1922
1923 void
SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode * node)1924 SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node)
1925 {
1926 PR_ASSERT(node->key);
1927 SECKEY_DestroyPrivateKey(node->key);
1928 node->key = NULL;
1929 PR_REMOVE_LINK(&node->links);
1930 return;
1931 }
1932
1933 SECStatus
SECKEY_AddPrivateKeyToListTail(SECKEYPrivateKeyList * list,SECKEYPrivateKey * key)1934 SECKEY_AddPrivateKeyToListTail(SECKEYPrivateKeyList *list,
1935 SECKEYPrivateKey *key)
1936 {
1937 SECKEYPrivateKeyListNode *node;
1938
1939 node = (SECKEYPrivateKeyListNode *)PORT_ArenaZAlloc(list->arena,
1940 sizeof(SECKEYPrivateKeyListNode));
1941 if (node == NULL) {
1942 goto loser;
1943 }
1944
1945 PR_INSERT_BEFORE(&node->links, &list->list);
1946 node->key = key;
1947 return (SECSuccess);
1948
1949 loser:
1950 return (SECFailure);
1951 }
1952
1953 SECKEYPublicKeyList *
SECKEY_NewPublicKeyList(void)1954 SECKEY_NewPublicKeyList(void)
1955 {
1956 PLArenaPool *arena = NULL;
1957 SECKEYPublicKeyList *ret = NULL;
1958
1959 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1960 if (arena == NULL) {
1961 goto loser;
1962 }
1963
1964 ret = (SECKEYPublicKeyList *)PORT_ArenaZAlloc(arena,
1965 sizeof(SECKEYPublicKeyList));
1966 if (ret == NULL) {
1967 goto loser;
1968 }
1969
1970 ret->arena = arena;
1971
1972 PR_INIT_CLIST(&ret->list);
1973
1974 return (ret);
1975
1976 loser:
1977 if (arena != NULL) {
1978 PORT_FreeArena(arena, PR_FALSE);
1979 }
1980
1981 return (NULL);
1982 }
1983
1984 void
SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList * keys)1985 SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys)
1986 {
1987 while (!PR_CLIST_IS_EMPTY(&keys->list)) {
1988 SECKEY_RemovePublicKeyListNode(
1989 (SECKEYPublicKeyListNode *)(PR_LIST_HEAD(&keys->list)));
1990 }
1991
1992 PORT_FreeArena(keys->arena, PR_FALSE);
1993
1994 return;
1995 }
1996
1997 void
SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode * node)1998 SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node)
1999 {
2000 PR_ASSERT(node->key);
2001 SECKEY_DestroyPublicKey(node->key);
2002 node->key = NULL;
2003 PR_REMOVE_LINK(&node->links);
2004 return;
2005 }
2006
2007 SECStatus
SECKEY_AddPublicKeyToListTail(SECKEYPublicKeyList * list,SECKEYPublicKey * key)2008 SECKEY_AddPublicKeyToListTail(SECKEYPublicKeyList *list,
2009 SECKEYPublicKey *key)
2010 {
2011 SECKEYPublicKeyListNode *node;
2012
2013 node = (SECKEYPublicKeyListNode *)PORT_ArenaZAlloc(list->arena,
2014 sizeof(SECKEYPublicKeyListNode));
2015 if (node == NULL) {
2016 goto loser;
2017 }
2018
2019 PR_INSERT_BEFORE(&node->links, &list->list);
2020 node->key = key;
2021 return (SECSuccess);
2022
2023 loser:
2024 return (SECFailure);
2025 }
2026
2027 #define SECKEY_CacheAttribute(key, attribute) \
2028 if (CK_TRUE == PK11_HasAttributeSet(key->pkcs11Slot, key->pkcs11ID, attribute, PR_FALSE)) { \
2029 key->staticflags |= SECKEY_##attribute; \
2030 } else { \
2031 key->staticflags &= (~SECKEY_##attribute); \
2032 }
2033
2034 SECStatus
SECKEY_CacheStaticFlags(SECKEYPrivateKey * key)2035 SECKEY_CacheStaticFlags(SECKEYPrivateKey *key)
2036 {
2037 SECStatus rv = SECFailure;
2038 if (key && key->pkcs11Slot && key->pkcs11ID) {
2039 key->staticflags |= SECKEY_Attributes_Cached;
2040 SECKEY_CacheAttribute(key, CKA_PRIVATE);
2041 SECKEY_CacheAttribute(key, CKA_ALWAYS_AUTHENTICATE);
2042 rv = SECSuccess;
2043 }
2044 return rv;
2045 }
2046
2047 SECOidTag
SECKEY_GetECCOid(const SECKEYECParams * params)2048 SECKEY_GetECCOid(const SECKEYECParams *params)
2049 {
2050 SECItem oid = { siBuffer, NULL, 0 };
2051 SECOidData *oidData = NULL;
2052
2053 /*
2054 * params->data needs to contain the ASN encoding of an object ID (OID)
2055 * representing a named curve. Here, we strip away everything
2056 * before the actual OID and use the OID to look up a named curve.
2057 */
2058 if (params->data[0] != SEC_ASN1_OBJECT_ID)
2059 return 0;
2060 oid.len = params->len - 2;
2061 oid.data = params->data + 2;
2062 if ((oidData = SECOID_FindOID(&oid)) == NULL)
2063 return 0;
2064
2065 return oidData->offset;
2066 }
2067
2068 static CK_MECHANISM_TYPE
sec_GetHashMechanismByOidTag(SECOidTag tag)2069 sec_GetHashMechanismByOidTag(SECOidTag tag)
2070 {
2071 switch (tag) {
2072 case SEC_OID_SHA512:
2073 return CKM_SHA512;
2074 case SEC_OID_SHA384:
2075 return CKM_SHA384;
2076 case SEC_OID_SHA256:
2077 return CKM_SHA256;
2078 case SEC_OID_SHA224:
2079 return CKM_SHA224;
2080 case SEC_OID_SHA1:
2081 return CKM_SHA_1;
2082 default:
2083 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
2084 return CKM_INVALID_MECHANISM;
2085 }
2086 }
2087
2088 static CK_RSA_PKCS_MGF_TYPE
sec_GetMgfTypeByOidTag(SECOidTag tag)2089 sec_GetMgfTypeByOidTag(SECOidTag tag)
2090 {
2091 switch (tag) {
2092 case SEC_OID_SHA512:
2093 return CKG_MGF1_SHA512;
2094 case SEC_OID_SHA384:
2095 return CKG_MGF1_SHA384;
2096 case SEC_OID_SHA256:
2097 return CKG_MGF1_SHA256;
2098 case SEC_OID_SHA224:
2099 return CKG_MGF1_SHA224;
2100 case SEC_OID_SHA1:
2101 return CKG_MGF1_SHA1;
2102 default:
2103 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
2104 return 0;
2105 }
2106 }
2107
2108 SECStatus
sec_DecodeRSAPSSParams(PLArenaPool * arena,const SECItem * params,SECOidTag * retHashAlg,SECOidTag * retMaskHashAlg,unsigned long * retSaltLength)2109 sec_DecodeRSAPSSParams(PLArenaPool *arena,
2110 const SECItem *params,
2111 SECOidTag *retHashAlg, SECOidTag *retMaskHashAlg,
2112 unsigned long *retSaltLength)
2113 {
2114 SECKEYRSAPSSParams pssParams;
2115 SECOidTag hashAlg;
2116 SECOidTag maskHashAlg;
2117 unsigned long saltLength;
2118 unsigned long trailerField;
2119 SECStatus rv;
2120
2121 PORT_Memset(&pssParams, 0, sizeof(pssParams));
2122 rv = SEC_QuickDERDecodeItem(arena, &pssParams,
2123 SECKEY_RSAPSSParamsTemplate,
2124 params);
2125 if (rv != SECSuccess) {
2126 return rv;
2127 }
2128
2129 if (pssParams.hashAlg) {
2130 hashAlg = SECOID_GetAlgorithmTag(pssParams.hashAlg);
2131 } else {
2132 hashAlg = SEC_OID_SHA1; /* default, SHA-1 */
2133 }
2134
2135 if (pssParams.maskAlg) {
2136 SECAlgorithmID algId;
2137
2138 if (SECOID_GetAlgorithmTag(pssParams.maskAlg) != SEC_OID_PKCS1_MGF1) {
2139 /* only MGF1 is known to PKCS#11 */
2140 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
2141 return SECFailure;
2142 }
2143
2144 rv = SEC_QuickDERDecodeItem(arena, &algId,
2145 SEC_ASN1_GET(SECOID_AlgorithmIDTemplate),
2146 &pssParams.maskAlg->parameters);
2147 if (rv != SECSuccess) {
2148 return rv;
2149 }
2150 maskHashAlg = SECOID_GetAlgorithmTag(&algId);
2151 } else {
2152 maskHashAlg = SEC_OID_SHA1; /* default, MGF1 with SHA-1 */
2153 }
2154
2155 if (pssParams.saltLength.data) {
2156 rv = SEC_ASN1DecodeInteger((SECItem *)&pssParams.saltLength, &saltLength);
2157 if (rv != SECSuccess) {
2158 return rv;
2159 }
2160 } else {
2161 saltLength = 20; /* default, 20 */
2162 }
2163
2164 if (pssParams.trailerField.data) {
2165 rv = SEC_ASN1DecodeInteger((SECItem *)&pssParams.trailerField, &trailerField);
2166 if (rv != SECSuccess) {
2167 return rv;
2168 }
2169 if (trailerField != 1) {
2170 /* the value must be 1, which represents the trailer field
2171 * with hexadecimal value 0xBC */
2172 PORT_SetError(SEC_ERROR_INVALID_ARGS);
2173 return SECFailure;
2174 }
2175 }
2176
2177 if (retHashAlg) {
2178 *retHashAlg = hashAlg;
2179 }
2180 if (retMaskHashAlg) {
2181 *retMaskHashAlg = maskHashAlg;
2182 }
2183 if (retSaltLength) {
2184 *retSaltLength = saltLength;
2185 }
2186
2187 return SECSuccess;
2188 }
2189
2190 SECStatus
sec_DecodeRSAPSSParamsToMechanism(PLArenaPool * arena,const SECItem * params,CK_RSA_PKCS_PSS_PARAMS * mech)2191 sec_DecodeRSAPSSParamsToMechanism(PLArenaPool *arena,
2192 const SECItem *params,
2193 CK_RSA_PKCS_PSS_PARAMS *mech)
2194 {
2195 SECOidTag hashAlg;
2196 SECOidTag maskHashAlg;
2197 unsigned long saltLength;
2198 SECStatus rv;
2199
2200 rv = sec_DecodeRSAPSSParams(arena, params,
2201 &hashAlg, &maskHashAlg, &saltLength);
2202 if (rv != SECSuccess) {
2203 return SECFailure;
2204 }
2205
2206 mech->hashAlg = sec_GetHashMechanismByOidTag(hashAlg);
2207 if (mech->hashAlg == CKM_INVALID_MECHANISM) {
2208 return SECFailure;
2209 }
2210
2211 mech->mgf = sec_GetMgfTypeByOidTag(maskHashAlg);
2212 if (mech->mgf == 0) {
2213 return SECFailure;
2214 }
2215
2216 mech->sLen = saltLength;
2217
2218 return SECSuccess;
2219 }
2220