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