Bug Summary

File:s/lib/cryptohi/seckey.c
Warning:line 691, column 21
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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