cms_sd.c revision 1.20
1/* $OpenBSD: cms_sd.c,v 1.20 2019/08/11 10:41:49 jsing 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 "cryptlib.h" 56#include <openssl/asn1t.h> 57#include <openssl/pem.h> 58#include <openssl/x509.h> 59#include <openssl/x509v3.h> 60#include <openssl/err.h> 61#include <openssl/cms.h> 62#include "cms_lcl.h" 63#include "asn1/asn1_locl.h" 64#include "evp/evp_locl.h" 65 66/* CMS SignedData Utilities */ 67 68static CMS_SignedData * 69cms_get0_signed(CMS_ContentInfo *cms) 70{ 71 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) { 72 CMSerror(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); 73 return NULL; 74 } 75 return cms->d.signedData; 76} 77 78static CMS_SignedData * 79cms_signed_data_init(CMS_ContentInfo *cms) 80{ 81 if (cms->d.other == NULL) { 82 cms->d.signedData = M_ASN1_new_of(CMS_SignedData); 83 if (!cms->d.signedData) { 84 CMSerror(ERR_R_MALLOC_FAILURE); 85 return NULL; 86 } 87 cms->d.signedData->version = 1; 88 cms->d.signedData->encapContentInfo->eContentType = 89 OBJ_nid2obj(NID_pkcs7_data); 90 cms->d.signedData->encapContentInfo->partial = 1; 91 ASN1_OBJECT_free(cms->contentType); 92 cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); 93 return cms->d.signedData; 94 } 95 return cms_get0_signed(cms); 96} 97 98/* Just initialise SignedData e.g. for certs only structure */ 99 100int 101CMS_SignedData_init(CMS_ContentInfo *cms) 102{ 103 if (cms_signed_data_init(cms)) 104 return 1; 105 else 106 return 0; 107} 108 109/* Check structures and fixup version numbers (if necessary) */ 110 111static void 112cms_sd_set_version(CMS_SignedData *sd) 113{ 114 int i; 115 CMS_CertificateChoices *cch; 116 CMS_RevocationInfoChoice *rch; 117 CMS_SignerInfo *si; 118 119 for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) { 120 cch = sk_CMS_CertificateChoices_value(sd->certificates, i); 121 if (cch->type == CMS_CERTCHOICE_OTHER) { 122 if (sd->version < 5) 123 sd->version = 5; 124 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { 125 if (sd->version < 4) 126 sd->version = 4; 127 } else if (cch->type == CMS_CERTCHOICE_V1ACERT) { 128 if (sd->version < 3) 129 sd->version = 3; 130 } 131 } 132 133 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) { 134 rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i); 135 if (rch->type == CMS_REVCHOICE_OTHER) { 136 if (sd->version < 5) 137 sd->version = 5; 138 } 139 } 140 141 if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data) 142 && (sd->version < 3)) 143 sd->version = 3; 144 145 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { 146 si = sk_CMS_SignerInfo_value(sd->signerInfos, i); 147 if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { 148 if (si->version < 3) 149 si->version = 3; 150 if (sd->version < 3) 151 sd->version = 3; 152 } else if (si->version < 1) 153 si->version = 1; 154 } 155 156 if (sd->version < 1) 157 sd->version = 1; 158} 159 160/* Copy an existing messageDigest value */ 161 162static int 163cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) 164{ 165 STACK_OF(CMS_SignerInfo) *sinfos; 166 CMS_SignerInfo *sitmp; 167 int i; 168 169 sinfos = CMS_get0_SignerInfos(cms); 170 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 171 ASN1_OCTET_STRING *messageDigest; 172 sitmp = sk_CMS_SignerInfo_value(sinfos, i); 173 if (sitmp == si) 174 continue; 175 if (CMS_signed_get_attr_count(sitmp) < 0) 176 continue; 177 if (OBJ_cmp(si->digestAlgorithm->algorithm, 178 sitmp->digestAlgorithm->algorithm)) 179 continue; 180 messageDigest = CMS_signed_get0_data_by_OBJ(sitmp, 181 OBJ_nid2obj(NID_pkcs9_messageDigest), -3, V_ASN1_OCTET_STRING); 182 if (!messageDigest) { 183 CMSerror(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); 184 return 0; 185 } 186 187 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, 188 V_ASN1_OCTET_STRING, messageDigest, -1)) 189 return 1; 190 else 191 return 0; 192 } 193 194 CMSerror(CMS_R_NO_MATCHING_DIGEST); 195 196 return 0; 197} 198 199int 200cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) 201{ 202 switch (type) { 203 case CMS_SIGNERINFO_ISSUER_SERIAL: 204 if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert)) 205 return 0; 206 break; 207 208 case CMS_SIGNERINFO_KEYIDENTIFIER: 209 if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert)) 210 return 0; 211 break; 212 213 default: 214 CMSerror(CMS_R_UNKNOWN_ID); 215 return 0; 216 } 217 218 sid->type = type; 219 220 return 1; 221} 222 223int 224cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, 225 ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno) 226{ 227 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { 228 if (issuer) 229 *issuer = sid->d.issuerAndSerialNumber->issuer; 230 if (sno) 231 *sno = sid->d.issuerAndSerialNumber->serialNumber; 232 } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { 233 if (keyid) 234 *keyid = sid->d.subjectKeyIdentifier; 235 } else 236 return 0; 237 238 return 1; 239} 240 241int 242cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) 243{ 244 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) 245 return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert); 246 else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) 247 return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert); 248 else 249 return -1; 250} 251 252static int 253cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd) 254{ 255 EVP_PKEY *pkey = si->pkey; 256 int i; 257 258 if (!pkey->ameth || !pkey->ameth->pkey_ctrl) 259 return 1; 260 i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si); 261 if (i == -2) { 262 CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 263 return 0; 264 } 265 if (i <= 0) { 266 CMSerror(CMS_R_CTRL_FAILURE); 267 return 0; 268 } 269 270 return 1; 271} 272 273CMS_SignerInfo * 274CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, 275 const EVP_MD *md, unsigned int flags) 276{ 277 CMS_SignedData *sd; 278 CMS_SignerInfo *si = NULL; 279 X509_ALGOR *alg; 280 int i, type; 281 282 if (!X509_check_private_key(signer, pk)) { 283 CMSerror(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 284 return NULL; 285 } 286 sd = cms_signed_data_init(cms); 287 if (!sd) 288 goto err; 289 si = M_ASN1_new_of(CMS_SignerInfo); 290 if (!si) 291 goto merr; 292 /* Call for side-effect of computing hash and caching extensions */ 293 X509_check_purpose(signer, -1, -1); 294 295 X509_up_ref(signer); 296 EVP_PKEY_up_ref(pk); 297 298 si->pkey = pk; 299 si->signer = signer; 300 si->mctx = EVP_MD_CTX_new(); 301 si->pctx = NULL; 302 303 if (si->mctx == NULL) { 304 CMSerror(ERR_R_MALLOC_FAILURE); 305 goto err; 306 } 307 308 if (flags & CMS_USE_KEYID) { 309 si->version = 3; 310 if (sd->version < 3) 311 sd->version = 3; 312 type = CMS_SIGNERINFO_KEYIDENTIFIER; 313 } else { 314 type = CMS_SIGNERINFO_ISSUER_SERIAL; 315 si->version = 1; 316 } 317 318 if (!cms_set1_SignerIdentifier(si->sid, signer, type)) 319 goto err; 320 321 if (md == NULL) { 322 int def_nid; 323 if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) 324 goto err; 325 md = EVP_get_digestbynid(def_nid); 326 if (md == NULL) { 327 CMSerror(CMS_R_NO_DEFAULT_DIGEST); 328 goto err; 329 } 330 } 331 332 if (!md) { 333 CMSerror(CMS_R_NO_DIGEST_SET); 334 goto err; 335 } 336 337 X509_ALGOR_set_md(si->digestAlgorithm, md); 338 339 /* See if digest is present in digestAlgorithms */ 340 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { 341 const ASN1_OBJECT *aoid; 342 alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); 343 X509_ALGOR_get0(&aoid, NULL, NULL, alg); 344 if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) 345 break; 346 } 347 348 if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { 349 alg = X509_ALGOR_new(); 350 if (alg == NULL) 351 goto merr; 352 X509_ALGOR_set_md(alg, md); 353 if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { 354 X509_ALGOR_free(alg); 355 goto merr; 356 } 357 } 358 359 if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0)) 360 goto err; 361 if (!(flags & CMS_NOATTR)) { 362 /* 363 * Initialize signed attributes structure so other attributes 364 * such as signing time etc are added later even if we add none here. 365 */ 366 if (!si->signedAttrs) { 367 si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); 368 if (!si->signedAttrs) 369 goto merr; 370 } 371 372 if (!(flags & CMS_NOSMIMECAP)) { 373 STACK_OF(X509_ALGOR) *smcap = NULL; 374 375 i = CMS_add_standard_smimecap(&smcap); 376 if (i) 377 i = CMS_add_smimecap(si, smcap); 378 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 379 if (!i) 380 goto merr; 381 } 382 if (flags & CMS_REUSE_DIGEST) { 383 if (!cms_copy_messageDigest(cms, si)) 384 goto err; 385 if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) && 386 !CMS_SignerInfo_sign(si)) 387 goto err; 388 } 389 } 390 391 if (!(flags & CMS_NOCERTS)) { 392 /* NB ignore -1 return for duplicate cert */ 393 if (!CMS_add1_cert(cms, signer)) 394 goto merr; 395 } 396 397 if (flags & CMS_KEY_PARAM) { 398 if (flags & CMS_NOATTR) { 399 si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL); 400 if (si->pctx == NULL) 401 goto err; 402 if (EVP_PKEY_sign_init(si->pctx) <= 0) 403 goto err; 404 if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0) 405 goto err; 406 } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, 407 NULL, pk) <= 0) 408 goto err; 409 } 410 411 if (!sd->signerInfos) 412 sd->signerInfos = sk_CMS_SignerInfo_new_null(); 413 if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) 414 goto merr; 415 416 return si; 417 418 merr: 419 CMSerror(ERR_R_MALLOC_FAILURE); 420 err: 421 M_ASN1_free_of(si, CMS_SignerInfo); 422 423 return NULL; 424} 425 426static int 427cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) 428{ 429 ASN1_TIME *tt; 430 int r = 0; 431 432 if (t) 433 tt = t; 434 else 435 tt = X509_gmtime_adj(NULL, 0); 436 437 if (!tt) 438 goto merr; 439 440 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, 441 tt->type, tt, -1) <= 0) 442 goto merr; 443 444 r = 1; 445 446 merr: 447 if (!t) 448 ASN1_TIME_free(tt); 449 if (!r) 450 CMSerror(ERR_R_MALLOC_FAILURE); 451 452 return r; 453} 454 455EVP_PKEY_CTX * 456CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si) 457{ 458 return si->pctx; 459} 460 461EVP_MD_CTX * 462CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si) 463{ 464 return si->mctx; 465} 466 467STACK_OF(CMS_SignerInfo) * 468CMS_get0_SignerInfos(CMS_ContentInfo *cms) 469{ 470 CMS_SignedData *sd; 471 472 sd = cms_get0_signed(cms); 473 if (!sd) 474 return NULL; 475 476 return sd->signerInfos; 477} 478 479STACK_OF(X509) * 480CMS_get0_signers(CMS_ContentInfo *cms) 481{ 482 STACK_OF(X509) *signers = NULL; 483 STACK_OF(CMS_SignerInfo) *sinfos; 484 CMS_SignerInfo *si; 485 int i; 486 487 sinfos = CMS_get0_SignerInfos(cms); 488 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 489 si = sk_CMS_SignerInfo_value(sinfos, i); 490 if (si->signer) { 491 if (!signers) { 492 signers = sk_X509_new_null(); 493 if (!signers) 494 return NULL; 495 } 496 if (!sk_X509_push(signers, si->signer)) { 497 sk_X509_free(signers); 498 return NULL; 499 } 500 } 501 } 502 503 return signers; 504} 505 506void 507CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) 508{ 509 if (signer) { 510 X509_up_ref(signer); 511 EVP_PKEY_free(si->pkey); 512 si->pkey = X509_get_pubkey(signer); 513 } 514 X509_free(si->signer); 515 si->signer = signer; 516} 517 518int 519CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, ASN1_OCTET_STRING **keyid, 520 X509_NAME **issuer, ASN1_INTEGER **sno) 521{ 522 return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); 523} 524 525int 526CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) 527{ 528 return cms_SignerIdentifier_cert_cmp(si->sid, cert); 529} 530 531int 532CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, 533 unsigned int flags) 534{ 535 CMS_SignedData *sd; 536 CMS_SignerInfo *si; 537 CMS_CertificateChoices *cch; 538 STACK_OF(CMS_CertificateChoices) *certs; 539 X509 *x; 540 int i, j; 541 int ret = 0; 542 543 sd = cms_get0_signed(cms); 544 if (!sd) 545 return -1; 546 certs = sd->certificates; 547 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { 548 si = sk_CMS_SignerInfo_value(sd->signerInfos, i); 549 if (si->signer) 550 continue; 551 552 for (j = 0; j < sk_X509_num(scerts); j++) { 553 x = sk_X509_value(scerts, j); 554 if (CMS_SignerInfo_cert_cmp(si, x) == 0) { 555 CMS_SignerInfo_set1_signer_cert(si, x); 556 ret++; 557 break; 558 } 559 } 560 561 if (si->signer || (flags & CMS_NOINTERN)) 562 continue; 563 564 for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { 565 cch = sk_CMS_CertificateChoices_value(certs, j); 566 if (cch->type != 0) 567 continue; 568 x = cch->d.certificate; 569 if (CMS_SignerInfo_cert_cmp(si, x) == 0) { 570 CMS_SignerInfo_set1_signer_cert(si, x); 571 ret++; 572 break; 573 } 574 } 575 } 576 return ret; 577} 578 579void 580CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, 581X509_ALGOR **pdig, X509_ALGOR **psig) 582{ 583 if (pk) 584 *pk = si->pkey; 585 if (signer) 586 *signer = si->signer; 587 if (pdig) 588 *pdig = si->digestAlgorithm; 589 if (psig) 590 *psig = si->signatureAlgorithm; 591} 592 593ASN1_OCTET_STRING * 594CMS_SignerInfo_get0_signature(CMS_SignerInfo *si) 595{ 596 return si->signature; 597} 598 599static int 600cms_SignerInfo_content_sign(CMS_ContentInfo *cms, CMS_SignerInfo *si, BIO *chain) 601{ 602 EVP_MD_CTX *mctx = EVP_MD_CTX_new(); 603 int r = 0; 604 EVP_PKEY_CTX *pctx = NULL; 605 606 if (mctx == NULL) { 607 CMSerror(ERR_R_MALLOC_FAILURE); 608 return 0; 609 } 610 611 if (!si->pkey) { 612 CMSerror(CMS_R_NO_PRIVATE_KEY); 613 goto err; 614 } 615 616 if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm)) 617 goto err; 618 /* Set SignerInfo algorithm details if we used custom parameter */ 619 if (si->pctx && !cms_sd_asn1_ctrl(si, 0)) 620 goto err; 621 622 /* 623 * If any signed attributes calculate and add messageDigest attribute 624 */ 625 626 if (CMS_signed_get_attr_count(si) >= 0) { 627 ASN1_OBJECT *ctype = 628 cms->d.signedData->encapContentInfo->eContentType; 629 unsigned char md[EVP_MAX_MD_SIZE]; 630 unsigned int mdlen; 631 632 if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) 633 goto err; 634 if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, 635 V_ASN1_OCTET_STRING, md, mdlen)) 636 goto err; 637 /* Copy content type across */ 638 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType, 639 V_ASN1_OBJECT, ctype, -1) <= 0) 640 goto err; 641 if (!CMS_SignerInfo_sign(si)) 642 goto err; 643 } else if (si->pctx) { 644 unsigned char *sig; 645 size_t siglen; 646 unsigned char md[EVP_MAX_MD_SIZE]; 647 unsigned int mdlen; 648 649 pctx = si->pctx; 650 if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) 651 goto err; 652 siglen = EVP_PKEY_size(si->pkey); 653 sig = malloc(siglen); 654 if (sig == NULL) { 655 CMSerror(ERR_R_MALLOC_FAILURE); 656 goto err; 657 } 658 if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) { 659 free(sig); 660 goto err; 661 } 662 ASN1_STRING_set0(si->signature, sig, siglen); 663 } else { 664 unsigned char *sig; 665 unsigned int siglen; 666 667 sig = malloc(EVP_PKEY_size(si->pkey)); 668 if (sig == NULL) { 669 CMSerror(ERR_R_MALLOC_FAILURE); 670 goto err; 671 } 672 if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) { 673 CMSerror(CMS_R_SIGNFINAL_ERROR); 674 free(sig); 675 goto err; 676 } 677 ASN1_STRING_set0(si->signature, sig, siglen); 678 } 679 680 r = 1; 681 682 err: 683 EVP_MD_CTX_free(mctx); 684 EVP_PKEY_CTX_free(pctx); 685 686 return r; 687} 688 689int 690cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) 691{ 692 STACK_OF(CMS_SignerInfo) *sinfos; 693 CMS_SignerInfo *si; 694 int i; 695 696 sinfos = CMS_get0_SignerInfos(cms); 697 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 698 si = sk_CMS_SignerInfo_value(sinfos, i); 699 if (!cms_SignerInfo_content_sign(cms, si, chain)) 700 return 0; 701 } 702 cms->d.signedData->encapContentInfo->partial = 0; 703 704 return 1; 705} 706 707int 708CMS_SignerInfo_sign(CMS_SignerInfo *si) 709{ 710 EVP_MD_CTX *mctx = si->mctx; 711 EVP_PKEY_CTX *pctx = NULL; 712 unsigned char *abuf = NULL; 713 int alen; 714 size_t siglen; 715 const EVP_MD *md = NULL; 716 717 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 718 if (md == NULL) 719 return 0; 720 721 if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { 722 if (!cms_add1_signingTime(si, NULL)) 723 goto err; 724 } 725 726 if (si->pctx) 727 pctx = si->pctx; 728 else { 729 EVP_MD_CTX_reset(mctx); 730 if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) 731 goto err; 732 si->pctx = pctx; 733 } 734 735 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 736 EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { 737 CMSerror(CMS_R_CTRL_ERROR); 738 goto err; 739 } 740 741 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, 742 &CMS_Attributes_Sign_it); 743 if (!abuf) 744 goto err; 745 if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0) 746 goto err; 747 if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0) 748 goto err; 749 free(abuf); 750 abuf = malloc(siglen); 751 if (abuf == NULL) 752 goto err; 753 if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) 754 goto err; 755 756 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 757 EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { 758 CMSerror(CMS_R_CTRL_ERROR); 759 goto err; 760 } 761 762 EVP_MD_CTX_reset(mctx); 763 764 ASN1_STRING_set0(si->signature, abuf, siglen); 765 766 return 1; 767 768 err: 769 free(abuf); 770 EVP_MD_CTX_reset(mctx); 771 772 return 0; 773} 774 775int 776CMS_SignerInfo_verify(CMS_SignerInfo *si) 777{ 778 EVP_MD_CTX *mctx = NULL; 779 unsigned char *abuf = NULL; 780 int alen, r = -1; 781 const EVP_MD *md = NULL; 782 783 if (!si->pkey) { 784 CMSerror(CMS_R_NO_PUBLIC_KEY); 785 return -1; 786 } 787 788 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 789 if (md == NULL) 790 return -1; 791 if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) { 792 CMSerror(ERR_R_MALLOC_FAILURE); 793 return -1; 794 } 795 mctx = si->mctx; 796 if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0) 797 goto err; 798 799 if (!cms_sd_asn1_ctrl(si, 1)) 800 goto err; 801 802 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, 803 &CMS_Attributes_Verify_it); 804 if (!abuf) 805 goto err; 806 r = EVP_DigestVerifyUpdate(mctx, abuf, alen); 807 free(abuf); 808 if (r <= 0) { 809 r = -1; 810 goto err; 811 } 812 813 r = EVP_DigestVerifyFinal(mctx, si->signature->data, 814 si->signature->length); 815 if (r <= 0) 816 CMSerror(CMS_R_VERIFICATION_FAILURE); 817 818 err: 819 EVP_MD_CTX_reset(mctx); 820 821 return r; 822} 823 824/* Create a chain of digest BIOs from a CMS ContentInfo */ 825 826BIO * 827cms_SignedData_init_bio(CMS_ContentInfo *cms) 828{ 829 int i; 830 CMS_SignedData *sd; 831 BIO *chain = NULL; 832 833 sd = cms_get0_signed(cms); 834 if (!sd) 835 return NULL; 836 if (cms->d.signedData->encapContentInfo->partial) 837 cms_sd_set_version(sd); 838 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { 839 X509_ALGOR *digestAlgorithm; 840 BIO *mdbio; 841 digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); 842 mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); 843 if (!mdbio) 844 goto err; 845 if (chain) 846 BIO_push(chain, mdbio); 847 else 848 chain = mdbio; 849 } 850 851 return chain; 852 853 err: 854 BIO_free_all(chain); 855 856 return NULL; 857} 858 859int 860CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) 861{ 862 ASN1_OCTET_STRING *os = NULL; 863 EVP_MD_CTX *mctx = EVP_MD_CTX_new(); 864 EVP_PKEY_CTX *pkctx = NULL; 865 int r = -1; 866 unsigned char mval[EVP_MAX_MD_SIZE]; 867 unsigned int mlen; 868 869 if (mctx == NULL) { 870 CMSerror(ERR_R_MALLOC_FAILURE); 871 goto err; 872 } 873 /* If we have any signed attributes look for messageDigest value */ 874 if (CMS_signed_get_attr_count(si) >= 0) { 875 os = CMS_signed_get0_data_by_OBJ(si, 876 OBJ_nid2obj(NID_pkcs9_messageDigest), -3, 877 V_ASN1_OCTET_STRING); 878 if (!os) { 879 CMSerror(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); 880 goto err; 881 } 882 } 883 884 if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm)) 885 goto err; 886 887 if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) { 888 CMSerror(CMS_R_UNABLE_TO_FINALIZE_CONTEXT); 889 goto err; 890 } 891 892 /* If messageDigest found compare it */ 893 894 if (os) { 895 if (mlen != (unsigned int)os->length) { 896 CMSerror(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); 897 goto err; 898 } 899 900 if (memcmp(mval, os->data, mlen)) { 901 CMSerror(CMS_R_VERIFICATION_FAILURE); 902 r = 0; 903 } else 904 r = 1; 905 } else { 906 const EVP_MD *md = EVP_MD_CTX_md(mctx); 907 908 pkctx = EVP_PKEY_CTX_new(si->pkey, NULL); 909 if (pkctx == NULL) 910 goto err; 911 if (EVP_PKEY_verify_init(pkctx) <= 0) 912 goto err; 913 if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0) 914 goto err; 915 si->pctx = pkctx; 916 if (!cms_sd_asn1_ctrl(si, 1)) 917 goto err; 918 r = EVP_PKEY_verify(pkctx, si->signature->data, 919 si->signature->length, mval, mlen); 920 if (r <= 0) { 921 CMSerror(CMS_R_VERIFICATION_FAILURE); 922 r = 0; 923 } 924 } 925 926 err: 927 EVP_PKEY_CTX_free(pkctx); 928 EVP_MD_CTX_free(mctx); 929 930 return r; 931} 932 933int 934CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) 935{ 936 unsigned char *smder = NULL; 937 int smderlen, r; 938 939 smderlen = i2d_X509_ALGORS(algs, &smder); 940 if (smderlen <= 0) 941 return 0; 942 r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities, 943 V_ASN1_SEQUENCE, smder, smderlen); 944 free(smder); 945 946 return r; 947} 948 949int 950CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, int algnid, int keysize) 951{ 952 X509_ALGOR *alg; 953 ASN1_INTEGER *key = NULL; 954 955 if (keysize > 0) { 956 key = ASN1_INTEGER_new(); 957 if (key == NULL || !ASN1_INTEGER_set(key, keysize)) 958 return 0; 959 } 960 alg = X509_ALGOR_new(); 961 if (alg == NULL) { 962 ASN1_INTEGER_free(key); 963 return 0; 964 } 965 966 X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), 967 key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); 968 if (*algs == NULL) 969 *algs = sk_X509_ALGOR_new_null(); 970 if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) { 971 X509_ALGOR_free(alg); 972 return 0; 973 } 974 975 return 1; 976} 977 978/* Check to see if a cipher exists and if so add S/MIME capabilities */ 979 980static int 981cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 982{ 983 if (EVP_get_cipherbynid(nid)) 984 return CMS_add_simple_smimecap(sk, nid, arg); 985 return 1; 986} 987 988static int 989cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 990{ 991 if (EVP_get_digestbynid(nid)) 992 return CMS_add_simple_smimecap(sk, nid, arg); 993 return 1; 994} 995 996int 997CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) 998{ 999 if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) || 1000 !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1) || 1001 !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1) || 1002 !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) || 1003 !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) || 1004 !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) || 1005 !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) || 1006 !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) || 1007 !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) || 1008 !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) || 1009 !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) || 1010 !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) 1011 return 0; 1012 1013 return 1; 1014} 1015