File openssl-3-support-mdless-cms.patch of Package openssl-3.40081

Backport support for md-less signature schemes in CMS

Signature schemes like Ed25519 or ML-DSA use "pure" signing,
i.e. they directly sign the tbs data instead of signing a digest.

This is already supported in the X509 code, but not in CMS.
This commit adds support for such schemes to CMS.

This is a minimalistic set of changes, based in the work done
by David von Oheimb.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26867)

--- a/crypto/cms/cms_sd.c	2023-10-24 13:41:51.000000000 +0000
+++ b/crypto/cms/cms_sd.c	2025-07-01 12:21:04.571922806 +0000
@@ -227,6 +227,14 @@ int ossl_cms_SignerIdentifier_cert_cmp(C
         return -1;
 }
 
+static int cms_signature_nomd(EVP_PKEY *pkey)
+{
+    char def_md[80];
+
+    return EVP_PKEY_get_default_digest_name(pkey, def_md, sizeof(def_md)) == 2
+        && strcmp(def_md, "UNDEF") == 0 ? 1 : 0;
+}
+
 /* Method to map any, incl. provider-implemented PKEY types to OIDs */
 /* ECDSA and DSA and all provider-delivered signatures implementation is the same */
 static int cms_generic_sign(CMS_SignerInfo *si, int verify)
@@ -251,7 +259,9 @@ static int cms_generic_sign(CMS_SignerIn
             if (typename != NULL)
                 pknid = OBJ_txt2nid(typename);
         }
-        if (!OBJ_find_sigid_by_algs(&snid, hnid, pknid))
+        if (pknid > 0 && cms_signature_nomd(pkey))
+            snid = pknid;
+        else if (!OBJ_find_sigid_by_algs(&snid, hnid, pknid))
             return -1;
         return X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, NULL);
     }
@@ -821,11 +831,12 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *
     int alen;
     size_t siglen;
     const CMS_CTX *ctx = si->cms_ctx;
-    char md_name[OSSL_MAX_NAME_SIZE];
+    char md_name_buf[OSSL_MAX_NAME_SIZE], *md_name;
 
-    if (OBJ_obj2txt(md_name, sizeof(md_name),
+    if (OBJ_obj2txt(md_name_buf, sizeof(md_name_buf),
                      si->digestAlgorithm->algorithm, 0) <= 0)
         return 0;
+    md_name = cms_signature_nomd(si->pkey) ? NULL : md_name_buf;
 
     if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
         if (!cms_add1_signingTime(si, NULL))
@@ -847,6 +858,13 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *
         si->pctx = pctx;
     }
 
+    if (md_name == NULL) {
+        if (ASN1_item_sign_ctx(ASN1_ITEM_rptr(CMS_Attributes_Sign), NULL,
+                               NULL, si->signature, si->signedAttrs, mctx) <= 0)
+            goto err;
+        return 1;
+    }
+
     alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
                          ASN1_ITEM_rptr(CMS_Attributes_Sign));
     if (!abuf)
@@ -894,6 +912,16 @@ int CMS_SignerInfo_verify(CMS_SignerInfo
     if (!ossl_cms_si_check_attributes(si))
         return -1;
 
+    if (cms_signature_nomd(si->pkey)) {
+        r = ASN1_item_verify_ex(ASN1_ITEM_rptr(CMS_Attributes_Sign),
+                                si->signatureAlgorithm, si->signature,
+                                si->signedAttrs, NULL, si->pkey,
+                                libctx, propq);
+        if (r <= 0)
+            ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE);
+        return r;
+    }
+
     OBJ_obj2txt(name, sizeof(name), si->digestAlgorithm->algorithm, 0);
 
     (void)ERR_set_mark();
openSUSE Build Service is sponsored by