cms_sd.c revision 1.31
1/* $OpenBSD: cms_sd.c,v 1.31 2024/03/29 06:41:58 tb Exp $ */ 2/* 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4 * project. 5 */ 6/* ==================================================================== 7 * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * licensing@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 */ 54 55#include <stdlib.h> 56#include <string.h> 57 58#include <openssl/asn1.h> 59#include <openssl/bio.h> 60#include <openssl/err.h> 61#include <openssl/evp.h> 62#include <openssl/cms.h> 63#include <openssl/objects.h> 64#include <openssl/x509.h> 65#include <openssl/x509v3.h> 66 67#include "asn1_local.h" 68#include "cms_local.h" 69#include "evp_local.h" 70#include "x509_local.h" 71 72/* CMS SignedData Utilities */ 73 74static CMS_SignedData * 75cms_get0_signed(CMS_ContentInfo *cms) 76{ 77 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) { 78 CMSerror(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); 79 return NULL; 80 } 81 return cms->d.signedData; 82} 83 84static CMS_SignedData * 85cms_signed_data_init(CMS_ContentInfo *cms) 86{ 87 if (cms->d.other == NULL) { 88 cms->d.signedData = (CMS_SignedData *)ASN1_item_new(&CMS_SignedData_it); 89 if (!cms->d.signedData) { 90 CMSerror(ERR_R_MALLOC_FAILURE); 91 return NULL; 92 } 93 cms->d.signedData->version = 1; 94 cms->d.signedData->encapContentInfo->eContentType = 95 OBJ_nid2obj(NID_pkcs7_data); 96 cms->d.signedData->encapContentInfo->partial = 1; 97 ASN1_OBJECT_free(cms->contentType); 98 cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); 99 return cms->d.signedData; 100 } 101 return cms_get0_signed(cms); 102} 103 104/* Just initialise SignedData e.g. for certs only structure */ 105 106int 107CMS_SignedData_init(CMS_ContentInfo *cms) 108{ 109 if (cms_signed_data_init(cms)) 110 return 1; 111 else 112 return 0; 113} 114LCRYPTO_ALIAS(CMS_SignedData_init); 115 116/* Check structures and fixup version numbers (if necessary) */ 117 118static void 119cms_sd_set_version(CMS_SignedData *sd) 120{ 121 int i; 122 CMS_CertificateChoices *cch; 123 CMS_RevocationInfoChoice *rch; 124 CMS_SignerInfo *si; 125 126 for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) { 127 cch = sk_CMS_CertificateChoices_value(sd->certificates, i); 128 if (cch->type == CMS_CERTCHOICE_OTHER) { 129 if (sd->version < 5) 130 sd->version = 5; 131 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { 132 if (sd->version < 4) 133 sd->version = 4; 134 } else if (cch->type == CMS_CERTCHOICE_V1ACERT) { 135 if (sd->version < 3) 136 sd->version = 3; 137 } 138 } 139 140 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) { 141 rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i); 142 if (rch->type == CMS_REVCHOICE_OTHER) { 143 if (sd->version < 5) 144 sd->version = 5; 145 } 146 } 147 148 if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data) 149 && (sd->version < 3)) 150 sd->version = 3; 151 152 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { 153 si = sk_CMS_SignerInfo_value(sd->signerInfos, i); 154 if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { 155 if (si->version < 3) 156 si->version = 3; 157 if (sd->version < 3) 158 sd->version = 3; 159 } else if (si->version < 1) 160 si->version = 1; 161 } 162 163 if (sd->version < 1) 164 sd->version = 1; 165} 166 167/* Copy an existing messageDigest value */ 168 169static int 170cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) 171{ 172 STACK_OF(CMS_SignerInfo) *sinfos; 173 CMS_SignerInfo *sitmp; 174 int i; 175 176 sinfos = CMS_get0_SignerInfos(cms); 177 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 178 ASN1_OCTET_STRING *messageDigest; 179 sitmp = sk_CMS_SignerInfo_value(sinfos, i); 180 if (sitmp == si) 181 continue; 182 if (CMS_signed_get_attr_count(sitmp) < 0) 183 continue; 184 if (OBJ_cmp(si->digestAlgorithm->algorithm, 185 sitmp->digestAlgorithm->algorithm)) 186 continue; 187 messageDigest = CMS_signed_get0_data_by_OBJ(sitmp, 188 OBJ_nid2obj(NID_pkcs9_messageDigest), -3, V_ASN1_OCTET_STRING); 189 if (!messageDigest) { 190 CMSerror(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); 191 return 0; 192 } 193 194 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, 195 V_ASN1_OCTET_STRING, messageDigest, -1)) 196 return 1; 197 else 198 return 0; 199 } 200 201 CMSerror(CMS_R_NO_MATCHING_DIGEST); 202 203 return 0; 204} 205 206int 207cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) 208{ 209 switch (type) { 210 case CMS_SIGNERINFO_ISSUER_SERIAL: 211 if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert)) 212 return 0; 213 break; 214 215 case CMS_SIGNERINFO_KEYIDENTIFIER: 216 if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert)) 217 return 0; 218 break; 219 220 default: 221 CMSerror(CMS_R_UNKNOWN_ID); 222 return 0; 223 } 224 225 sid->type = type; 226 227 return 1; 228} 229 230int 231cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, 232 ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno) 233{ 234 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { 235 if (issuer) 236 *issuer = sid->d.issuerAndSerialNumber->issuer; 237 if (sno) 238 *sno = sid->d.issuerAndSerialNumber->serialNumber; 239 } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { 240 if (keyid) 241 *keyid = sid->d.subjectKeyIdentifier; 242 } else 243 return 0; 244 245 return 1; 246} 247 248int 249cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) 250{ 251 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) 252 return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert); 253 else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) 254 return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert); 255 else 256 return -1; 257} 258 259static int 260cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd) 261{ 262 EVP_PKEY *pkey = si->pkey; 263 int ret; 264 265 if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) 266 return 1; 267 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si); 268 if (ret == -2) { 269 CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 270 return 0; 271 } 272 if (ret <= 0) { 273 CMSerror(CMS_R_CTRL_FAILURE); 274 return 0; 275 } 276 277 return 1; 278} 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 338CMS_SignerInfo * 339CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, 340 const EVP_MD *md, unsigned int flags) 341{ 342 CMS_SignedData *sd; 343 CMS_SignerInfo *si = NULL; 344 X509_ALGOR *alg = NULL; 345 int i, type; 346 347 if (!X509_check_private_key(signer, pk)) { 348 CMSerror(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 349 return NULL; 350 } 351 sd = cms_signed_data_init(cms); 352 if (!sd) 353 goto err; 354 si = (CMS_SignerInfo *)ASN1_item_new(&CMS_SignerInfo_it); 355 if (!si) 356 goto merr; 357 /* Call for side-effect of computing hash and caching extensions */ 358 X509_check_purpose(signer, -1, -1); 359 360 X509_up_ref(signer); 361 EVP_PKEY_up_ref(pk); 362 363 si->pkey = pk; 364 si->signer = signer; 365 si->mctx = EVP_MD_CTX_new(); 366 si->pctx = NULL; 367 368 if (si->mctx == NULL) { 369 CMSerror(ERR_R_MALLOC_FAILURE); 370 goto err; 371 } 372 373 if (flags & CMS_USE_KEYID) { 374 si->version = 3; 375 if (sd->version < 3) 376 sd->version = 3; 377 type = CMS_SIGNERINFO_KEYIDENTIFIER; 378 } else { 379 type = CMS_SIGNERINFO_ISSUER_SERIAL; 380 si->version = 1; 381 } 382 383 if (!cms_set1_SignerIdentifier(si->sid, signer, type)) 384 goto err; 385 386 if (md == NULL) 387 md = cms_SignerInfo_default_digest_md(si); 388 if (md == NULL) { 389 CMSerror(CMS_R_NO_DEFAULT_DIGEST); 390 goto err; 391 } 392 393 if (!X509_ALGOR_set_evp_md(si->digestAlgorithm, md)) 394 goto err; 395 396 /* See if digest is present in digestAlgorithms */ 397 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { 398 const X509_ALGOR *x509_alg; 399 const ASN1_OBJECT *aoid; 400 401 x509_alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); 402 X509_ALGOR_get0(&aoid, NULL, NULL, x509_alg); 403 if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) 404 break; 405 } 406 407 if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { 408 if ((alg = X509_ALGOR_new()) == NULL) 409 goto merr; 410 if (!X509_ALGOR_set_evp_md(alg, md)) 411 goto merr; 412 if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { 413 goto merr; 414 } 415 alg = NULL; 416 } 417 418 if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0)) 419 goto err; 420 if (!(flags & CMS_NOATTR)) { 421 /* 422 * Initialize signed attributes structure so other attributes 423 * such as signing time etc are added later even if we add none here. 424 */ 425 if (!si->signedAttrs) { 426 si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); 427 if (!si->signedAttrs) 428 goto merr; 429 } 430 431 if (!(flags & CMS_NOSMIMECAP)) { 432 STACK_OF(X509_ALGOR) *smcap = NULL; 433 434 i = CMS_add_standard_smimecap(&smcap); 435 if (i) 436 i = CMS_add_smimecap(si, smcap); 437 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 438 if (!i) 439 goto merr; 440 } 441 if (flags & CMS_REUSE_DIGEST) { 442 if (!cms_copy_messageDigest(cms, si)) 443 goto err; 444 if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) && 445 !CMS_SignerInfo_sign(si)) 446 goto err; 447 } 448 } 449 450 if (!(flags & CMS_NOCERTS)) { 451 /* NB ignore -1 return for duplicate cert */ 452 if (!CMS_add1_cert(cms, signer)) 453 goto merr; 454 } 455 456 if (flags & CMS_KEY_PARAM) { 457 if (flags & CMS_NOATTR) { 458 si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL); 459 if (si->pctx == NULL) 460 goto err; 461 if (EVP_PKEY_sign_init(si->pctx) <= 0) 462 goto err; 463 if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0) 464 goto err; 465 } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, 466 NULL, pk) <= 0) 467 goto err; 468 } 469 470 if (!sd->signerInfos) 471 sd->signerInfos = sk_CMS_SignerInfo_new_null(); 472 if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) 473 goto merr; 474 475 return si; 476 477 merr: 478 CMSerror(ERR_R_MALLOC_FAILURE); 479 err: 480 ASN1_item_free((ASN1_VALUE *)si, &CMS_SignerInfo_it); 481 X509_ALGOR_free(alg); 482 483 return NULL; 484} 485LCRYPTO_ALIAS(CMS_add1_signer); 486 487static int 488cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) 489{ 490 ASN1_TIME *tt; 491 int r = 0; 492 493 if (t) 494 tt = t; 495 else 496 tt = X509_gmtime_adj(NULL, 0); 497 498 if (!tt) 499 goto merr; 500 501 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, 502 tt->type, tt, -1) <= 0) 503 goto merr; 504 505 r = 1; 506 507 merr: 508 if (!t) 509 ASN1_TIME_free(tt); 510 if (!r) 511 CMSerror(ERR_R_MALLOC_FAILURE); 512 513 return r; 514} 515 516EVP_PKEY_CTX * 517CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si) 518{ 519 return si->pctx; 520} 521LCRYPTO_ALIAS(CMS_SignerInfo_get0_pkey_ctx); 522 523EVP_MD_CTX * 524CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si) 525{ 526 return si->mctx; 527} 528LCRYPTO_ALIAS(CMS_SignerInfo_get0_md_ctx); 529 530STACK_OF(CMS_SignerInfo) * 531CMS_get0_SignerInfos(CMS_ContentInfo *cms) 532{ 533 CMS_SignedData *sd; 534 535 sd = cms_get0_signed(cms); 536 if (!sd) 537 return NULL; 538 539 return sd->signerInfos; 540} 541LCRYPTO_ALIAS(CMS_get0_SignerInfos); 542 543STACK_OF(X509) * 544CMS_get0_signers(CMS_ContentInfo *cms) 545{ 546 STACK_OF(X509) *signers = NULL; 547 STACK_OF(CMS_SignerInfo) *sinfos; 548 CMS_SignerInfo *si; 549 int i; 550 551 sinfos = CMS_get0_SignerInfos(cms); 552 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 553 si = sk_CMS_SignerInfo_value(sinfos, i); 554 if (si->signer) { 555 if (!signers) { 556 signers = sk_X509_new_null(); 557 if (!signers) 558 return NULL; 559 } 560 if (!sk_X509_push(signers, si->signer)) { 561 sk_X509_free(signers); 562 return NULL; 563 } 564 } 565 } 566 567 return signers; 568} 569LCRYPTO_ALIAS(CMS_get0_signers); 570 571void 572CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) 573{ 574 if (signer) { 575 X509_up_ref(signer); 576 EVP_PKEY_free(si->pkey); 577 si->pkey = X509_get_pubkey(signer); 578 } 579 X509_free(si->signer); 580 si->signer = signer; 581} 582LCRYPTO_ALIAS(CMS_SignerInfo_set1_signer_cert); 583 584int 585CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, ASN1_OCTET_STRING **keyid, 586 X509_NAME **issuer, ASN1_INTEGER **sno) 587{ 588 return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); 589} 590LCRYPTO_ALIAS(CMS_SignerInfo_get0_signer_id); 591 592int 593CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) 594{ 595 return cms_SignerIdentifier_cert_cmp(si->sid, cert); 596} 597LCRYPTO_ALIAS(CMS_SignerInfo_cert_cmp); 598 599int 600CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, 601 unsigned int flags) 602{ 603 CMS_SignedData *sd; 604 CMS_SignerInfo *si; 605 CMS_CertificateChoices *cch; 606 STACK_OF(CMS_CertificateChoices) *certs; 607 X509 *x; 608 int i, j; 609 int ret = 0; 610 611 sd = cms_get0_signed(cms); 612 if (!sd) 613 return -1; 614 certs = sd->certificates; 615 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { 616 si = sk_CMS_SignerInfo_value(sd->signerInfos, i); 617 if (si->signer) 618 continue; 619 620 for (j = 0; j < sk_X509_num(scerts); j++) { 621 x = sk_X509_value(scerts, j); 622 if (CMS_SignerInfo_cert_cmp(si, x) == 0) { 623 CMS_SignerInfo_set1_signer_cert(si, x); 624 ret++; 625 break; 626 } 627 } 628 629 if (si->signer || (flags & CMS_NOINTERN)) 630 continue; 631 632 for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { 633 cch = sk_CMS_CertificateChoices_value(certs, j); 634 if (cch->type != 0) 635 continue; 636 x = cch->d.certificate; 637 if (CMS_SignerInfo_cert_cmp(si, x) == 0) { 638 CMS_SignerInfo_set1_signer_cert(si, x); 639 ret++; 640 break; 641 } 642 } 643 } 644 return ret; 645} 646LCRYPTO_ALIAS(CMS_set1_signers_certs); 647 648void 649CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, 650X509_ALGOR **pdig, X509_ALGOR **psig) 651{ 652 if (pk) 653 *pk = si->pkey; 654 if (signer) 655 *signer = si->signer; 656 if (pdig) 657 *pdig = si->digestAlgorithm; 658 if (psig) 659 *psig = si->signatureAlgorithm; 660} 661LCRYPTO_ALIAS(CMS_SignerInfo_get0_algs); 662 663ASN1_OCTET_STRING * 664CMS_SignerInfo_get0_signature(CMS_SignerInfo *si) 665{ 666 return si->signature; 667} 668LCRYPTO_ALIAS(CMS_SignerInfo_get0_signature); 669 670static int 671cms_SignerInfo_content_sign(CMS_ContentInfo *cms, CMS_SignerInfo *si, BIO *chain) 672{ 673 EVP_MD_CTX *mctx = EVP_MD_CTX_new(); 674 int r = 0; 675 EVP_PKEY_CTX *pctx = NULL; 676 677 if (mctx == NULL) { 678 CMSerror(ERR_R_MALLOC_FAILURE); 679 return 0; 680 } 681 682 if (!si->pkey) { 683 CMSerror(CMS_R_NO_PRIVATE_KEY); 684 goto err; 685 } 686 687 if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm)) 688 goto err; 689 /* Set SignerInfo algorithm details if we used custom parameter */ 690 if (si->pctx && !cms_sd_asn1_ctrl(si, 0)) 691 goto err; 692 693 /* 694 * If any signed attributes calculate and add messageDigest attribute 695 */ 696 697 if (CMS_signed_get_attr_count(si) >= 0) { 698 ASN1_OBJECT *ctype = 699 cms->d.signedData->encapContentInfo->eContentType; 700 unsigned char md[EVP_MAX_MD_SIZE]; 701 unsigned int mdlen; 702 703 if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) 704 goto err; 705 if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, 706 V_ASN1_OCTET_STRING, md, mdlen)) 707 goto err; 708 /* Copy content type across */ 709 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType, 710 V_ASN1_OBJECT, ctype, -1) <= 0) 711 goto err; 712 if (!CMS_SignerInfo_sign(si)) 713 goto err; 714 } else if (si->pctx) { 715 unsigned char *sig; 716 size_t siglen; 717 unsigned char md[EVP_MAX_MD_SIZE]; 718 unsigned int mdlen; 719 720 pctx = si->pctx; 721 if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) 722 goto err; 723 siglen = EVP_PKEY_size(si->pkey); 724 sig = malloc(siglen); 725 if (sig == NULL) { 726 CMSerror(ERR_R_MALLOC_FAILURE); 727 goto err; 728 } 729 if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) { 730 free(sig); 731 goto err; 732 } 733 ASN1_STRING_set0(si->signature, sig, siglen); 734 } else { 735 unsigned char *sig; 736 unsigned int siglen; 737 738 sig = malloc(EVP_PKEY_size(si->pkey)); 739 if (sig == NULL) { 740 CMSerror(ERR_R_MALLOC_FAILURE); 741 goto err; 742 } 743 if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) { 744 CMSerror(CMS_R_SIGNFINAL_ERROR); 745 free(sig); 746 goto err; 747 } 748 ASN1_STRING_set0(si->signature, sig, siglen); 749 } 750 751 r = 1; 752 753 err: 754 EVP_MD_CTX_free(mctx); 755 EVP_PKEY_CTX_free(pctx); 756 757 return r; 758} 759 760int 761cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) 762{ 763 STACK_OF(CMS_SignerInfo) *sinfos; 764 CMS_SignerInfo *si; 765 int i; 766 767 sinfos = CMS_get0_SignerInfos(cms); 768 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 769 si = sk_CMS_SignerInfo_value(sinfos, i); 770 if (!cms_SignerInfo_content_sign(cms, si, chain)) 771 return 0; 772 } 773 cms->d.signedData->encapContentInfo->partial = 0; 774 775 return 1; 776} 777 778int 779CMS_SignerInfo_sign(CMS_SignerInfo *si) 780{ 781 const EVP_MD *md; 782 unsigned char *buf = NULL, *sig = NULL; 783 int buf_len = 0; 784 size_t sig_len = 0; 785 int ret = 0; 786 787 if ((md = cms_SignerInfo_signature_md(si)) == NULL) 788 goto err; 789 790 if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { 791 if (!cms_add1_signingTime(si, NULL)) 792 goto err; 793 } 794 795 if (si->pctx == NULL) { 796 (void)EVP_MD_CTX_reset(si->mctx); 797 if (!EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, si->pkey)) 798 goto err; 799 } 800 801 if (EVP_PKEY_CTX_ctrl(si->pctx, -1, EVP_PKEY_OP_SIGN, 802 EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { 803 CMSerror(CMS_R_CTRL_ERROR); 804 goto err; 805 } 806 807 if ((buf_len = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &buf, 808 &CMS_Attributes_Sign_it)) <= 0) { 809 buf_len = 0; 810 goto err; 811 } 812 if (!EVP_DigestSign(si->mctx, NULL, &sig_len, buf, buf_len)) 813 goto err; 814 if ((sig = calloc(1, sig_len)) == NULL) 815 goto err; 816 if (!EVP_DigestSign(si->mctx, sig, &sig_len, buf, buf_len)) 817 goto err; 818 819 if (EVP_PKEY_CTX_ctrl(si->pctx, -1, EVP_PKEY_OP_SIGN, 820 EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { 821 CMSerror(CMS_R_CTRL_ERROR); 822 goto err; 823 } 824 825 ASN1_STRING_set0(si->signature, sig, sig_len); 826 sig = NULL; 827 828 ret = 1; 829 830 err: 831 (void)EVP_MD_CTX_reset(si->mctx); 832 freezero(buf, buf_len); 833 freezero(sig, sig_len); 834 835 return ret; 836} 837LCRYPTO_ALIAS(CMS_SignerInfo_sign); 838 839int 840CMS_SignerInfo_verify(CMS_SignerInfo *si) 841{ 842 const EVP_MD *md; 843 unsigned char *buf = NULL; 844 int buf_len = 0; 845 int ret = -1; 846 847 if ((md = cms_SignerInfo_signature_md(si)) == NULL) 848 goto err; 849 850 if (si->mctx == NULL) 851 si->mctx = EVP_MD_CTX_new(); 852 if (si->mctx == NULL) { 853 CMSerror(ERR_R_MALLOC_FAILURE); 854 goto err; 855 } 856 857 if (EVP_DigestVerifyInit(si->mctx, &si->pctx, md, NULL, si->pkey) <= 0) 858 goto err; 859 860 if (!cms_sd_asn1_ctrl(si, 1)) 861 goto err; 862 863 if ((buf_len = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &buf, 864 &CMS_Attributes_Verify_it)) <= 0) { 865 buf_len = 0; 866 goto err; 867 } 868 869 ret = EVP_DigestVerify(si->mctx, si->signature->data, si->signature->length, 870 buf, buf_len); 871 if (ret <= 0) { 872 CMSerror(CMS_R_VERIFICATION_FAILURE); 873 goto err; 874 } 875 876 err: 877 (void)EVP_MD_CTX_reset(si->mctx); 878 freezero(buf, buf_len); 879 880 return ret; 881} 882LCRYPTO_ALIAS(CMS_SignerInfo_verify); 883 884/* Create a chain of digest BIOs from a CMS ContentInfo */ 885 886BIO * 887cms_SignedData_init_bio(CMS_ContentInfo *cms) 888{ 889 int i; 890 CMS_SignedData *sd; 891 BIO *chain = NULL; 892 893 sd = cms_get0_signed(cms); 894 if (!sd) 895 return NULL; 896 if (cms->d.signedData->encapContentInfo->partial) 897 cms_sd_set_version(sd); 898 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { 899 X509_ALGOR *digestAlgorithm; 900 BIO *mdbio; 901 digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); 902 mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); 903 if (!mdbio) 904 goto err; 905 if (chain) 906 BIO_push(chain, mdbio); 907 else 908 chain = mdbio; 909 } 910 911 return chain; 912 913 err: 914 BIO_free_all(chain); 915 916 return NULL; 917} 918 919int 920CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) 921{ 922 ASN1_OCTET_STRING *os = NULL; 923 EVP_MD_CTX *mctx = EVP_MD_CTX_new(); 924 EVP_PKEY_CTX *pkctx = NULL; 925 int r = -1; 926 unsigned char mval[EVP_MAX_MD_SIZE]; 927 unsigned int mlen; 928 929 if (mctx == NULL) { 930 CMSerror(ERR_R_MALLOC_FAILURE); 931 goto err; 932 } 933 /* If we have any signed attributes look for messageDigest value */ 934 if (CMS_signed_get_attr_count(si) >= 0) { 935 os = CMS_signed_get0_data_by_OBJ(si, 936 OBJ_nid2obj(NID_pkcs9_messageDigest), -3, 937 V_ASN1_OCTET_STRING); 938 if (!os) { 939 CMSerror(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); 940 goto err; 941 } 942 } 943 944 if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm)) 945 goto err; 946 947 if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) { 948 CMSerror(CMS_R_UNABLE_TO_FINALIZE_CONTEXT); 949 goto err; 950 } 951 952 /* If messageDigest found compare it */ 953 954 if (os) { 955 if (mlen != (unsigned int)os->length) { 956 CMSerror(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); 957 goto err; 958 } 959 960 if (memcmp(mval, os->data, mlen)) { 961 CMSerror(CMS_R_VERIFICATION_FAILURE); 962 r = 0; 963 } else 964 r = 1; 965 } else { 966 const EVP_MD *md = EVP_MD_CTX_md(mctx); 967 968 pkctx = EVP_PKEY_CTX_new(si->pkey, NULL); 969 if (pkctx == NULL) 970 goto err; 971 if (EVP_PKEY_verify_init(pkctx) <= 0) 972 goto err; 973 if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0) 974 goto err; 975 si->pctx = pkctx; 976 if (!cms_sd_asn1_ctrl(si, 1)) 977 goto err; 978 r = EVP_PKEY_verify(pkctx, si->signature->data, 979 si->signature->length, mval, mlen); 980 if (r <= 0) { 981 CMSerror(CMS_R_VERIFICATION_FAILURE); 982 r = 0; 983 } 984 } 985 986 err: 987 EVP_PKEY_CTX_free(pkctx); 988 EVP_MD_CTX_free(mctx); 989 990 return r; 991} 992LCRYPTO_ALIAS(CMS_SignerInfo_verify_content); 993 994int 995CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) 996{ 997 unsigned char *smder = NULL; 998 int smderlen, r; 999 1000 smderlen = i2d_X509_ALGORS(algs, &smder); 1001 if (smderlen <= 0) 1002 return 0; 1003 r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities, 1004 V_ASN1_SEQUENCE, smder, smderlen); 1005 free(smder); 1006 1007 return r; 1008} 1009LCRYPTO_ALIAS(CMS_add_smimecap); 1010 1011int 1012CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, int algnid, int keysize) 1013{ 1014 X509_ALGOR *alg; 1015 ASN1_INTEGER *key = NULL; 1016 1017 if (keysize > 0) { 1018 if ((key = ASN1_INTEGER_new()) == NULL) 1019 return 0; 1020 if (!ASN1_INTEGER_set(key, keysize)) { 1021 ASN1_INTEGER_free(key); 1022 return 0; 1023 } 1024 } 1025 alg = X509_ALGOR_new(); 1026 if (alg == NULL) { 1027 ASN1_INTEGER_free(key); 1028 return 0; 1029 } 1030 1031 X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), 1032 key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); 1033 if (*algs == NULL) 1034 *algs = sk_X509_ALGOR_new_null(); 1035 if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) { 1036 X509_ALGOR_free(alg); 1037 return 0; 1038 } 1039 1040 return 1; 1041} 1042LCRYPTO_ALIAS(CMS_add_simple_smimecap); 1043 1044/* Check to see if a cipher exists and if so add S/MIME capabilities */ 1045 1046static int 1047cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 1048{ 1049 if (EVP_get_cipherbynid(nid)) 1050 return CMS_add_simple_smimecap(sk, nid, arg); 1051 return 1; 1052} 1053 1054static int 1055cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 1056{ 1057 if (EVP_get_digestbynid(nid)) 1058 return CMS_add_simple_smimecap(sk, nid, arg); 1059 return 1; 1060} 1061 1062int 1063CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) 1064{ 1065 if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) || 1066 !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) || 1067 !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) || 1068 !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) || 1069 !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) || 1070 !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) || 1071 !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) || 1072 !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) || 1073 !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) || 1074 !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) 1075 return 0; 1076 1077 return 1; 1078} 1079LCRYPTO_ALIAS(CMS_add_standard_smimecap); 1080