Revert the behavior change of CMS_get1_certs() and CMS_get1_crls()

Fixes #26079

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/26100)

(cherry picked from commit afd36cbef8b3b7b00bd4bcdc33802d4cb39fdffa)
This commit is contained in:
Tomas Mraz 2024-12-03 12:40:01 +01:00
parent 5f9814d95c
commit e2ffc9e7d0
5 changed files with 65 additions and 22 deletions

View File

@ -81,7 +81,15 @@ OpenSSL 3.5
OpenSSL 3.4 OpenSSL 3.4
----------- -----------
### Changes between 3.3 and 3.4 [xx XXX xxxx] ### Changes between 3.4.0 and 3.4.1 [xx XXX xxxx]
* Reverted the behavior change of CMS_get1_certs() and CMS_get1_crls()
that happened in the 3.4.0 release. These functions now return NULL
again if there are no certs or crls in the CMS object.
*Tomáš Mráz*
### Changes between 3.3 and 3.4.0 [22 Oct 2024]
* For the FIPS provider only, replaced the primary DRBG with a continuous * For the FIPS provider only, replaced the primary DRBG with a continuous
health check module. This also removes the now forbidden DRBG chaining. health check module. This also removes the now forbidden DRBG chaining.

View File

@ -620,59 +620,91 @@ int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
{ {
STACK_OF(X509) *certs = NULL; STACK_OF(X509) *certs = NULL;
if (!ossl_cms_get1_certs_ex(cms, &certs))
return NULL;
if (sk_X509_num(certs) == 0) {
sk_X509_free(certs);
return NULL;
}
return certs;
}
int ossl_cms_get1_certs_ex(CMS_ContentInfo *cms, STACK_OF(X509) **certs)
{
CMS_CertificateChoices *cch; CMS_CertificateChoices *cch;
STACK_OF(CMS_CertificateChoices) **pcerts; STACK_OF(CMS_CertificateChoices) **pcerts;
int i, n; int i, n;
if (certs == NULL)
return 0;
*certs = NULL;
pcerts = cms_get0_certificate_choices(cms); pcerts = cms_get0_certificate_choices(cms);
if (pcerts == NULL) if (pcerts == NULL)
return NULL; return 0;
/* make sure to return NULL only on error */ /* make sure to return NULL *certs only on error */
n = sk_CMS_CertificateChoices_num(*pcerts); n = sk_CMS_CertificateChoices_num(*pcerts);
if ((certs = sk_X509_new_reserve(NULL, n)) == NULL) if ((*certs = sk_X509_new_reserve(NULL, n)) == NULL)
return NULL; return 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
cch = sk_CMS_CertificateChoices_value(*pcerts, i); cch = sk_CMS_CertificateChoices_value(*pcerts, i);
if (cch->type == 0) { if (cch->type == 0) {
if (!ossl_x509_add_cert_new(&certs, cch->d.certificate, if (!X509_add_cert(*certs, cch->d.certificate,
X509_ADD_FLAG_UP_REF)) { X509_ADD_FLAG_UP_REF)) {
OSSL_STACK_OF_X509_free(certs); OSSL_STACK_OF_X509_free(*certs);
return NULL; *certs = NULL;
return 0;
} }
} }
} }
return certs; return 1;
} }
STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
{ {
STACK_OF(X509_CRL) *crls = NULL; STACK_OF(X509_CRL) *crls = NULL;
if (!ossl_cms_get1_crls_ex(cms, &crls))
return NULL;
if (sk_X509_CRL_num(crls) == 0) {
sk_X509_CRL_free(crls);
return NULL;
}
return crls;
}
int ossl_cms_get1_crls_ex(CMS_ContentInfo *cms, STACK_OF(X509_CRL) **crls)
{
STACK_OF(CMS_RevocationInfoChoice) **pcrls; STACK_OF(CMS_RevocationInfoChoice) **pcrls;
CMS_RevocationInfoChoice *rch; CMS_RevocationInfoChoice *rch;
int i, n; int i, n;
if (crls == NULL)
return 0;
*crls = NULL;
pcrls = cms_get0_revocation_choices(cms); pcrls = cms_get0_revocation_choices(cms);
if (pcrls == NULL) if (pcrls == NULL)
return NULL; return 0;
/* make sure to return NULL only on error */ /* make sure to return NULL *crls only on error */
n = sk_CMS_RevocationInfoChoice_num(*pcrls); n = sk_CMS_RevocationInfoChoice_num(*pcrls);
if ((crls = sk_X509_CRL_new_reserve(NULL, n)) == NULL) if ((*crls = sk_X509_CRL_new_reserve(NULL, n)) == NULL)
return NULL; return 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
if (rch->type == 0) { if (rch->type == 0) {
if (!sk_X509_CRL_push(crls, rch->d.crl) if (!sk_X509_CRL_push(*crls, rch->d.crl)
|| !X509_CRL_up_ref(rch->d.crl)) { || !X509_CRL_up_ref(rch->d.crl)) {
sk_X509_CRL_pop_free(crls, X509_CRL_free); sk_X509_CRL_pop_free(*crls, X509_CRL_free);
return NULL; *crls = NULL;
return 0;
} }
} }
} }
return crls; return 1;
} }
int ossl_cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert) int ossl_cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert)

