Add 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)
This commit is contained in:
parent
91c6e157c6
commit
cad3520bf7
2 changed files with 53 additions and 4 deletions
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue