diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/cms/cms_sd.c | 84 | ||||
| -rw-r--r-- | src/lib/libcrypto/ec/ecx_methods.c | 63 |
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 | ||
| 280 | static const EVP_MD * | ||
| 281 | cms_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 | |||
| 309 | static const EVP_MD * | ||
| 310 | cms_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 | |||
| 280 | CMS_SignerInfo * | 338 | CMS_SignerInfo * |
| 281 | CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, | 339 | CMS_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 | ||
| 535 | static int | ||
| 536 | ecx_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, ¶m_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 | |||
| 533 | static int | 587 | static int |
| 534 | ecx_sign_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) | 588 | ecx_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 | } |
