Coverage Report

Created: 2024-11-21 07:03

/src/nss-nspr/nss/lib/cryptohi/seckey.c
Line
Count
Source (jump to first uncovered line)
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
#include "nss.h"
18
19
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
20
SEC_ASN1_MKSUB(SEC_IntegerTemplate)
21
22
const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[] = {
23
    { SEC_ASN1_SEQUENCE,
24
      0, NULL, sizeof(CERTSubjectPublicKeyInfo) },
25
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
26
      offsetof(CERTSubjectPublicKeyInfo, algorithm),
27
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
28
    { SEC_ASN1_BIT_STRING,
29
      offsetof(CERTSubjectPublicKeyInfo, subjectPublicKey) },
30
    { 0 }
31
};
32
33
const SEC_ASN1Template CERT_PublicKeyAndChallengeTemplate[] = {
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
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRSAPSSParams) },
55
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
56
          SEC_ASN1_CONTEXT_SPECIFIC | 0,
57
      offsetof(SECKEYRSAPSSParams, hashAlg),
58
      seckey_PointerToAlgorithmIDTemplate },
59
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
60
          SEC_ASN1_CONTEXT_SPECIFIC | 1,
61
      offsetof(SECKEYRSAPSSParams, maskAlg),
62
      seckey_PointerToAlgorithmIDTemplate },
63
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
64
          SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 2,
65
      offsetof(SECKEYRSAPSSParams, saltLength),
66
      SEC_ASN1_SUB(SEC_IntegerTemplate) },
67
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
68
          SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 3,
69
      offsetof(SECKEYRSAPSSParams, trailerField),
70
      SEC_ASN1_SUB(SEC_IntegerTemplate) },
71
    { 0 }
72
};
73
74
const SEC_ASN1Template SECKEY_DSAPublicKeyTemplate[] = {
75
    { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dsa.publicValue) },
76
    { 0 }
77
};
78
79
const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = {
80
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) },
81
    { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, prime) },
82
    { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, subPrime) },
83
    { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, base) },
84
    { 0 }
85
};
86
87
const SEC_ASN1Template SECKEY_DHPublicKeyTemplate[] = {
88
    { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dh.publicValue) },
89
    { 0 }
90
};
91
92
const SEC_ASN1Template SECKEY_DHParamKeyTemplate[] = {
93
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPublicKey) },
94
    { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dh.prime) },
95
    { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dh.base) },
96
    /* XXX chrisk: this needs to be expanded for decoding of j and validationParms (RFC2459 7.3.2) */
97
    { SEC_ASN1_SKIP_REST },
98
    { 0 }
99
};
100
101
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_DSAPublicKeyTemplate)
102
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPublicKeyTemplate)
103
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPSSParamsTemplate)
104
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SubjectPublicKeyInfoTemplate)
105
106
/*
107
 * See bugzilla bug 125359
108
 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
109
 * all of the templates above that en/decode into integers must be converted
110
 * from ASN.1's signed integer type.  This is done by marking either the
111
 * source or destination (encoding or decoding, respectively) type as
112
 * siUnsignedInteger.
113
 */
114
static void
115
prepare_rsa_pub_key_for_asn1(SECKEYPublicKey *pubk)
116
0
{
117
0
    pubk->u.rsa.modulus.type = siUnsignedInteger;
118
0
    pubk->u.rsa.publicExponent.type = siUnsignedInteger;
119
0
}
120
121
static void
122
prepare_dsa_pub_key_for_asn1(SECKEYPublicKey *pubk)
123
0
{
124
0
    pubk->u.dsa.publicValue.type = siUnsignedInteger;
125
0
}
126
127
static void
128
prepare_pqg_params_for_asn1(SECKEYPQGParams *params)
129
0
{
130
0
    params->prime.type = siUnsignedInteger;
131
0
    params->subPrime.type = siUnsignedInteger;
132
0
    params->base.type = siUnsignedInteger;
133
0
}
134
135
static void
136
prepare_dh_pub_key_for_asn1(SECKEYPublicKey *pubk)
137
0
{
138
0
    pubk->u.dh.prime.type = siUnsignedInteger;
139
0
    pubk->u.dh.base.type = siUnsignedInteger;
140
0
    pubk->u.dh.publicValue.type = siUnsignedInteger;
141
0
}
142
143
/* Create an RSA key pair is any slot able to do so.
144
** The created keys are "session" (temporary), not "token" (permanent),
145
** and they are "sensitive", which makes them costly to move to another token.
146
*/
147
SECKEYPrivateKey *
148
SECKEY_CreateRSAPrivateKey(int keySizeInBits, SECKEYPublicKey **pubk, void *cx)
149
0
{
150
0
    SECKEYPrivateKey *privk;
151
0
    PK11RSAGenParams param;
152
0
    PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, cx);
153
0
    if (!slot) {
154
0
        return NULL;
155
0
    }
156
157
0
    param.keySizeInBits = keySizeInBits;
158
0
    param.pe = 65537L;
159
160
0
    privk = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &param, pubk,
161
0
                                 PR_FALSE, PR_TRUE, cx);
162
0
    PK11_FreeSlot(slot);
163
0
    return (privk);
164
0
}
165
166
/* Create a DH key pair in any slot able to do so,
167
** This is a "session" (temporary), not "token" (permanent) key.
168
** Because of the high probability that this key will need to be moved to
169
** another token, and the high cost of moving "sensitive" keys, we attempt
170
** to create this key pair without the "sensitive" attribute, but revert to
171
** creating a "sensitive" key if necessary.
172
*/
173
SECKEYPrivateKey *
174
SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *cx)
175
0
{
176
0
    SECKEYPrivateKey *privk;
177
0
    PK11SlotInfo *slot;
178
179
0
    if (!param || !param->base.data || !param->prime.data ||
180
0
        SECKEY_BigIntegerBitLength(&param->prime) < DH_MIN_P_BITS ||
181
0
        param->base.len == 0 || param->base.len > param->prime.len + 1 ||
182
0
        (param->base.len == 1 && param->base.data[0] == 0)) {
183
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
184
0
        return NULL;
185
0
    }
186
187
0
    slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN, cx);
188
0
    if (!slot) {
189
0
        return NULL;
190
0
    }
191
192
0
    privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param,
193
0
                                 pubk, PR_FALSE, PR_FALSE, cx);
194
0
    if (!privk)
195
0
        privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param,
196
0
                                     pubk, PR_FALSE, PR_TRUE, cx);
197
198
0
    PK11_FreeSlot(slot);
199
0
    return (privk);
200
0
}
201
202
/* Create an EC key pair in any slot able to do so,
203
** This is a "session" (temporary), not "token" (permanent) key.
204
** Because of the high probability that this key will need to be moved to
205
** another token, and the high cost of moving "sensitive" keys, we attempt
206
** to create this key pair without the "sensitive" attribute, but revert to
207
** creating a "sensitive" key if necessary.
208
*/
209
SECKEYPrivateKey *
210
SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *cx)
211
0
{
212
0
    SECKEYPrivateKey *privk;
213
0
    PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_KEY_PAIR_GEN, cx);
214
0
    if (!slot) {
215
0
        return NULL;
216
0
    }
217
218
0
    privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_KEY_PAIR_GEN,
219
0
                                            param, pubk,
220
0
                                            PK11_ATTR_SESSION |
221
0
                                                PK11_ATTR_INSENSITIVE |
222
0
                                                PK11_ATTR_PUBLIC,
223
0
                                            CKF_DERIVE, CKF_DERIVE | CKF_SIGN,
224
0
                                            cx);
225
0
    if (!privk)
226
0
        privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_KEY_PAIR_GEN,
227
0
                                                param, pubk,
228
0
                                                PK11_ATTR_SESSION |
229
0
                                                    PK11_ATTR_SENSITIVE |
230
0
                                                    PK11_ATTR_PRIVATE,
231
0
                                                CKF_DERIVE, CKF_DERIVE | CKF_SIGN,
232
0
                                                cx);
233
234
0
    PK11_FreeSlot(slot);
235
0
    return (privk);
236
0
}
237
238
SECKEYPrivateKey *
239
SECKEY_CreateEDPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *cx)
240
0
{
241
0
    SECKEYPrivateKey *privk;
242
0
    PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_EDWARDS_KEY_PAIR_GEN, cx);
243
0
    if (!slot) {
244
0
        return NULL;
245
0
    }
246
247
0
    privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_EDWARDS_KEY_PAIR_GEN,
248
0
                                            param, pubk,
249
0
                                            PK11_ATTR_SESSION |
250
0
                                                PK11_ATTR_INSENSITIVE |
251
0
                                                PK11_ATTR_PUBLIC,
252
0
                                            CKF_SIGN, CKF_SIGN, cx);
253
0
    if (!privk)
254
0
        privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_EDWARDS_KEY_PAIR_GEN,
255
0
                                                param, pubk,
256
0
                                                PK11_ATTR_SESSION |
257
0
                                                    PK11_ATTR_SENSITIVE |
258
0
                                                    PK11_ATTR_PRIVATE,
259
0
                                                CKF_SIGN, CKF_SIGN, cx);
260
261
0
    PK11_FreeSlot(slot);
262
0
    return (privk);
263
0
}
264
265
void
266
SECKEY_DestroyPrivateKey(SECKEYPrivateKey *privk)
267
0
{
268
0
    if (privk) {
269
0
        if (privk->pkcs11Slot) {
270
0
            if (privk->pkcs11IsTemp) {
271
0
                PK11_DestroyObject(privk->pkcs11Slot, privk->pkcs11ID);
272
0
            }
273
0
            PK11_FreeSlot(privk->pkcs11Slot);
274
0
        }
275
0
        if (privk->arena) {
276
0
            PORT_FreeArena(privk->arena, PR_TRUE);
277
0
        }
278
0
    }
279
0
}
280
281
void
282
SECKEY_DestroyPublicKey(SECKEYPublicKey *pubk)
283
0
{
284
0
    if (pubk) {
285
0
        if (pubk->pkcs11Slot) {
286
0
            if (!PK11_IsPermObject(pubk->pkcs11Slot, pubk->pkcs11ID)) {
287
0
                PK11_DestroyObject(pubk->pkcs11Slot, pubk->pkcs11ID);
288
0
            }
289
0
            PK11_FreeSlot(pubk->pkcs11Slot);
290
0
        }
291
0
        if (pubk->arena) {
292
0
            PORT_FreeArena(pubk->arena, PR_FALSE);
293
0
        }
294
0
    }
295
0
}
296
297
SECStatus
298
SECKEY_CopySubjectPublicKeyInfo(PLArenaPool *arena,
299
                                CERTSubjectPublicKeyInfo *to,
300
                                CERTSubjectPublicKeyInfo *from)
301
0
{
302
0
    SECStatus rv;
303
0
    SECItem spk;
304
305
0
    rv = SECOID_CopyAlgorithmID(arena, &to->algorithm, &from->algorithm);
306
0
    if (rv == SECSuccess) {
307
        /*
308
         * subjectPublicKey is a bit string, whose length is in bits.
309
         * Convert the length from bits to bytes for SECITEM_CopyItem.
310
         */
311
0
        spk = from->subjectPublicKey;
312
0
        DER_ConvertBitString(&spk);
313
0
        rv = SECITEM_CopyItem(arena, &to->subjectPublicKey, &spk);
314
        /* Set the length back to bits. */
315
0
        if (rv == SECSuccess) {
316
0
            to->subjectPublicKey.len = from->subjectPublicKey.len;
317
0
        }
318
0
    }
319
320
0
    return rv;
321
0
}
322
323
/* Procedure to update the pqg parameters for a cert's public key.
324
 * pqg parameters only need to be updated for DSA certificates.
325
 * The procedure uses calls to itself recursively to update a certificate
326
 * issuer's pqg parameters.  Some important rules are:
327
 *    - Do nothing if the cert already has PQG parameters.
328
 *    - If the cert does not have PQG parameters, obtain them from the issuer.
329
 *    - A valid cert chain cannot have a DSA cert without
330
 *      pqg parameters that has a parent that is not a DSA cert.  */