View File

@ -485,6 +485,9 @@ int ossl_cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt);
int ossl_cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt); int ossl_cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt);
int ossl_cms_rsa_sign(CMS_SignerInfo *si, int verify); int ossl_cms_rsa_sign(CMS_SignerInfo *si, int verify);
int ossl_cms_get1_certs_ex(CMS_ContentInfo *cms, STACK_OF(X509) **certs);
int ossl_cms_get1_crls_ex(CMS_ContentInfo *cms, STACK_OF(X509_CRL) **crls);
DECLARE_ASN1_ITEM(CMS_CertificateChoices) DECLARE_ASN1_ITEM(CMS_CertificateChoices)
DECLARE_ASN1_ITEM(CMS_DigestedData) DECLARE_ASN1_ITEM(CMS_DigestedData)
DECLARE_ASN1_ITEM(CMS_EncryptedData) DECLARE_ASN1_ITEM(CMS_EncryptedData)

View File

@ -361,7 +361,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
if (si_chains == NULL) if (si_chains == NULL)
goto err; goto err;
} }
if ((untrusted = CMS_get1_certs(cms)) == NULL) if (!ossl_cms_get1_certs_ex(cms, &untrusted))
goto err; goto err;
if (sk_X509_num(certs) > 0 if (sk_X509_num(certs) > 0
&& !ossl_x509_add_certs_new(&untrusted, certs, && !ossl_x509_add_certs_new(&untrusted, certs,
@ -370,7 +370,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
goto err; goto err;
if ((flags & CMS_NOCRL) == 0 if ((flags & CMS_NOCRL) == 0
&& (crls = CMS_get1_crls(cms)) == NULL) && !ossl_cms_get1_crls_ex(cms, &crls))
goto err; goto err;
for (i = 0; i < scount; i++) { for (i = 0; i < scount; i++) {
si = sk_CMS_SignerInfo_value(sinfos, i); si = sk_CMS_SignerInfo_value(sinfos, i);

View File

@ -57,8 +57,8 @@ For enveloped data they are added to B<OriginatorInfo>.
CMS_add0_cert(), CMS_add1_cert() and CMS_add0_crl() and CMS_add1_crl() return CMS_add0_cert(), CMS_add1_cert() and CMS_add0_crl() and CMS_add1_crl() return
1 for success and 0 for failure. 1 for success and 0 for failure.
CMS_get1_certs() and CMS_get1_crls() return the STACK of certificates or CRLs, CMS_get1_certs() and CMS_get1_crls() return the STACK of certificates or CRLs
which is empty if there are none. They return NULL on error. or NULL if there are none or an error occurs.
Besides out-of-memory, the only error which will occur Besides out-of-memory, the only error which will occur
in practice is if the I<cms> type is invalid. in practice is if the I<cms> type is invalid.