summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/cms/cms_sd.c84
-rw-r--r--src/lib/libcrypto/ec/ecx_methods.c63
2 files changed, 126 insertions, 21 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) {
diff --git a/src/lib/libcrypto/ec/ecx_methods.c b/src/lib/libcrypto/ec/ecx_methods.c
index cd512a447f..ab299a8d6b 100644
--- a/src/lib/libcrypto/ec/ecx_methods.c
+++ b/src/lib/libcrypto/ec/ecx_methods.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecx_methods.c,v 1.11 2024/01/04 17:01:26 tb Exp $ */ 1/* $OpenBSD: ecx_methods.c,v 1.12 2024/03/29 06:41:58 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2022 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2022 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -17,6 +17,7 @@
17 17
18#include <string.h> 18#include <string.h>
19 19
20#include <openssl/cms.h>
20#include <openssl/curve25519.h> 21#include <openssl/curve25519.h>
21#include <openssl/ec.h> 22#include <openssl/ec.h>
22#include <openssl/err.h> 23#include <openssl/err.h>
@@ -530,10 +531,67 @@ ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
530 return -2; 531 return -2;
531} 532}
532 533
534#ifndef OPENSSL_NO_CMS
535static int
536ecx_cms_sign_or_verify(EVP_PKEY *pkey, long verify, CMS_SignerInfo *si)
537{
538 X509_ALGOR *digestAlgorithm, *signatureAlgorithm;
539 ASN1_OBJECT *aobj;
540
541 if (verify != 0 && verify != 1)
542 return -1;
543
544 /* Check that we have an Ed25519 public key. */
545 if (EVP_PKEY_id(pkey) != NID_ED25519)
546 return -1;
547
548 CMS_SignerInfo_get0_algs(si, NULL, NULL, &digestAlgorithm,
549 &signatureAlgorithm);
550
551 /* RFC 8419, section 2.3: digestAlgorithm MUST be SHA-512. */
552 if (digestAlgorithm == NULL)
553 return -1;
554 if (OBJ_obj2nid(digestAlgorithm->algorithm) != NID_sha512)
555 return -1;
556
557 /*
558 * RFC 8419, section 2.4: signatureAlgorithm MUST be Ed25519, and the
559 * parameters MUST be absent. For verification check that this is the
560 * case, for signing set the signatureAlgorithm accordingly.
561 */
562 if (verify) {
563 const ASN1_OBJECT *obj;
564 int param_type;
565
566 if (signatureAlgorithm == NULL)
567 return -1;
568
569 X509_ALGOR_get0(&obj, &param_type, NULL, signatureAlgorithm);
570 if (OBJ_obj2nid(obj) != NID_ED25519)
571 return -1;
572 if (param_type != V_ASN1_UNDEF)
573 return -1;
574
575 return 1;
576 }
577
578 if ((aobj = OBJ_nid2obj(NID_ED25519)) == NULL)
579 return -1;
580 if (!X509_ALGOR_set0(signatureAlgorithm, aobj, V_ASN1_UNDEF, NULL))
581 return -1;
582
583 return 1;
584}
585#endif
586
533static int 587static int
534ecx_sign_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 588ecx_sign_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
535{ 589{
536 switch (op) { 590 switch (op) {
591#ifndef OPENSSL_NO_CMS
592 case ASN1_PKEY_CTRL_CMS_SIGN:
593 return ecx_cms_sign_or_verify(pkey, arg1, arg2);
594#endif
537 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 595 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
538 /* PureEdDSA does its own hashing. */ 596 /* PureEdDSA does its own hashing. */
539 *(int *)arg2 = NID_undef; 597 *(int *)arg2 = NID_undef;
@@ -806,6 +864,9 @@ pkey_ecx_ed_ctrl(EVP_PKEY_CTX *pkey_ctx, int op, int arg1, void *arg2)
806 } 864 }
807 return 1; 865 return 1;
808 866
867#ifndef OPENSSL_NO_CMS
868 case EVP_PKEY_CTRL_CMS_SIGN:
869#endif
809 case EVP_PKEY_CTRL_DIGESTINIT: 870 case EVP_PKEY_CTRL_DIGESTINIT:
810 return 1; 871 return 1;
811 } 872 }