331
332
static SECStatus
333
seckey_UpdateCertPQGChain(CERTCertificate *subjectCert, int count)
334
0
{
335
0
    SECStatus rv;
336
0
    SECOidData *oid = NULL;
337
0
    int tag;
338
0
    CERTSubjectPublicKeyInfo *subjectSpki = NULL;
339
0
    CERTSubjectPublicKeyInfo *issuerSpki = NULL;
340
0
    CERTCertificate *issuerCert = NULL;
341
342
    /* increment cert chain length counter*/
343
0
    count++;
344
345
    /* check if cert chain length exceeds the maximum length*/
346
0
    if (count > CERT_MAX_CERT_CHAIN) {
347
0
        return SECFailure;
348
0
    }
349
350
0
    oid = SECOID_FindOID(&subjectCert->subjectPublicKeyInfo.algorithm.algorithm);
351
0
    if (oid != NULL) {
352
0
        tag = oid->offset;
353
354
        /* Check if cert has a DSA or EC public key. If not, return
355
         * success since no PQG params need to be updated.
356
         *
357
         * Question: do we really need to do this for EC keys. They don't have
358
         * PQG parameters, but they do have parameters. The question is does
359
         * the child cert inherit those parameters for EC from the parent, or
360
         * do we always include those parameters in each cert.
361
         */
362
363
0
        if ((tag != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
364
0
            (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
365
0
            (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST) &&
366
0
            (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST) &&
367
0
            (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
368
0
            (tag != SEC_OID_SDN702_DSA_SIGNATURE) &&
369
0
            (tag != SEC_OID_ED25519_PUBLIC_KEY) &&
370
0
            (tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) {
371
372
0
            return SECSuccess;
373
0
        }
374
0
    } else {
375
0
        return SECFailure; /* return failure if oid is NULL */
376
0
    }
377
378
    /* if cert has PQG parameters, return success */
379
380
0
    subjectSpki = &subjectCert->subjectPublicKeyInfo;
381
382
0
    if (subjectSpki->algorithm.parameters.len != 0) {
383
0
        return SECSuccess;
384
0
    }
385
386
    /* check if the cert is self-signed */
387
0
    if (subjectCert->isRoot) {
388
        /* fail since cert is self-signed and has no pqg params. */
389
0
        return SECFailure;
390
0
    }
391
392
    /* get issuer cert */
393
0
    issuerCert = CERT_FindCertIssuer(subjectCert, PR_Now(), certUsageAnyCA);
394
0
    if (!issuerCert) {
395
0
        return SECFailure;
396
0
    }
397
398
    /* if parent is not DSA, return failure since
399
       we don't allow this case. */
400
401
0
    oid = SECOID_FindOID(&issuerCert->subjectPublicKeyInfo.algorithm.algorithm);
402
0
    if (oid != NULL) {
403
0
        tag = oid->offset;
404
405
        /* Check if issuer cert has a DSA public key. If not,
406
         * return failure.   */
407
408
0
        if ((tag != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
409
0
            (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
410
0
            (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST) &&
411
0
            (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST) &&
412
0
            (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
413
0
            (tag != SEC_OID_SDN702_DSA_SIGNATURE) &&
414
0
            (tag != SEC_OID_ED25519_PUBLIC_KEY) &&
415
0
            (tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) {
416
0
            rv = SECFailure;
417
0
            goto loser;
418
0
        }
419
0
    } else {
420
0
        rv = SECFailure; /* return failure if oid is NULL */
421
0
        goto loser;
422
0
    }
423
424
    /* at this point the subject cert has no pqg parameters and the
425
     * issuer cert has a DSA public key.  Update the issuer's
426
     * pqg parameters with a recursive call to this same function. */
427
428
0
    rv = seckey_UpdateCertPQGChain(issuerCert, count);
429
0
    if (rv != SECSuccess) {
430
0
        rv = SECFailure;
431
0
        goto loser;
432
0
    }
433
434
    /* ensure issuer has pqg parameters */
435
436
0
    issuerSpki = &issuerCert->subjectPublicKeyInfo;
437
0
    if (issuerSpki->algorithm.parameters.len == 0) {
438
0
        rv = SECFailure;
439
0
    }
440
441
    /* if update was successful and pqg params present, then copy the
442
     * parameters to the subject cert's key. */
443
444
0
    if (rv == SECSuccess) {
445
0
        rv = SECITEM_CopyItem(subjectCert->arena,
446
0
                              &subjectSpki->algorithm.parameters,
447
0
                              &issuerSpki->algorithm.parameters);
448
0
    }
449
450
0
loser:
451
0
    if (issuerCert) {
452
0
        CERT_DestroyCertificate(issuerCert);
453
0
    }
454
0
    return rv;
455
0
}
456
457
SECStatus
458
SECKEY_UpdateCertPQG(CERTCertificate *subjectCert)
459
0
{
460
0
    if (!subjectCert) {
461
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
462
0
        return SECFailure;
463
0
    }
464
0
    return seckey_UpdateCertPQGChain(subjectCert, 0);
465
0
}
466
467
/* Decode the DSA PQG parameters.  The params could be stored in two
468
 * possible formats, the old fortezza-only wrapped format or
469
 * the normal standard format.  Store the decoded parameters in
470
 * a V3 certificate data structure.  */
471
472
static SECStatus
473
seckey_DSADecodePQG(PLArenaPool *arena, SECKEYPublicKey *pubk,
474
                    const SECItem *params)
475
0
{
476
0
    SECStatus rv;
477
0
    SECItem newparams;
478
479
0
    if (params == NULL)
480
0
        return SECFailure;
481
482
0
    if (params->data == NULL)
483
0
        return SECFailure;
484
485
0
    PORT_Assert(arena);
486
487
    /* make a copy of the data into the arena so QuickDER output is valid */
488
0
    rv = SECITEM_CopyItem(arena, &newparams, params);
489
490
    /* Check if params use the standard format.
491
     * The value 0xa1 will appear in the first byte of the parameter data
492
     * if the PQG parameters are not using the standard format.  This
493
     * code should be changed to use a better method to detect non-standard
494
     * parameters.    */
495
496
0
    if ((newparams.data[0] != 0xa1) &&
497
0
        (newparams.data[0] != 0xa0)) {
498
499
0
        if (SECSuccess == rv) {
500
            /* PQG params are in the standard format */
501
0
            prepare_pqg_params_for_asn1(&pubk->u.dsa.params);
502
0
            rv = SEC_QuickDERDecodeItem(arena, &pubk->u.dsa.params,
503
0
                                        SECKEY_PQGParamsTemplate,
504
0
                                        &newparams);
505
0
        }
506
0
    } else {
507
508
0
        if (SECSuccess == rv) {
509
            /* else the old fortezza-only wrapped format is used. */
510
0
            PORT_SetError(SEC_ERROR_BAD_DER);
511
0
            rv = SECFailure;
512
0
        }
513
0
    }
514
0
    return rv;
515
0
}
516
517
/* Function used to make an oid tag to a key type */
518
KeyType
519
seckey_GetKeyType(SECOidTag tag)
520
0
{
521
0
    KeyType keyType;
522
523
0
    switch (tag) {
524
0
        case SEC_OID_X500_RSA_ENCRYPTION:
525
0
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
526
0
            keyType = rsaKey;
527
0
            break;
528
0
        case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
529
0
            keyType = rsaPssKey;
530
0
            break;
531
0
        case SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION:
532
0
            keyType = rsaOaepKey;
533
0
            break;
534
0
        case SEC_OID_ANSIX9_DSA_SIGNATURE:
535
0
            keyType = dsaKey;
536
0
            break;
537
0
        case SEC_OID_MISSI_KEA_DSS_OLD:
538
0
        case SEC_OID_MISSI_KEA_DSS:
539
0
        case SEC_OID_MISSI_DSS_OLD:
540
0
        case SEC_OID_MISSI_DSS:
541
0
            keyType = fortezzaKey;
542
0
            break;
543
0
        case SEC_OID_MISSI_KEA:
544
0
        case SEC_OID_MISSI_ALT_KEA:
545
0
            keyType = keaKey;
546
0
            break;
547
0
        case SEC_OID_X942_DIFFIE_HELMAN_KEY:
548
0
            keyType = dhKey;
549
0
            break;
550
0
        case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
551
0
            keyType = ecKey;
552
0
            break;
553
0
        case SEC_OID_ED25519_PUBLIC_KEY:
554
0
            keyType = edKey;
555
0
            break;
556
        /* accommodate applications that hand us a signature type when they
557
         * should be handing us a cipher type */
558
0
        case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
559
0
        case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
560
0
        case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
561
0
        case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
562
0
        case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
563
0
        case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
564
0
            keyType = rsaKey;
565
0
            break;
566
0
        default:
567
0
            keyType = nullKey;
568
0
    }
569
0
    return keyType;
570
0
}
571
572
/* Function used to determine what kind of cert we are dealing with. */
573
KeyType
574
CERT_GetCertKeyType(const CERTSubjectPublicKeyInfo *spki)
575
0
{
576
0
    return seckey_GetKeyType(SECOID_GetAlgorithmTag(&spki->algorithm));
577
0
}
578
579
/* Ensure pubKey contains an OID */
580
static SECStatus
581
seckey_HasCurveOID(const SECKEYPublicKey *pubKey)
582
0
{
583
0
    SECItem oid;
584
0
    SECStatus rv;
585
0
    PORTCheapArenaPool tmpArena;
586
587
0
    PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
588
    /* If we can decode it, an OID is available. */
589
0
    rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &oid,
590
0
                                SEC_ASN1_GET(SEC_ObjectIDTemplate),
591
0
                                &pubKey->u.ec.DEREncodedParams);
592
0
    PORT_DestroyCheapArena(&tmpArena);
593
0
    return rv;
594
0
}
595
596
static SECKEYPublicKey *
597
seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki)
598
0
{
599
0
    SECKEYPublicKey *pubk;
600
0
    SECItem os, newOs, newParms;
601
0
    SECStatus rv;
602
0
    PLArenaPool *arena;
603
0
    SECOidTag tag;
604
605
0
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
606
0
    if (arena == NULL)
607
0
        return NULL;
608
609
0
    pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
610
0
    if (pubk == NULL) {
611
0
        PORT_FreeArena(arena, PR_FALSE);
612
0
        return NULL;
613
0
    }
614
615
0
    pubk->arena = arena;
616
0
    pubk->pkcs11Slot = 0;
617
0
    pubk->pkcs11ID = CK_INVALID_HANDLE;
618
619
    /* Convert bit string length from bits to bytes */
620
0
    os = spki->subjectPublicKey;
621
0
    DER_ConvertBitString(&os);
622
623
0
    tag = SECOID_GetAlgorithmTag(&spki->algorithm);
624
625
    /* copy the DER into the arena, since Quick DER returns data that points
626
       into the DER input, which may get freed by the caller */
627
0
    rv = SECITEM_CopyItem(arena, &newOs, &os);
628
0
    if (rv == SECSuccess)
629
0
        switch (tag) {
630
0
            case SEC_OID_X500_RSA_ENCRYPTION:
631
0
            case SEC_OID_PKCS1_RSA_ENCRYPTION:
632
0
            case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
633
0
                pubk->keyType = rsaKey;
634
0
                prepare_rsa_pub_key_for_asn1(pubk);
635
0
                rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, &newOs);
636
0
                if (rv == SECSuccess)
637
0
                    return pubk;
638
0
                break;
639
0
            case SEC_OID_ANSIX9_DSA_SIGNATURE:
640
0
            case SEC_OID_SDN702_DSA_SIGNATURE:
641
0
                pubk->keyType = dsaKey;
642
0
                prepare_dsa_pub_key_for_asn1(pubk);
643
0
                rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &newOs);
644
0
                if (rv != SECSuccess)
645
0
                    break;
646
647
0
                rv = seckey_DSADecodePQG(arena, pubk,
648
0
                                         &spki->algorithm.parameters);
649
650
0
                if (rv == SECSuccess)
651
0
                    return pubk;
652
0
                break;
653
0
            case SEC_OID_X942_DIFFIE_HELMAN_KEY:
654
0
                pubk->keyType = dhKey;
655
0
                prepare_dh_pub_key_for_asn1(pubk);
656
0
                rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHPublicKeyTemplate, &newOs);
657
0
                if (rv != SECSuccess)
658
0
                    break;
659
660
                /* copy the DER into the arena, since Quick DER returns data that points
661
                   into the DER input, which may get freed by the caller */
662
0
                rv = SECITEM_CopyItem(arena, &newParms, &spki->algorithm.parameters);
663
0
                if (rv != SECSuccess)
664
0
                    break;
665
666
0
                rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHParamKeyTemplate,
667
0
                                            &newParms);
668
669
0
                if (rv == SECSuccess)
670
0
                    return pubk;
671
0
                break;
672
0
            case SEC_OID_X25519:
673
0
            case SEC_OID_ED25519_PUBLIC_KEY:
674
                /* A basic consistency check on inputs. */
675
0
                if (newOs.len == 0) {
676
0
                    PORT_SetError(SEC_ERROR_INPUT_LEN);
677
0
                    break;
678
0
                }
679
680
                /* Currently supporting only (Pure)Ed25519 .*/
681
0
                if (spki->algorithm.parameters.len != 0) {
682
0
                    PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
683
0
                    break;
684
0
                }
685
686
                /* edKey corresponds to Ed25519 mechanism.
687
                 * ecMontKey corresponds to X25519 mechanism.
688
                 * The other options are not supported. */
689
0
                if (tag == SEC_OID_X25519) {
690
0
                    pubk->keyType = ecMontKey;
691
0
                } else {
692
                    /* tag == SEC_OID_ED25519_PUBLIC_KEY */
693
0
                    pubk->keyType = edKey;
694
0
                }
695
696
0
                pubk->u.ec.size = 0;
697
698
0
                SECOidData *oid25519 = SECOID_FindOIDByTag(tag);
699
0
                if (!oid25519) {
700
0
                    break;
701
0
                }
702
703
0
                if (!SECITEM_AllocItem(arena, &pubk->u.ec.DEREncodedParams, oid25519->oid.len + 2)) {
704
0
                    break;
705
0
                }
706
0
                pubk->u.ec.DEREncodedParams.data[0] = SEC_ASN1_OBJECT_ID;
707
0
                pubk->u.ec.DEREncodedParams.data[1] = oid25519->oid.len;
708
0
                PORT_Memcpy(pubk->u.ec.DEREncodedParams.data + 2, oid25519->oid.data, oid25519->oid.len);
709
710
0
                rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &newOs);
711
0
                if (rv != SECSuccess) {
712
0
                    break;
713
0
                }
714
0
                return pubk;
715
0
            case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
716
                /* A basic sanity check on inputs. */
717
0
                if (spki->algorithm.parameters.len == 0 || newOs.len == 0) {
718
0
                    PORT_SetError(SEC_ERROR_INPUT_LEN);
719
0
                    break;
720
0
                }
721
0
                pubk->keyType = ecKey;
722
0
                pubk->u.ec.size = 0;
723
724
                /* Since PKCS#11 directly takes the DER encoding of EC params
725
                 * and public value, we don't need any decoding here.
726
                 */
727
0
                rv = SECITEM_CopyItem(arena, &pubk->u.ec.DEREncodedParams,
728
0
                                      &spki->algorithm.parameters);
729
0
                if (rv != SECSuccess) {
730
0
                    break;
731
0
                }
732
0
                rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &newOs);
733
0
                if (rv != SECSuccess) {
734
0
                    break;
735
0
                }
736
0
                pubk->u.ec.encoding = ECPoint_Undefined;
737
0
                rv = seckey_HasCurveOID(pubk);
738
0
                if (rv == SECSuccess) {
739
0
                    return pubk;
740
0
                }
741
0
                break;
742
743
0
            default:
744
0
                PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
745
0
                break;
746
0
        }
747
748
0
    SECKEY_DestroyPublicKey(pubk);
749
0
    return NULL;
750
0
}
751
752
/* required for JSS */
753
SECKEYPublicKey *
754
SECKEY_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki)
755
0
{
756
0
    return seckey_ExtractPublicKey(spki);
757
0
}
758
759
SECKEYPublicKey *
760
CERT_ExtractPublicKey(CERTCertificate *cert)
761
0
{
762
0
    return seckey_ExtractPublicKey(&cert->subjectPublicKeyInfo);
763
0
}
764
765
int
766
SECKEY_ECParamsToKeySize(const SECItem *encodedParams)
767
0
{
768
0
    SECOidTag tag;
769
0
    SECItem oid = { siBuffer, NULL, 0 };
770
771
    /* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID),
772
     * followed by the length of the curve oid and the curve oid.
773
     */
774
0
    oid.len = encodedParams->data[1];
775
0
    oid.data = encodedParams->data + 2;
776
0
    if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)
