Coverage Report

Created: 2025-12-20 07:02

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