1 /* $OpenBSD: bio_lib.c,v 1.36 2022/08/15 10:48:45 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 133 BIO * 134 BIO_new(const BIO_METHOD *method) 135 { 136 BIO *ret = NULL; 137 138 /* XXX calloc */ 139 ret = malloc(sizeof(BIO)); 140 if (ret == NULL) { 141 BIOerror(ERR_R_MALLOC_FAILURE); 142 return (NULL); 143 } 144 if (!BIO_set(ret, method)) { 145 free(ret); 146 ret = NULL; 147 } 148 return (ret); 149 } 150 151 int 152 BIO_set(BIO *bio, const BIO_METHOD *method) 153 { 154 bio->method = method; 155 bio->callback = NULL; 156 bio->callback_ex = NULL; 157 bio->cb_arg = NULL; 158 bio->init = 0; 159 bio->shutdown = 1; 160 bio->flags = 0; 161 bio->retry_reason = 0; 162 bio->num = 0; 163 bio->ptr = NULL; 164 bio->prev_bio = NULL; 165 bio->next_bio = NULL; 166 bio->references = 1; 167 bio->num_read = 0L; 168 bio->num_write = 0L; 169 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); 170 if (method->create != NULL) { 171 if (!method->create(bio)) { 172 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, 173 &bio->ex_data); 174 return (0); 175 } 176 } 177 return (1); 178 } 179 180 int 181 BIO_free(BIO *a) 182 { 183 int ret; 184 185 if (a == NULL) 186 return (0); 187 188 if (CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO) > 0) 189 return (1); 190 191 if (a->callback != NULL || a->callback_ex != NULL) { 192 if ((ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 193 0L, 1L, NULL)) <= 0) 194 return (ret); 195 } 196 197 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data); 198 199 if (a->method != NULL && a->method->destroy != NULL) 200 a->method->destroy(a); 201 free(a); 202 return (1); 203 } 204 205 void 206 BIO_vfree(BIO *a) 207 { 208 BIO_free(a); 209 } 210 211 int 212 BIO_up_ref(BIO *bio) 213 { 214 int refs = CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO); 215 return (refs > 1) ? 1 : 0; 216 } 217 218 void * 219 BIO_get_data(BIO *a) 220 { 221 return (a->ptr); 222 } 223 224 void 225 BIO_set_data(BIO *a, void *ptr) 226 { 227 a->ptr = ptr; 228 } 229 230 int 231 BIO_get_init(BIO *a) 232 { 233 return a->init; 234 } 235 236 void 237 BIO_set_init(BIO *a, int init) 238 { 239 a->init = init; 240 } 241 242 int 243 BIO_get_shutdown(BIO *a) 244 { 245 return (a->shutdown); 246 } 247 248 void 249 BIO_set_shutdown(BIO *a, int shut) 250 { 251 a->shutdown = shut; 252 } 253 254 void 255 BIO_clear_flags(BIO *b, int flags) 256 { 257 b->flags &= ~flags; 258 } 259 260 int 261 BIO_test_flags(const BIO *b, int flags) 262 { 263 return (b->flags & flags); 264 } 265 266 void 267 BIO_set_flags(BIO *b, int flags) 268 { 269 b->flags |= flags; 270 } 271 272 BIO_callback_fn 273 BIO_get_callback(const BIO *b) 274 { 275 return b->callback; 276 } 277 278 void 279 BIO_set_callback(BIO *b, BIO_callback_fn cb) 280 { 281 b->callback = cb; 282 } 283 284 BIO_callback_fn_ex 285 BIO_get_callback_ex(const BIO *b) 286 { 287 return b->callback_ex; 288 } 289 290 void 291 BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex cb) 292 { 293 b->callback_ex = cb; 294 } 295 296 void 297 BIO_set_callback_arg(BIO *b, char *arg) 298 { 299 b->cb_arg = arg; 300 } 301 302 char * 303 BIO_get_callback_arg(const BIO *b) 304 { 305 return b->cb_arg; 306 } 307 308 const char * 309 BIO_method_name(const BIO *b) 310 { 311 return b->method->name; 312 } 313 314 int 315 BIO_method_type(const BIO *b) 316 { 317 return b->method->type; 318 } 319 320 int 321 BIO_read(BIO *b, void *out, int outl) 322 { 323 size_t readbytes = 0; 324 int ret; 325 326 if (b == NULL) 327 return (0); 328 329 if (out == NULL || outl <= 0) 330 return (0); 331 332 if (b->method == NULL || b->method->bread == NULL) { 333 BIOerror(BIO_R_UNSUPPORTED_METHOD); 334 return (-2); 335 } 336 337 if (b->callback != NULL || b->callback_ex != NULL) { 338 if ((ret = (int)bio_call_callback(b, BIO_CB_READ, out, outl, 0, 339 0L, 1L, NULL)) <= 0) 340 return (ret); 341 } 342 343 if (!b->init) { 344 BIOerror(BIO_R_UNINITIALIZED); 345 return (-2); 346 } 347 348 if ((ret = b->method->bread(b, out, outl)) > 0) 349 readbytes = (size_t)ret; 350 351 b->num_read += readbytes; 352 353 if (b->callback != NULL || b->callback_ex != NULL) { 354 ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, 355 out, outl, 0, 0L, (ret > 0) ? 1 : ret, &readbytes); 356 } 357 358 if (ret > 0) { 359 if (readbytes > INT_MAX) { 360 BIOerror(BIO_R_LENGTH_TOO_LONG); 361 ret = -1; 362 } else { 363 ret = (int)readbytes; 364 } 365 } 366 367 return (ret); 368 } 369 370 int 371 BIO_write(BIO *b, const void *in, int inl) 372 { 373 size_t writebytes = 0; 374 int ret; 375 376 if (b == NULL) 377 return (0); 378 379 if (in == NULL || inl <= 0) 380 return (0); 381 382 if (b->method == NULL || b->method->bwrite == NULL) { 383 BIOerror(BIO_R_UNSUPPORTED_METHOD); 384 return (-2); 385 } 386 387 if (b->callback != NULL || b->callback_ex != NULL) { 388 if ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, in, inl, 0, 389 0L, 1L, NULL)) <= 0) 390 return (ret); 391 } 392 393 if (!b->init) { 394 BIOerror(BIO_R_UNINITIALIZED); 395 return (-2); 396 } 397 398 if ((ret = b->method->bwrite(b, in, inl)) > 0) 399 writebytes = ret; 400 401 b->num_write += writebytes; 402 403 if (b->callback != NULL || b->callback_ex != NULL) { 404 ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, 405 in, inl, 0, 0L, (ret > 0) ? 1 : ret, &writebytes); 406 } 407 408 if (ret > 0) { 409 if (writebytes > INT_MAX) { 410 BIOerror(BIO_R_LENGTH_TOO_LONG); 411 ret = -1; 412 } else { 413 ret = (int)writebytes; 414 } 415 } 416 417 return (ret); 418 } 419 420 int 421 BIO_puts(BIO *b, const char *in) 422 { 423 size_t writebytes = 0; 424 int ret; 425 426 if (b == NULL || b->method == NULL || b->method->bputs == NULL) { 427 BIOerror(BIO_R_UNSUPPORTED_METHOD); 428 return (-2); 429 } 430 431 if (b->callback != NULL || b->callback_ex != NULL) { 432 if ((ret = (int)bio_call_callback(b, BIO_CB_PUTS, in, 0, 0, 0L, 433 1L, NULL)) <= 0) 434 return (ret); 435 } 436 437 if (!b->init) { 438 BIOerror(BIO_R_UNINITIALIZED); 439 return (-2); 440 } 441 442 if ((ret = b->method->bputs(b, in)) > 0) 443 writebytes = ret; 444 445 b->num_write += writebytes; 446 447 if (b->callback != NULL || b->callback_ex != NULL) { 448 ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, 449 in, 0, 0, 0L, (ret > 0) ? 1 : ret, &writebytes); 450 } 451 452 if (ret > 0) { 453 if (writebytes > INT_MAX) { 454 BIOerror(BIO_R_LENGTH_TOO_LONG); 455 ret = -1; 456 } else { 457 ret = (int)writebytes; 458 } 459 } 460 461 return (ret); 462 } 463 464 int 465 BIO_gets(BIO *b, char *in, int inl) 466 { 467 size_t readbytes = 0; 468 int ret; 469 470 if (b == NULL || b->method == NULL || b->method->bgets == NULL) { 471 BIOerror(BIO_R_UNSUPPORTED_METHOD); 472 return (-2); 473 } 474 475 if (b->callback != NULL || b->callback_ex != NULL) { 476 if ((ret = (int)bio_call_callback(b, BIO_CB_GETS, in, inl, 0, 0L, 477 1, NULL)) <= 0) 478 return (ret); 479 } 480 481 if (!b->init) { 482 BIOerror(BIO_R_UNINITIALIZED); 483 return (-2); 484 } 485 486 if ((ret = b->method->bgets(b, in, inl)) > 0) 487 readbytes = ret; 488 489 if (b->callback != NULL || b->callback_ex != NULL) { 490 ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, in, 491 inl, 0, 0L, (ret > 0) ? 1 : ret, &readbytes); 492 } 493 494 if (ret > 0) { 495 if (readbytes > INT_MAX) { 496 BIOerror(BIO_R_LENGTH_TOO_LONG); 497 ret = -1; 498 } else { 499 ret = (int)readbytes; 500 } 501 } 502 503 return (ret); 504 } 505 506 int 507 BIO_indent(BIO *b, int indent, int max) 508 { 509 if (indent > max) 510 indent = max; 511 if (indent < 0) 512 indent = 0; 513 while (indent--) 514 if (BIO_puts(b, " ") != 1) 515 return 0; 516 return 1; 517 } 518 519 long 520 BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) 521 { 522 int i; 523 524 i = iarg; 525 return (BIO_ctrl(b, cmd, larg, (char *)&i)); 526 } 527 528 char * 529 BIO_ptr_ctrl(BIO *b, int cmd, long larg) 530 { 531 char *p = NULL; 532 533 if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0) 534 return (NULL); 535 else 536 return (p); 537 } 538 539 long 540 BIO_ctrl(BIO *b, int cmd, long larg, void *parg) 541 { 542 long ret; 543 544 if (b == NULL) 545 return (0); 546 547 if (b->method == NULL || b->method->ctrl == NULL) { 548 BIOerror(BIO_R_UNSUPPORTED_METHOD); 549 return (-2); 550 } 551 552 if (b->callback != NULL || b->callback_ex != NULL) { 553 if ((ret = bio_call_callback(b, BIO_CB_CTRL, parg, 0, cmd, larg, 554 1L, NULL)) <= 0) 555 return (ret); 556 } 557 558 ret = b->method->ctrl(b, cmd, larg, parg); 559 560 if (b->callback != NULL || b->callback_ex != NULL) { 561 ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0, 562 cmd, larg, ret, NULL); 563 } 564 565 return (ret); 566 } 567 568 long 569 BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) 570 { 571 long ret; 572 573 if (b == NULL) 574 return (0); 575 576 if (b->method == NULL || b->method->callback_ctrl == NULL || 577 cmd != BIO_CTRL_SET_CALLBACK) { 578 BIOerror(BIO_R_UNSUPPORTED_METHOD); 579 return (-2); 580 } 581 582 if (b->callback != NULL || b->callback_ex != NULL) { 583 if ((ret = bio_call_callback(b, BIO_CB_CTRL, (void *)&fp, 0, 584 cmd, 0, 1L, NULL)) <= 0) 585 return (ret); 586 } 587 588 ret = b->method->callback_ctrl(b, cmd, fp); 589 590 if (b->callback != NULL || b->callback_ex != NULL) { 591 ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, 592 (void *)&fp, 0, cmd, 0, ret, NULL); 593 } 594 595 return (ret); 596 } 597 598 /* It is unfortunate to duplicate in functions what the BIO_(w)pending macros 599 * do; but those macros have inappropriate return type, and for interfacing 600 * from other programming languages, C macros aren't much of a help anyway. */ 601 size_t 602 BIO_ctrl_pending(BIO *bio) 603 { 604 return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); 605 } 606 607 size_t 608 BIO_ctrl_wpending(BIO *bio) 609 { 610 return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); 611 } 612 613 614 /* put the 'bio' on the end of b's list of operators */ 615 BIO * 616 BIO_push(BIO *b, BIO *bio) 617 { 618 BIO *lb; 619 620 if (b == NULL) 621 return (bio); 622 lb = b; 623 while (lb->next_bio != NULL) 624 lb = lb->next_bio; 625 lb->next_bio = bio; 626 if (bio != NULL) 627 bio->prev_bio = lb; 628 /* called to do internal processing */ 629 BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb); 630 return (b); 631 } 632 633 /* Remove the first and return the rest */ 634 BIO * 635 BIO_pop(BIO *b) 636 { 637 BIO *ret; 638 639 if (b == NULL) 640 return (NULL); 641 ret = b->next_bio; 642 643 BIO_ctrl(b, BIO_CTRL_POP, 0, b); 644 645 if (b->prev_bio != NULL) 646 b->prev_bio->next_bio = b->next_bio; 647 if (b->next_bio != NULL) 648 b->next_bio->prev_bio = b->prev_bio; 649 650 b->next_bio = NULL; 651 b->prev_bio = NULL; 652 return (ret); 653 } 654 655 BIO * 656 BIO_get_retry_BIO(BIO *bio, int *reason) 657 { 658 BIO *b, *last; 659 660 b = last = bio; 661 for (;;) { 662 if (!BIO_should_retry(b)) 663 break; 664 last = b; 665 b = b->next_bio; 666 if (b == NULL) 667 break; 668 } 669 if (reason != NULL) 670 *reason = last->retry_reason; 671 return (last); 672 } 673 674 int 675 BIO_get_retry_reason(BIO *bio) 676 { 677 return (bio->retry_reason); 678 } 679 680 void 681 BIO_set_retry_reason(BIO *bio, int reason) 682 { 683 bio->retry_reason = reason; 684 } 685 686 BIO * 687 BIO_find_type(BIO *bio, int type) 688 { 689 int mt, mask; 690 691 if (!bio) 692 return NULL; 693 mask = type & 0xff; 694 do { 695 if (bio->method != NULL) { 696 mt = bio->method->type; 697 if (!mask) { 698 if (mt & type) 699 return (bio); 700 } else if (mt == type) 701 return (bio); 702 } 703 bio = bio->next_bio; 704 } while (bio != NULL); 705 return (NULL); 706 } 707 708 BIO * 709 BIO_next(BIO *b) 710 { 711 if (!b) 712 return NULL; 713 return b->next_bio; 714 } 715 716 void 717 BIO_set_next(BIO *b, BIO *next) 718 { 719 b->next_bio = next; 720 } 721 722 void 723 BIO_free_all(BIO *bio) 724 { 725 BIO *b; 726 int ref; 727 728 while (bio != NULL) { 729 b = bio; 730 ref = b->references; 731 bio = bio->next_bio; 732 BIO_free(b); 733 /* Since ref count > 1, don't free anyone else. */ 734 if (ref > 1) 735 break; 736 } 737 } 738 739 BIO * 740 BIO_dup_chain(BIO *in) 741 { 742 BIO *ret = NULL, *eoc = NULL, *bio, *new_bio; 743 744 for (bio = in; bio != NULL; bio = bio->next_bio) { 745 if ((new_bio = BIO_new(bio->method)) == NULL) 746 goto err; 747 new_bio->callback = bio->callback; 748 new_bio->callback_ex = bio->callback_ex; 749 new_bio->cb_arg = bio->cb_arg; 750 new_bio->init = bio->init; 751 new_bio->shutdown = bio->shutdown; 752 new_bio->flags = bio->flags; 753 754 /* This will let SSL_s_sock() work with stdin/stdout */ 755 new_bio->num = bio->num; 756 757 if (!BIO_dup_state(bio, (char *)new_bio)) { 758 BIO_free(new_bio); 759 goto err; 760 } 761 762 /* copy app data */ 763 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, 764 &new_bio->ex_data, &bio->ex_data)) 765 goto err; 766 767 if (ret == NULL) { 768 eoc = new_bio; 769 ret = eoc; 770 } else { 771 BIO_push(eoc, new_bio); 772 eoc = new_bio; 773 } 774 } 775 return (ret); 776 err: 777 BIO_free(ret); 778 return (NULL); 779 780 } 781 782 void 783 BIO_copy_next_retry(BIO *b) 784 { 785 BIO_set_flags(b, BIO_get_retry_flags(b->next_bio)); 786 b->retry_reason = b->next_bio->retry_reason; 787 } 788 789 int 790 BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 791 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 792 { 793 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp, 794 new_func, dup_func, free_func); 795 } 796 797 int 798 BIO_set_ex_data(BIO *bio, int idx, void *data) 799 { 800 return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data)); 801 } 802 803 void * 804 BIO_get_ex_data(BIO *bio, int idx) 805 { 806 return (CRYPTO_get_ex_data(&(bio->ex_data), idx)); 807 } 808 809 unsigned long 810 BIO_number_read(BIO *bio) 811 { 812 if (bio) 813 return bio->num_read; 814 return 0; 815 } 816 817 unsigned long 818 BIO_number_written(BIO *bio) 819 { 820 if (bio) 821 return bio->num_write; 822 return 0; 823 } 824