Replace NSS with Pale Moon's

This commit is contained in:
wuggy 2026-06-29 21:29:25 +01:00
commit 8c2e376f94
2870 changed files with 1762232 additions and 1374220 deletions

View file

@ -26,8 +26,6 @@ include $(CORE_DEPTH)/coreconf/config.mk
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
-include config.mk
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
@ -45,5 +43,4 @@ include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
export:: private_export

View file

@ -1,15 +0,0 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Override TARGETS variable so that only static libraries
# are specifed as dependencies within rules.mk.
#
TARGETS = $(LIBRARY)
SHARED_LIBRARY =
IMPORT_LIBRARY =
PROGRAM =

View file

@ -15,13 +15,12 @@ typedef struct {
SECItem s;
} DSA_ASN1Signature;
const SEC_ASN1Template DSA_SignatureTemplate[] =
{
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(DSA_ASN1Signature) },
{ SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature, r) },
{ SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature, s) },
{ 0 }
};
const SEC_ASN1Template DSA_SignatureTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(DSA_ASN1Signature) },
{ SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature, r) },
{ SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature, s) },
{ 0 }
};
/* Input is variable length multi-byte integer, MSB first (big endian).
** Most signficant bit of first byte is NOT treated as a sign bit.
@ -73,19 +72,18 @@ DSAU_ConvertSignedToFixedUnsigned(SECItem *dest, SECItem *src)
unsigned char *pDst = dest->data;
unsigned int cntSrc = src->len;
unsigned int cntDst = dest->len;
int zCount = cntDst - cntSrc;
if (zCount > 0) {
if (cntSrc <= cntDst) {
unsigned int zCount = cntDst - cntSrc;
PORT_Memset(pDst, 0, zCount);
PORT_Memcpy(pDst + zCount, pSrc, cntSrc);
return SECSuccess;
}
if (zCount <= 0) {
/* Source is longer than destination. Check for leading zeros. */
while (zCount++ < 0) {
if (*pSrc++ != 0)
goto loser;
}
/* Source is longer than destination: extra leading bytes must be zero. */
unsigned int extra = cntSrc - cntDst;
while (extra--) {
if (*pSrc++ != 0)
goto loser;
}
PORT_Memcpy(pDst, pSrc, cntDst);
return SECSuccess;
@ -191,6 +189,12 @@ common_DecodeDerSig(const SECItem *item, unsigned int len)
if (status != SECSuccess)
goto loser;
/* A valid DER INTEGER for r or s is at most len+1 bytes (len bytes of
** magnitude plus at most one leading zero sign byte). Reject anything
** larger before attempting the conversion to avoid pathological inputs. */
if (sig.r.len > len + 1 || sig.s.len > len + 1)
goto loser;
/* Convert sig.r and sig.s from variable length signed integers to
** fixed length unsigned integers.
*/

View file

@ -52,6 +52,11 @@ extern unsigned SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk);
*/
extern unsigned SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk);
/*
** Return the strength of the private key in bits
*/
extern unsigned SECKEY_PrivateKeyStrengthInBits(const SECKEYPrivateKey *privk);
/*
** Return the length of the signature in bytes
*/

View file

@ -4,6 +4,7 @@
#ifndef _KEYI_H_
#define _KEYI_H_
#include "secerr.h"
SEC_BEGIN_PROTOS
/* NSS private functions */
@ -17,6 +18,9 @@ KeyType seckey_GetKeyType(SECOidTag pubKeyOid);
SECStatus sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg);
/* just get the 'encryption' oid from the combined signature oid */
SECOidTag sec_GetEncAlgFromSigAlg(SECOidTag sigAlg);
/* extract the RSA-PSS hash algorithms and salt length from
* parameters, taking into account of the default implications.
*
@ -33,6 +37,9 @@ SECStatus sec_DecodeRSAPSSParamsToMechanism(PLArenaPool *arena,
const SECItem *params,
CK_RSA_PKCS_PSS_PARAMS *mech);
/* make sure the key length matches the policy for keyType */
SECStatus seckey_EnforceKeySize(KeyType keyType, unsigned keyLength,
SECErrorCodes error);
SEC_END_PROTOS
#endif /* _KEYHI_H_ */

View file

@ -9,6 +9,7 @@ MODULE = nss
REQUIRES = nssutil
LIBRARY_NAME = cryptohi
SHARED_LIBRARY = $(NULL)
EXPORTS = \
cryptohi.h \

View file

