From 6725ca40301fd732efa539cad733ec516b3e190f Mon Sep 17 00:00:00 2001 From: roytam1 Date: Tue, 26 May 2026 00:11:51 +0800 Subject: [PATCH] import from UXP: [NSS] Align PKCS7 digest array with digestAlgorithms. (089170ae) --- security/nss/lib/pkcs7/p7decode.c | 37 ++++++++++++++++++++++--------- security/nss/lib/pkcs7/p7encode.c | 4 +--- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c index 4687c239c..3f7f1eb6e 100644 --- a/security/nss/lib/pkcs7/p7decode.c +++ b/security/nss/lib/pkcs7/p7decode.c @@ -160,7 +160,9 @@ sec_pkcs7_decoder_work_data(SEC_PKCS7DecoderContext *p7dcx, */ if (len) { for (i = 0; i < worker->digcnt; i++) { - (*worker->digobjs[i]->update)(worker->digcxs[i], data, len); + if (worker->digobjs[i]) { + (*worker->digobjs[i]->update)(worker->digcxs[i], data, len); + } } } @@ -249,10 +251,10 @@ sec_pkcs7_decoder_start_digests(SEC_PKCS7DecoderContext *p7dcx, int depth, if (digcnt == 0) return SECSuccess; - p7dcx->worker.digcxs = (void **)PORT_ArenaAlloc(p7dcx->tmp_poolp, - digcnt * sizeof(void *)); - p7dcx->worker.digobjs = (const SECHashObject **)PORT_ArenaAlloc(p7dcx->tmp_poolp, - digcnt * sizeof(SECHashObject *)); + p7dcx->worker.digcxs = (void **)PORT_ArenaZAlloc(p7dcx->tmp_poolp, + digcnt * sizeof(void *)); + p7dcx->worker.digobjs = (const SECHashObject **)PORT_ArenaZAlloc(p7dcx->tmp_poolp, + digcnt * sizeof(SECHashObject *)); if (p7dcx->worker.digcxs == NULL || p7dcx->worker.digobjs == NULL) { p7dcx->error = SEC_ERROR_NO_MEMORY; return SECFailure; @@ -261,8 +263,10 @@ sec_pkcs7_decoder_start_digests(SEC_PKCS7DecoderContext *p7dcx, int depth, p7dcx->worker.depth = depth; /* - * Create a digest context for each algorithm. + * Create a digest context for each algorithm. Store at the original + * index so digcxs/digobjs stay aligned with digestAlgorithms. */ + PRBool hasDigests = PR_FALSE; for (i = 0; i < digcnt; i++) { SECAlgorithmID *algid = digestalgs[i]; SECOidTag oidTag = SECOID_FindOIDTag(&(algid->algorithm)); @@ -284,13 +288,14 @@ sec_pkcs7_decoder_start_digests(SEC_PKCS7DecoderContext *p7dcx, int depth, digcx = (*digobj->create)(); if (digcx != NULL) { (*digobj->begin)(digcx); - p7dcx->worker.digobjs[p7dcx->worker.digcnt] = digobj; - p7dcx->worker.digcxs[p7dcx->worker.digcnt] = digcx; - p7dcx->worker.digcnt++; + p7dcx->worker.digobjs[i] = digobj; + p7dcx->worker.digcxs[i] = digcx; + hasDigests = PR_TRUE; } } + p7dcx->worker.digcnt = digcnt; - if (p7dcx->worker.digcnt != 0) + if (hasDigests) SEC_ASN1DecoderSetFilterProc(p7dcx->dcx, sec_pkcs7_decoder_filter, p7dcx, @@ -358,6 +363,9 @@ sec_pkcs7_decoder_finish_digests(SEC_PKCS7DecoderContext *p7dcx, for (int i = 0; i < worker->digcnt; i++) { const SECHashObject *digobj = worker->digobjs[i]; + if (!digobj) { + continue; + } digests[i] = SECITEM_AllocItem(poolp, NULL, digobj->length); if (!digests[i]) { p7dcx->error = PORT_GetError(); @@ -370,6 +378,9 @@ sec_pkcs7_decoder_finish_digests(SEC_PKCS7DecoderContext *p7dcx, void *digcx = worker->digcxs[i]; const SECHashObject *digobj = worker->digobjs[i]; + if (!digobj) { + continue; + } (*digobj->end)(digcx, digests[i]->data, &(digests[i]->len), digests[i]->len); (*digobj->destroy)(digcx, PR_TRUE); } @@ -1473,7 +1484,7 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, * stashed in the struct itself or passed in explicitly (as would * be done for detached contents). */ - if ((digests == NULL || digests[0] == NULL) && (detached_digest == NULL || detached_digest->data == NULL)) + if (digests == NULL && (detached_digest == NULL || detached_digest->data == NULL)) goto done; /* @@ -1517,6 +1528,10 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, } digest = digests[i]; + if (digest == NULL) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } } encTag = SECOID_FindOIDTag(&(signerinfo->digestEncAlg.algorithm)); diff --git a/security/nss/lib/pkcs7/p7encode.c b/security/nss/lib/pkcs7/p7encode.c index af3da5918..52d064a19 100644 --- a/security/nss/lib/pkcs7/p7encode.c +++ b/security/nss/lib/pkcs7/p7encode.c @@ -714,11 +714,9 @@ sec_pkcs7_encoder_sig_and_certs(SEC_PKCS7ContentInfo *cinfo, if (digestalgtag == SECOID_GetAlgorithmTag(digestalgs[di])) break; } - if (digestalgs[di] == NULL) { - /* XXX oops; do what? set an error? */ + if (digestalgs[di] == NULL || digests[di] == NULL) { return SECFailure; } - PORT_Assert(digests[di] != NULL); cert = signerinfo->cert; privkey = PK11_FindKeyByAnyCert(cert, pwfnarg);