777
0
        return 0;
778
779
0
    switch (tag) {
780
0
        case SEC_OID_SECG_EC_SECP112R1:
781
0
        case SEC_OID_SECG_EC_SECP112R2:
782
0
            return 112;
783
784
0
        case SEC_OID_SECG_EC_SECT113R1:
785
0
        case SEC_OID_SECG_EC_SECT113R2:
786
0
            return 113;
787
788
0
        case SEC_OID_SECG_EC_SECP128R1:
789
0
        case SEC_OID_SECG_EC_SECP128R2:
790
0
            return 128;
791
792
0
        case SEC_OID_SECG_EC_SECT131R1:
793
0
        case SEC_OID_SECG_EC_SECT131R2:
794
0
            return 131;
795
796
0
        case SEC_OID_SECG_EC_SECP160K1:
797
0
        case SEC_OID_SECG_EC_SECP160R1:
798
0
        case SEC_OID_SECG_EC_SECP160R2:
799
0
            return 160;
800
801
0
        case SEC_OID_SECG_EC_SECT163K1:
802
0
        case SEC_OID_SECG_EC_SECT163R1:
803
0
        case SEC_OID_SECG_EC_SECT163R2:
804
0
        case SEC_OID_ANSIX962_EC_C2PNB163V1:
805
0
        case SEC_OID_ANSIX962_EC_C2PNB163V2:
806
0
        case SEC_OID_ANSIX962_EC_C2PNB163V3:
807
0
            return 163;
808
809
0
        case SEC_OID_ANSIX962_EC_C2PNB176V1:
810
0
            return 176;
811
812
0
        case SEC_OID_ANSIX962_EC_C2TNB191V1:
813
0
        case SEC_OID_ANSIX962_EC_C2TNB191V2:
814
0
        case SEC_OID_ANSIX962_EC_C2TNB191V3:
815
0
        case SEC_OID_ANSIX962_EC_C2ONB191V4:
816
0
        case SEC_OID_ANSIX962_EC_C2ONB191V5:
817
0
            return 191;
818
819
0
        case SEC_OID_SECG_EC_SECP192K1:
820
0
        case SEC_OID_ANSIX962_EC_PRIME192V1:
821
0
        case SEC_OID_ANSIX962_EC_PRIME192V2:
822
0
        case SEC_OID_ANSIX962_EC_PRIME192V3:
823
0
            return 192;
824
825
0
        case SEC_OID_SECG_EC_SECT193R1:
826
0
        case SEC_OID_SECG_EC_SECT193R2:
827
0
            return 193;
828
829
0
        case SEC_OID_ANSIX962_EC_C2PNB208W1:
830
0
            return 208;
831
832
0
        case SEC_OID_SECG_EC_SECP224K1:
833
0
        case SEC_OID_SECG_EC_SECP224R1:
834
0
            return 224;
835
836
0
        case SEC_OID_SECG_EC_SECT233K1:
837
0
        case SEC_OID_SECG_EC_SECT233R1:
838
0
            return 233;
839
840
0
        case SEC_OID_SECG_EC_SECT239K1:
841
0
        case SEC_OID_ANSIX962_EC_C2TNB239V1:
842
0
        case SEC_OID_ANSIX962_EC_C2TNB239V2:
843
0
        case SEC_OID_ANSIX962_EC_C2TNB239V3:
844
0
        case SEC_OID_ANSIX962_EC_C2ONB239V4:
845
0
        case SEC_OID_ANSIX962_EC_C2ONB239V5:
846
0
        case SEC_OID_ANSIX962_EC_PRIME239V1:
847
0
        case SEC_OID_ANSIX962_EC_PRIME239V2:
848
0
        case SEC_OID_ANSIX962_EC_PRIME239V3:
849
0
            return 239;
850
851
0
        case SEC_OID_SECG_EC_SECP256K1:
852
0
        case SEC_OID_ANSIX962_EC_PRIME256V1:
853
0
            return 256;
854
855
0
        case SEC_OID_ANSIX962_EC_C2PNB272W1:
856
0
            return 272;
857
858
0
        case SEC_OID_SECG_EC_SECT283K1:
859
0
        case SEC_OID_SECG_EC_SECT283R1:
860
0
            return 283;
861
862
0
        case SEC_OID_ANSIX962_EC_C2PNB304W1:
863
0
            return 304;
864
865
0
        case SEC_OID_ANSIX962_EC_C2TNB359V1:
866
0
            return 359;
867
868
0
        case SEC_OID_ANSIX962_EC_C2PNB368W1:
869
0
            return 368;
870
871
0
        case SEC_OID_SECG_EC_SECP384R1:
872
0
            return 384;
873
874
0
        case SEC_OID_SECG_EC_SECT409K1:
875
0
        case SEC_OID_SECG_EC_SECT409R1:
876
0
            return 409;
877
878
0
        case SEC_OID_ANSIX962_EC_C2TNB431R1:
879
0
            return 431;
880
881
0
        case SEC_OID_SECG_EC_SECP521R1:
882
0
            return 521;
883
884
0
        case SEC_OID_SECG_EC_SECT571K1:
885
0
        case SEC_OID_SECG_EC_SECT571R1:
886
0
            return 571;
887
888
0
        case SEC_OID_X25519:
889
0
        case SEC_OID_CURVE25519:
890
0
        case SEC_OID_ED25519_PUBLIC_KEY:
891
0
            return 255;
892
893
0
        default:
894
0
            PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
895
0
            return 0;
896
0
    }
897
0
}
898
899
int
900
SECKEY_ECParamsToBasePointOrderLen(const SECItem *encodedParams)
901
0
{
902
0
    SECOidTag tag;
903
0
    SECItem oid = { siBuffer, NULL, 0 };
904
905
    /* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID),
906
     * followed by the length of the curve oid and the curve oid.
907
     */
908
0
    oid.len = encodedParams->data[1];
909
0
    oid.data = encodedParams->data + 2;
910
0
    if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)
911
0
        return 0;
