1 /* $OpenBSD: pk7_asn1.c,v 1.12 2015/07/25 15:33:06 jsing Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project 2000. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 #include <stdio.h> 60 61 #include <openssl/asn1t.h> 62 #include <openssl/pkcs7.h> 63 #include <openssl/x509.h> 64 65 /* PKCS#7 ASN1 module */ 66 67 /* This is the ANY DEFINED BY table for the top level PKCS#7 structure */ 68 69 static const ASN1_TEMPLATE p7default_tt = { 70 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, 71 .tag = 0, 72 .offset = offsetof(PKCS7, d.other), 73 .field_name = "d.other", 74 .item = &ASN1_ANY_it, 75 }; 76 77 static const ASN1_ADB_TABLE PKCS7_adbtbl[] = { 78 { 79 .value = NID_pkcs7_data, 80 .tt = { 81 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, 82 .tag = 0, 83 .offset = offsetof(PKCS7, d.data), 84 .field_name = "d.data", 85 .item = &ASN1_OCTET_STRING_NDEF_it, 86 }, 87 88 }, 89 { 90 .value = NID_pkcs7_signed, 91 .tt = { 92 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, 93 .tag = 0, 94 .offset = offsetof(PKCS7, d.sign), 95 .field_name = "d.sign", 96 .item = &PKCS7_SIGNED_it, 97 }, 98 99 }, 100 { 101 .value = NID_pkcs7_enveloped, 102 .tt = { 103 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, 104 .tag = 0, 105 .offset = offsetof(PKCS7, d.enveloped), 106 .field_name = "d.enveloped", 107 .item = &PKCS7_ENVELOPE_it, 108 }, 109 110 }, 111 { 112 .value = NID_pkcs7_signedAndEnveloped, 113 .tt = { 114 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, 115 .tag = 0, 116 .offset = offsetof(PKCS7, d.signed_and_enveloped), 117 .field_name = "d.signed_and_enveloped", 118 .item = &PKCS7_SIGN_ENVELOPE_it, 119 }, 120 121 }, 122 { 123 .value = NID_pkcs7_digest, 124 .tt = { 125 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, 126 .tag = 0, 127 .offset = offsetof(PKCS7, d.digest), 128 .field_name = "d.digest", 129 .item = &PKCS7_DIGEST_it, 130 }, 131 132 }, 133 { 134 .value = NID_pkcs7_encrypted, 135 .tt = { 136 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF, 137 .tag = 0, 138 .offset = offsetof(PKCS7, d.encrypted), 139 .field_name = "d.encrypted", 140 .item = &PKCS7_ENCRYPT_it, 141 }, 142 143 }, 144 }; 145 146 static const ASN1_ADB PKCS7_adb = { 147 .flags = 0, 148 .offset = offsetof(PKCS7, type), 149 .app_items = 0, 150 .tbl = PKCS7_adbtbl, 151 .tblcount = sizeof(PKCS7_adbtbl) / sizeof(ASN1_ADB_TABLE), 152 .default_tt = &p7default_tt, 153 .null_tt = NULL, 154 }; 155 156 /* PKCS#7 streaming support */ 157 static int 158 pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) 159 { 160 ASN1_STREAM_ARG *sarg = exarg; 161 PKCS7 **pp7 = (PKCS7 **)pval; 162 163 switch (operation) { 164 case ASN1_OP_STREAM_PRE: 165 if (PKCS7_stream(&sarg->boundary, *pp7) <= 0) 166 return 0; 167 168 case ASN1_OP_DETACHED_PRE: 169 sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out); 170 if (!sarg->ndef_bio) 171 return 0; 172 break; 173 174 case ASN1_OP_STREAM_POST: 175 case ASN1_OP_DETACHED_POST: 176 if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0) 177 return 0; 178 break; 179 } 180 return 1; 181 } 182 183 static const ASN1_AUX PKCS7_aux = { 184 .app_data = NULL, 185 .flags = 0, 186 .ref_offset = 0, 187 .ref_lock = 0, 188 .asn1_cb = pk7_cb, 189 .enc_offset = 0, 190 }; 191 static const ASN1_TEMPLATE PKCS7_seq_tt[] = { 192 { 193 .flags = 0, 194 .tag = 0, 195 .offset = offsetof(PKCS7, type), 196 .field_name = "type", 197 .item = &ASN1_OBJECT_it, 198 }, 199 { 200 .flags = ASN1_TFLG_ADB_OID, 201 .tag = -1, 202 .offset = 0, 203 .field_name = "PKCS7", 204 .item = (const ASN1_ITEM *)&PKCS7_adb, 205 }, 206 }; 207 208 const ASN1_ITEM PKCS7_it = { 209 .itype = ASN1_ITYPE_NDEF_SEQUENCE, 210 .utype = V_ASN1_SEQUENCE, 211 .templates = PKCS7_seq_tt, 212 .tcount = sizeof(PKCS7_seq_tt) / sizeof(ASN1_TEMPLATE), 213 .funcs = &PKCS7_aux, 214 .size = sizeof(PKCS7), 215 .sname = "PKCS7", 216 }; 217 218 219 PKCS7 * 220 d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len) 221 { 222 return (PKCS7 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 223 &PKCS7_it); 224 } 225 226 int 227 i2d_PKCS7(PKCS7 *a, unsigned char **out) 228 { 229 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_it); 230 } 231 232 PKCS7 * 233 PKCS7_new(void) 234 { 235 return (PKCS7 *)ASN1_item_new(&PKCS7_it); 236 } 237 238 void 239 PKCS7_free(PKCS7 *a) 240 { 241 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_it); 242 } 243 244 int 245 i2d_PKCS7_NDEF(PKCS7 *a, unsigned char **out) 246 { 247 return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, &PKCS7_it); 248 } 249 250 PKCS7 * 251 PKCS7_dup(PKCS7 *x) 252 { 253 return ASN1_item_dup(&PKCS7_it, x); 254 } 255 256 static const ASN1_TEMPLATE PKCS7_SIGNED_seq_tt[] = { 257 { 258 .flags = 0, 259 .tag = 0, 260 .offset = offsetof(PKCS7_SIGNED, version), 261 .field_name = "version", 262 .item = &ASN1_INTEGER_it, 263 }, 264 { 265 .flags = ASN1_TFLG_SET_OF, 266 .tag = 0, 267 .offset = offsetof(PKCS7_SIGNED, md_algs), 268 .field_name = "md_algs", 269 .item = &X509_ALGOR_it, 270 }, 271 { 272 .flags = 0, 273 .tag = 0, 274 .offset = offsetof(PKCS7_SIGNED, contents), 275 .field_name = "contents", 276 .item = &PKCS7_it, 277 }, 278 { 279 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, 280 .tag = 0, 281 .offset = offsetof(PKCS7_SIGNED, cert), 282 .field_name = "cert", 283 .item = &X509_it, 284 }, 285 { 286 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, 287 .tag = 1, 288 .offset = offsetof(PKCS7_SIGNED, crl), 289 .field_name = "crl", 290 .item = &X509_CRL_it, 291 }, 292 { 293 .flags = ASN1_TFLG_SET_OF, 294 .tag = 0, 295 .offset = offsetof(PKCS7_SIGNED, signer_info), 296 .field_name = "signer_info", 297 .item = &PKCS7_SIGNER_INFO_it, 298 }, 299 }; 300 301 const ASN1_ITEM PKCS7_SIGNED_it = { 302 .itype = ASN1_ITYPE_NDEF_SEQUENCE, 303 .utype = V_ASN1_SEQUENCE, 304 .templates = PKCS7_SIGNED_seq_tt, 305 .tcount = sizeof(PKCS7_SIGNED_seq_tt) / sizeof(ASN1_TEMPLATE), 306 .funcs = NULL, 307 .size = sizeof(PKCS7_SIGNED), 308 .sname = "PKCS7_SIGNED", 309 }; 310 311 312 PKCS7_SIGNED * 313 d2i_PKCS7_SIGNED(PKCS7_SIGNED **a, const unsigned char **in, long len) 314 { 315 return (PKCS7_SIGNED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 316 &PKCS7_SIGNED_it); 317 } 318 319 int 320 i2d_PKCS7_SIGNED(PKCS7_SIGNED *a, unsigned char **out) 321 { 322 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNED_it); 323 } 324 325 PKCS7_SIGNED * 326 PKCS7_SIGNED_new(void) 327 { 328 return (PKCS7_SIGNED *)ASN1_item_new(&PKCS7_SIGNED_it); 329 } 330 331 void 332 PKCS7_SIGNED_free(PKCS7_SIGNED *a) 333 { 334 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNED_it); 335 } 336 337 /* Minor tweak to operation: free up EVP_PKEY */ 338 static int 339 si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) 340 { 341 if (operation == ASN1_OP_FREE_POST) { 342 PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; 343 EVP_PKEY_free(si->pkey); 344 } 345 return 1; 346 } 347 348 static const ASN1_AUX PKCS7_SIGNER_INFO_aux = { 349 .app_data = NULL, 350 .flags = 0, 351 .ref_offset = 0, 352 .ref_lock = 0, 353 .asn1_cb = si_cb, 354 .enc_offset = 0, 355 }; 356 static const ASN1_TEMPLATE PKCS7_SIGNER_INFO_seq_tt[] = { 357 { 358 .flags = 0, 359 .tag = 0, 360 .offset = offsetof(PKCS7_SIGNER_INFO, version), 361 .field_name = "version", 362 .item = &ASN1_INTEGER_it, 363 }, 364 { 365 .flags = 0, 366 .tag = 0, 367 .offset = offsetof(PKCS7_SIGNER_INFO, issuer_and_serial), 368 .field_name = "issuer_and_serial", 369 .item = &PKCS7_ISSUER_AND_SERIAL_it, 370 }, 371 { 372 .flags = 0, 373 .tag = 0, 374 .offset = offsetof(PKCS7_SIGNER_INFO, digest_alg), 375 .field_name = "digest_alg", 376 .item = &X509_ALGOR_it, 377 }, 378 /* NB this should be a SET OF but we use a SEQUENCE OF so the 379 * original order * is retained when the structure is reencoded. 380 * Since the attributes are implicitly tagged this will not affect 381 * the encoding. 382 */ 383 { 384 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, 385 .tag = 0, 386 .offset = offsetof(PKCS7_SIGNER_INFO, auth_attr), 387 .field_name = "auth_attr", 388 .item = &X509_ATTRIBUTE_it, 389 }, 390 { 391 .flags = 0, 392 .tag = 0, 393 .offset = offsetof(PKCS7_SIGNER_INFO, digest_enc_alg), 394 .field_name = "digest_enc_alg", 395 .item = &X509_ALGOR_it, 396 }, 397 { 398 .flags = 0, 399 .tag = 0, 400 .offset = offsetof(PKCS7_SIGNER_INFO, enc_digest), 401 .field_name = "enc_digest", 402 .item = &ASN1_OCTET_STRING_it, 403 }, 404 { 405 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, 406 .tag = 1, 407 .offset = offsetof(PKCS7_SIGNER_INFO, unauth_attr), 408 .field_name = "unauth_attr", 409 .item = &X509_ATTRIBUTE_it, 410 }, 411 }; 412 413 const ASN1_ITEM PKCS7_SIGNER_INFO_it = { 414 .itype = ASN1_ITYPE_SEQUENCE, 415 .utype = V_ASN1_SEQUENCE, 416 .templates = PKCS7_SIGNER_INFO_seq_tt, 417 .tcount = sizeof(PKCS7_SIGNER_INFO_seq_tt) / sizeof(ASN1_TEMPLATE), 418 .funcs = &PKCS7_SIGNER_INFO_aux, 419 .size = sizeof(PKCS7_SIGNER_INFO), 420 .sname = "PKCS7_SIGNER_INFO", 421 }; 422 423 424 PKCS7_SIGNER_INFO * 425 d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO **a, const unsigned char **in, long len) 426 { 427 return (PKCS7_SIGNER_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 428 &PKCS7_SIGNER_INFO_it); 429 } 430 431 int 432 i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO *a, unsigned char **out) 433 { 434 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNER_INFO_it); 435 } 436 437 PKCS7_SIGNER_INFO * 438 PKCS7_SIGNER_INFO_new(void) 439 { 440 return (PKCS7_SIGNER_INFO *)ASN1_item_new(&PKCS7_SIGNER_INFO_it); 441 } 442 443 void 444 PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a) 445 { 446 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNER_INFO_it); 447 } 448 449 static const ASN1_TEMPLATE PKCS7_ISSUER_AND_SERIAL_seq_tt[] = { 450 { 451 .flags = 0, 452 .tag = 0, 453 .offset = offsetof(PKCS7_ISSUER_AND_SERIAL, issuer), 454 .field_name = "issuer", 455 .item = &X509_NAME_it, 456 }, 457 { 458 .flags = 0, 459 .tag = 0, 460 .offset = offsetof(PKCS7_ISSUER_AND_SERIAL, serial), 461 .field_name = "serial", 462 .item = &ASN1_INTEGER_it, 463 }, 464 }; 465 466 const ASN1_ITEM PKCS7_ISSUER_AND_SERIAL_it = { 467 .itype = ASN1_ITYPE_SEQUENCE, 468 .utype = V_ASN1_SEQUENCE, 469 .templates = PKCS7_ISSUER_AND_SERIAL_seq_tt, 470 .tcount = sizeof(PKCS7_ISSUER_AND_SERIAL_seq_tt) / sizeof(ASN1_TEMPLATE), 471 .funcs = NULL, 472 .size = sizeof(PKCS7_ISSUER_AND_SERIAL), 473 .sname = "PKCS7_ISSUER_AND_SERIAL", 474 }; 475 476 477 PKCS7_ISSUER_AND_SERIAL * 478 d2i_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL **a, const unsigned char **in, long len) 479 { 480 return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 481 &PKCS7_ISSUER_AND_SERIAL_it); 482 } 483 484 int 485 i2d_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL *a, unsigned char **out) 486 { 487 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ISSUER_AND_SERIAL_it); 488 } 489 490 PKCS7_ISSUER_AND_SERIAL * 491 PKCS7_ISSUER_AND_SERIAL_new(void) 492 { 493 return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_new(&PKCS7_ISSUER_AND_SERIAL_it); 494 } 495 496 void 497 PKCS7_ISSUER_AND_SERIAL_free(PKCS7_ISSUER_AND_SERIAL *a) 498 { 499 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ISSUER_AND_SERIAL_it); 500 } 501 502 static const ASN1_TEMPLATE PKCS7_ENVELOPE_seq_tt[] = { 503 { 504 .flags = 0, 505 .tag = 0, 506 .offset = offsetof(PKCS7_ENVELOPE, version), 507 .field_name = "version", 508 .item = &ASN1_INTEGER_it, 509 }, 510 { 511 .flags = ASN1_TFLG_SET_OF, 512 .tag = 0, 513 .offset = offsetof(PKCS7_ENVELOPE, recipientinfo), 514 .field_name = "recipientinfo", 515 .item = &PKCS7_RECIP_INFO_it, 516 }, 517 { 518 .flags = 0, 519 .tag = 0, 520 .offset = offsetof(PKCS7_ENVELOPE, enc_data), 521 .field_name = "enc_data", 522 .item = &PKCS7_ENC_CONTENT_it, 523 }, 524 }; 525 526 const ASN1_ITEM PKCS7_ENVELOPE_it = { 527 .itype = ASN1_ITYPE_NDEF_SEQUENCE, 528 .utype = V_ASN1_SEQUENCE, 529 .templates = PKCS7_ENVELOPE_seq_tt, 530 .tcount = sizeof(PKCS7_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE), 531 .funcs = NULL, 532 .size = sizeof(PKCS7_ENVELOPE), 533 .sname = "PKCS7_ENVELOPE", 534 }; 535 536 537 PKCS7_ENVELOPE * 538 d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE **a, const unsigned char **in, long len) 539 { 540 return (PKCS7_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 541 &PKCS7_ENVELOPE_it); 542 } 543 544 int 545 i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a, unsigned char **out) 546 { 547 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENVELOPE_it); 548 } 549 550 PKCS7_ENVELOPE * 551 PKCS7_ENVELOPE_new(void) 552 { 553 return (PKCS7_ENVELOPE *)ASN1_item_new(&PKCS7_ENVELOPE_it); 554 } 555 556 void 557 PKCS7_ENVELOPE_free(PKCS7_ENVELOPE *a) 558 { 559 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENVELOPE_it); 560 } 561 562 /* Minor tweak to operation: free up X509 */ 563 static int 564 ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) 565 { 566 if (operation == ASN1_OP_FREE_POST) { 567 PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; 568 X509_free(ri->cert); 569 } 570 return 1; 571 } 572 573 static const ASN1_AUX PKCS7_RECIP_INFO_aux = { 574 .app_data = NULL, 575 .flags = 0, 576 .ref_offset = 0, 577 .ref_lock = 0, 578 .asn1_cb = ri_cb, 579 .enc_offset = 0, 580 }; 581 static const ASN1_TEMPLATE PKCS7_RECIP_INFO_seq_tt[] = { 582 { 583 .flags = 0, 584 .tag = 0, 585 .offset = offsetof(PKCS7_RECIP_INFO, version), 586 .field_name = "version", 587 .item = &ASN1_INTEGER_it, 588 }, 589 { 590 .flags = 0, 591 .tag = 0, 592 .offset = offsetof(PKCS7_RECIP_INFO, issuer_and_serial), 593 .field_name = "issuer_and_serial", 594 .item = &PKCS7_ISSUER_AND_SERIAL_it, 595 }, 596 { 597 .flags = 0, 598 .tag = 0, 599 .offset = offsetof(PKCS7_RECIP_INFO, key_enc_algor), 600 .field_name = "key_enc_algor", 601 .item = &X509_ALGOR_it, 602 }, 603 { 604 .flags = 0, 605 .tag = 0, 606 .offset = offsetof(PKCS7_RECIP_INFO, enc_key), 607 .field_name = "enc_key", 608 .item = &ASN1_OCTET_STRING_it, 609 }, 610 }; 611 612 const ASN1_ITEM PKCS7_RECIP_INFO_it = { 613 .itype = ASN1_ITYPE_SEQUENCE, 614 .utype = V_ASN1_SEQUENCE, 615 .templates = PKCS7_RECIP_INFO_seq_tt, 616 .tcount = sizeof(PKCS7_RECIP_INFO_seq_tt) / sizeof(ASN1_TEMPLATE), 617 .funcs = &PKCS7_RECIP_INFO_aux, 618 .size = sizeof(PKCS7_RECIP_INFO), 619 .sname = "PKCS7_RECIP_INFO", 620 }; 621 622 623 PKCS7_RECIP_INFO * 624 d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO **a, const unsigned char **in, long len) 625 { 626 return (PKCS7_RECIP_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 627 &PKCS7_RECIP_INFO_it); 628 } 629 630 int 631 i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO *a, unsigned char **out) 632 { 633 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_RECIP_INFO_it); 634 } 635 636 PKCS7_RECIP_INFO * 637 PKCS7_RECIP_INFO_new(void) 638 { 639 return (PKCS7_RECIP_INFO *)ASN1_item_new(&PKCS7_RECIP_INFO_it); 640 } 641 642 void 643 PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO *a) 644 { 645 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_RECIP_INFO_it); 646 } 647 648 static const ASN1_TEMPLATE PKCS7_ENC_CONTENT_seq_tt[] = { 649 { 650 .flags = 0, 651 .tag = 0, 652 .offset = offsetof(PKCS7_ENC_CONTENT, content_type), 653 .field_name = "content_type", 654 .item = &ASN1_OBJECT_it, 655 }, 656 { 657 .flags = 0, 658 .tag = 0, 659 .offset = offsetof(PKCS7_ENC_CONTENT, algorithm), 660 .field_name = "algorithm", 661 .item = &X509_ALGOR_it, 662 }, 663 { 664 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, 665 .tag = 0, 666 .offset = offsetof(PKCS7_ENC_CONTENT, enc_data), 667 .field_name = "enc_data", 668 .item = &ASN1_OCTET_STRING_NDEF_it, 669 }, 670 }; 671 672 const ASN1_ITEM PKCS7_ENC_CONTENT_it = { 673 .itype = ASN1_ITYPE_NDEF_SEQUENCE, 674 .utype = V_ASN1_SEQUENCE, 675 .templates = PKCS7_ENC_CONTENT_seq_tt, 676 .tcount = sizeof(PKCS7_ENC_CONTENT_seq_tt) / sizeof(ASN1_TEMPLATE), 677 .funcs = NULL, 678 .size = sizeof(PKCS7_ENC_CONTENT), 679 .sname = "PKCS7_ENC_CONTENT", 680 }; 681 682 683 PKCS7_ENC_CONTENT * 684 d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT **a, const unsigned char **in, long len) 685 { 686 return (PKCS7_ENC_CONTENT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 687 &PKCS7_ENC_CONTENT_it); 688 } 689 690 int 691 i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a, unsigned char **out) 692 { 693 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENC_CONTENT_it); 694 } 695 696 PKCS7_ENC_CONTENT * 697 PKCS7_ENC_CONTENT_new(void) 698 { 699 return (PKCS7_ENC_CONTENT *)ASN1_item_new(&PKCS7_ENC_CONTENT_it); 700 } 701 702 void 703 PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT *a) 704 { 705 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENC_CONTENT_it); 706 } 707 708 static const ASN1_TEMPLATE PKCS7_SIGN_ENVELOPE_seq_tt[] = { 709 { 710 .flags = 0, 711 .tag = 0, 712 .offset = offsetof(PKCS7_SIGN_ENVELOPE, version), 713 .field_name = "version", 714 .item = &ASN1_INTEGER_it, 715 }, 716 { 717 .flags = ASN1_TFLG_SET_OF, 718 .tag = 0, 719 .offset = offsetof(PKCS7_SIGN_ENVELOPE, recipientinfo), 720 .field_name = "recipientinfo", 721 .item = &PKCS7_RECIP_INFO_it, 722 }, 723 { 724 .flags = ASN1_TFLG_SET_OF, 725 .tag = 0, 726 .offset = offsetof(PKCS7_SIGN_ENVELOPE, md_algs), 727 .field_name = "md_algs", 728 .item = &X509_ALGOR_it, 729 }, 730 { 731 .flags = 0, 732 .tag = 0, 733 .offset = offsetof(PKCS7_SIGN_ENVELOPE, enc_data), 734 .field_name = "enc_data", 735 .item = &PKCS7_ENC_CONTENT_it, 736 }, 737 { 738 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, 739 .tag = 0, 740 .offset = offsetof(PKCS7_SIGN_ENVELOPE, cert), 741 .field_name = "cert", 742 .item = &X509_it, 743 }, 744 { 745 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL, 746 .tag = 1, 747 .offset = offsetof(PKCS7_SIGN_ENVELOPE, crl), 748 .field_name = "crl", 749 .item = &X509_CRL_it, 750 }, 751 { 752 .flags = ASN1_TFLG_SET_OF, 753 .tag = 0, 754 .offset = offsetof(PKCS7_SIGN_ENVELOPE, signer_info), 755 .field_name = "signer_info", 756 .item = &PKCS7_SIGNER_INFO_it, 757 }, 758 }; 759 760 const ASN1_ITEM PKCS7_SIGN_ENVELOPE_it = { 761 .itype = ASN1_ITYPE_NDEF_SEQUENCE, 762 .utype = V_ASN1_SEQUENCE, 763 .templates = PKCS7_SIGN_ENVELOPE_seq_tt, 764 .tcount = sizeof(PKCS7_SIGN_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE), 765 .funcs = NULL, 766 .size = sizeof(PKCS7_SIGN_ENVELOPE), 767 .sname = "PKCS7_SIGN_ENVELOPE", 768 }; 769 770 771 PKCS7_SIGN_ENVELOPE * 772 d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE **a, const unsigned char **in, long len) 773 { 774 return (PKCS7_SIGN_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 775 &PKCS7_SIGN_ENVELOPE_it); 776 } 777 778 int 779 i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE *a, unsigned char **out) 780 { 781 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGN_ENVELOPE_it); 782 } 783 784 PKCS7_SIGN_ENVELOPE * 785 PKCS7_SIGN_ENVELOPE_new(void) 786 { 787 return (PKCS7_SIGN_ENVELOPE *)ASN1_item_new(&PKCS7_SIGN_ENVELOPE_it); 788 } 789 790 void 791 PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE *a) 792 { 793 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGN_ENVELOPE_it); 794 } 795 796 static const ASN1_TEMPLATE PKCS7_ENCRYPT_seq_tt[] = { 797 { 798 .flags = 0, 799 .tag = 0, 800 .offset = offsetof(PKCS7_ENCRYPT, version), 801 .field_name = "version", 802 .item = &ASN1_INTEGER_it, 803 }, 804 { 805 .flags = 0, 806 .tag = 0, 807 .offset = offsetof(PKCS7_ENCRYPT, enc_data), 808 .field_name = "enc_data", 809 .item = &PKCS7_ENC_CONTENT_it, 810 }, 811 }; 812 813 const ASN1_ITEM PKCS7_ENCRYPT_it = { 814 .itype = ASN1_ITYPE_NDEF_SEQUENCE, 815 .utype = V_ASN1_SEQUENCE, 816 .templates = PKCS7_ENCRYPT_seq_tt, 817 .tcount = sizeof(PKCS7_ENCRYPT_seq_tt) / sizeof(ASN1_TEMPLATE), 818 .funcs = NULL, 819 .size = sizeof(PKCS7_ENCRYPT), 820 .sname = "PKCS7_ENCRYPT", 821 }; 822 823 824 PKCS7_ENCRYPT * 825 d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT **a, const unsigned char **in, long len) 826 { 827 return (PKCS7_ENCRYPT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 828 &PKCS7_ENCRYPT_it); 829 } 830 831 int 832 i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT *a, unsigned char **out) 833 { 834 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENCRYPT_it); 835 } 836 837 PKCS7_ENCRYPT * 838 PKCS7_ENCRYPT_new(void) 839 { 840 return (PKCS7_ENCRYPT *)ASN1_item_new(&PKCS7_ENCRYPT_it); 841 } 842 843 void 844 PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a) 845 { 846 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENCRYPT_it); 847 } 848 849 static const ASN1_TEMPLATE PKCS7_DIGEST_seq_tt[] = { 850 { 851 .flags = 0, 852 .tag = 0, 853 .offset = offsetof(PKCS7_DIGEST, version), 854 .field_name = "version", 855 .item = &ASN1_INTEGER_it, 856 }, 857 { 858 .flags = 0, 859 .tag = 0, 860 .offset = offsetof(PKCS7_DIGEST, md), 861 .field_name = "md", 862 .item = &X509_ALGOR_it, 863 }, 864 { 865 .flags = 0, 866 .tag = 0, 867 .offset = offsetof(PKCS7_DIGEST, contents), 868 .field_name = "contents", 869 .item = &PKCS7_it, 870 }, 871 { 872 .flags = 0, 873 .tag = 0, 874 .offset = offsetof(PKCS7_DIGEST, digest), 875 .field_name = "digest", 876 .item = &ASN1_OCTET_STRING_it, 877 }, 878 }; 879 880 const ASN1_ITEM PKCS7_DIGEST_it = { 881 .itype = ASN1_ITYPE_NDEF_SEQUENCE, 882 .utype = V_ASN1_SEQUENCE, 883 .templates = PKCS7_DIGEST_seq_tt, 884 .tcount = sizeof(PKCS7_DIGEST_seq_tt) / sizeof(ASN1_TEMPLATE), 885 .funcs = NULL, 886 .size = sizeof(PKCS7_DIGEST), 887 .sname = "PKCS7_DIGEST", 888 }; 889 890 891 PKCS7_DIGEST * 892 d2i_PKCS7_DIGEST(PKCS7_DIGEST **a, const unsigned char **in, long len) 893 { 894 return (PKCS7_DIGEST *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 895 &PKCS7_DIGEST_it); 896 } 897 898 int 899 i2d_PKCS7_DIGEST(PKCS7_DIGEST *a, unsigned char **out) 900 { 901 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_DIGEST_it); 902 } 903 904 PKCS7_DIGEST * 905 PKCS7_DIGEST_new(void) 906 { 907 return (PKCS7_DIGEST *)ASN1_item_new(&PKCS7_DIGEST_it); 908 } 909 910 void 911 PKCS7_DIGEST_free(PKCS7_DIGEST *a) 912 { 913 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_DIGEST_it); 914 } 915 916 /* Specials for authenticated attributes */ 917 918 /* When signing attributes we want to reorder them to match the sorted 919 * encoding. 920 */ 921 922 static const ASN1_TEMPLATE PKCS7_ATTR_SIGN_item_tt = { 923 .flags = ASN1_TFLG_SET_ORDER, 924 .tag = 0, 925 .offset = 0, 926 .field_name = "PKCS7_ATTRIBUTES", 927 .item = &X509_ATTRIBUTE_it, 928 }; 929 930 const ASN1_ITEM PKCS7_ATTR_SIGN_it = { 931 .itype = ASN1_ITYPE_PRIMITIVE, 932 .utype = -1, 933 .templates = &PKCS7_ATTR_SIGN_item_tt, 934 .tcount = 0, 935 .funcs = NULL, 936 .size = 0, 937 .sname = "PKCS7_ATTR_SIGN", 938 }; 939 940 /* When verifying attributes we need to use the received order. So 941 * we use SEQUENCE OF and tag it to SET OF 942 */ 943 944 static const ASN1_TEMPLATE PKCS7_ATTR_VERIFY_item_tt = { 945 .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, 946 .tag = V_ASN1_SET, 947 .offset = 0, 948 .field_name = "PKCS7_ATTRIBUTES", 949 .item = &X509_ATTRIBUTE_it, 950 }; 951 952 const ASN1_ITEM PKCS7_ATTR_VERIFY_it = { 953 .itype = ASN1_ITYPE_PRIMITIVE, 954 .utype = -1, 955 .templates = &PKCS7_ATTR_VERIFY_item_tt, 956 .tcount = 0, 957 .funcs = NULL, 958 .size = 0, 959 .sname = "PKCS7_ATTR_VERIFY", 960 }; 961 962 963 int 964 PKCS7_print_ctx(BIO *out, PKCS7 *x, int indent, const ASN1_PCTX *pctx) 965 { 966 return ASN1_item_print(out, (ASN1_VALUE *)x, indent, 967 &PKCS7_it, pctx); 968 } 969