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