912
913
0
    switch (tag) {
914
0
        case SEC_OID_SECG_EC_SECP112R1:
915
0
            return 112;
916
0
        case SEC_OID_SECG_EC_SECP112R2:
917
0
            return 110;
918
919
0
        case SEC_OID_SECG_EC_SECT113R1:
920
0
        case SEC_OID_SECG_EC_SECT113R2:
921
0
            return 113;
922
923
0
        case SEC_OID_SECG_EC_SECP128R1:
924
0
            return 128;
925
0
        case SEC_OID_SECG_EC_SECP128R2:
926
0
            return 126;
927
928
0
        case SEC_OID_SECG_EC_SECT131R1:
929
0
        case SEC_OID_SECG_EC_SECT131R2:
930
0
            return 131;
931
932
0
        case SEC_OID_SECG_EC_SECP160K1:
933
0
        case SEC_OID_SECG_EC_SECP160R1:
934
0
        case SEC_OID_SECG_EC_SECP160R2:
935
0
            return 161;
936
937
0
        case SEC_OID_SECG_EC_SECT163K1:
938
0
            return 163;
939
0
        case SEC_OID_SECG_EC_SECT163R1:
940
0
            return 162;
941
0
        case SEC_OID_SECG_EC_SECT163R2:
942
0
        case SEC_OID_ANSIX962_EC_C2PNB163V1:
943
0
            return 163;
944
0
        case SEC_OID_ANSIX962_EC_C2PNB163V2:
945
0
        case SEC_OID_ANSIX962_EC_C2PNB163V3:
946
0
            return 162;
947
948
0
        case SEC_OID_ANSIX962_EC_C2PNB176V1:
949
0
            return 161;
950
951
0
        case SEC_OID_ANSIX962_EC_C2TNB191V1:
952
0
            return 191;
953
0
        case SEC_OID_ANSIX962_EC_C2TNB191V2:
954
0
            return 190;
955
0
        case SEC_OID_ANSIX962_EC_C2TNB191V3:
956
0
            return 189;
957
0
        case SEC_OID_ANSIX962_EC_C2ONB191V4:
958
0
            return 191;
959
0
        case SEC_OID_ANSIX962_EC_C2ONB191V5:
960
0
            return 188;
961
962
0
        case SEC_OID_SECG_EC_SECP192K1:
963
0
        case SEC_OID_ANSIX962_EC_PRIME192V1:
964
0
        case SEC_OID_ANSIX962_EC_PRIME192V2:
965
0
        case SEC_OID_ANSIX962_EC_PRIME192V3:
966
0
            return 192;
967
968
0
        case SEC_OID_SECG_EC_SECT193R1:
969
0
        case SEC_OID_SECG_EC_SECT193R2:
970
0
            return 193;
971
972
0
        case SEC_OID_ANSIX962_EC_C2PNB208W1:
973
0
            return 193;
974
975
0
        case SEC_OID_SECG_EC_SECP224K1:
976
0
            return 225;
977
0
        case SEC_OID_SECG_EC_SECP224R1:
978
0
            return 224;
979
980
0
        case SEC_OID_SECG_EC_SECT233K1:
981
0
            return 232;
982
0
        case SEC_OID_SECG_EC_SECT233R1:
983
0
            return 233;
984
985
0
        case SEC_OID_SECG_EC_SECT239K1:
986
0
        case SEC_OID_ANSIX962_EC_C2TNB239V1:
987
0
            return 238;
988
0
        case SEC_OID_ANSIX962_EC_C2TNB239V2:
989
0
            return 237;
990
0
        case SEC_OID_ANSIX962_EC_C2TNB239V3:
991
0
            return 236;
992
0
        case SEC_OID_ANSIX962_EC_C2ONB239V4:
993
0
            return 238;
994
0
        case SEC_OID_ANSIX962_EC_C2ONB239V5:
995
0
            return 237;
996
0
        case SEC_OID_ANSIX962_EC_PRIME239V1:
997
0
        case SEC_OID_ANSIX962_EC_PRIME239V2:
998
0
        case SEC_OID_ANSIX962_EC_PRIME239V3:
999
0
            return 239;
1000
1001
0
        case SEC_OID_SECG_EC_SECP256K1:
1002
0
        case SEC_OID_ANSIX962_EC_PRIME256V1:
1003
0
            return 256;
1004
1005
0
        case SEC_OID_ANSIX962_EC_C2PNB272W1:
1006
0
            return 257;
1007
1008
0
        case SEC_OID_SECG_EC_SECT283K1:
1009
0
            return 281;
1010
0
        case SEC_OID_SECG_EC_SECT283R1:
1011
0
            return 282;
1012
1013
0
        case SEC_OID_ANSIX962_EC_C2PNB304W1:
1014
0
            return 289;
1015
1016
0
        case SEC_OID_ANSIX962_EC_C2TNB359V1:
1017
0
            return 353;
1018
1019
0
        case SEC_OID_ANSIX962_EC_C2PNB368W1:
1020
0
            return 353;
1021
1022
0
        case SEC_OID_SECG_EC_SECP384R1:
1023
0
            return 384;
1024
1025
0
        case SEC_OID_SECG_EC_SECT409K1:
1026
0
            return 407;
1027
0
        case SEC_OID_SECG_EC_SECT409R1:
1028
0
            return 409;
1029
1030
0
        case SEC_OID_ANSIX962_EC_C2TNB431R1:
1031
0
            return 418;
1032
1033
0
        case SEC_OID_SECG_EC_SECP521R1:
1034
0
            return 521;
1035
1036
0
        case SEC_OID_SECG_EC_SECT571K1:
1037
0
        case SEC_OID_SECG_EC_SECT571R1:
1038
0
            return 570;
1039
1040
0
        case SEC_OID_X25519:
1041
0
        case SEC_OID_CURVE25519:
1042
0
        case SEC_OID_ED25519_PUBLIC_KEY:
1043
0
            return 255;
1044
1045
0
        default:
1046
0
            PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
1047
0
            return 0;
1048
0
    }
1049
0
}
1050
1051
/* The number of bits in the number from the first non-zero bit onward. */
1052
unsigned
1053
SECKEY_BigIntegerBitLength(const SECItem *number)
1054
0
{
1055
0
    const unsigned char *p;
1056
0
    unsigned octets;
1057
0
    unsigned bits;
1058
1059
0
    if (!number || !number->data) {
1060
0
        PORT_SetError(SEC_ERROR_INVALID_KEY);
1061
0
        return 0;
1062
0
    }
1063
1064
0
    p = number->data;
1065
0
    octets = number->len;
1066
0
    while (octets > 0 && !*p) {
1067
0
        ++p;
1068
0
        --octets;
1069
0
    }
1070
0
    if (octets == 0) {
1071
0
        return 0;
1072
0
    }
1073
    /* bits = 7..1 because we know at least one bit is set already */
1074
    /* Note: This could do a binary search, but this is faster for keys if we
1075
     * assume that good keys will have the MSB set. */
1076
0
    for (bits = 7; bits > 0; --bits) {
1077
0
        if (*p & (1 << bits)) {
1078
0
            break;
1079
0
        }
1080
0
    }
1081
0
    return octets * 8 + bits - 7;
1082
0
}
1083
1084
/* returns key strength in bytes (not bits) */
1085
unsigned
1086
SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk)
1087
0
{
1088
0
    return (SECKEY_PublicKeyStrengthInBits(pubk) + 7) / 8;
1089
0
}
1090
1091
/* returns key strength in bits */
1092
unsigned
1093
SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk)
1094
0
{
1095
0
    unsigned bitSize = 0;
1096
1097
0
    if (!pubk) {
1098
0
        PORT_SetError(SEC_ERROR_INVALID_KEY);
1099
0
        return 0;
1100
0
    }
1101
1102
    /* interpret modulus length as key strength */
1103
0
    switch (pubk->keyType) {
1104
0
        case rsaKey:
1105
0
            bitSize = SECKEY_BigIntegerBitLength(&pubk->u.rsa.modulus);
1106
0
            break;
1107
0
        case dsaKey:
1108
0
            bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dsa.params.prime);
1109
0
            break;
1110
0
        case dhKey:
1111
0
            bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dh.prime);
1112
0
            break;
1113
0
        case ecKey:
1114
0
        case edKey:
1115
0
        case ecMontKey:
1116
0
            bitSize = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
1117
0
            break;
1118
0
        default:
1119
0
            PORT_SetError(SEC_ERROR_INVALID_KEY);
1120
0
            break;
1121
0
    }
1122
0
    return bitSize;
1123
0
}
1124
1125
unsigned
1126
SECKEY_PrivateKeyStrengthInBits(const SECKEYPrivateKey *privk)
1127
0
{
1128
0
    unsigned bitSize = 0;
1129
0
    SECItem params = { siBuffer, NULL, 0 };
1130
0
    SECStatus rv;
1131
1132
0
    if (!privk) {
1133
0
        PORT_SetError(SEC_ERROR_INVALID_KEY);
1134
0
        return 0;
1135
0
    }
1136
1137
    /* interpret modulus length as key strength */
1138
0
    switch (privk->keyType) {
1139
0
        case rsaKey:
1140
0
        case rsaPssKey:
1141
0
        case rsaOaepKey:
1142
            /* some tokens don't export CKA_MODULUS on the private key,
1143
             * PK11_SignatureLen works around this if necessary */
1144
0
            bitSize = PK11_SignatureLen((SECKEYPrivateKey *)privk) * PR_BITS_PER_BYTE;
1145
0
            if (bitSize == -1) {
1146
0
                bitSize = 0;
1147
0
            }
1148
0
            return bitSize;
1149
0
        case dsaKey:
1150
0
        case fortezzaKey:
1151
0
        case dhKey:
1152
0
        case keaKey:
1153
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1154
0
                                    CKA_PRIME, NULL, &params);
1155
0
            if ((rv != SECSuccess) || (params.data == NULL)) {
1156
0
                PORT_SetError(SEC_ERROR_INVALID_KEY);
1157
0
                return 0;
1158
0
            }
1159
0
            bitSize = SECKEY_BigIntegerBitLength(&params);
1160
0
            PORT_Free(params.data);
1161
0
            return bitSize;
1162
0
        case ecKey:
1163
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1164
0
                                    CKA_EC_PARAMS, NULL, &params);
1165
0
            if ((rv != SECSuccess) || (params.data == NULL)) {
1166
0
                return 0;
1167
0
            }
1168
0
            bitSize = SECKEY_ECParamsToKeySize(&params);
1169
0
            PORT_Free(params.data);
1170
0
            return bitSize;
1171
0
        default:
1172
0
            break;
1173
0
    }
1174
0
    PORT_SetError(SEC_ERROR_INVALID_KEY);
1175
0
    return 0;
1176
0
}
1177
1178
/* returns signature length in bytes (not bits) */
1179
unsigned
1180
SECKEY_SignatureLen(const SECKEYPublicKey *pubk)
1181
0
{
1182
0
    unsigned size;
1183
1184
0
    switch (pubk->keyType) {
1185
0
        case rsaKey:
1186
0
        case rsaPssKey:
1187
0
            if (pubk->u.rsa.modulus.len == 0) {
1188
0
                return 0;
1189
0
            }
1190
0
            if (pubk->u.rsa.modulus.data[0] == 0) {
1191
0
                return pubk->u.rsa.modulus.len - 1;
1192
0
            }
1193
0
            return pubk->u.rsa.modulus.len;
1194
0
        case dsaKey:
1195
0
            return pubk->u.dsa.params.subPrime.len * 2;
1196
0
        case ecKey:
1197
0
        case edKey:
1198
0
        case ecMontKey:
1199
            /* Get the base point order length in bits and adjust */
1200
0
            size = SECKEY_ECParamsToBasePointOrderLen(
1201
0
                &pubk->u.ec.DEREncodedParams);
1202
0
            return ((size + 7) / 8) * 2;
1203
0
        default:
1204
0
            break;
1205
0
    }
1206
0
    PORT_SetError(SEC_ERROR_INVALID_KEY);
1207
0
    return 0;
1208
0
}
1209
1210
SECKEYPrivateKey *
1211
SECKEY_CopyPrivateKey(const SECKEYPrivateKey *privk)
1212
0
{
1213
0
    SECKEYPrivateKey *copyk;
1214
0
    PLArenaPool *arena;
1215
1216
0
    if (!privk || !privk->pkcs11Slot) {
1217
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
1218
0
        return NULL;
1219
0
    }
1220
1221
0
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1222
0
    if (arena == NULL) {
1223
0
        return NULL;
1224
0
    }
1225
1226
0
    copyk = (SECKEYPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey));
1227
0
    if (copyk) {
1228
0
        copyk->arena = arena;
1229
0
        copyk->keyType = privk->keyType;
1230
1231
        /* copy the PKCS #11 parameters */
1232
0
        copyk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot);
1233
        /* if the key we're referencing was a temparary key we have just
1234
         * created, that we want to go away when we're through, we need
1235
         * to make a copy of it */
1236
0
        if (privk->pkcs11IsTemp) {
1237
0
            copyk->pkcs11ID =
1238
0
                PK11_CopyKey(privk->pkcs11Slot, privk->pkcs11ID);
1239
0
            if (copyk->pkcs11ID == CK_INVALID_HANDLE)
1240
0
                goto fail;
1241
0
        } else {
1242
0
            copyk->pkcs11ID = privk->pkcs11ID;
1243
0
        }
1244
0
        copyk->pkcs11IsTemp = privk->pkcs11IsTemp;
1245
0
        copyk->wincx = privk->wincx;
1246
0
        copyk->staticflags = privk->staticflags;
1247
0
        return copyk;
1248
0
    } else {
1249
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1250
0
    }
1251
1252
0
fail:
1253
0
    PORT_FreeArena(arena, PR_FALSE);
