cms_sd.c revision 296465
117721Speter/* crypto/cms/cms_sd.c */ 217721Speter/* 317721Speter * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 417721Speter * project. 532785Speter */ 617721Speter/* ==================================================================== 717721Speter * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 817721Speter * 917721Speter * Redistribution and use in source and binary forms, with or without 1017721Speter * modification, are permitted provided that the following conditions 1117721Speter * are met: 1217721Speter * 1317721Speter * 1. Redistributions of source code must retain the above copyright 1417721Speter * notice, this list of conditions and the following disclaimer. 1517721Speter * 1617721Speter * 2. Redistributions in binary form must reproduce the above copyright 1717721Speter * notice, this list of conditions and the following disclaimer in 1817721Speter * the documentation and/or other materials provided with the 1966525Speter * distribution. 2017721Speter * 2166525Speter * 3. All advertising materials mentioning features or use of this 2217721Speter * software must display the following acknowledgment: 2317721Speter * "This product includes software developed by the OpenSSL Project 2417721Speter * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2517721Speter * 2617721Speter * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2717721Speter * endorse or promote products derived from this software without 2817721Speter * prior written permission. For written permission, please contact 2917721Speter * licensing@OpenSSL.org. 3017721Speter * 3117721Speter * 5. Products derived from this software may not be called "OpenSSL" 3217721Speter * nor may "OpenSSL" appear in their names without prior written 3317721Speter * permission of the OpenSSL Project. 3417721Speter * 3517721Speter * 6. Redistributions of any form whatsoever must retain the following 3617721Speter * acknowledgment: 3717721Speter * "This product includes software developed by the OpenSSL Project 3817721Speter * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3917721Speter * 4017721Speter * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4117721Speter * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4217721Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4317721Speter * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4417721Speter * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4517721Speter * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4617721Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4717721Speter * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4817721Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4917721Speter * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5032785Speter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5117721Speter * OF THE POSSIBILITY OF SUCH DAMAGE. 5232785Speter * ==================================================================== 5317721Speter */ 5417721Speter 5517721Speter#include "cryptlib.h" 5617721Speter#include <openssl/asn1t.h> 5717721Speter#include <openssl/pem.h> 5817721Speter#include <openssl/x509v3.h> 5934461Speter#include <openssl/err.h> 60#include <openssl/cms.h> 61#include "cms_lcl.h" 62 63/* CMS SignedData Utilities */ 64 65DECLARE_ASN1_ITEM(CMS_SignedData) 66 67static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms) 68{ 69 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) { 70 CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); 71 return NULL; 72 } 73 return cms->d.signedData; 74} 75 76static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) 77{ 78 if (cms->d.other == NULL) { 79 cms->d.signedData = M_ASN1_new_of(CMS_SignedData); 80 if (!cms->d.signedData) { 81 CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE); 82 return NULL; 83 } 84 cms->d.signedData->version = 1; 85 cms->d.signedData->encapContentInfo->eContentType = 86 OBJ_nid2obj(NID_pkcs7_data); 87 cms->d.signedData->encapContentInfo->partial = 1; 88 ASN1_OBJECT_free(cms->contentType); 89 cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); 90 return cms->d.signedData; 91 } 92 return cms_get0_signed(cms); 93} 94 95/* Just initialize SignedData e.g. for certs only structure */ 96 97int CMS_SignedData_init(CMS_ContentInfo *cms) 98{ 99 if (cms_signed_data_init(cms)) 100 return 1; 101 else 102 return 0; 103} 104 105/* Check structures and fixup version numbers (if necessary) */ 106 107static void cms_sd_set_version(CMS_SignedData *sd) 108{ 109 int i; 110 CMS_CertificateChoices *cch; 111 CMS_RevocationInfoChoice *rch; 112 CMS_SignerInfo *si; 113 114 for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) { 115 cch = sk_CMS_CertificateChoices_value(sd->certificates, i); 116 if (cch->type == CMS_CERTCHOICE_OTHER) { 117 if (sd->version < 5) 118 sd->version = 5; 119 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { 120 if (sd->version < 4) 121 sd->version = 4; 122 } else if (cch->type == CMS_CERTCHOICE_V1ACERT) { 123 if (sd->version < 3) 124 sd->version = 3; 125 } 126 } 127 128 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) { 129 rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i); 130 if (rch->type == CMS_REVCHOICE_OTHER) { 131 if (sd->version < 5) 132 sd->version = 5; 133 } 134 } 135 136 if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data) 137 && (sd->version < 3)) 138 sd->version = 3; 139 140 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { 141 si = sk_CMS_SignerInfo_value(sd->signerInfos, i); 142 if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { 143 if (si->version < 3) 144 si->version = 3; 145 if (sd->version < 3) 146 sd->version = 3; 147 } else if (si->version < 1) 148 si->version = 1; 149 } 150 151 if (sd->version < 1) 152 sd->version = 1; 153 154} 155 156/* Copy an existing messageDigest value */ 157 158static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) 159{ 160 STACK_OF(CMS_SignerInfo) *sinfos; 161 CMS_SignerInfo *sitmp; 162 int i; 163 sinfos = CMS_get0_SignerInfos(cms); 164 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 165 ASN1_OCTET_STRING *messageDigest; 166 sitmp = sk_CMS_SignerInfo_value(sinfos, i); 167 if (sitmp == si) 168 continue; 169 if (CMS_signed_get_attr_count(sitmp) < 0) 170 continue; 171 if (OBJ_cmp(si->digestAlgorithm->algorithm, 172 sitmp->digestAlgorithm->algorithm)) 173 continue; 174 messageDigest = CMS_signed_get0_data_by_OBJ(sitmp, 175 OBJ_nid2obj 176 (NID_pkcs9_messageDigest), 177 -3, V_ASN1_OCTET_STRING); 178 if (!messageDigest) { 179 CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, 180 CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); 181 return 0; 182 } 183 184 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, 185 V_ASN1_OCTET_STRING, 186 messageDigest, -1)) 187 return 1; 188 else 189 return 0; 190 } 191 CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST); 192 return 0; 193} 194 195int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) 196{ 197 switch (type) { 198 case CMS_SIGNERINFO_ISSUER_SERIAL: 199 sid->d.issuerAndSerialNumber = 200 M_ASN1_new_of(CMS_IssuerAndSerialNumber); 201 if (!sid->d.issuerAndSerialNumber) 202 goto merr; 203 if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer, 204 X509_get_issuer_name(cert))) 205 goto merr; 206 ASN1_STRING_free(sid->d.issuerAndSerialNumber->serialNumber); 207 sid->d.issuerAndSerialNumber->serialNumber = 208 ASN1_STRING_dup(X509_get_serialNumber(cert)); 209 if (!sid->d.issuerAndSerialNumber->serialNumber) 210 goto merr; 211 break; 212 213 case CMS_SIGNERINFO_KEYIDENTIFIER: 214 if (!cert->skid) { 215 CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, 216 CMS_R_CERTIFICATE_HAS_NO_KEYID); 217 return 0; 218 } 219 sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid); 220 if (!sid->d.subjectKeyIdentifier) 221 goto merr; 222 break; 223 224 default: 225 CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID); 226 return 0; 227 } 228 229 sid->type = type; 230 231 return 1; 232 233 merr: 234 CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE); 235 return 0; 236 237} 238 239int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, 240 ASN1_OCTET_STRING **keyid, 241 X509_NAME **issuer, 242 ASN1_INTEGER **sno) 243{ 244 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { 245 if (issuer) 246 *issuer = sid->d.issuerAndSerialNumber->issuer; 247 if (sno) 248 *sno = sid->d.issuerAndSerialNumber->serialNumber; 249 } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { 250 if (keyid) 251 *keyid = sid->d.subjectKeyIdentifier; 252 } else 253 return 0; 254 return 1; 255} 256 257int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) 258{ 259 int ret; 260 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { 261 ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer, 262 X509_get_issuer_name(cert)); 263 if (ret) 264 return ret; 265 return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber, 266 X509_get_serialNumber(cert)); 267 } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { 268 X509_check_purpose(cert, -1, -1); 269 if (!cert->skid) 270 return -1; 271 return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier, cert->skid); 272 } else 273 return -1; 274} 275 276CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, 277 X509 *signer, EVP_PKEY *pk, const EVP_MD *md, 278 unsigned int flags) 279{ 280 CMS_SignedData *sd; 281 CMS_SignerInfo *si = NULL; 282 X509_ALGOR *alg; 283 int i, type; 284 if (!X509_check_private_key(signer, pk)) { 285 CMSerr(CMS_F_CMS_ADD1_SIGNER, 286 CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 287 return NULL; 288 } 289 sd = cms_signed_data_init(cms); 290 if (!sd) 291 goto err; 292 si = M_ASN1_new_of(CMS_SignerInfo); 293 if (!si) 294 goto merr; 295 X509_check_purpose(signer, -1, -1); 296 297 CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); 298 CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); 299 300 si->pkey = pk; 301 si->signer = signer; 302 303 if (flags & CMS_USE_KEYID) { 304 si->version = 3; 305 if (sd->version < 3) 306 sd->version = 3; 307 type = CMS_SIGNERINFO_KEYIDENTIFIER; 308 } else { 309 type = CMS_SIGNERINFO_ISSUER_SERIAL; 310 si->version = 1; 311 } 312 313 if (!cms_set1_SignerIdentifier(si->sid, signer, type)) 314 goto err; 315 316 /* Since no EVP_PKEY_METHOD in 0.9.8 hard code SHA1 as default */ 317 if (md == NULL) 318 md = EVP_sha1(); 319 320 /* OpenSSL 0.9.8 only supports SHA1 with non-RSA keys */ 321 322 if ((pk->type != EVP_PKEY_RSA) && (EVP_MD_type(md) != NID_sha1)) { 323 CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 324 goto err; 325 } 326 327 cms_DigestAlgorithm_set(si->digestAlgorithm, md); 328 329 /* See if digest is present in digestAlgorithms */ 330 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { 331 ASN1_OBJECT *aoid; 332 alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); 333 X509_ALGOR_get0(&aoid, NULL, NULL, alg); 334 if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) 335 break; 336 } 337 338 if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { 339 alg = X509_ALGOR_new(); 340 if (!alg) 341 goto merr; 342 cms_DigestAlgorithm_set(alg, md); 343 if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { 344 X509_ALGOR_free(alg); 345 goto merr; 346 } 347 } 348 349 /* 350 * Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, hard code 351 * algorithm parameters. 352 */ 353 354 switch (pk->type) { 355 356 case EVP_PKEY_RSA: 357 X509_ALGOR_set0(si->signatureAlgorithm, 358 OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); 359 break; 360 361 case EVP_PKEY_DSA: 362 X509_ALGOR_set0(si->signatureAlgorithm, 363 OBJ_nid2obj(NID_dsaWithSHA1), V_ASN1_UNDEF, 0); 364 break; 365 366 case EVP_PKEY_EC: 367 X509_ALGOR_set0(si->signatureAlgorithm, 368 OBJ_nid2obj(NID_ecdsa_with_SHA1), V_ASN1_UNDEF, 0); 369 break; 370 371 default: 372 CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 373 goto err; 374 375 } 376 377 if (!(flags & CMS_NOATTR)) { 378 /* 379 * Initialialize signed attributes strutucture so other attributes 380 * such as signing time etc are added later even if we add none here. 381 */ 382 if (!si->signedAttrs) { 383 si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); 384 if (!si->signedAttrs) 385 goto merr; 386 } 387 388 if (!(flags & CMS_NOSMIMECAP)) { 389 STACK_OF(X509_ALGOR) *smcap = NULL; 390 i = CMS_add_standard_smimecap(&smcap); 391 if (i) 392 i = CMS_add_smimecap(si, smcap); 393 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 394 if (!i) 395 goto merr; 396 } 397 if (flags & CMS_REUSE_DIGEST) { 398 if (!cms_copy_messageDigest(cms, si)) 399 goto err; 400 if (!(flags & CMS_PARTIAL) && !CMS_SignerInfo_sign(si)) 401 goto err; 402 } 403 } 404 405 if (!(flags & CMS_NOCERTS)) { 406 /* NB ignore -1 return for duplicate cert */ 407 if (!CMS_add1_cert(cms, signer)) 408 goto merr; 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 CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); 420 err: 421 if (si) 422 M_ASN1_free_of(si, CMS_SignerInfo); 423 return NULL; 424 425} 426 427static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) 428{ 429 ASN1_TIME *tt; 430 int r = 0; 431 if (t) 432 tt = t; 433 else 434 tt = X509_gmtime_adj(NULL, 0); 435 436 if (!tt) 437 goto merr; 438 439 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, 440 tt->type, tt, -1) <= 0) 441 goto merr; 442 443 r = 1; 444 445 merr: 446 447 if (!t) 448 ASN1_TIME_free(tt); 449 450 if (!r) 451 CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE); 452 453 return r; 454 455} 456 457STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms) 458{ 459 CMS_SignedData *sd; 460 sd = cms_get0_signed(cms); 461 if (!sd) 462 return NULL; 463 return sd->signerInfos; 464} 465 466STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) 467{ 468 STACK_OF(X509) *signers = NULL; 469 STACK_OF(CMS_SignerInfo) *sinfos; 470 CMS_SignerInfo *si; 471 int i; 472 sinfos = CMS_get0_SignerInfos(cms); 473 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 474 si = sk_CMS_SignerInfo_value(sinfos, i); 475 if (si->signer) { 476 if (!signers) { 477 signers = sk_X509_new_null(); 478 if (!signers) 479 return NULL; 480 } 481 if (!sk_X509_push(signers, si->signer)) { 482 sk_X509_free(signers); 483 return NULL; 484 } 485 } 486 } 487 return signers; 488} 489 490void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) 491{ 492 if (signer) { 493 CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); 494 if (si->pkey) 495 EVP_PKEY_free(si->pkey); 496 si->pkey = X509_get_pubkey(signer); 497 } 498 if (si->signer) 499 X509_free(si->signer); 500 si->signer = signer; 501} 502 503int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, 504 ASN1_OCTET_STRING **keyid, 505 X509_NAME **issuer, ASN1_INTEGER **sno) 506{ 507 return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); 508} 509 510int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) 511{ 512 return cms_SignerIdentifier_cert_cmp(si->sid, cert); 513} 514 515int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, 516 unsigned int flags) 517{ 518 CMS_SignedData *sd; 519 CMS_SignerInfo *si; 520 CMS_CertificateChoices *cch; 521 STACK_OF(CMS_CertificateChoices) *certs; 522 X509 *x; 523 int i, j; 524 int ret = 0; 525 sd = cms_get0_signed(cms); 526 if (!sd) 527 return -1; 528 certs = sd->certificates; 529 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { 530 si = sk_CMS_SignerInfo_value(sd->signerInfos, i); 531 if (si->signer) 532 continue; 533 534 for (j = 0; j < sk_X509_num(scerts); j++) { 535 x = sk_X509_value(scerts, j); 536 if (CMS_SignerInfo_cert_cmp(si, x) == 0) { 537 CMS_SignerInfo_set1_signer_cert(si, x); 538 ret++; 539 break; 540 } 541 } 542 543 if (si->signer || (flags & CMS_NOINTERN)) 544 continue; 545 546 for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { 547 cch = sk_CMS_CertificateChoices_value(certs, j); 548 if (cch->type != 0) 549 continue; 550 x = cch->d.certificate; 551 if (CMS_SignerInfo_cert_cmp(si, x) == 0) { 552 CMS_SignerInfo_set1_signer_cert(si, x); 553 ret++; 554 break; 555 } 556 } 557 } 558 return ret; 559} 560 561void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, 562 X509 **signer, X509_ALGOR **pdig, 563 X509_ALGOR **psig) 564{ 565 if (pk) 566 *pk = si->pkey; 567 if (signer) 568 *signer = si->signer; 569 if (pdig) 570 *pdig = si->digestAlgorithm; 571 if (psig) 572 *psig = si->signatureAlgorithm; 573} 574 575/* 576 * In OpenSSL 0.9.8 we have the link between digest types and public key 577 * types so we need to fixup the digest type if the public key type is not 578 * appropriate. 579 */ 580 581static void cms_fixup_mctx(EVP_MD_CTX *mctx, EVP_PKEY *pkey) 582{ 583 if (EVP_MD_CTX_type(mctx) != NID_sha1) 584 return; 585#ifndef OPENSSL_NO_DSA 586 if (pkey->type == EVP_PKEY_DSA) 587 mctx->digest = EVP_dss1(); 588#endif 589#ifndef OPENSSL_NO_ECDSA 590 if (pkey->type == EVP_PKEY_EC) 591 mctx->digest = EVP_ecdsa(); 592#endif 593} 594 595static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, 596 CMS_SignerInfo *si, BIO *chain) 597{ 598 EVP_MD_CTX mctx; 599 int r = 0; 600 EVP_MD_CTX_init(&mctx); 601 602 if (!si->pkey) { 603 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY); 604 return 0; 605 } 606 607 if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) 608 goto err; 609 610 /* 611 * If any signed attributes calculate and add messageDigest attribute 612 */ 613 614 if (CMS_signed_get_attr_count(si) >= 0) { 615 ASN1_OBJECT *ctype = 616 cms->d.signedData->encapContentInfo->eContentType; 617 unsigned char md[EVP_MAX_MD_SIZE]; 618 unsigned int mdlen; 619 EVP_DigestFinal_ex(&mctx, md, &mdlen); 620 if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, 621 V_ASN1_OCTET_STRING, md, mdlen)) 622 goto err; 623 /* Copy content type across */ 624 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType, 625 V_ASN1_OBJECT, ctype, -1) <= 0) 626 goto err; 627 if (!CMS_SignerInfo_sign(si)) 628 goto err; 629 } else { 630 unsigned char *sig; 631 unsigned int siglen; 632 sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey)); 633 if (!sig) { 634 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); 635 goto err; 636 } 637 cms_fixup_mctx(&mctx, si->pkey); 638 if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) { 639 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR); 640 OPENSSL_free(sig); 641 goto err; 642 } 643 ASN1_STRING_set0(si->signature, sig, siglen); 644 } 645 646 r = 1; 647 648 err: 649 EVP_MD_CTX_cleanup(&mctx); 650 return r; 651 652} 653 654int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) 655{ 656 STACK_OF(CMS_SignerInfo) *sinfos; 657 CMS_SignerInfo *si; 658 int i; 659 sinfos = CMS_get0_SignerInfos(cms); 660 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 661 si = sk_CMS_SignerInfo_value(sinfos, i); 662 if (!cms_SignerInfo_content_sign(cms, si, chain)) 663 return 0; 664 } 665 cms->d.signedData->encapContentInfo->partial = 0; 666 return 1; 667} 668 669int CMS_SignerInfo_sign(CMS_SignerInfo *si) 670{ 671 EVP_MD_CTX mctx; 672 unsigned char *abuf = NULL; 673 int alen; 674 unsigned int siglen; 675 const EVP_MD *md = NULL; 676 677 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 678 if (md == NULL) 679 return 0; 680 681 EVP_MD_CTX_init(&mctx); 682 683 if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { 684 if (!cms_add1_signingTime(si, NULL)) 685 goto err; 686 } 687 688 if (EVP_SignInit_ex(&mctx, md, NULL) <= 0) 689 goto err; 690 691#if 0 692 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 693 EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { 694 CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); 695 goto err; 696 } 697#endif 698 699 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, 700 ASN1_ITEM_rptr(CMS_Attributes_Sign)); 701 if (!abuf) 702 goto err; 703 if (EVP_SignUpdate(&mctx, abuf, alen) <= 0) 704 goto err; 705 siglen = EVP_PKEY_size(si->pkey); 706 OPENSSL_free(abuf); 707 abuf = OPENSSL_malloc(siglen); 708 if (!abuf) 709 goto err; 710 cms_fixup_mctx(&mctx, si->pkey); 711 if (EVP_SignFinal(&mctx, abuf, &siglen, si->pkey) <= 0) 712 goto err; 713#if 0 714 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 715 EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { 716 CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); 717 goto err; 718 } 719#endif 720 EVP_MD_CTX_cleanup(&mctx); 721 722 ASN1_STRING_set0(si->signature, abuf, siglen); 723 724 return 1; 725 726 err: 727 if (abuf) 728 OPENSSL_free(abuf); 729 EVP_MD_CTX_cleanup(&mctx); 730 return 0; 731 732} 733 734int CMS_SignerInfo_verify(CMS_SignerInfo *si) 735{ 736 EVP_MD_CTX mctx; 737 unsigned char *abuf = NULL; 738 int alen, r = -1; 739 const EVP_MD *md = NULL; 740 741 if (!si->pkey) { 742 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY); 743 return -1; 744 } 745 746 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 747 if (md == NULL) 748 return -1; 749 EVP_MD_CTX_init(&mctx); 750 if (EVP_VerifyInit_ex(&mctx, md, NULL) <= 0) 751 goto err; 752 753 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, 754 ASN1_ITEM_rptr(CMS_Attributes_Verify)); 755 if (!abuf) 756 goto err; 757 r = EVP_VerifyUpdate(&mctx, abuf, alen); 758 OPENSSL_free(abuf); 759 if (r <= 0) { 760 r = -1; 761 goto err; 762 } 763 cms_fixup_mctx(&mctx, si->pkey); 764 r = EVP_VerifyFinal(&mctx, 765 si->signature->data, si->signature->length, si->pkey); 766 if (r <= 0) 767 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); 768 err: 769 EVP_MD_CTX_cleanup(&mctx); 770 return r; 771} 772 773/* Create a chain of digest BIOs from a CMS ContentInfo */ 774 775BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms) 776{ 777 int i; 778 CMS_SignedData *sd; 779 BIO *chain = NULL; 780 sd = cms_get0_signed(cms); 781 if (!sd) 782 return NULL; 783 if (cms->d.signedData->encapContentInfo->partial) 784 cms_sd_set_version(sd); 785 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { 786 X509_ALGOR *digestAlgorithm; 787 BIO *mdbio; 788 digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); 789 mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); 790 if (!mdbio) 791 goto err; 792 if (chain) 793 BIO_push(chain, mdbio); 794 else 795 chain = mdbio; 796 } 797 return chain; 798 err: 799 if (chain) 800 BIO_free_all(chain); 801 return NULL; 802} 803 804int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) 805{ 806 ASN1_OCTET_STRING *os = NULL; 807 EVP_MD_CTX mctx; 808 int r = -1; 809 EVP_MD_CTX_init(&mctx); 810 /* If we have any signed attributes look for messageDigest value */ 811 if (CMS_signed_get_attr_count(si) >= 0) { 812 os = CMS_signed_get0_data_by_OBJ(si, 813 OBJ_nid2obj(NID_pkcs9_messageDigest), 814 -3, V_ASN1_OCTET_STRING); 815 if (!os) { 816 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 817 CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); 818 goto err; 819 } 820 } 821 822 if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) 823 goto err; 824 825 /* If messageDigest found compare it */ 826 827 if (os) { 828 unsigned char mval[EVP_MAX_MD_SIZE]; 829 unsigned int mlen; 830 if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) { 831 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 832 CMS_R_UNABLE_TO_FINALIZE_CONTEXT); 833 goto err; 834 } 835 if (mlen != (unsigned int)os->length) { 836 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 837 CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); 838 goto err; 839 } 840 841 if (memcmp(mval, os->data, mlen)) { 842 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 843 CMS_R_VERIFICATION_FAILURE); 844 r = 0; 845 } else 846 r = 1; 847 } else { 848 cms_fixup_mctx(&mctx, si->pkey); 849 r = EVP_VerifyFinal(&mctx, si->signature->data, 850 si->signature->length, si->pkey); 851 if (r <= 0) { 852 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 853 CMS_R_VERIFICATION_FAILURE); 854 r = 0; 855 } 856 } 857 858 err: 859 EVP_MD_CTX_cleanup(&mctx); 860 return r; 861 862} 863 864int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) 865{ 866 unsigned char *smder = NULL; 867 int smderlen, r; 868 smderlen = i2d_X509_ALGORS(algs, &smder); 869 if (smderlen <= 0) 870 return 0; 871 r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities, 872 V_ASN1_SEQUENCE, smder, smderlen); 873 OPENSSL_free(smder); 874 return r; 875} 876 877int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, 878 int algnid, int keysize) 879{ 880 X509_ALGOR *alg; 881 ASN1_INTEGER *key = NULL; 882 if (keysize > 0) { 883 key = ASN1_INTEGER_new(); 884 if (!key || !ASN1_INTEGER_set(key, keysize)) 885 return 0; 886 } 887 alg = X509_ALGOR_new(); 888 if (!alg) { 889 if (key) 890 ASN1_INTEGER_free(key); 891 return 0; 892 } 893 894 X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), 895 key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); 896 if (!*algs) 897 *algs = sk_X509_ALGOR_new_null(); 898 if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) { 899 X509_ALGOR_free(alg); 900 return 0; 901 } 902 return 1; 903} 904 905/* Check to see if a cipher exists and if so add S/MIME capabilities */ 906 907static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 908{ 909 if (EVP_get_cipherbynid(nid)) 910 return CMS_add_simple_smimecap(sk, nid, arg); 911 return 1; 912} 913 914#if 0 915static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 916{ 917 if (EVP_get_digestbynid(nid)) 918 return CMS_add_simple_smimecap(sk, nid, arg); 919 return 1; 920} 921#endif 922int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) 923{ 924 if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) 925 || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) 926 || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) 927 || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) 928 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) 929 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) 930 || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) 931 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) 932 return 0; 933 return 1; 934} 935