Update NSS to 3.35-RTM

This commit is contained in:
wolfbeast 2018-02-23 11:04:39 +01:00 committed by Roy Tam
commit 66dd670b60
388 changed files with 39075 additions and 20752 deletions

View file

@ -136,6 +136,8 @@ struct VFYContextStr {
unsigned char dsasig[DSA_MAX_SIGNATURE_LEN];
/* the full ECDSA signature */
unsigned char ecdsasig[2 * MAX_ECKEY_LEN];
/* the full RSA signature, only used in RSA-PSS */
unsigned char rsasig[(RSA_MAX_MODULUS_BITS + 7) / 8];
} u;
unsigned int pkcs1RSADigestInfoLen;
/* the encoded DigestInfo from a RSA PKCS#1 signature */
@ -148,6 +150,7 @@ struct VFYContextStr {
* VFY_CreateContext call. If false, the
* signature must be provided with a
* VFY_EndWithSignature call. */
SECItem *params;
};
static SECStatus
@ -250,9 +253,38 @@ sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
*hashalg = SEC_OID_SHA1;
break;
case SEC_OID_PKCS1_RSA_ENCRYPTION:
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
*hashalg = SEC_OID_UNKNOWN; /* get it from the RSA signature */
break;
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
if (param && param->data) {
SECKEYRSAPSSParams pssParam;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
return SECFailure;
}
PORT_Memset(&pssParam, 0, sizeof pssParam);
rv = SEC_QuickDERDecodeItem(arena, &pssParam,
SECKEY_RSAPSSParamsTemplate,
param);
if (rv != SECSuccess) {
PORT_FreeArena(arena, PR_FALSE);
return rv;
}
if (pssParam.hashAlg) {
*hashalg = SECOID_GetAlgorithmTag(pssParam.hashAlg);
} else {
*hashalg = SEC_OID_SHA1; /* default, SHA-1 */
}
PORT_FreeArena(arena, PR_FALSE);
/* only accept hash algorithms */
if (HASH_GetHashTypeByOidTag(*hashalg) == HASH_AlgNULL) {
/* error set by HASH_GetHashTypeByOidTag */
return SECFailure;
}
} else {
*hashalg = SEC_OID_SHA1; /* default, SHA-1 */
}
break;
case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
@ -434,6 +466,20 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig,
cx->key,
sig, wincx);
break;
case rsaPssKey:
sigLen = SECKEY_SignatureLen(key);
if (sigLen == 0) {
/* error set by SECKEY_SignatureLen */
rv = SECFailure;
break;
}
if (sig->len != sigLen) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
rv = SECFailure;
break;
}
PORT_Memcpy(cx->u.buffer, sig->data, sigLen);
break;
case dsaKey:
case ecKey:
sigLen = SECKEY_SignatureLen(key);
@ -496,6 +542,7 @@ VFYContext *
VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key, const SECItem *sig,
const SECAlgorithmID *sigAlgorithm, SECOidTag *hash, void *wincx)
{
VFYContext *cx;
SECOidTag encAlg, hashAlg;
SECStatus rv = sec_DecodeSigAlg(key,
SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm),
@ -503,7 +550,13 @@ VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key, const SECItem *sig,
if (rv != SECSuccess) {
return NULL;
}
return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
cx = vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
if (sigAlgorithm->parameters.data) {
cx->params = SECITEM_DupItem(&sigAlgorithm->parameters);
}
return cx;
}
void
@ -520,6 +573,9 @@ VFY_DestroyContext(VFYContext *cx, PRBool freeit)
if (cx->pkcs1RSADigestInfo) {
PORT_Free(cx->pkcs1RSADigestInfo);
}
if (cx->params) {
SECITEM_FreeItem(cx->params, PR_TRUE);
}
if (freeit) {
PORT_ZFree(cx, sizeof(VFYContext));
}
@ -562,7 +618,7 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
{
unsigned char final[HASH_LENGTH_MAX];
unsigned part;
SECItem hash, dsasig; /* dsasig is also used for ECDSA */
SECItem hash, rsasig, dsasig; /* dsasig is also used for ECDSA */
SECStatus rv;
if ((cx->hasSignature == PR_FALSE) && (sig == NULL)) {
@ -598,25 +654,70 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
return SECFailure;
}
break;
case rsaKey: {
SECItem digest;
digest.data = final;
digest.len = part;
if (sig) {
SECOidTag hashid;
PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN);
rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid,
&cx->pkcs1RSADigestInfo,
&cx->pkcs1RSADigestInfoLen,
cx->key,
sig, cx->wincx);
PORT_Assert(cx->hashAlg == hashid);
case rsaKey:
if (cx->encAlg == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
CK_RSA_PKCS_PSS_PARAMS mech;
SECItem mechItem = { siBuffer, (unsigned char *)&mech, sizeof(mech) };
SECKEYRSAPSSParams params;
PLArenaPool *arena;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
return SECFailure;
}
PORT_Memset(&params, 0, sizeof(params));
rv = SEC_QuickDERDecodeItem(arena, &params,
SECKEY_RSAPSSParamsTemplate,
cx->params);
if (rv != SECSuccess) {
PORT_FreeArena(arena, PR_FALSE);
return SECFailure;
}
rv = sec_RSAPSSParamsToMechanism(&mech, &params);
PORT_FreeArena(arena, PR_FALSE);
if (rv != SECSuccess) {
return SECFailure;
}
rsasig.data = cx->u.buffer;
rsasig.len = SECKEY_SignatureLen(cx->key);
if (rsasig.len == 0) {
return SECFailure;
}
if (sig) {
if (sig->len != rsasig.len) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
return SECFailure;
}
PORT_Memcpy(rsasig.data, sig->data, rsasig.len);
}
hash.data = final;
hash.len = part;
if (PK11_VerifyWithMechanism(cx->key, CKM_RSA_PKCS_PSS, &mechItem,
&rsasig, &hash, cx->wincx) != SECSuccess) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
return SECFailure;
}
} else {
SECItem digest;
digest.data = final;
digest.len = part;
if (sig) {
SECOidTag hashid;
PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN);
rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid,
&cx->pkcs1RSADigestInfo,
&cx->pkcs1RSADigestInfoLen,
cx->key,
sig, cx->wincx);
PORT_Assert(cx->hashAlg == hashid);
if (rv != SECSuccess) {
return SECFailure;
}
}
return verifyPKCS1DigestInfo(cx, &digest);
}
return verifyPKCS1DigestInfo(cx, &digest);
}
break;
default:
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
return SECFailure; /* shouldn't happen */
@ -722,7 +823,7 @@ VFY_VerifyDigestWithAlgorithmID(const SECItem *digest,
static SECStatus
vfy_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key,
const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg,
SECOidTag *hash, void *wincx)
const SECItem *params, SECOidTag *hash, void *wincx)
{
SECStatus rv;
VFYContext *cx;
@ -730,6 +831,9 @@ vfy_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key,
cx = vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
if (cx == NULL)
return SECFailure;
if (params) {
cx->params = SECITEM_DupItem(params);
}
rv = VFY_Begin(cx);
if (rv == SECSuccess) {
@ -748,7 +852,7 @@ VFY_VerifyDataDirect(const unsigned char *buf, int len,
SECOidTag encAlg, SECOidTag hashAlg,
SECOidTag *hash, void *wincx)
{
return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx);
return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, NULL, hash, wincx);
}
SECStatus
@ -760,7 +864,7 @@ VFY_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key,
if (rv != SECSuccess) {
return rv;
}
return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, NULL, wincx);
return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, NULL, NULL, wincx);
}
SECStatus
@ -777,5 +881,6 @@ VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, int len,
if (rv != SECSuccess) {
return rv;
}
return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx);
return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg,
&sigAlgorithm->parameters, hash, wincx);
}