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, &param, pubk,
162                                  PR_FALSE, PR_TRUE, cx);
163     PK11_FreeSlot(slot);
164     return (privk);
165 }
166 
167 /* Create a DH key pair in any slot able to do so,
168 ** This is a "session" (temporary), not "token" (permanent) key.
169 ** Because of the high probability that this key will need to be moved to
170 ** another token, and the high cost of moving "sensitive" keys, we attempt
171 ** to create this key pair without the "sensitive" attribute, but revert to
172 ** creating a "sensitive" key if necessary.
173 */
174 SECKEYPrivateKey *
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(&param->prime) < DH_MIN_P_BITS ||
182         param->base.len == 0 || param->base.len > param->prime.len + 1 ||
183         (param->base.len == 1 && param->base.data[0] == 0)) {
184         PORT_SetError(SEC_ERROR_INVALID_ARGS);
185         return NULL;
186     }
187 
188     slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN, cx);
189     if (!slot) {
190         return NULL;
191     }
192 
193     privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param,
194                                  pubk, PR_FALSE, PR_FALSE, cx);
195     if (!privk)
196         privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param,
197                                      pubk, PR_FALSE, PR_TRUE, cx);
198 
199     PK11_FreeSlot(slot);
200     return (privk);
201 }
202 
203 /* Create an EC key pair in any slot able to do so,
204 ** This is a "session" (temporary), not "token" (permanent) key.
205 ** Because of the high probability that this key will need to be moved to
206 ** another token, and the high cost of moving "sensitive" keys, we attempt
207 ** to create this key pair without the "sensitive" attribute, but revert to
208 ** creating a "sensitive" key if necessary.
209 */
210 SECKEYPrivateKey *
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, &copyk->u.rsa.modulus,
1151                                   &pubk->u.rsa.modulus);
1152             if (rv == SECSuccess) {
1153                 rv = SECITEM_CopyItem(arena, &copyk->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, &copyk->u.dsa.publicValue,
1161                                   &pubk->u.dsa.publicValue);
1162             if (rv != SECSuccess)
1163                 break;
1164             rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.prime,
1165                                   &pubk->u.dsa.params.prime);
1166             if (rv != SECSuccess)
1167                 break;
1168             rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.subPrime,
1169                                   &pubk->u.dsa.params.subPrime);
1170             if (rv != SECSuccess)
1171                 break;
1172             rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.base,
1173                                   &pubk->u.dsa.params.base);
1174             break;
1175         case dhKey:
1176             rv = SECITEM_CopyItem(arena, &copyk->u.dh.prime, &pubk->u.dh.prime);
1177             if (rv != SECSuccess)
1178                 break;
1179             rv = SECITEM_CopyItem(arena, &copyk->u.dh.base, &pubk->u.dh.base);
1180             if (rv != SECSuccess)
1181                 break;
1182             rv = SECITEM_CopyItem(arena, &copyk->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, &copyk->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, &copyk->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, &params, &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                                                &params);
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(&params, PR_FALSE);
1448                 break;
1449             case ecKey:
1450                 rv = SECITEM_CopyItem(arena, &params,
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                                            &params);
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