1 /* $OpenBSD: bio_lib.c,v 1.48 2023/08/07 10:58:56 tb Exp $ */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59 #include <errno.h> 60 #include <limits.h> 61 #include <stdio.h> 62 63 #include <openssl/bio.h> 64 #include <openssl/crypto.h> 65 #include <openssl/err.h> 66 #include <openssl/stack.h> 67 68 #include "bio_local.h" 69 70 /* 71 * Helper function to work out whether to call the new style callback or the old 72 * one, and translate between the two. 73 * 74 * This has a long return type for consistency with the old callback. Similarly 75 * for the "long" used for "inret" 76 */ 77 static long 78 bio_call_callback(BIO *b, int oper, const char *argp, size_t len, int argi, 79 long argl, long inret, size_t *processed) 80 { 81 long ret; 82 int bareoper; 83 84 if (b->callback_ex != NULL) 85 return b->callback_ex(b, oper, argp, len, argi, argl, inret, 86 processed); 87 88 /* 89 * We have an old style callback, so we will have to do nasty casts and 90 * check for overflows. 91 */ 92 93 bareoper = oper & ~BIO_CB_RETURN; 94 95 if (bareoper == BIO_CB_READ || bareoper == BIO_CB_WRITE || 96 bareoper == BIO_CB_GETS) { 97 /* In this case len is set and should be used instead of argi. */ 98 if (len > INT_MAX) 99 return -1; 100 argi = (int)len; 101 } 102 103 if (inret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) { 104 if (*processed > INT_MAX) 105 return -1; 106 inret = *processed; 107 } 108 109 ret = b->callback(b, oper, argp, argi, argl, inret); 110 111 if (ret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) { 112 *processed = (size_t)ret; 113 ret = 1; 114 } 115 116 return ret; 117 } 118 119 int 120 BIO_get_new_index(void) 121 { 122 static int bio_type_index = BIO_TYPE_START; 123 int index; 124 125 /* The index will collide with the BIO flag bits if it exceeds 255. */ 126 index = CRYPTO_add(&bio_type_index, 1, CRYPTO_LOCK_BIO); 127 if (index > 255) 128 return -1; 129 130 return index; 131 } 132 LCRYPTO_ALIAS(BIO_get_new_index); 133 134 BIO * 135 BIO_new(const BIO_METHOD *method) 136 { 137 BIO *ret = NULL; 138 139 /* XXX calloc */ 140 ret = malloc(sizeof(BIO)); 141 if (ret == NULL) { 142 BIOerror(ERR_R_MALLOC_FAILURE); 143 return (NULL); 144 } 145 if (!BIO_set(ret, method)) { 146 free(ret); 147 ret = NULL; 148 } 149 return (ret); 150 } 151 LCRYPTO_ALIAS(BIO_new); 152 153 int 154 BIO_set(BIO *bio, const BIO_METHOD *method) 155 { 156 bio->method = method; 157 bio->callback = NULL; 158 bio->callback_ex = NULL; 159 bio->cb_arg = NULL; 160 bio->init = 0; 161 bio->shutdown = 1; 162 bio->flags = 0; 163 bio->retry_reason = 0; 164 bio->num = 0; 165 bio->ptr = NULL; 166 bio->prev_bio = NULL; 167 bio->next_bio = NULL; 168 bio->references = 1; 169 bio->num_read = 0L; 170 bio->num_write = 0L; 171 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); 172 if (method->create != NULL) { 173 if (!method->create(bio)) { 174 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, 175 &bio->ex_data); 176 return (0); 177 } 178 } 179 return (1); 180 } 181 LCRYPTO_ALIAS(BIO_set); 182 183 int 184 BIO_free(BIO *a) 185 { 186 int ret; 187 188 if (a == NULL) 189 return (0); 190 191 if (CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO) > 0) 192 return (1); 193 194 if (a->callback != NULL || a->callback_ex != NULL) { 195 if ((ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 196 0L, 1L, NULL)) <= 0) 197 return (ret); 198 } 199 200 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data); 201 202 if (a->method != NULL && a->method->destroy != NULL) 203 a->method->destroy(a); 204 free(a); 205 return (1); 206 } 207 LCRYPTO_ALIAS(BIO_free); 208 209 void 210 BIO_vfree(BIO *a) 211 { 212 BIO_free(a); 213 } 214 LCRYPTO_ALIAS(BIO_vfree); 215 216 int 217 BIO_up_ref(BIO *bio) 218 { 219 int refs = CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO); 220 return (refs > 1) ? 1 : 0; 221 } 222 LCRYPTO_ALIAS(BIO_up_ref); 223 224 void * 225 BIO_get_data(BIO *a) 226 { 227 return (a->ptr); 228 } 229 LCRYPTO_ALIAS(BIO_get_data); 230 231 void 232 BIO_set_data(BIO *a, void *ptr) 233 { 234 a->ptr = ptr; 235 } 236 LCRYPTO_ALIAS(BIO_set_data); 237 238 int 239 BIO_get_init(BIO *a) 240 { 241 return a->init; 242 } 243 LCRYPTO_ALIAS(BIO_get_init); 244 245 void 246 BIO_set_init(BIO *a, int init) 247 { 248 a->init = init; 249 } 250 LCRYPTO_ALIAS(BIO_set_init); 251 252 int 253 BIO_get_shutdown(BIO *a) 254 { 255 return (a->shutdown); 256 } 257 LCRYPTO_ALIAS(BIO_get_shutdown); 258 259 void 260 BIO_set_shutdown(BIO *a, int shut) 261 { 262 a->shutdown = shut; 263 } 264 LCRYPTO_ALIAS(BIO_set_shutdown); 265 266 void 267 BIO_clear_flags(BIO *b, int flags) 268 { 269 b->flags &= ~flags; 270 } 271 LCRYPTO_ALIAS(BIO_clear_flags); 272 273 int 274 BIO_test_flags(const BIO *b, int flags) 275 { 276 return (b->flags & flags); 277 } 278 LCRYPTO_ALIAS(BIO_test_flags); 279 280 void 281 BIO_set_flags(BIO *b, int flags) 282 { 283 b->flags |= flags; 284 } 285 LCRYPTO_ALIAS(BIO_set_flags); 286 287 BIO_callback_fn 288 BIO_get_callback(const BIO *b) 289 { 290 return b->callback; 291 } 292 LCRYPTO_ALIAS(BIO_get_callback); 293 294 void 295 BIO_set_callback(BIO *b, BIO_callback_fn cb) 296 { 297 b->callback = cb; 298 } 299 LCRYPTO_ALIAS(BIO_set_callback); 300 301 BIO_callback_fn_ex 302 BIO_get_callback_ex(const BIO *b) 303 { 304 return b->callback_ex; 305 } 306 LCRYPTO_ALIAS(BIO_get_callback_ex); 307 308 void 309 BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex cb) 310 { 311 b->callback_ex = cb; 312 } 313 LCRYPTO_ALIAS(BIO_set_callback_ex); 314 315 void 316 BIO_set_callback_arg(BIO *b, char *arg) 317 { 318 b->cb_arg = arg; 319 } 320 LCRYPTO_ALIAS(BIO_set_callback_arg); 321 322 char * 323 BIO_get_callback_arg(const BIO *b) 324 { 325 return b->cb_arg; 326 } 327 LCRYPTO_ALIAS(BIO_get_callback_arg); 328 329 const char * 330 BIO_method_name(const BIO *b) 331 { 332 return b->method->name; 333 } 334 LCRYPTO_ALIAS(BIO_method_name); 335 336 int 337 BIO_method_type(const BIO *b) 338 { 339 return b->method->type; 340 } 341 LCRYPTO_ALIAS(BIO_method_type); 342 343 int 344 BIO_read(BIO *b, void *out, int outl) 345 { 346 size_t readbytes = 0; 347 int ret; 348 349 if (b == NULL) { 350 BIOerror(ERR_R_PASSED_NULL_PARAMETER); 351 return (-1); 352 } 353 354 if (outl <= 0) 355 return (0); 356 357 if (out == NULL) { 358 BIOerror(ERR_R_PASSED_NULL_PARAMETER); 359 return (-1); 360 } 361 362 if (b->method == NULL || b->method->bread == NULL) { 363 BIOerror(BIO_R_UNSUPPORTED_METHOD); 364 return (-2); 365 } 366 367 if (b->callback != NULL || b->callback_ex != NULL) { 368 if ((ret = (int)bio_call_callback(b, BIO_CB_READ, out, outl, 0, 369 0L, 1L, NULL)) <= 0) 370 return (ret); 371 } 372 373 if (!b->init) { 374 BIOerror(BIO_R_UNINITIALIZED); 375 return (-2); 376 } 377 378 if ((ret = b->method->bread(b, out, outl)) > 0) 379 readbytes = (size_t)ret; 380 381 b->num_read += readbytes; 382 383 if (b->callback != NULL || b->callback_ex != NULL) { 384 ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, 385 out, outl, 0, 0L, (ret > 0) ? 1 : ret, &readbytes); 386 } 387 388 if (ret > 0) { 389 if (readbytes > INT_MAX) { 390 BIOerror(BIO_R_LENGTH_TOO_LONG); 391 ret = -1; 392 } else { 393 ret = (int)readbytes; 394 } 395 } 396 397 return (ret); 398 } 399 LCRYPTO_ALIAS(BIO_read); 400 401 int 402 BIO_write(BIO *b, const void *in, int inl) 403 { 404 size_t writebytes = 0; 405 int ret; 406 407 /* Not an error. Things like SMIME_text() assume that this succeeds. */ 408 if (b == NULL) 409 return (0); 410 411 if (inl <= 0) 412 return (0); 413 414 if (in == NULL) { 415 BIOerror(ERR_R_PASSED_NULL_PARAMETER); 416 return (-1); 417 } 418 419 if (b->method == NULL || b->method->bwrite == NULL) { 420 BIOerror(BIO_R_UNSUPPORTED_METHOD); 421 return (-2); 422 } 423 424 if (b->callback != NULL || b->callback_ex != NULL) { 425 if ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, in, inl, 0, 426 0L, 1L, NULL)) <= 0) 427 return (ret); 428 } 429 430 if (!b->init) { 431 BIOerror(BIO_R_UNINITIALIZED); 432 return (-2); 433 } 434 435 if ((ret = b->method->bwrite(b, in, inl)) > 0) 436 writebytes = ret; 437 438 b->num_write += writebytes; 439 440 if (b->callback != NULL || b->callback_ex != NULL) { 441 ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, 442 in, inl, 0, 0L, (ret > 0) ? 1 : ret, &writebytes); 443 } 444 445 if (ret > 0) { 446 if (writebytes > INT_MAX) { 447 BIOerror(BIO_R_LENGTH_TOO_LONG); 448 ret = -1; 449 } else { 450 ret = (int)writebytes; 451 } 452 } 453 454 return (ret); 455 } 456 LCRYPTO_ALIAS(BIO_write); 457 458 int 459 BIO_puts(BIO *b, const char *in) 460 { 461 size_t writebytes = 0; 462 int ret; 463 464 if (b == NULL || b->method == NULL || b->method->bputs == NULL) { 465 BIOerror(BIO_R_UNSUPPORTED_METHOD); 466 return (-2); 467 } 468 469 if (b->callback != NULL || b->callback_ex != NULL) { 470 if ((ret = (int)bio_call_callback(b, BIO_CB_PUTS, in, 0, 0, 0L, 471 1L, NULL)) <= 0) 472 return (ret); 473 } 474 475 if (!b->init) { 476 BIOerror(BIO_R_UNINITIALIZED); 477 return (-2); 478 } 479 480 if ((ret = b->method->bputs(b, in)) > 0) 481 writebytes = ret; 482 483 b->num_write += writebytes; 484 485 if (b->callback != NULL || b->callback_ex != NULL) { 486 ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, 487 in, 0, 0, 0L, (ret > 0) ? 1 : ret, &writebytes); 488 } 489 490 if (ret > 0) { 491 if (writebytes > INT_MAX) { 492 BIOerror(BIO_R_LENGTH_TOO_LONG); 493 ret = -1; 494 } else { 495 ret = (int)writebytes; 496 } 497 } 498 499 return (ret); 500 } 501 LCRYPTO_ALIAS(BIO_puts); 502 503 int 504 BIO_gets(BIO *b, char *in, int inl) 505 { 506 size_t readbytes = 0; 507 int ret; 508 509 if (b == NULL || b->method == NULL || b->method->bgets == NULL) { 510 BIOerror(BIO_R_UNSUPPORTED_METHOD); 511 return (-2); 512 } 513 514 if (b->callback != NULL || b->callback_ex != NULL) { 515 if ((ret = (int)bio_call_callback(b, BIO_CB_GETS, in, inl, 0, 0L, 516 1, NULL)) <= 0) 517 return (ret); 518 } 519 520 if (!b->init) { 521 BIOerror(BIO_R_UNINITIALIZED); 522 return (-2); 523 } 524 525 if ((ret = b->method->bgets(b, in, inl)) > 0) 526 readbytes = ret; 527 528 if (b->callback != NULL || b->callback_ex != NULL) { 529 ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, in, 530 inl, 0, 0L, (ret > 0) ? 1 : ret, &readbytes); 531 } 532 533 if (ret > 0) { 534 if (readbytes > INT_MAX) { 535 BIOerror(BIO_R_LENGTH_TOO_LONG); 536 ret = -1; 537 } else { 538 ret = (int)readbytes; 539 } 540 } 541 542 return (ret); 543 } 544 LCRYPTO_ALIAS(BIO_gets); 545 546 int 547 BIO_indent(BIO *b, int indent, int max) 548 { 549 if (indent > max) 550 indent = max; 551 if (indent <= 0) 552 return 1; 553 if (BIO_printf(b, "%*s", indent, "") <= 0) 554 return 0; 555 return 1; 556 } 557 LCRYPTO_ALIAS(BIO_indent); 558 559 long 560 BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) 561 { 562 int i; 563 564 i = iarg; 565 return (BIO_ctrl(b, cmd, larg, (char *)&i)); 566 } 567 LCRYPTO_ALIAS(BIO_int_ctrl); 568 569 char * 570 BIO_ptr_ctrl(BIO *b, int cmd, long larg) 571 { 572 char *p = NULL; 573 574 if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0) 575 return (NULL); 576 else 577 return (p); 578 } 579 LCRYPTO_ALIAS(BIO_ptr_ctrl); 580 581 long 582 BIO_ctrl(BIO *b, int cmd, long larg, void *parg) 583 { 584 long ret; 585 586 if (b == NULL) 587 return (0); 588 589 if (b->method == NULL || b->method->ctrl == NULL) { 590 BIOerror(BIO_R_UNSUPPORTED_METHOD); 591 return (-2); 592 } 593 594 if (b->callback != NULL || b->callback_ex != NULL) { 595 if ((ret = bio_call_callback(b, BIO_CB_CTRL, parg, 0, cmd, larg, 596 1L, NULL)) <= 0) 597 return (ret); 598 } 599 600 ret = b->method->ctrl(b, cmd, larg, parg); 601 602 if (b->callback != NULL || b->callback_ex != NULL) { 603 ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0, 604 cmd, larg, ret, NULL); 605 } 606 607 return (ret); 608 } 609 LCRYPTO_ALIAS(BIO_ctrl); 610 611 long 612 BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) 613 { 614 long ret; 615 616 if (b == NULL) 617 return (0); 618 619 if (b->method == NULL || b->method->callback_ctrl == NULL || 620 cmd != BIO_CTRL_SET_CALLBACK) { 621 BIOerror(BIO_R_UNSUPPORTED_METHOD); 622 return (-2); 623 } 624 625 if (b->callback != NULL || b->callback_ex != NULL) { 626 if ((ret = bio_call_callback(b, BIO_CB_CTRL, (void *)&fp, 0, 627 cmd, 0, 1L, NULL)) <= 0) 628 return (ret); 629 } 630 631 ret = b->method->callback_ctrl(b, cmd, fp); 632 633 if (b->callback != NULL || b->callback_ex != NULL) { 634 ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, 635 (void *)&fp, 0, cmd, 0, ret, NULL); 636 } 637 638 return (ret); 639 } 640 LCRYPTO_ALIAS(BIO_callback_ctrl); 641 642 /* It is unfortunate to duplicate in functions what the BIO_(w)pending macros 643 * do; but those macros have inappropriate return type, and for interfacing 644 * from other programming languages, C macros aren't much of a help anyway. */ 645 size_t 646 BIO_ctrl_pending(BIO *bio) 647 { 648 return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); 649 } 650 LCRYPTO_ALIAS(BIO_ctrl_pending); 651 652 size_t 653 BIO_ctrl_wpending(BIO *bio) 654 { 655 return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); 656 } 657 LCRYPTO_ALIAS(BIO_ctrl_wpending); 658 659 660 /* 661 * Append "bio" to the end of the chain containing "b": 662 * Two chains "b -> lb" and "oldhead -> bio" 663 * become two chains "b -> lb -> bio" and "oldhead". 664 */ 665 BIO * 666 BIO_push(BIO *b, BIO *bio) 667 { 668 BIO *lb; 669 670 if (b == NULL) 671 return (bio); 672 lb = b; 673 while (lb->next_bio != NULL) 674 lb = lb->next_bio; 675 lb->next_bio = bio; 676 if (bio != NULL) { 677 if (bio->prev_bio != NULL) 678 bio->prev_bio->next_bio = NULL; 679 bio->prev_bio = lb; 680 } 681 /* called to do internal processing */ 682 BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb); 683 return (b); 684 } 685 LCRYPTO_ALIAS(BIO_push); 686 687 /* Remove the first and return the rest */ 688 BIO * 689 BIO_pop(BIO *b) 690 { 691 BIO *ret; 692 693 if (b == NULL) 694 return (NULL); 695 ret = b->next_bio; 696 697 BIO_ctrl(b, BIO_CTRL_POP, 0, b); 698 699 if (b->prev_bio != NULL) 700 b->prev_bio->next_bio = b->next_bio; 701 if (b->next_bio != NULL) 702 b->next_bio->prev_bio = b->prev_bio; 703 704 b->next_bio = NULL; 705 b->prev_bio = NULL; 706 return (ret); 707 } 708 LCRYPTO_ALIAS(BIO_pop); 709 710 BIO * 711 BIO_get_retry_BIO(BIO *bio, int *reason) 712 { 713 BIO *b, *last; 714 715 b = last = bio; 716 for (;;) { 717 if (!BIO_should_retry(b)) 718 break; 719 last = b; 720 b = b->next_bio; 721 if (b == NULL) 722 break; 723 } 724 if (reason != NULL) 725 *reason = last->retry_reason; 726 return (last); 727 } 728 LCRYPTO_ALIAS(BIO_get_retry_BIO); 729 730 int 731 BIO_get_retry_reason(BIO *bio) 732 { 733 return (bio->retry_reason); 734 } 735 LCRYPTO_ALIAS(BIO_get_retry_reason); 736 737 void 738 BIO_set_retry_reason(BIO *bio, int reason) 739 { 740 bio->retry_reason = reason; 741 } 742 LCRYPTO_ALIAS(BIO_set_retry_reason); 743 744 BIO * 745 BIO_find_type(BIO *bio, int type) 746 { 747 int mt, mask; 748 749 if (!bio) 750 return NULL; 751 mask = type & 0xff; 752 do { 753 if (bio->method != NULL) { 754 mt = bio->method->type; 755 if (!mask) { 756 if (mt & type) 757 return (bio); 758 } else if (mt == type) 759 return (bio); 760 } 761 bio = bio->next_bio; 762 } while (bio != NULL); 763 return (NULL); 764 } 765 LCRYPTO_ALIAS(BIO_find_type); 766 767 BIO * 768 BIO_next(BIO *b) 769 { 770 if (!b) 771 return NULL; 772 return b->next_bio; 773 } 774 LCRYPTO_ALIAS(BIO_next); 775 776 /* 777 * Two chains "bio -> oldtail" and "oldhead -> next" become 778 * three chains "oldtail", "bio -> next", and "oldhead". 779 */ 780 void 781 BIO_set_next(BIO *bio, BIO *next) 782 { 783 /* Cut off the tail of the chain containing bio after bio. */ 784 if (bio->next_bio != NULL) 785 bio->next_bio->prev_bio = NULL; 786 787 /* Cut off the head of the chain containing next before next. */ 788 if (next != NULL && next->prev_bio != NULL) 789 next->prev_bio->next_bio = NULL; 790 791 /* Append the chain starting at next to the chain ending at bio. */ 792 bio->next_bio = next; 793 if (next != NULL) 794 next->prev_bio = bio; 795 } 796 LCRYPTO_ALIAS(BIO_set_next); 797 798 void 799 BIO_free_all(BIO *bio) 800 { 801 BIO *b; 802 int ref; 803 804 while (bio != NULL) { 805 b = bio; 806 ref = b->references; 807 bio = bio->next_bio; 808 BIO_free(b); 809 /* Since ref count > 1, don't free anyone else. */ 810 if (ref > 1) 811 break; 812 } 813 } 814 LCRYPTO_ALIAS(BIO_free_all); 815 816 BIO * 817 BIO_dup_chain(BIO *in) 818 { 819 BIO *new_chain = NULL, *new_bio = NULL, *tail = NULL; 820 BIO *bio; 821 822 for (bio = in; bio != NULL; bio = bio->next_bio) { 823 if ((new_bio = BIO_new(bio->method)) == NULL) 824 goto err; 825 new_bio->callback = bio->callback; 826 new_bio->callback_ex = bio->callback_ex; 827 new_bio->cb_arg = bio->cb_arg; 828 new_bio->init = bio->init; 829 new_bio->shutdown = bio->shutdown; 830 new_bio->flags = bio->flags; 831 new_bio->num = bio->num; 832 833 if (!BIO_dup_state(bio, new_bio)) 834 goto err; 835 836 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, 837 &new_bio->ex_data, &bio->ex_data)) 838 goto err; 839 840 if (BIO_push(tail, new_bio) == NULL) 841 goto err; 842 843 tail = new_bio; 844 if (new_chain == NULL) 845 new_chain = new_bio; 846 } 847 848 return new_chain; 849 850 err: 851 BIO_free(new_bio); 852 BIO_free_all(new_chain); 853 854 return NULL; 855 } 856 LCRYPTO_ALIAS(BIO_dup_chain); 857 858 void 859 BIO_copy_next_retry(BIO *b) 860 { 861 BIO_set_flags(b, BIO_get_retry_flags(b->next_bio)); 862 b->retry_reason = b->next_bio->retry_reason; 863 } 864 LCRYPTO_ALIAS(BIO_copy_next_retry); 865 866 int 867 BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 868 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 869 { 870 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp, 871 new_func, dup_func, free_func); 872 } 873 874 int 875 BIO_set_ex_data(BIO *bio, int idx, void *data) 876 { 877 return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data)); 878 } 879 LCRYPTO_ALIAS(BIO_set_ex_data); 880 881 void * 882 BIO_get_ex_data(BIO *bio, int idx) 883 { 884 return (CRYPTO_get_ex_data(&(bio->ex_data), idx)); 885 } 886 LCRYPTO_ALIAS(BIO_get_ex_data); 887 888 unsigned long 889 BIO_number_read(BIO *bio) 890 { 891 if (bio) 892 return bio->num_read; 893 return 0; 894 } 895 LCRYPTO_ALIAS(BIO_number_read); 896 897 unsigned long 898 BIO_number_written(BIO *bio) 899 { 900 if (bio) 901 return bio->num_write; 902 return 0; 903 } 904 LCRYPTO_ALIAS(BIO_number_written); 905