summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/cms/cms_sd.c
diff options
context:
space:
mode:
authortb <>2024-03-29 06:41:58 +0000
committertb <>2024-03-29 06:41:58 +0000
commit207bd9bb06ecc406c0e992892c96391e5f299077 (patch)
tree9e3cf5441b7d3f91c3005a042dbb01a1c6413df4 /src/lib/libcrypto/cms/cms_sd.c
parent5d94d0325a5b03c1ba85b2e0d51af503a072cc2a (diff)
downloadopenbsd-207bd9bb06ecc406c0e992892c96391e5f299077.tar.gz
openbsd-207bd9bb06ecc406c0e992892c96391e5f299077.tar.bz2
openbsd-207bd9bb06ecc406c0e992892c96391e5f299077.zip
Implement Ed25519 signatures for CMS (RFC 8419)
This adds support for Edwards curve digital signature algorithms in the cryptographic message syntax, as specified in RFC 8419. Only Ed25519 is supported since that is the only EdDSA algorithm that LibreSSL supports (this is unlikely to change ever, but, as they say - never is a very long time). This has the usual curly interactions between EVP and CMS with poorly documented interfaces and lots of confusing magic return values and controls. This improves upon existing control handlers by documenting what is being done and why. Unlike other (draft) implementations we also happen to use the correct hashing algorithm. There are no plans to implement RFC 8418. joint work with job at p2k23 ok jsing
Diffstat (limited to 'src/lib/libcrypto/cms/cms_sd.c')
-rw-r--r--src/lib/libcrypto/cms/cms_sd.c84
1 files changed, 64 insertions, 20 deletions
diff --git a/src/lib/libcrypto/cms/cms_sd.c b/src/lib/libcrypto/cms/cms_sd.c
index b644717bbb..5a38bf59aa 100644
--- a/src/lib/libcrypto/cms/cms_sd.c
+++ b/src/lib/libcrypto/cms/cms_sd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cms_sd.c,v 1.30 2024/02/02 14:13:11 tb Exp $ */ 1/* $OpenBSD: cms_sd.c,v 1.31 2024/03/29 06:41:58 tb Exp $ */
2/* 2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 * project. 4 * project.
@@ -277,6 +277,64 @@ cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
277 return 1; 277 return 1;
278} 278}
279 279
280static const EVP_MD *
281cms_SignerInfo_default_digest_md(const CMS_SignerInfo *si)
282{
283 int rv, nid;
284
285 if (si->pkey == NULL) {
286 CMSerror(CMS_R_NO_PUBLIC_KEY);
287 return NULL;
288 }
289
290 /* On failure or unsupported operation, give up. */
291 if ((rv = EVP_PKEY_get_default_digest_nid(si->pkey, &nid)) <= 0)
292 return NULL;
293 if (rv > 2)
294 return NULL;
295
296 /*
297 * XXX - we need to identify EdDSA in a better way. Figure out where
298 * and how. This mimics EdDSA checks in openssl/ca.c and openssl/req.c.
299 */
300
301 /* The digest md is required to be EVP_sha512() (EdDSA). */
302 if (rv == 2 && nid == NID_undef)
303 return EVP_sha512();
304
305 /* Use mandatory or default digest. */
306 return EVP_get_digestbynid(nid);
307}
308
309static const EVP_MD *
310cms_SignerInfo_signature_md(const CMS_SignerInfo *si)
311{
312 int rv, nid;
313
314 if (si->pkey == NULL) {
315 CMSerror(CMS_R_NO_PUBLIC_KEY);
316 return NULL;
317 }
318
319 /* Fall back to digestAlgorithm unless pkey has a mandatory digest. */
320 if ((rv = EVP_PKEY_get_default_digest_nid(si->pkey, &nid)) <= 1)
321 return EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
322 if (rv > 2)
323 return NULL;
324
325 /*
326 * XXX - we need to identify EdDSA in a better way. Figure out where
327 * and how. This mimics EdDSA checks in openssl/ca.c and openssl/req.c.
328 */
329
330 /* The signature md is required to be EVP_md_null() (EdDSA). */
331 if (nid == NID_undef)
332 return EVP_md_null();
333
334 /* Use mandatory digest. */
335 return EVP_get_digestbynid(nid);
336}
337
280CMS_SignerInfo * 338CMS_SignerInfo *
281CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, 339CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk,
282 const EVP_MD *md, unsigned int flags) 340 const EVP_MD *md, unsigned int flags)
@@ -325,19 +383,10 @@ CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk,
325 if (!cms_set1_SignerIdentifier(si->sid, signer, type)) 383 if (!cms_set1_SignerIdentifier(si->sid, signer, type))
326 goto err; 384 goto err;
327 385
386 if (md == NULL)
387 md = cms_SignerInfo_default_digest_md(si);
328 if (md == NULL) { 388 if (md == NULL) {
329 int def_nid; 389 CMSerror(CMS_R_NO_DEFAULT_DIGEST);
330 if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
331 goto err;
332 md = EVP_get_digestbynid(def_nid);
333 if (md == NULL) {
334 CMSerror(CMS_R_NO_DEFAULT_DIGEST);
335 goto err;
336 }
337 }
338
339 if (!md) {
340 CMSerror(CMS_R_NO_DIGEST_SET);
341 goto err; 390 goto err;
342 } 391 }
343 392
@@ -735,7 +784,7 @@ CMS_SignerInfo_sign(CMS_SignerInfo *si)
735 size_t sig_len = 0; 784 size_t sig_len = 0;
736 int ret = 0; 785 int ret = 0;
737 786
738 if ((md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm)) == NULL) 787 if ((md = cms_SignerInfo_signature_md(si)) == NULL)
739 goto err; 788 goto err;
740 789
741 if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { 790 if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
@@ -795,14 +844,9 @@ CMS_SignerInfo_verify(CMS_SignerInfo *si)
795 int buf_len = 0; 844 int buf_len = 0;
796 int ret = -1; 845 int ret = -1;
797 846
798 if ((md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm)) == NULL) 847 if ((md = cms_SignerInfo_signature_md(si)) == NULL)
799 goto err; 848 goto err;
800 849
801 if (si->pkey == NULL) {
802 CMSerror(CMS_R_NO_PUBLIC_KEY);
803 goto err;
804 }
805
806 if (si->mctx == NULL) 850 if (si->mctx == NULL)
807 si->mctx = EVP_MD_CTX_new(); 851 si->mctx = EVP_MD_CTX_new();
808 if (si->mctx == NULL) { 852 if (si->mctx == NULL) {