1254
0
    return NULL;
1255
0
}
1256
1257
SECKEYPublicKey *
1258
SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk)
1259
0
{
1260
0
    SECKEYPublicKey *copyk;
1261
0
    PLArenaPool *arena;
1262
0
    SECStatus rv = SECSuccess;
1263
1264
0
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1265
0
    if (arena == NULL) {
1266
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1267
0
        return NULL;
1268
0
    }
1269
1270
0
    copyk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
1271
0
    if (!copyk) {
1272
0
        PORT_FreeArena(arena, PR_FALSE);
1273
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1274
0
        return NULL;
1275
0
    }
1276
1277
0
    copyk->arena = arena;
1278
0
    copyk->keyType = pubk->keyType;
1279
0
    if (pubk->pkcs11Slot &&
1280
0
        PK11_IsPermObject(pubk->pkcs11Slot, pubk->pkcs11ID)) {
1281
0
        copyk->pkcs11Slot = PK11_ReferenceSlot(pubk->pkcs11Slot);
1282
0
        copyk->pkcs11ID = pubk->pkcs11ID;
1283
0
    } else {
1284
0
        copyk->pkcs11Slot = NULL; /* go get own reference */
1285
0
        copyk->pkcs11ID = CK_INVALID_HANDLE;
1286
0
    }
1287
0
    switch (pubk->keyType) {
1288
0
        case rsaKey:
1289
0
            rv = SECITEM_CopyItem(arena, &copyk->u.rsa.modulus,
1290
0
                                  &pubk->u.rsa.modulus);
1291
0
            if (rv == SECSuccess) {
1292
0
                rv = SECITEM_CopyItem(arena, &copyk->u.rsa.publicExponent,
1293
0
                                      &pubk->u.rsa.publicExponent);
1294
0
                if (rv == SECSuccess)
1295
0
                    return copyk;
1296
0
            }
1297
0
            break;
1298
0
        case dsaKey:
1299
0
            rv = SECITEM_CopyItem(arena, &copyk->u.dsa.publicValue,
1300
0
                                  &pubk->u.dsa.publicValue);
1301
0
            if (rv != SECSuccess)
1302
0
                break;
1303
0
            rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.prime,
1304
0
                                  &pubk->u.dsa.params.prime);
1305
0
            if (rv != SECSuccess)
1306
0
                break;
1307
0
            rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.subPrime,
1308
0
                                  &pubk->u.dsa.params.subPrime);
1309
0
            if (rv != SECSuccess)
1310
0
                break;
1311
0
            rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.base,
1312
0
                                  &pubk->u.dsa.params.base);
1313
0
            break;
1314
0
        case dhKey:
1315
0
            rv = SECITEM_CopyItem(arena, &copyk->u.dh.prime, &pubk->u.dh.prime);
1316
0
            if (rv != SECSuccess)
1317
0
                break;
1318
0
            rv = SECITEM_CopyItem(arena, &copyk->u.dh.base, &pubk->u.dh.base);
1319
0
            if (rv != SECSuccess)
1320
0
                break;
1321
0
            rv = SECITEM_CopyItem(arena, &copyk->u.dh.publicValue,
1322
0
                                  &pubk->u.dh.publicValue);
1323
0
            break;
1324
0
        case ecKey:
1325
0
        case edKey:
1326
0
        case ecMontKey:
1327
0
            copyk->u.ec.size = pubk->u.ec.size;
1328
0
            rv = seckey_HasCurveOID(pubk);
1329
0
            if (rv != SECSuccess) {
1330
0
                break;
1331
0
            }
1332
0
            rv = SECITEM_CopyItem(arena, &copyk->u.ec.DEREncodedParams,
1333
0
                                  &pubk->u.ec.DEREncodedParams);
1334
0
            if (rv != SECSuccess) {
1335
0
                break;
1336
0
            }
1337
0
            copyk->u.ec.encoding = ECPoint_Undefined;
1338
0
            rv = SECITEM_CopyItem(arena, &copyk->u.ec.publicValue,
1339
0
                                  &pubk->u.ec.publicValue);
1340
0
            break;
1341
0
        case nullKey:
1342
0
            return copyk;
1343
0
        case kyberKey:
1344
0
            copyk->u.kyber.params = pubk->u.kyber.params;
1345
0
            rv = SECITEM_CopyItem(arena, &copyk->u.kyber.publicValue,
1346
0
                                  &pubk->u.kyber.publicValue);
1347
0
            break;
1348
0
        default:
1349
0
            PORT_SetError(SEC_ERROR_INVALID_KEY);
1350
0
            rv = SECFailure;
1351
0
            break;
1352
0
    }
1353
0
    if (rv == SECSuccess)
1354
0
        return copyk;
1355
1356
0
    SECKEY_DestroyPublicKey(copyk);
1357
0
    return NULL;
1358
0
}
1359
1360
/*
1361
 * Check that a given key meets the policy limits for the given key
1362
 * size.
1363
 */
1364
SECStatus
1365
SECKEY_EnforceKeySize(KeyType keyType, unsigned keyLength, SECErrorCodes error)
1366
0
{
1367
0
    PRInt32 opt = -1;
1368
0
    PRInt32 optVal;
1369
0
    SECStatus rv;
1370
1371
0
    switch (keyType) {
1372
0
        case rsaKey:
1373
0
        case rsaPssKey:
1374
0
        case rsaOaepKey:
1375
0
            opt = NSS_RSA_MIN_KEY_SIZE;
1376
0
            break;
1377
0
        case dsaKey:
1378
0
        case fortezzaKey:
1379
0
            opt = NSS_DSA_MIN_KEY_SIZE;
1380
0
            break;
1381
0
        case dhKey:
1382
0
        case keaKey:
1383
0
            opt = NSS_DH_MIN_KEY_SIZE;
1384
0
            break;
1385
0
        case ecKey:
1386
0
            opt = NSS_ECC_MIN_KEY_SIZE;
1387
0
            break;
1388
0
        case nullKey:
1389
0
        default:
1390
0
            PORT_SetError(SEC_ERROR_INVALID_KEY);
1391
0
            return SECFailure;
1392
0
    }
1393
0
    PORT_Assert(opt != -1);
1394
0
    rv = NSS_OptionGet(opt, &optVal);
1395
0
    if (rv != SECSuccess) {
1396
0
        return rv;
1397
0
    }
1398
0
    if (optVal > keyLength) {
1399
0
        PORT_SetError(error);
1400
0
        return SECFailure;
1401
0
    }
1402
0
    return SECSuccess;
1403
0
}
1404
1405
/*
1406
 * Use the private key to find a public key handle. The handle will be on
1407
 * the same slot as the private key.
1408
 */
1409
static CK_OBJECT_HANDLE
1410
seckey_FindPublicKeyHandle(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk)
1411
0
{
1412
0
    CK_OBJECT_HANDLE keyID;
1413
1414
    /* this helper function is only used below. If we want to make this more
1415
     * general, we would need to free up any already cached handles if the
1416
     * slot doesn't match up with the private key slot */
1417
0
    PORT_Assert(pubk->pkcs11ID == CK_INVALID_HANDLE);
1418
1419
    /* first look for a matching public key */
1420
0
    keyID = PK11_MatchItem(privk->pkcs11Slot, privk->pkcs11ID, CKO_PUBLIC_KEY);
1421
0
    if (keyID != CK_INVALID_HANDLE) {
1422
0
        return keyID;
1423
0
    }
1424
1425
    /* none found, create a temp one, make the pubk the owner */
1426
0
    pubk->pkcs11ID = PK11_DerivePubKeyFromPrivKey(privk);
1427
0
    if (pubk->pkcs11ID == CK_INVALID_HANDLE) {
1428
        /* end of the road. Token doesn't have matching public key, nor can
1429
         * token regenerate a new public key from and existing private key. */
1430
0
        return CK_INVALID_HANDLE;
1431
0
    }
1432
0
    pubk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot);
1433
0
    return pubk->pkcs11ID;
1434
0
}
1435
1436
SECKEYPublicKey *
1437
SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
1438
0
{
1439
0
    SECKEYPublicKey *pubk;
1440
0
    PLArenaPool *arena;
1441
0
    CERTCertificate *cert;
1442
0
    SECStatus rv;
1443
0
    CK_OBJECT_HANDLE pubKeyHandle;
1444
0
    SECItem decodedPoint;
1445
1446
    /*
1447
     * First try to look up the cert.
1448
     */
1449
0
    cert = PK11_GetCertFromPrivateKey(privk);
1450
0
    if (cert) {
1451
0
        pubk = CERT_ExtractPublicKey(cert);
1452
0
        CERT_DestroyCertificate(cert);
1453
0
        return pubk;
1454
0
    }
1455
1456
    /* couldn't find the cert, build pub key by hand */
1457
0
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1458
0
    if (arena == NULL) {
1459
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1460
0
        return NULL;
1461
0
    }
1462
0
    pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena,
1463
0
                                               sizeof(SECKEYPublicKey));
1464
0
    if (pubk == NULL) {
1465
0
        PORT_FreeArena(arena, PR_FALSE);
1466
0
        return NULL;
1467
0
    }
1468
0
    pubk->keyType = privk->keyType;
1469
0
    pubk->pkcs11Slot = NULL;
1470
0
    pubk->pkcs11ID = CK_INVALID_HANDLE;
1471
0
    pubk->arena = arena;
1472
1473
0
    switch (privk->keyType) {
1474
0
        case nullKey:
1475
            /* Nothing to query, if the cert isn't there, we're done -- no way
1476
             * to get the public key */
1477
0
            break;
1478
0
        case dsaKey:
1479
0
            pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
1480
0
            if (pubKeyHandle == CK_INVALID_HANDLE)
1481
0
                break;
1482
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1483
0
                                    CKA_BASE, arena, &pubk->u.dsa.params.base);
1484
0
            if (rv != SECSuccess)
1485
0
                break;
1486
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1487
0
                                    CKA_PRIME, arena, &pubk->u.dsa.params.prime);
1488
0
            if (rv != SECSuccess)
1489
0
                break;
1490
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1491
0
                                    CKA_SUBPRIME, arena, &pubk->u.dsa.params.subPrime);
1492
0
            if (rv != SECSuccess)
1493
0
                break;
1494
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1495
0
                                    CKA_VALUE, arena, &pubk->u.dsa.publicValue);
1496
0
            if (rv != SECSuccess)
1497
0
                break;
1498
0
            return pubk;
1499
0
        case dhKey:
1500
0
            pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
1501
0
            if (pubKeyHandle == CK_INVALID_HANDLE)
1502
0
                break;
1503
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1504
0
                                    CKA_BASE, arena, &pubk->u.dh.base);
1505
0
            if (rv != SECSuccess)
1506
0
                break;
1507
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1508
0
                                    CKA_PRIME, arena, &pubk->u.dh.prime);
1509
0
            if (rv != SECSuccess)
1510
0
                break;
1511
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1512
0
                                    CKA_VALUE, arena, &pubk->u.dh.publicValue);
1513
0
            if (rv != SECSuccess)
1514
0
                break;
1515
0
            return pubk;
1516
0
        case rsaKey:
1517
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1518
0
                                    CKA_MODULUS, arena, &pubk->u.rsa.modulus);
1519
0
            if (rv != SECSuccess)
1520
0
                break;
1521
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1522
0
                                    CKA_PUBLIC_EXPONENT, arena, &pubk->u.rsa.publicExponent);
1523
0
            if (rv != SECSuccess)
1524
0
                break;
1525
0
            return pubk;
1526
0
        case ecKey:
1527
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1528
0
                                    CKA_EC_PARAMS, arena, &pubk->u.ec.DEREncodedParams);
1529
0
            if (rv != SECSuccess) {
1530
0
                break;
1531
0
            }
1532
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1533
0
                                    CKA_EC_POINT, arena, &pubk->u.ec.publicValue);
1534
0
            if (rv != SECSuccess || pubk->u.ec.publicValue.len == 0) {
1535
0
                pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
1536
0
                if (pubKeyHandle == CK_INVALID_HANDLE)
1537
0
                    break;
1538
0
                rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1539
0
                                        CKA_EC_POINT, arena, &pubk->u.ec.publicValue);
1540
0
                if (rv != SECSuccess)
1541
0
                    break;
1542
0
            }
1543
            /* ec.publicValue should be decoded, PKCS #11 defines CKA_EC_POINT
1544
             * as encoded, but it's not always. try do decoded it and if it
1545
             * succeeds store the decoded value */
1546
0
            rv = SEC_QuickDERDecodeItem(arena, &decodedPoint,
1547
0
                                        SEC_ASN1_GET(SEC_OctetStringTemplate), &pubk->u.ec.publicValue);
1548
0
            if (rv == SECSuccess) {
1549
                /* both values are in the public key arena, so it's safe to
1550
                 * overwrite  the old value */
1551
0
                pubk->u.ec.publicValue = decodedPoint;
1552
0
            }
1553
1554
0
            pubk->u.ec.encoding = ECPoint_Undefined;
1555
0
            return pubk;
1556
0
        case edKey:
1557
0
        case ecMontKey:
1558
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1559
0
                                    CKA_EC_PARAMS, arena, &pubk->u.ec.DEREncodedParams);
1560
0
            if (rv != SECSuccess) {
1561
0
                break;
1562
0
            }
1563
0
            rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
1564
0
                                    CKA_EC_POINT, arena, &pubk->u.ec.publicValue);
1565
0
            if (rv != SECSuccess || pubk->u.ec.publicValue.len == 0) {
1566
0
                pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
1567
0
                if (pubKeyHandle == CK_INVALID_HANDLE) {
1568
0
                    break;
1569
0
                }
1570
0
                rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
1571
0
                                        CKA_EC_POINT, arena, &pubk->u.ec.publicValue);
1572
0
                if (rv != SECSuccess) {
1573
0
                    break;
1574
0
                }
1575
0
            }
1576
0
            pubk->u.ec.encoding = ECPoint_Undefined;
1577
0
            return pubk;
1578
0
        default:
1579
0
            break;
1580
0
    }
1581
1582
    /* must use Destroy public key here, because some paths create temporary
1583
     * PKCS #11 objects which need to be freed */
1584
0
    SECKEY_DestroyPublicKey(pubk);
1585
0
    return NULL;
1586
0
}
1587
1588
static CERTSubjectPublicKeyInfo *
1589
seckey_CreateSubjectPublicKeyInfo_helper(SECKEYPublicKey *pubk)
1590
0
{
1591
0
    CERTSubjectPublicKeyInfo *spki;
1592
0
    PLArenaPool *arena;
1593
0
    SECItem params = { siBuffer, NULL, 0 };
1594
0
    SECOidTag tag;
1595
1596
0
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1597
0
    if (arena == NULL) {
1598
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1599
0
        return NULL;
1600
0
    }
1601
1602
0
    spki = (CERTSubjectPublicKeyInfo *)PORT_ArenaZAlloc(arena, sizeof(*spki));
1603
0
    if (spki != NULL) {
1604
0
        SECStatus rv;
1605
0
        SECItem *rv_item;
1606
1607
0
        spki->arena = arena;
1608
0
        switch (pubk->keyType) {
1609
0
            case rsaKey:
1610
0
                rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
1611
0
                                           SEC_OID_PKCS1_RSA_ENCRYPTION, 0);
1612
0
                if (rv == SECSuccess) {
1613
                    /*
1614
                     * DER encode the public key into the subjectPublicKeyInfo.
1615
                     */
1616
0
                    prepare_rsa_pub_key_for_asn1(pubk);
1617
0
                    rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
1618
0
                                                 pubk, SECKEY_RSAPublicKeyTemplate);
1619
0
                    if (rv_item != NULL) {
1620
                        /*
1621
                         * The stored value is supposed to be a BIT_STRING,
1622
                         * so convert the length.
1623
                         */
1624
0
                        spki->subjectPublicKey.len <<= 3;
1625
                        /*
1626
                         * We got a good one; return it.
1627
                         */
1628
0
                        return spki;
1629
0
                    }
1630
0
                }
1631
0
                break;
1632
0
            case dsaKey:
1633
                /* DER encode the params. */
1634
0
                prepare_pqg_params_for_asn1(&pubk->u.dsa.params);
1635
0
                rv_item = SEC_ASN1EncodeItem(arena, &params, &pubk->u.dsa.params,
1636
0
                                             SECKEY_PQGParamsTemplate);
1637
0
                if (rv_item != NULL) {
1638
0
                    rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
1639
0
                                               SEC_OID_ANSIX9_DSA_SIGNATURE,
1640
0
                                               &params);
1641
0
                    if (rv == SECSuccess) {
1642
                        /*
1643
                         * DER encode the public key into the subjectPublicKeyInfo.
1644
                         */
1645
0
                        prepare_dsa_pub_key_for_asn1(pubk);
1646
0
                        rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
1647
0
                                                     pubk,
1648
0
                                                     SECKEY_DSAPublicKeyTemplate);
1649
0
                        if (rv_item != NULL) {
1650
                            /*
1651
                             * The stored value is supposed to be a BIT_STRING,
1652
                             * so convert the length.
1653
                             */
1654
0
                            spki->subjectPublicKey.len <<= 3;
1655
                            /*
1656
                             * We got a good one; return it.
1657
                             */
1658
0
                            return spki;
1659
0
                        }
1660
0
                    }
1661
0
                }
1662
0
                SECITEM_FreeItem(&params, PR_FALSE);
1663
0
                break;
1664
0
            case ecKey:
1665
0
                rv = SECITEM_CopyItem(arena, &params,
1666
0
                                      &pubk->u.ec.DEREncodedParams);
1667
0
                if (rv != SECSuccess) {
1668
0
                    break;
1669
0
                }
1670
1671
0
                tag = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
1672
0
                rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
1673
0
                                           tag,
1674
0
                                           &params);
1675
0
                if (rv != SECSuccess) {
1676
0
                    break;
1677
0
                }
1678
1679
0
                rv = SECITEM_CopyItem(arena, &spki->subjectPublicKey,
1680
0
                                      &pubk->u.ec.publicValue);
1681
1682
0
                if (rv == SECSuccess) {
1683
                    /*
1684
                     * The stored value is supposed to be a BIT_STRING,
1685
                     * so convert the length.
1686
                     */
1687
0
                    spki->subjectPublicKey.len <<= 3;
1688
                    /*
1689
                     * We got a good one; return it.
1690
                     */
1691
0
                    return spki;
1692
0
                }
1693
0
                break;
1694
0
            case edKey:
1695
0
            case ecMontKey:
1696
0
                tag = SECKEY_GetECCOid(&pubk->u.ec.DEREncodedParams);
1697
0
                rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
1698
0
                                           tag,
1699
0
                                           &params);
1700
0
                if (rv != SECSuccess) {
1701
0
                    break;
1702
0
                }
1703
1704
0
                rv = SECITEM_CopyItem(arena, &spki->subjectPublicKey,
1705
0
                                      &pubk->u.ec.publicValue);
1706
1707
0
                if (rv == SECSuccess) {
1708
                    /*
1709
                     * The stored value is supposed to be a BIT_STRING,
1710
                     * so convert the length.
1711
                     */
1712
0
                    spki->subjectPublicKey.len <<= 3;
1713
                    /*
1714
                     * We got a good one; return it.
1715
                     */
1716
0
                    return spki;
1717
0
                }
1718
0
                break;
1719
0
            case dhKey: /* later... */
1720
1721
0
                break;
1722
0
            default:
1723
0
                break;
1724
0
        }
1725
0
    } else {
1726
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1727
0
    }
1728
1729
0
    PORT_FreeArena(arena, PR_FALSE);
1730
0
    return NULL;
1731
0
}
1732
1733
CERTSubjectPublicKeyInfo *
1734
SECKEY_CreateSubjectPublicKeyInfo(const SECKEYPublicKey *pubk)
1735
0
{
1736
0
    CERTSubjectPublicKeyInfo *spki;
1737
0
    SECKEYPublicKey *tempKey;
1738
1739
0
    if (!pubk) {
1740
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
1741
0
        return NULL;
1742
0
    }
1743
1744
0
    tempKey = SECKEY_CopyPublicKey(pubk);
1745
0
    if (!tempKey) {
1746
0
        return NULL;
1747
0
    }
1748
0
    spki = seckey_CreateSubjectPublicKeyInfo_helper(tempKey);
1749
0
    SECKEY_DestroyPublicKey(tempKey);
1750
0
    return spki;
1751
0
}
1752
1753
void
1754
SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki)
1755
0
{
1756
0
    if (spki && spki->arena) {
1757
0
        PORT_FreeArena(spki->arena, PR_FALSE);
1758
0
    }
1759
0
}
1760
1761
SECItem *
1762
SECKEY_EncodeDERSubjectPublicKeyInfo(const SECKEYPublicKey *pubk)
1763
0
{
1764
0
    CERTSubjectPublicKeyInfo *spki = NULL;
1765
0
    SECItem *spkiDER = NULL;
1766
1767
    /* get the subjectpublickeyinfo */
1768
0
    spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);
1769
0
    if (spki == NULL) {
1770
0
        goto finish;
1771
0
    }
1772
1773
    /* DER-encode the subjectpublickeyinfo */
1774
0
    spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL /*dest*/, spki,
1775
0
                                 CERT_SubjectPublicKeyInfoTemplate);
1776
1777
0
    SECKEY_DestroySubjectPublicKeyInfo(spki);
1778
1779
0
finish:
1780
0
    return spkiDER;
1781
0
}
1782
1783
CERTSubjectPublicKeyInfo *
1784
SECKEY_DecodeDERSubjectPublicKeyInfo(const SECItem *spkider)
1785
0
{
1786
0
    PLArenaPool *arena;
1787
0
    CERTSubjectPublicKeyInfo *spki;
1788
0
    SECStatus rv;
1789
0
    SECItem newSpkider;
1790
1791
0
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1792
0
    if (arena == NULL) {
1793
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1794
0
        return NULL;
1795
0
    }
1796
1797
0
    spki = (CERTSubjectPublicKeyInfo *)
1798
0
        PORT_ArenaZAlloc(arena, sizeof(CERTSubjectPublicKeyInfo));
1799
0
    if (spki != NULL) {
1800
0
        spki->arena = arena;
1801
1802
        /* copy the DER into the arena, since Quick DER returns data that points
1803
           into the DER input, which may get freed by the caller */
1804
0
        rv = SECITEM_CopyItem(arena, &newSpkider, spkider);
1805
0
        if (rv == SECSuccess) {
1806
0
            rv = SEC_QuickDERDecodeItem(arena, spki,
1807
0
                                        CERT_SubjectPublicKeyInfoTemplate, &newSpkider);
1808
0
        }
1809
0
        if (rv == SECSuccess) {
1810
0
            return spki;
1811
0
        }
1812
0
    } else {
1813
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1814
0
    }
1815
1816
0
    PORT_FreeArena(arena, PR_FALSE);
1817
0
    return NULL;
1818
0
}
1819
1820
/*
1821
 * Decode a base64 ascii encoded DER encoded subject public key info.
1822
 */
1823
CERTSubjectPublicKeyInfo *
1824
SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(const char *spkistr)
1825
0
{
1826
0
    CERTSubjectPublicKeyInfo *spki;
1827
0
    SECStatus rv;
1828
0
    SECItem der;
1829
1830
0
    rv = ATOB_ConvertAsciiToItem(&der, spkistr);
1831
0
    if (rv != SECSuccess)
1832
0
        return NULL;
1833
1834
0
    spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
1835
1836
0
    PORT_Free(der.data);
1837
0
    return spki;
1838
0
}
1839
1840
/*
1841
 * Decode a base64 ascii encoded DER encoded public key and challenge
1842
 * Verify digital signature and make sure challenge matches
1843
 */
1844
CERTSubjectPublicKeyInfo *
1845
SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,
1846
                                             void *wincx)
