1 /* 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/objects.h> 13 #include <openssl/x509.h> 14 #include "crypto/asn1.h" 15 #include "crypto/evp.h" 16 17 long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) 18 { 19 int nid; 20 long ret; 21 22 nid = OBJ_obj2nid(p7->type); 23 24 switch (cmd) { 25 /* NOTE(emilia): does not support detached digested data. */ 26 case PKCS7_OP_SET_DETACHED_SIGNATURE: 27 if (nid == NID_pkcs7_signed) { 28 ret = p7->detached = (int)larg; 29 if (ret && PKCS7_type_is_data(p7->d.sign->contents)) { 30 ASN1_OCTET_STRING *os; 31 os = p7->d.sign->contents->d.data; 32 ASN1_OCTET_STRING_free(os); 33 p7->d.sign->contents->d.data = NULL; 34 } 35 } else { 36 PKCS7err(PKCS7_F_PKCS7_CTRL, 37 PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); 38 ret = 0; 39 } 40 break; 41 case PKCS7_OP_GET_DETACHED_SIGNATURE: 42 if (nid == NID_pkcs7_signed) { 43 if (!p7->d.sign || !p7->d.sign->contents->d.ptr) 44 ret = 1; 45 else 46 ret = 0; 47 48 p7->detached = ret; 49 } else { 50 PKCS7err(PKCS7_F_PKCS7_CTRL, 51 PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); 52 ret = 0; 53 } 54 55 break; 56 default: 57 PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION); 58 ret = 0; 59 } 60 return ret; 61 } 62 63 int PKCS7_content_new(PKCS7 *p7, int type) 64 { 65 PKCS7 *ret = NULL; 66 67 if ((ret = PKCS7_new()) == NULL) 68 goto err; 69 if (!PKCS7_set_type(ret, type)) 70 goto err; 71 if (!PKCS7_set_content(p7, ret)) 72 goto err; 73 74 return 1; 75 err: 76 PKCS7_free(ret); 77 return 0; 78 } 79 80 int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) 81 { 82 int i; 83 84 i = OBJ_obj2nid(p7->type); 85 switch (i) { 86 case NID_pkcs7_signed: 87 PKCS7_free(p7->d.sign->contents); 88 p7->d.sign->contents = p7_data; 89 break; 90 case NID_pkcs7_digest: 91 PKCS7_free(p7->d.digest->contents); 92 p7->d.digest->contents = p7_data; 93 break; 94 case NID_pkcs7_data: 95 case NID_pkcs7_enveloped: 96 case NID_pkcs7_signedAndEnveloped: 97 case NID_pkcs7_encrypted: 98 default: 99 PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 100 goto err; 101 } 102 return 1; 103 err: 104 return 0; 105 } 106 107 int PKCS7_set_type(PKCS7 *p7, int type) 108 { 109 ASN1_OBJECT *obj; 110 111 /* 112 * PKCS7_content_free(p7); 113 */ 114 obj = OBJ_nid2obj(type); /* will not fail */ 115 116 switch (type) { 117 case NID_pkcs7_signed: 118 p7->type = obj; 119 if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL) 120 goto err; 121 if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) { 122 PKCS7_SIGNED_free(p7->d.sign); 123 p7->d.sign = NULL; 124 goto err; 125 } 126 break; 127 case NID_pkcs7_data: 128 p7->type = obj; 129 if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL) 130 goto err; 131 break; 132 case NID_pkcs7_signedAndEnveloped: 133 p7->type = obj; 134 if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new()) 135 == NULL) 136 goto err; 137 if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1)) 138 goto err; 139 p7->d.signed_and_enveloped->enc_data->content_type 140 = OBJ_nid2obj(NID_pkcs7_data); 141 break; 142 case NID_pkcs7_enveloped: 143 p7->type = obj; 144 if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) 145 == NULL) 146 goto err; 147 if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0)) 148 goto err; 149 p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); 150 break; 151 case NID_pkcs7_encrypted: 152 p7->type = obj; 153 if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) 154 == NULL) 155 goto err; 156 if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0)) 157 goto err; 158 p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); 159 break; 160 161 case NID_pkcs7_digest: 162 p7->type = obj; 163 if ((p7->d.digest = PKCS7_DIGEST_new()) 164 == NULL) 165 goto err; 166 if (!ASN1_INTEGER_set(p7->d.digest->version, 0)) 167 goto err; 168 break; 169 default: 170 PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 171 goto err; 172 } 173 return 1; 174 err: 175 return 0; 176 } 177 178 int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other) 179 { 180 p7->type = OBJ_nid2obj(type); 181 p7->d.other = other; 182 return 1; 183 } 184 185 int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) 186 { 187 int i, j, nid; 188 X509_ALGOR *alg; 189 STACK_OF(PKCS7_SIGNER_INFO) *signer_sk; 190 STACK_OF(X509_ALGOR) *md_sk; 191 192 i = OBJ_obj2nid(p7->type); 193 switch (i) { 194 case NID_pkcs7_signed: 195 signer_sk = p7->d.sign->signer_info; 196 md_sk = p7->d.sign->md_algs; 197 break; 198 case NID_pkcs7_signedAndEnveloped: 199 signer_sk = p7->d.signed_and_enveloped->signer_info; 200 md_sk = p7->d.signed_and_enveloped->md_algs; 201 break; 202 default: 203 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE); 204 return 0; 205 } 206 207 nid = OBJ_obj2nid(psi->digest_alg->algorithm); 208 209 /* If the digest is not currently listed, add it */ 210 j = 0; 211 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { 212 alg = sk_X509_ALGOR_value(md_sk, i); 213 if (OBJ_obj2nid(alg->algorithm) == nid) { 214 j = 1; 215 break; 216 } 217 } 218 if (!j) { /* we need to add another algorithm */ 219 if ((alg = X509_ALGOR_new()) == NULL 220 || (alg->parameter = ASN1_TYPE_new()) == NULL) { 221 X509_ALGOR_free(alg); 222 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, ERR_R_MALLOC_FAILURE); 223 return 0; 224 } 225 alg->algorithm = OBJ_nid2obj(nid); 226 alg->parameter->type = V_ASN1_NULL; 227 if (!sk_X509_ALGOR_push(md_sk, alg)) { 228 X509_ALGOR_free(alg); 229 return 0; 230 } 231 } 232 233 if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi)) 234 return 0; 235 return 1; 236 } 237 238 int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) 239 { 240 int i; 241 STACK_OF(X509) **sk; 242 243 i = OBJ_obj2nid(p7->type); 244 switch (i) { 245 case NID_pkcs7_signed: 246 sk = &(p7->d.sign->cert); 247 break; 248 case NID_pkcs7_signedAndEnveloped: 249 sk = &(p7->d.signed_and_enveloped->cert); 250 break; 251 default: 252 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE); 253 return 0; 254 } 255 256 if (*sk == NULL) 257 *sk = sk_X509_new_null(); 258 if (*sk == NULL) { 259 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE); 260 return 0; 261 } 262 X509_up_ref(x509); 263 if (!sk_X509_push(*sk, x509)) { 264 X509_free(x509); 265 return 0; 266 } 267 return 1; 268 } 269 270 int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) 271 { 272 int i; 273 STACK_OF(X509_CRL) **sk; 274 275 i = OBJ_obj2nid(p7->type); 276 switch (i) { 277 case NID_pkcs7_signed: 278 sk = &(p7->d.sign->crl); 279 break; 280 case NID_pkcs7_signedAndEnveloped: 281 sk = &(p7->d.signed_and_enveloped->crl); 282 break; 283 default: 284 PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE); 285 return 0; 286 } 287 288 if (*sk == NULL) 289 *sk = sk_X509_CRL_new_null(); 290 if (*sk == NULL) { 291 PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE); 292 return 0; 293 } 294 295 X509_CRL_up_ref(crl); 296 if (!sk_X509_CRL_push(*sk, crl)) { 297 X509_CRL_free(crl); 298 return 0; 299 } 300 return 1; 301 } 302 303 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, 304 const EVP_MD *dgst) 305 { 306 int ret; 307 308 /* We now need to add another PKCS7_SIGNER_INFO entry */ 309 if (!ASN1_INTEGER_set(p7i->version, 1)) 310 goto err; 311 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, 312 X509_get_issuer_name(x509))) 313 goto err; 314 315 /* 316 * because ASN1_INTEGER_set is used to set a 'long' we will do things the 317 * ugly way. 318 */ 319 ASN1_INTEGER_free(p7i->issuer_and_serial->serial); 320 if (!(p7i->issuer_and_serial->serial = 321 ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) 322 goto err; 323 324 /* lets keep the pkey around for a while */ 325 EVP_PKEY_up_ref(pkey); 326 p7i->pkey = pkey; 327 328 /* Set the algorithms */ 329 330 X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)), 331 V_ASN1_NULL, NULL); 332 333 if (pkey->ameth && pkey->ameth->pkey_ctrl) { 334 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i); 335 if (ret > 0) 336 return 1; 337 if (ret != -2) { 338 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, 339 PKCS7_R_SIGNING_CTRL_FAILURE); 340 return 0; 341 } 342 } 343 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, 344 PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 345 err: 346 return 0; 347 } 348 349 PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, 350 const EVP_MD *dgst) 351 { 352 PKCS7_SIGNER_INFO *si = NULL; 353 354 if (dgst == NULL) { 355 int def_nid; 356 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) 357 goto err; 358 dgst = EVP_get_digestbynid(def_nid); 359 if (dgst == NULL) { 360 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, PKCS7_R_NO_DEFAULT_DIGEST); 361 goto err; 362 } 363 } 364 365 if ((si = PKCS7_SIGNER_INFO_new()) == NULL) 366 goto err; 367 if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst)) 368 goto err; 369 if (!PKCS7_add_signer(p7, si)) 370 goto err; 371 return si; 372 err: 373 PKCS7_SIGNER_INFO_free(si); 374 return NULL; 375 } 376 377 int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) 378 { 379 if (PKCS7_type_is_digest(p7)) { 380 if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) { 381 PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, ERR_R_MALLOC_FAILURE); 382 return 0; 383 } 384 p7->d.digest->md->parameter->type = V_ASN1_NULL; 385 p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md)); 386 return 1; 387 } 388 389 PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE); 390 return 1; 391 } 392 393 STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7) 394 { 395 if (p7 == NULL || p7->d.ptr == NULL) 396 return NULL; 397 if (PKCS7_type_is_signed(p7)) { 398 return p7->d.sign->signer_info; 399 } else if (PKCS7_type_is_signedAndEnveloped(p7)) { 400 return p7->d.signed_and_enveloped->signer_info; 401 } else 402 return NULL; 403 } 404 405 void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, 406 X509_ALGOR **pdig, X509_ALGOR **psig) 407 { 408 if (pk) 409 *pk = si->pkey; 410 if (pdig) 411 *pdig = si->digest_alg; 412 if (psig) 413 *psig = si->digest_enc_alg; 414 } 415 416 void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc) 417 { 418 if (penc) 419 *penc = ri->key_enc_algor; 420 } 421 422 PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) 423 { 424 PKCS7_RECIP_INFO *ri; 425 426 if ((ri = PKCS7_RECIP_INFO_new()) == NULL) 427 goto err; 428 if (!PKCS7_RECIP_INFO_set(ri, x509)) 429 goto err; 430 if (!PKCS7_add_recipient_info(p7, ri)) 431 goto err; 432 return ri; 433 err: 434 PKCS7_RECIP_INFO_free(ri); 435 return NULL; 436 } 437 438 int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) 439 { 440 int i; 441 STACK_OF(PKCS7_RECIP_INFO) *sk; 442 443 i = OBJ_obj2nid(p7->type); 444 switch (i) { 445 case NID_pkcs7_signedAndEnveloped: 446 sk = p7->d.signed_and_enveloped->recipientinfo; 447 break; 448 case NID_pkcs7_enveloped: 449 sk = p7->d.enveloped->recipientinfo; 450 break; 451 default: 452 PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO, 453 PKCS7_R_WRONG_CONTENT_TYPE); 454 return 0; 455 } 456 457 if (!sk_PKCS7_RECIP_INFO_push(sk, ri)) 458 return 0; 459 return 1; 460 } 461 462 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) 463 { 464 int ret; 465 EVP_PKEY *pkey = NULL; 466 if (!ASN1_INTEGER_set(p7i->version, 0)) 467 return 0; 468 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, 469 X509_get_issuer_name(x509))) 470 return 0; 471 472 ASN1_INTEGER_free(p7i->issuer_and_serial->serial); 473 if (!(p7i->issuer_and_serial->serial = 474 ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) 475 return 0; 476 477 pkey = X509_get0_pubkey(x509); 478 479 if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) { 480 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, 481 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 482 goto err; 483 } 484 485 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i); 486 if (ret == -2) { 487 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, 488 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 489 goto err; 490 } 491 if (ret <= 0) { 492 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, 493 PKCS7_R_ENCRYPTION_CTRL_FAILURE); 494 goto err; 495 } 496 497 X509_up_ref(x509); 498 p7i->cert = x509; 499 500 return 1; 501 502 err: 503 return 0; 504 } 505 506 X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) 507 { 508 if (PKCS7_type_is_signed(p7)) 509 return (X509_find_by_issuer_and_serial(p7->d.sign->cert, 510 si->issuer_and_serial->issuer, 511 si-> 512 issuer_and_serial->serial)); 513 else 514 return NULL; 515 } 516 517 int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) 518 { 519 int i; 520 PKCS7_ENC_CONTENT *ec; 521 522 i = OBJ_obj2nid(p7->type); 523 switch (i) { 524 case NID_pkcs7_signedAndEnveloped: 525 ec = p7->d.signed_and_enveloped->enc_data; 526 break; 527 case NID_pkcs7_enveloped: 528 ec = p7->d.enveloped->enc_data; 529 break; 530 default: 531 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE); 532 return 0; 533 } 534 535 /* Check cipher OID exists and has data in it */ 536 i = EVP_CIPHER_type(cipher); 537 if (i == NID_undef) { 538 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, 539 PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); 540 return 0; 541 } 542 543 ec->cipher = cipher; 544 return 1; 545 } 546 547 int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) 548 { 549 ASN1_OCTET_STRING *os = NULL; 550 551 switch (OBJ_obj2nid(p7->type)) { 552 case NID_pkcs7_data: 553 os = p7->d.data; 554 break; 555 556 case NID_pkcs7_signedAndEnveloped: 557 os = p7->d.signed_and_enveloped->enc_data->enc_data; 558 if (os == NULL) { 559 os = ASN1_OCTET_STRING_new(); 560 p7->d.signed_and_enveloped->enc_data->enc_data = os; 561 } 562 break; 563 564 case NID_pkcs7_enveloped: 565 os = p7->d.enveloped->enc_data->enc_data; 566 if (os == NULL) { 567 os = ASN1_OCTET_STRING_new(); 568 p7->d.enveloped->enc_data->enc_data = os; 569 } 570 break; 571 572 case NID_pkcs7_signed: 573 os = p7->d.sign->contents->d.data; 574 break; 575 576 default: 577 os = NULL; 578 break; 579 } 580 581 if (os == NULL) 582 return 0; 583 584 os->flags |= ASN1_STRING_FLAG_NDEF; 585 *boundary = &os->data; 586 587 return 1; 588 } 589