diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c index 04b21455a9..a23fe9f97b 100644 --- a/crypto/cms/cms_sd.c +++ b/crypto/cms/cms_sd.c @@ -225,6 +225,14 @@ int ossl_cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) 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 */ /* (EC)DSA and all provider-delivered signatures implementation is the same */ static int cms_generic_sign(CMS_SignerInfo *si, int verify) @@ -249,7 +257,9 @@ static int cms_generic_sign(CMS_SignerInfo *si, int verify) 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); } @@ -847,11 +857,12 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) 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 (!si->omit_signing_time && CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { @@ -875,6 +886,13 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) 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 (alen < 0 || abuf == NULL) @@ -922,6 +940,16 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) 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(); diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t index c25cb7c949..d0801994c7 100644 --- a/test/recipes/80-test_cms.t +++ b/test/recipes/80-test_cms.t @@ -52,7 +52,7 @@ my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib) $no_rc2 = 1 if disabled("legacy"); -plan tests => 27; +plan tests => 28; ok(run(test(["pkcs7_test"])), "test pkcs7"); @@ -1377,3 +1377,24 @@ subtest "encrypt to three recipients with RSA-OAEP, key only decrypt" => sub { "decrypt with key only"); is(compare($pt, $ptpt), 0, "compare original message with decrypted ciphertext"); }; + +subtest "EdDSA tests for CMS \n" => sub { + plan tests => 2; + + SKIP: { + skip "ECX (EdDSA) is not supported in this build", 2 + if disabled("ecx"); + + my $crt1 = srctop_file("test", "certs", "root-ed25519.pem"); + my $key1 = srctop_file("test", "certs", "root-ed25519.privkey.pem"); + my $sig1 = "sig1.cms"; + + ok(run(app(["openssl", "cms", @prov, "-sign", "-md", "sha512", "-in", $smcont, + "-signer", $crt1, "-inkey", $key1, "-out", $sig1])), + "accept CMS signature with Ed25519"); + + ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig1, + "-CAfile", $crt1, "-content", $smcont])), + "accept CMS verify with Ed25519"); + } +};