1847
0
{
1848
0
    CERTSubjectPublicKeyInfo *spki = NULL;
1849
0
    CERTPublicKeyAndChallenge pkac;
1850
0
    SECStatus rv;
1851
0
    SECItem signedItem;
1852
0
    PLArenaPool *arena = NULL;
1853
0
    CERTSignedData sd;
1854
0
    SECItem sig;
1855
0
    SECKEYPublicKey *pubKey = NULL;
1856
0
    unsigned int len;
1857
1858
0
    signedItem.data = NULL;
1859
1860
    /* convert the base64 encoded data to binary */
1861
0
    rv = ATOB_ConvertAsciiToItem(&signedItem, pkacstr);
1862
0
    if (rv != SECSuccess) {
1863
0
        goto loser;
1864
0
    }
1865
1866
    /* create an arena */
1867
0
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1868
0
    if (arena == NULL) {
1869
0
        goto loser;
1870
0
    }
1871
1872
    /* decode the outer wrapping of signed data */
1873
0
    PORT_Memset(&sd, 0, sizeof(CERTSignedData));
1874
0
    rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, &signedItem);
1875
0
    if (rv) {
1876
0
        goto loser;
1877
0
    }
1878
1879
    /* decode the public key and challenge wrapper */
1880
0
    PORT_Memset(&pkac, 0, sizeof(CERTPublicKeyAndChallenge));
1881
0
    rv = SEC_QuickDERDecodeItem(arena, &pkac, CERT_PublicKeyAndChallengeTemplate,
1882
0
                                &sd.data);
1883
0
    if (rv) {
1884
0
        goto loser;
1885
0
    }
1886
1887
    /* decode the subject public key info */
1888
0
    spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&pkac.spki);
1889
0
    if (spki == NULL) {
1890
0
        goto loser;
1891
0
    }
1892
1893
    /* get the public key */
1894
0
    pubKey = seckey_ExtractPublicKey(spki);
1895
0
    if (pubKey == NULL) {
1896
0
        goto loser;
1897
0
    }
1898
1899
    /* check the signature */
1900
0
    sig = sd.signature;
1901
0
    DER_ConvertBitString(&sig);
1902
0
    rv = VFY_VerifyDataWithAlgorithmID(sd.data.data, sd.data.len, pubKey, &sig,
1903
0
                                       &(sd.signatureAlgorithm), NULL, wincx);
1904
0
    if (rv != SECSuccess) {
1905
0
        goto loser;
1906
0
    }
1907
1908
    /* check the challenge */
1909
0
    if (challenge) {
1910
0
        len = PORT_Strlen(challenge);
1911
        /* length is right */
1912
0
        if (len != pkac.challenge.len) {
1913
0
            goto loser;
1914
0
        }
1915
        /* actual data is right */
1916
0
        if (PORT_Memcmp(challenge, pkac.challenge.data, len) != 0) {
1917
0
            goto loser;
1918
0
        }
1919
0
    }
1920
0
    goto done;
1921
1922
0
loser:
1923
    /* make sure that we return null if we got an error */
1924
0
    if (spki) {
1925
0
        SECKEY_DestroySubjectPublicKeyInfo(spki);
1926
0
    }
1927
0
    spki = NULL;
1928
1929
0
done:
1930
0
    if (signedItem.data) {
1931
0
        PORT_Free(signedItem.data);
1932
0
    }
1933
0
    if (arena) {
1934
0
        PORT_FreeArena(arena, PR_FALSE);
1935
0
    }
1936
0
    if (pubKey) {
1937
0
        SECKEY_DestroyPublicKey(pubKey);
1938
0
    }
1939
1940
0
    return spki;
1941
0
}
1942
1943
void
1944
SECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo *pvk,
1945
                             PRBool freeit)
1946
0
{
1947
0
    PLArenaPool *poolp;
1948
1949
0
    if (pvk != NULL) {
1950
0
        if (pvk->arena) {
1951
0
            poolp = pvk->arena;
1952
            /* zero structure since PORT_FreeArena does not support
1953
             * this yet.
1954
             */
1955
0
            PORT_Memset(pvk->privateKey.data, 0, pvk->privateKey.len);
1956
0
            PORT_Memset(pvk, 0, sizeof(*pvk));
1957
0
            if (freeit == PR_TRUE) {
1958
0
                PORT_FreeArena(poolp, PR_TRUE);
1959
0
            } else {
1960
0
                pvk->arena = poolp;
1961
0
            }
1962
0
        } else {
1963
0
            SECITEM_ZfreeItem(&pvk->version, PR_FALSE);
1964
0
            SECITEM_ZfreeItem(&pvk->privateKey, PR_FALSE);
1965
0
            SECOID_DestroyAlgorithmID(&pvk->algorithm, PR_FALSE);
1966
0
            PORT_Memset(pvk, 0, sizeof(*pvk));
1967
0
            if (freeit == PR_TRUE) {
1968
0
                PORT_Free(pvk);
1969
0
            }
1970
0
        }
1971
0
    }
1972
0
}
1973
1974
void
1975
SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki,
1976
                                      PRBool freeit)
1977
0
{
1978
0
    PLArenaPool *poolp;
1979
1980
0
    if (epki != NULL) {
1981
0
        if (epki->arena) {
1982
0
            poolp = epki->arena;
1983
            /* zero structure since PORT_FreeArena does not support
1984
             * this yet.
1985
             */
1986
0
            PORT_Memset(epki->encryptedData.data, 0, epki->encryptedData.len);
1987
0
            PORT_Memset(epki, 0, sizeof(*epki));
1988
0
            if (freeit == PR_TRUE) {
1989
0
                PORT_FreeArena(poolp, PR_TRUE);
1990
0
            } else {
1991
0
                epki->arena = poolp;
1992
0
            }
1993
0
        } else {
1994
0
            SECITEM_ZfreeItem(&epki->encryptedData, PR_FALSE);
1995
0
            SECOID_DestroyAlgorithmID(&epki->algorithm, PR_FALSE);
1996
0
            PORT_Memset(epki, 0, sizeof(*epki));
1997
0
            if (freeit == PR_TRUE) {
1998
0
                PORT_Free(epki);
1999
0
            }
2000
0
        }
2001
0
    }
2002
0
}
2003
2004
SECStatus
2005
SECKEY_CopyPrivateKeyInfo(PLArenaPool *poolp,
2006
                          SECKEYPrivateKeyInfo *to,
2007
                          const SECKEYPrivateKeyInfo *from)
2008
0
{
2009
0
    SECStatus rv = SECFailure;
2010
2011
0
    if ((to == NULL) || (from == NULL)) {
2012
0
        return SECFailure;
2013
0
    }
2014
2015
0
    rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);
2016
0
    if (rv != SECSuccess) {
2017
0
        return SECFailure;
2018
0
    }
2019
0
    rv = SECITEM_CopyItem(poolp, &to->privateKey, &from->privateKey);
2020
0
    if (rv != SECSuccess) {
2021
0
        return SECFailure;
2022
0
    }
2023
0
    rv = SECITEM_CopyItem(poolp, &to->version, &from->version);
2024
2025
0
    return rv;
2026
0
}
2027
2028
SECStatus
2029
SECKEY_CopyEncryptedPrivateKeyInfo(PLArenaPool *poolp,
2030
                                   SECKEYEncryptedPrivateKeyInfo *to,
2031
                                   const SECKEYEncryptedPrivateKeyInfo *from)
2032
0
{
2033
0
    SECStatus rv = SECFailure;
2034
2035
0
    if ((to == NULL) || (from == NULL)) {
2036
0
        return SECFailure;
2037
0
    }
2038
2039
0
    rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);
2040
0
    if (rv != SECSuccess) {
2041
0
        return SECFailure;
2042
0
    }
2043
0
    rv = SECITEM_CopyItem(poolp, &to->encryptedData, &from->encryptedData);
2044
2045
0
    return rv;
2046
0
}
2047
2048
KeyType
2049
SECKEY_GetPrivateKeyType(const SECKEYPrivateKey *privKey)
2050
0
{
2051
0
    return privKey->keyType;
2052
0
}
2053
2054
KeyType
2055
SECKEY_GetPublicKeyType(const SECKEYPublicKey *pubKey)
2056
0
{
2057
0
    return pubKey->keyType;
2058
0
}
2059
2060
SECKEYPublicKey *
2061
SECKEY_ImportDERPublicKey(const SECItem *derKey, CK_KEY_TYPE type)
2062
0
{
2063
0
    SECKEYPublicKey *pubk = NULL;
2064
0
    SECStatus rv = SECFailure;
2065
0
    SECItem newDerKey;
2066
0
    PLArenaPool *arena = NULL;
2067
2068
0
    if (!derKey) {
2069
0
        return NULL;
2070
0
    }
2071
2072
0
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
2073
0
    if (arena == NULL) {
2074
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
2075
0
        goto finish;
2076
0
    }
2077
2078
0
    pubk = PORT_ArenaZNew(arena, SECKEYPublicKey);
2079
0
    if (pubk == NULL) {
2080
0
        goto finish;
2081
0
    }
2082
0
    pubk->arena = arena;
2083
2084
0
    rv = SECITEM_CopyItem(pubk->arena, &newDerKey, derKey);
2085
0
    if (SECSuccess != rv) {
2086
0
        goto finish;
2087
0
    }
2088
2089
0
    pubk->pkcs11Slot = NULL;
2090
0
    pubk->pkcs11ID = CK_INVALID_HANDLE;
2091
2092
0
    switch (type) {
2093
0
        case CKK_RSA:
2094
0
            prepare_rsa_pub_key_for_asn1(pubk);
2095
0
            rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_RSAPublicKeyTemplate, &newDerKey);
2096
0
            pubk->keyType = rsaKey;
2097
0
            break;
2098
0
        case CKK_DSA:
2099
0
            prepare_dsa_pub_key_for_asn1(pubk);
2100
0
            rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_DSAPublicKeyTemplate, &newDerKey);
2101
0
            pubk->keyType = dsaKey;
2102
0
            break;
2103
0
        case CKK_DH:
2104
0
            prepare_dh_pub_key_for_asn1(pubk);
2105
0
            rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_DHPublicKeyTemplate, &newDerKey);
2106
0
            pubk->keyType = dhKey;
2107
0
            break;
2108
0
        default:
2109
0
            rv = SECFailure;
2110
0
            break;
2111
0
    }
2112
2113
0
finish:
2114
0
    if (rv != SECSuccess) {
2115
0
        if (arena != NULL) {
2116
0
            PORT_FreeArena(arena, PR_FALSE);
2117
0
        }
2118
0
        pubk = NULL;
2119
0
    }
2120
0
    return pubk;
2121
0
}
2122
2123
SECKEYPrivateKeyList *
2124
SECKEY_NewPrivateKeyList(void)
2125
0
{
2126
0
    PLArenaPool *arena = NULL;
2127
0
    SECKEYPrivateKeyList *ret = NULL;
2128
2129
0
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
2130
0
    if (arena == NULL) {
2131
0
        goto loser;
2132
0
    }
2133
2134
0
    ret = (SECKEYPrivateKeyList *)PORT_ArenaZAlloc(arena,
2135
0
                                                   sizeof(SECKEYPrivateKeyList));
2136
0
    if (ret == NULL) {
2137
0
        goto loser;
2138
0
    }
2139
2140
0
    ret->arena = arena;
2141
2142
0
    PR_INIT_CLIST(&ret->list);
2143
2144
0
    return (ret);
2145
2146
0
loser:
2147
0
    if (arena != NULL) {
2148
0
        PORT_FreeArena(arena, PR_FALSE);
2149
0
    }
2150
2151
0
    return (NULL);
2152
0
}
2153
2154
void
2155
SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys)
2156
0
{
2157
0
    while (!PR_CLIST_IS_EMPTY(&keys->list)) {
2158
0
        SECKEY_RemovePrivateKeyListNode(
2159
0
            (SECKEYPrivateKeyListNode *)(PR_LIST_HEAD(&keys->list)));
2160
0
    }
2161
2162
0
    PORT_FreeArena(keys->arena, PR_FALSE);
2163
2164
0
    return;
2165
0
}
2166
2167
void
2168
SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node)
2169
0
{
2170
0
    PR_ASSERT(node->key);
2171
0
    SECKEY_DestroyPrivateKey(node->key);
2172
0
    node->key = NULL;
2173
0
    PR_REMOVE_LINK(&node->links);
2174
0
    return;
2175
0
}
2176
2177
SECStatus
2178
SECKEY_AddPrivateKeyToListTail(SECKEYPrivateKeyList *list,
2179
                               SECKEYPrivateKey *key)