@ -14,6 +14,7 @@
#include "secdig.h"
#include "prtime.h"
#include "keyi.h"
#include "nss.h"
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
SEC_ASN1_MKSUB(SEC_IntegerTemplate)
@ -29,13 +30,12 @@ const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[] = {
{ 0 }
};
const SEC_ASN1Template CERT_PublicKeyAndChallengeTemplate[] =
{
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPublicKeyAndChallenge) },
{ SEC_ASN1_ANY, offsetof(CERTPublicKeyAndChallenge, spki) },
{ SEC_ASN1_IA5_STRING, offsetof(CERTPublicKeyAndChallenge, challenge) },
{ 0 }
};
const SEC_ASN1Template CERT_PublicKeyAndChallengeTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPublicKeyAndChallenge) },
{ SEC_ASN1_ANY, offsetof(CERTPublicKeyAndChallenge, spki) },
{ SEC_ASN1_IA5_STRING, offsetof(CERTPublicKeyAndChallenge, challenge) },
{ 0 }
};
const SEC_ASN1Template SECKEY_RSAPublicKeyTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPublicKey) },
@ -50,27 +50,26 @@ static const SEC_ASN1Template seckey_PointerToAlgorithmIDTemplate[] = {
};
/* Parameters for SEC_OID_PKCS1_RSA_PSS_SIGNATURE */
const SEC_ASN1Template SECKEY_RSAPSSParamsTemplate[] =
{
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRSAPSSParams) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
SEC_ASN1_CONTEXT_SPECIFIC | 0,
offsetof(SECKEYRSAPSSParams, hashAlg),
seckey_PointerToAlgorithmIDTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
SEC_ASN1_CONTEXT_SPECIFIC | 1,
offsetof(SECKEYRSAPSSParams, maskAlg),
seckey_PointerToAlgorithmIDTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 2,
offsetof(SECKEYRSAPSSParams, saltLength),
SEC_ASN1_SUB(SEC_IntegerTemplate) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 3,
offsetof(SECKEYRSAPSSParams, trailerField),
SEC_ASN1_SUB(SEC_IntegerTemplate) },
{ 0 }
};
const SEC_ASN1Template SECKEY_RSAPSSParamsTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRSAPSSParams) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
SEC_ASN1_CONTEXT_SPECIFIC | 0,
offsetof(SECKEYRSAPSSParams, hashAlg),
seckey_PointerToAlgorithmIDTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
SEC_ASN1_CONTEXT_SPECIFIC | 1,
offsetof(SECKEYRSAPSSParams, maskAlg),
seckey_PointerToAlgorithmIDTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 2,
offsetof(SECKEYRSAPSSParams, saltLength),
SEC_ASN1_SUB(SEC_IntegerTemplate) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 3,
offsetof(SECKEYRSAPSSParams, trailerField),
SEC_ASN1_SUB(SEC_IntegerTemplate) },
{ 0 }
};
const SEC_ASN1Template SECKEY_DSAPublicKeyTemplate[] = {
{ SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dsa.publicValue) },
@ -1042,18 +1041,75 @@ SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk)
return bitSize;
}
unsigned
SECKEY_PrivateKeyStrengthInBits(const SECKEYPrivateKey *privk)
{
unsigned bitSize = 0;
SECItem params = { siBuffer, NULL, 0 };
SECStatus rv;
if (!privk) {
PORT_SetError(SEC_ERROR_INVALID_KEY);
return 0;
}
/* interpret modulus length as key strength */
switch (privk->keyType) {
case rsaKey:
case rsaPssKey:
case rsaOaepKey:
/* some tokens don't export CKA_MODULUS on the private key,
* PK11_SignatureLen works around this if necessary */
bitSize = PK11_SignatureLen((SECKEYPrivateKey *)privk) * PR_BITS_PER_BYTE;
if (bitSize == -1) {
bitSize = 0;
}
return bitSize;
case dsaKey:
case fortezzaKey:
case dhKey:
case keaKey:
rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
CKA_PRIME, NULL, &params);
if ((rv != SECSuccess) || (params.data == NULL)) {
PORT_SetError(SEC_ERROR_INVALID_KEY);
return 0;
}
bitSize = SECKEY_BigIntegerBitLength(&params);
PORT_Free(params.data);
return bitSize;
case ecKey:
rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
CKA_EC_PARAMS, NULL, &params);
if ((rv != SECSuccess) || (params.data == NULL)) {
return 0;
}
bitSize = SECKEY_ECParamsToKeySize(&params);
PORT_Free(params.data);
return bitSize;
default:
break;
}
PORT_SetError(SEC_ERROR_INVALID_KEY);
return 0;
}
/* returns signature length in bytes (not bits) */
unsigned
SECKEY_SignatureLen(const SECKEYPublicKey *pubk)
{
unsigned char b0;
unsigned size;
switch (pubk->keyType) {
case rsaKey:
case rsaPssKey:
b0 = pubk->u.rsa.modulus.data[0];
return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
if (pubk->u.rsa.modulus.len == 0) {
return 0;
}
if (pubk->u.rsa.modulus.data[0] == 0) {
return pubk->u.rsa.modulus.len - 1;
}
return pubk->u.rsa.modulus.len;
case dsaKey:
return pubk->u.dsa.params.subPrime.len * 2;
case ecKey:
@ -1211,6 +1267,51 @@ SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk)
return NULL;
}
/*
* Check that a given key meets the policy limits for the given key
* size.
*/
SECStatus
seckey_EnforceKeySize(KeyType keyType, unsigned keyLength, SECErrorCodes error)
{
PRInt32 opt = -1;
PRInt32 optVal;
SECStatus rv;
switch (keyType) {
case rsaKey:
case rsaPssKey:
case rsaOaepKey:
opt = NSS_RSA_MIN_KEY_SIZE;
break;
case dsaKey:
case fortezzaKey:
opt = NSS_DSA_MIN_KEY_SIZE;
break;
case dhKey:
case keaKey:
opt = NSS_DH_MIN_KEY_SIZE;
break;
case ecKey:
opt = NSS_ECC_MIN_KEY_SIZE;
break;
case nullKey:
default:
PORT_SetError(SEC_ERROR_INVALID_KEY);
return SECFailure;
}
PORT_Assert(opt != -1);
rv = NSS_OptionGet(opt, &optVal);
if (rv != SECSuccess) {
return rv;
}
if (optVal > keyLength) {
PORT_SetError(error);
return SECFailure;
}
return SECSuccess;
}
/*
* Use the private key to find a public key handle. The handle will be on
* the same slot as the private key.

View file

@ -15,6 +15,7 @@
#include "pk11func.h"
#include "secerr.h"
#include "keyi.h"
#include "nss.h"
struct SGNContextStr {
SECOidTag signalg;
@ -31,6 +32,8 @@ sgn_NewContext(SECOidTag alg, SECItem *params, SECKEYPrivateKey *key)
SGNContext *cx;
SECOidTag hashalg, signalg;
KeyType keyType;
PRUint32 policyFlags;
PRInt32 optFlags;
SECStatus rv;
/* OK, map a PKCS #7 hash and encrypt algorithm into
@ -44,7 +47,7 @@ sgn_NewContext(SECOidTag alg, SECItem *params, SECKEYPrivateKey *key)
rv = sec_DecodeSigAlg(NULL, alg, params, &signalg, &hashalg);
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return 0;
return NULL;
}
keyType = seckey_GetKeyType(signalg);
@ -53,7 +56,29 @@ sgn_NewContext(SECOidTag alg, SECItem *params, SECKEYPrivateKey *key)
!((key->keyType == dsaKey) && (keyType == fortezzaKey)) &&
!((key->keyType == rsaKey) && (keyType == rsaPssKey))) {
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return 0;
return NULL;
}
if (NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &optFlags) != SECFailure) {
if (optFlags & NSS_KEY_SIZE_POLICY_SIGN_FLAG) {
rv = seckey_EnforceKeySize(key->keyType,
SECKEY_PrivateKeyStrengthInBits(key),
SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
if (rv != SECSuccess) {
return NULL;
}
}
}
/* check the policy on the hash algorithm */
if ((NSS_GetAlgorithmPolicy(hashalg, &policyFlags) == SECFailure) ||
!(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) {
PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
return NULL;
}
/* check the policy on the encryption algorithm */
if ((NSS_GetAlgorithmPolicy(signalg, &policyFlags) == SECFailure) ||
!(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) {
PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
return NULL;
}
cx = (SGNContext *)PORT_ZAlloc(sizeof(SGNContext));
@ -325,35 +350,33 @@ SEC_SignDataWithAlgorithmID(SECItem *res, const unsigned char *buf, int len,
/************************************************************************/
DERTemplate CERTSignedDataTemplate[] =
{
{ DER_SEQUENCE,
0, NULL, sizeof(CERTSignedData) },
{ DER_ANY,
offsetof(CERTSignedData, data) },
{ DER_INLINE,
offsetof(CERTSignedData, signatureAlgorithm),
SECAlgorithmIDTemplate },
{ DER_BIT_STRING,
offsetof(CERTSignedData, signature) },
{ 0 }
};
DERTemplate CERTSignedDataTemplate[] = {
{ DER_SEQUENCE,
0, NULL, sizeof(CERTSignedData) },
{ DER_ANY,
offsetof(CERTSignedData, data) },
{ DER_INLINE,
offsetof(CERTSignedData, signatureAlgorithm),
SECAlgorithmIDTemplate },
{ DER_BIT_STRING,
offsetof(CERTSignedData, signature) },
{ 0 }
};
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
const SEC_ASN1Template CERT_SignedDataTemplate[] =
{
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(CERTSignedData) },
{ SEC_ASN1_ANY,
offsetof(CERTSignedData, data) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
offsetof(CERTSignedData, signatureAlgorithm),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_BIT_STRING,
offsetof(CERTSignedData, signature) },
{ 0 }
};
const SEC_ASN1Template CERT_SignedDataTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(CERTSignedData) },
{ SEC_ASN1_ANY,
offsetof(CERTSignedData, data) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
offsetof(CERTSignedData, signatureAlgorithm),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_BIT_STRING,
offsetof(CERTSignedData, signature) },
{ 0 }
};
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SignedDataTemplate)
@ -418,7 +441,7 @@ sec_DerSignData(PLArenaPool *arena, SECItem *result,
/* DER encode the signed data object */
rv = DER_Encode(arena, result, CERTSignedDataTemplate, &sd);
/* FALL THROUGH */
/* FALL THROUGH */
loser:
PORT_Free(it.data);
@ -452,9 +475,38 @@ SGN_Digest(SECKEYPrivateKey *privKey,
SECItem digder;
PLArenaPool *arena = 0;
SGNDigestInfo *di = 0;
SECOidTag enctag;
PRUint32 policyFlags;
PRInt32 optFlags;
result->data = 0;
if (NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &optFlags) != SECFailure) {
if (optFlags & NSS_KEY_SIZE_POLICY_SIGN_FLAG) {
rv = seckey_EnforceKeySize(privKey->keyType,
SECKEY_PrivateKeyStrengthInBits(privKey),
SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
if (rv != SECSuccess) {
return SECFailure;
}
}
}
/* check the policy on the hash algorithm */
if ((NSS_GetAlgorithmPolicy(algtag, &policyFlags) == SECFailure) ||
!(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) {
PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
return SECFailure;
}
/* check the policy on the encryption algorithm */
enctag = sec_GetEncAlgFromSigAlg(
SEC_GetSignatureAlgorithmOidTag(privKey->keyType, algtag));
if ((enctag == SEC_OID_UNKNOWN) ||
(NSS_GetAlgorithmPolicy(enctag, &policyFlags) == SECFailure) ||
!(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) {
PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
return SECFailure;
}
if (privKey->keyType == rsaKey) {
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
@ -727,7 +779,7 @@ sec_CreateRSAPSSParameters(PLArenaPool *arena,
}
/* The specified salt length is too long */
if (saltLength > modBytes - hashLength - 2) {
if (saltLength > (unsigned long)(modBytes - hashLength - 2)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}

View file

@ -16,6 +16,7 @@
#include "secdig.h"
#include "secerr.h"
#include "keyi.h"
#include "nss.h"
/*
** Recover the DigestInfo from an RSA PKCS#1 signature.
@ -239,13 +240,62 @@ loser:
return SECFailure;
}
const SEC_ASN1Template hashParameterTemplate[] =
{
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) },
{ SEC_ASN1_OBJECT_ID, 0 },
{ SEC_ASN1_SKIP_REST },
{ 0 }
};
const SEC_ASN1Template hashParameterTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) },
{ SEC_ASN1_OBJECT_ID, 0 },
{ SEC_ASN1_SKIP_REST },
{ 0 }
};
/*
* Get just the encryption algorithm from the signature algorithm
*/
SECOidTag
sec_GetEncAlgFromSigAlg(SECOidTag sigAlg)
{
/* get the "encryption" algorithm */
switch (sigAlg) {
case SEC_OID_PKCS1_RSA_ENCRYPTION:
case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
return SEC_OID_PKCS1_RSA_ENCRYPTION;
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
return SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
/* what about normal DSA? */
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
return SEC_OID_ANSIX9_DSA_SIGNATURE;
case SEC_OID_MISSI_DSS:
case SEC_OID_MISSI_KEA_DSS:
case SEC_OID_MISSI_KEA_DSS_OLD:
case SEC_OID_MISSI_DSS_OLD:
return SEC_OID_MISSI_DSS;
case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
return SEC_OID_ANSIX962_EC_PUBLIC_KEY;
/* we don't implement MD4 hashes */
case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
default:
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
break;
}
return SEC_OID_UNKNOWN;
}
/*
* Pulls the hash algorithm, signing algorithm, and key type out of a
@ -260,15 +310,16 @@ const SEC_ASN1Template hashParameterTemplate[] =
*/
SECStatus
sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg)
const SECItem *param, SECOidTag *encalgp, SECOidTag *hashalg)
{
unsigned int len;
PLArenaPool *arena;
SECStatus rv;
SECItem oid;
SECOidTag encalg;
PR_ASSERT(hashalg != NULL);
PR_ASSERT(encalg != NULL);
PR_ASSERT(encalgp != NULL);
switch (sigAlg) {
/* We probably shouldn't be generating MD2 signatures either */
@ -385,52 +436,13 @@ sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return SECFailure;
}
/* get the "encryption" algorithm */
switch (sigAlg) {
case SEC_OID_PKCS1_RSA_ENCRYPTION:
case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
*encalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
break;
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
*encalg = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
break;
/* what about normal DSA? */
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
*encalg = SEC_OID_ANSIX9_DSA_SIGNATURE;
break;
case SEC_OID_MISSI_DSS:
case SEC_OID_MISSI_KEA_DSS:
case SEC_OID_MISSI_KEA_DSS_OLD:
case SEC_OID_MISSI_DSS_OLD:
*encalg = SEC_OID_MISSI_DSS;
break;
case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
*encalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
break;
/* we don't implement MD4 hashes */
case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
default:
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return SECFailure;
encalg = sec_GetEncAlgFromSigAlg(sigAlg);
if (encalg == SEC_OID_UNKNOWN) {
return SECFailure;
}
*encalgp = encalg;
return SECSuccess;
}
@ -454,6 +466,8 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig,
SECStatus rv;
unsigned int sigLen;
KeyType type;
PRUint32 policyFlags;
PRInt32 optFlags;
/* make sure the encryption algorithm matches the key type */
/* RSA-PSS algorithm can be used with both rsaKey and rsaPssKey */
@ -463,6 +477,22 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig,
PORT_SetError(SEC_ERROR_PKCS7_KEYALG_MISMATCH);
return NULL;
}
if (NSS_OptionGet(NSS_KEY_SIZE_POLICY_FLAGS, &optFlags) != SECFailure) {
if (optFlags & NSS_KEY_SIZE_POLICY_VERIFY_FLAG) {
rv = seckey_EnforceKeySize(key->keyType,
SECKEY_PublicKeyStrengthInBits(key),
SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
if (rv != SECSuccess) {
return NULL;
}
}
}
/* check the policy on the encryption algorithm */
if ((NSS_GetAlgorithmPolicy(encAlg, &policyFlags) == SECFailure) ||
!(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) {
PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
return NULL;
}
cx = (VFYContext *)PORT_ZAlloc(sizeof(VFYContext));
if (cx == NULL) {
@ -528,6 +558,14 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig,
/* error set by HASH_GetHashTypeByOidTag */
goto loser;
}
/* check the policy on the hash algorithm. Do this after
* the rsa decode because some uses of this function get hash implicitly
* from the RSA signature itself. */
if ((NSS_GetAlgorithmPolicy(cx->hashAlg, &policyFlags) == SECFailure) ||
!(policyFlags & NSS_USE_ALG_IN_ANY_SIGNATURE)) {
PORT_SetError(SEC_ERROR_SIGNATURE_ALGORITHM_DISABLED);
goto loser;
}
if (hash) {
*hash = cx->hashAlg;
@ -733,10 +771,10 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
&cx->pkcs1RSADigestInfoLen,
cx->key,
sig, cx->wincx);
PORT_Assert(cx->hashAlg == hashid);
if (rv != SECSuccess) {
return SECFailure;
}
PORT_Assert(cx->hashAlg == hashid);
}
return verifyPKCS1DigestInfo(cx, &digest);
}