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