2180
0
{
2181
0
    SECKEYPrivateKeyListNode *node;
2182
2183
0
    node = (SECKEYPrivateKeyListNode *)PORT_ArenaZAlloc(list->arena,
2184
0
                                                        sizeof(SECKEYPrivateKeyListNode));
2185
0
    if (node == NULL) {
2186
0
        goto loser;
2187
0
    }
2188
2189
0
    PR_INSERT_BEFORE(&node->links, &list->list);
2190
0
    node->key = key;
2191
0
    return (SECSuccess);
2192
2193
0
loser:
2194
0
    return (SECFailure);
2195
0
}
2196
2197
SECKEYPublicKeyList *
2198
SECKEY_NewPublicKeyList(void)
2199
0
{
2200
0
    PLArenaPool *arena = NULL;
2201
0
    SECKEYPublicKeyList *ret = NULL;
2202
2203
0
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
2204
0
    if (arena == NULL) {
2205
0
        goto loser;
2206
0
    }
2207
2208
0
    ret = (SECKEYPublicKeyList *)PORT_ArenaZAlloc(arena,
2209
0
                                                  sizeof(SECKEYPublicKeyList));
2210
0
    if (ret == NULL) {
2211
0
        goto loser;
2212
0
    }
2213
2214
0
    ret->arena = arena;
2215
2216
0
    PR_INIT_CLIST(&ret->list);
2217
2218
0
    return (ret);
2219
2220
0
loser:
2221
0
    if (arena != NULL) {
2222
0
        PORT_FreeArena(arena, PR_FALSE);
2223
0
    }
2224
2225
0
    return (NULL);
2226
0
}
2227
2228
void
2229
SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys)
2230
0
{
2231
0
    while (!PR_CLIST_IS_EMPTY(&keys->list)) {
2232
0
        SECKEY_RemovePublicKeyListNode(
2233
0
            (SECKEYPublicKeyListNode *)(PR_LIST_HEAD(&keys->list)));
2234
0
    }
2235
2236
0
    PORT_FreeArena(keys->arena, PR_FALSE);
2237
2238
0
    return;
2239
0
}
2240
2241
void
2242
SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node)
2243
0
{
2244
0
    PR_ASSERT(node->key);
2245
0
    SECKEY_DestroyPublicKey(node->key);
2246
0
    node->key = NULL;
2247
0
    PR_REMOVE_LINK(&node->links);
2248
0
    return;
2249
0
}
2250
2251
SECStatus
2252
SECKEY_AddPublicKeyToListTail(SECKEYPublicKeyList *list,
2253
                              SECKEYPublicKey *key)
2254
0
{
2255
0
    SECKEYPublicKeyListNode *node;
2256
2257
0
    node = (SECKEYPublicKeyListNode *)PORT_ArenaZAlloc(list->arena,
2258
0
                                                       sizeof(SECKEYPublicKeyListNode));
2259
0
    if (node == NULL) {
2260
0
        goto loser;
2261
0
    }
2262
2263
0
    PR_INSERT_BEFORE(&node->links, &list->list);
2264
0
    node->key = key;
2265
0
    return (SECSuccess);
2266
2267
0
loser:
2268
0
    return (SECFailure);
2269
0
}
2270
2271
#define SECKEY_CacheAttribute(key, attribute)                                                   \
2272
0
    if (CK_TRUE == PK11_HasAttributeSet(key->pkcs11Slot, key->pkcs11ID, attribute, PR_FALSE)) { \
2273
0
        key->staticflags |= SECKEY_##attribute;                                                 \
2274
0
    } else {                                                                                    \
2275
0
        key->staticflags &= (~SECKEY_##attribute);                                              \
2276
0
    }
2277
2278
SECStatus
2279
SECKEY_CacheStaticFlags(SECKEYPrivateKey *key)
2280
0
{
2281
0
    SECStatus rv = SECFailure;
2282
0
    if (key && key->pkcs11Slot && key->pkcs11ID) {
2283
0
        key->staticflags |= SECKEY_Attributes_Cached;
2284
0
        SECKEY_CacheAttribute(key, CKA_PRIVATE);
2285
0
        SECKEY_CacheAttribute(key, CKA_ALWAYS_AUTHENTICATE);
2286
0
        rv = SECSuccess;
2287
0
    }
2288
0
    return rv;
2289
0
}
2290
2291
SECOidTag
2292
SECKEY_GetECCOid(const SECKEYECParams *params)
2293
0
{
2294
0
    SECItem oid = { siBuffer, NULL, 0 };
2295
0
    SECOidData *oidData = NULL;
2296
2297
    /*
2298
     * params->data needs to contain the ASN encoding of an object ID (OID)
2299
     * representing a named curve. Here, we strip away everything
2300
     * before the actual OID and use the OID to look up a named curve.
2301
     */
2302
0
    if (params->data[0] != SEC_ASN1_OBJECT_ID)
2303
0
        return 0;
2304
0
    oid.len = params->len - 2;
2305
0
    oid.data = params->data + 2;
2306
0
    if ((oidData = SECOID_FindOID(&oid)) == NULL)
2307
0
        return 0;
2308
2309
0
    return oidData->offset;
2310
0
}
2311
2312
static CK_MECHANISM_TYPE
2313
sec_GetHashMechanismByOidTag(SECOidTag tag)
2314
0
{
2315
0
    switch (tag) {
2316
0
        case SEC_OID_SHA512:
2317
0
            return CKM_SHA512;
2318
0
        case SEC_OID_SHA384:
2319
0
            return CKM_SHA384;
2320
0
        case SEC_OID_SHA256:
2321
0
            return CKM_SHA256;
2322
0
        case SEC_OID_SHA224:
2323
0
            return CKM_SHA224;
2324
0
        case SEC_OID_SHA1:
2325
0
            return CKM_SHA_1;
2326
0
        default:
2327
0
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
2328
0
            return CKM_INVALID_MECHANISM;
2329
0
    }
2330
0
}
2331
2332
CK_RSA_PKCS_MGF_TYPE
2333
SEC_GetMgfTypeByOidTag(SECOidTag tag)
2334
0
{
2335
0
    switch (tag) {
2336
0
        case SEC_OID_SHA3_512:
2337
0
            return CKG_MGF1_SHA3_512;
2338
0
        case SEC_OID_SHA3_384:
2339
0
            return CKG_MGF1_SHA3_384;
2340
0
        case SEC_OID_SHA3_256:
2341
0
            return CKG_MGF1_SHA3_256;
2342
0
        case SEC_OID_SHA3_224:
2343
0
            return CKG_MGF1_SHA3_224;
2344
0
        case SEC_OID_SHA512:
2345
0
            return CKG_MGF1_SHA512;
2346
0
        case SEC_OID_SHA384:
2347
0
            return CKG_MGF1_SHA384;
2348
0
        case SEC_OID_SHA256:
2349
0
            return CKG_MGF1_SHA256;
2350
0
        case SEC_OID_SHA224:
2351
0
            return CKG_MGF1_SHA224;
2352
0
        case SEC_OID_SHA1:
2353
0
            return CKG_MGF1_SHA1;
2354
0
        default:
2355
0
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
2356
0
            return 0;
2357
0
    }
2358
0
}
2359
2360
SECStatus
2361
sec_DecodeRSAPSSParams(PLArenaPool *arena,
2362
                       const SECItem *params,
2363
                       SECOidTag *retHashAlg, SECOidTag *retMaskHashAlg,
2364
                       unsigned long *retSaltLength)
2365
0
{
2366
0
    SECKEYRSAPSSParams pssParams;
2367
0
    SECOidTag hashAlg;
2368
0
    SECOidTag maskHashAlg;
2369
0
    unsigned long saltLength;
2370
0
    unsigned long trailerField;
2371
0
    SECStatus rv;
2372
2373
0
    PORT_Memset(&pssParams, 0, sizeof(pssParams));
2374
0
    rv = SEC_QuickDERDecodeItem(arena, &pssParams,
2375
0
                                SECKEY_RSAPSSParamsTemplate,
2376
0
                                params);
2377
0
    if (rv != SECSuccess) {
2378
0
        return rv;
2379
0
    }
2380
2381
0
    if (pssParams.hashAlg) {
2382
0
        hashAlg = SECOID_GetAlgorithmTag(pssParams.hashAlg);
2383
0
    } else {
2384
0
        hashAlg = SEC_OID_SHA1; /* default, SHA-1 */
2385
0
    }
2386
2387
0
    if (pssParams.maskAlg) {
2388
0
        SECAlgorithmID algId;
2389
2390
0
        if (SECOID_GetAlgorithmTag(pssParams.maskAlg) != SEC_OID_PKCS1_MGF1) {
2391
            /* only MGF1 is known to PKCS#11 */
2392
0
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
2393
0
            return SECFailure;
2394
0
        }
2395
2396
0
        rv = SEC_QuickDERDecodeItem(arena, &algId,
2397
0
                                    SEC_ASN1_GET(SECOID_AlgorithmIDTemplate),
2398
0
                                    &pssParams.maskAlg->parameters);
2399
0
        if (rv != SECSuccess) {
2400
0
            return rv;
2401
0
        }
2402
0
        maskHashAlg = SECOID_GetAlgorithmTag(&algId);
2403
0
    } else {
2404
0
        maskHashAlg = SEC_OID_SHA1; /* default, MGF1 with SHA-1 */
2405
0
    }
2406
2407
0
    if (pssParams.saltLength.data) {
2408
0
        rv = SEC_ASN1DecodeInteger((SECItem *)&pssParams.saltLength, &saltLength);
2409
0
        if (rv != SECSuccess) {
2410
0
            return rv;
2411
0
        }
2412
0
    } else {
2413
0
        saltLength = 20; /* default, 20 */
2414
0
    }
2415
2416
0
    if (pssParams.trailerField.data) {
2417
0
        rv = SEC_ASN1DecodeInteger((SECItem *)&pssParams.trailerField, &trailerField);
2418
0
        if (rv != SECSuccess) {
2419
0
            return rv;
2420
0
        }
2421
0
        if (trailerField != 1) {
2422
            /* the value must be 1, which represents the trailer field
2423
             * with hexadecimal value 0xBC */
2424
0
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
2425
0
            return SECFailure;
2426
0
        }
2427
0
    }
2428
2429
0
    if (retHashAlg) {
2430
0
        *retHashAlg = hashAlg;
2431
0
    }
2432
0
    if (retMaskHashAlg) {
2433
0
        *retMaskHashAlg = maskHashAlg;
2434
0
    }
2435
0
    if (retSaltLength) {
2436
0
        *retSaltLength = saltLength;
2437
0
    }
2438
2439
0
    return SECSuccess;
2440
0
}
2441
2442
SECStatus
2443
sec_DecodeRSAPSSParamsToMechanism(PLArenaPool *arena,
2444
                                  const SECItem *params,
2445
                                  CK_RSA_PKCS_PSS_PARAMS *mech,
2446
                                  SECOidTag *hashAlgp)
2447
0
{
2448
0
    SECOidTag hashAlg;
2449
0
    SECOidTag maskHashAlg;
2450
0
    unsigned long saltLength;
2451
0
    SECStatus rv;
2452
2453
0
    rv = sec_DecodeRSAPSSParams(arena, params,
2454
0
                                &hashAlg, &maskHashAlg, &saltLength);
2455
0
    if (rv != SECSuccess) {
2456
0
        return SECFailure;
2457
0
    }
2458
0
    *hashAlgp = hashAlg;
2459
2460
0
    mech->hashAlg = sec_GetHashMechanismByOidTag(hashAlg);
2461
0
    if (mech->hashAlg == CKM_INVALID_MECHANISM) {
2462
0
        return SECFailure;
2463
0
    }
2464
2465
0
    mech->mgf = SEC_GetMgfTypeByOidTag(maskHashAlg);
2466
0
    if (mech->mgf == 0) {
2467
0
        return SECFailure;
2468
0
    }
2469
2470
0
    mech->sLen = saltLength;
2471
2472
0
    return SECSuccess;
2473
0
}