1 /* $OpenBSD: bss_bio.c,v 1.25 2022/01/07 09:02:17 tb Exp $ */ 2 /* ==================================================================== 3 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * openssl-core@openssl.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This product includes cryptographic software written by Eric Young 51 * (eay@cryptsoft.com). This product includes software written by Tim 52 * Hudson (tjh@cryptsoft.com). 53 * 54 */ 55 56 /* Special method for a BIO where the other endpoint is also a BIO 57 * of this kind, handled by the same thread (i.e. the "peer" is actually 58 * ourselves, wearing a different hat). 59 * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces 60 * for which no specific BIO method is available. 61 * See ssl/ssltest.c for some hints on how this can be used. */ 62 63 /* BIO_DEBUG implies BIO_PAIR_DEBUG */ 64 #ifdef BIO_DEBUG 65 # ifndef BIO_PAIR_DEBUG 66 # define BIO_PAIR_DEBUG 67 # endif 68 #endif 69 70 /* disable assert() unless BIO_PAIR_DEBUG has been defined */ 71 #ifndef BIO_PAIR_DEBUG 72 # ifndef NDEBUG 73 # define NDEBUG 74 # endif 75 #endif 76 77 #include <assert.h> 78 #include <limits.h> 79 #include <stdlib.h> 80 #include <string.h> 81 #include <sys/types.h> 82 83 #include <openssl/bio.h> 84 #include <openssl/err.h> 85 #include <openssl/crypto.h> 86 87 #include "bio_local.h" 88 89 static int bio_new(BIO *bio); 90 static int bio_free(BIO *bio); 91 static int bio_read(BIO *bio, char *buf, int size); 92 static int bio_write(BIO *bio, const char *buf, int num); 93 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); 94 static int bio_puts(BIO *bio, const char *str); 95 96 static int bio_make_pair(BIO *bio1, BIO *bio2); 97 static void bio_destroy_pair(BIO *bio); 98 99 static const BIO_METHOD methods_biop = { 100 .type = BIO_TYPE_BIO, 101 .name = "BIO pair", 102 .bwrite = bio_write, 103 .bread = bio_read, 104 .bputs = bio_puts, 105 .ctrl = bio_ctrl, 106 .create = bio_new, 107 .destroy = bio_free 108 }; 109 110 const BIO_METHOD * 111 BIO_s_bio(void) 112 { 113 return &methods_biop; 114 } 115 116 struct bio_bio_st { 117 BIO *peer; /* NULL if buf == NULL. 118 * If peer != NULL, then peer->ptr is also a bio_bio_st, 119 * and its "peer" member points back to us. 120 * peer != NULL iff init != 0 in the BIO. */ 121 122 /* This is for what we write (i.e. reading uses peer's struct): */ 123 int closed; /* valid iff peer != NULL */ 124 size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ 125 size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ 126 size_t size; 127 char *buf; /* "size" elements (if != NULL) */ 128 129 size_t request; /* valid iff peer != NULL; 0 if len != 0, 130 * otherwise set by peer to number of bytes 131 * it (unsuccessfully) tried to read, 132 * never more than buffer space (size-len) warrants. */ 133 }; 134 135 static int 136 bio_new(BIO *bio) 137 { 138 struct bio_bio_st *b; 139 140 b = malloc(sizeof *b); 141 if (b == NULL) 142 return 0; 143 144 b->peer = NULL; 145 b->size = 17 * 1024; /* enough for one TLS record (just a default) */ 146 b->buf = NULL; 147 148 bio->ptr = b; 149 return 1; 150 } 151 152 static int 153 bio_free(BIO *bio) 154 { 155 struct bio_bio_st *b; 156 157 if (bio == NULL) 158 return 0; 159 b = bio->ptr; 160 161 assert(b != NULL); 162 163 if (b->peer) 164 bio_destroy_pair(bio); 165 166 free(b->buf); 167 free(b); 168 return 1; 169 } 170 171 172 173 static int 174 bio_read(BIO *bio, char *buf, int size_) 175 { 176 size_t size = size_; 177 size_t rest; 178 struct bio_bio_st *b, *peer_b; 179 180 BIO_clear_retry_flags(bio); 181 182 if (!bio->init) 183 return 0; 184 185 b = bio->ptr; 186 assert(b != NULL); 187 assert(b->peer != NULL); 188 peer_b = b->peer->ptr; 189 assert(peer_b != NULL); 190 assert(peer_b->buf != NULL); 191 192 peer_b->request = 0; /* will be set in "retry_read" situation */ 193 194 if (buf == NULL || size == 0) 195 return 0; 196 197 if (peer_b->len == 0) { 198 if (peer_b->closed) 199 return 0; /* writer has closed, and no data is left */ 200 else { 201 BIO_set_retry_read(bio); /* buffer is empty */ 202 if (size <= peer_b->size) 203 peer_b->request = size; 204 else 205 /* don't ask for more than the peer can 206 * deliver in one write */ 207 peer_b->request = peer_b->size; 208 return -1; 209 } 210 } 211 212 /* we can read */ 213 if (peer_b->len < size) 214 size = peer_b->len; 215 216 /* now read "size" bytes */ 217 218 rest = size; 219 220 assert(rest > 0); 221 do /* one or two iterations */ 222 { 223 size_t chunk; 224 225 assert(rest <= peer_b->len); 226 if (peer_b->offset + rest <= peer_b->size) 227 chunk = rest; 228 else 229 /* wrap around ring buffer */ 230 chunk = peer_b->size - peer_b->offset; 231 assert(peer_b->offset + chunk <= peer_b->size); 232 233 memcpy(buf, peer_b->buf + peer_b->offset, chunk); 234 235 peer_b->len -= chunk; 236 if (peer_b->len) { 237 peer_b->offset += chunk; 238 assert(peer_b->offset <= peer_b->size); 239 if (peer_b->offset == peer_b->size) 240 peer_b->offset = 0; 241 buf += chunk; 242 } else { 243 /* buffer now empty, no need to advance "buf" */ 244 assert(chunk == rest); 245 peer_b->offset = 0; 246 } 247 rest -= chunk; 248 } while (rest); 249 250 return size; 251 } 252 253 /* non-copying interface: provide pointer to available data in buffer 254 * bio_nread0: return number of available bytes 255 * bio_nread: also advance index 256 * (example usage: bio_nread0(), read from buffer, bio_nread() 257 * or just bio_nread(), read from buffer) 258 */ 259 /* WARNING: The non-copying interface is largely untested as of yet 260 * and may contain bugs. */ 261 static ssize_t 262 bio_nread0(BIO *bio, char **buf) 263 { 264 struct bio_bio_st *b, *peer_b; 265 ssize_t num; 266 267 BIO_clear_retry_flags(bio); 268 269 if (!bio->init) 270 return 0; 271 272 b = bio->ptr; 273 assert(b != NULL); 274 assert(b->peer != NULL); 275 peer_b = b->peer->ptr; 276 assert(peer_b != NULL); 277 assert(peer_b->buf != NULL); 278 279 peer_b->request = 0; 280 281 if (peer_b->len == 0) { 282 char dummy; 283 284 /* avoid code duplication -- nothing available for reading */ 285 return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ 286 } 287 288 num = peer_b->len; 289 if (peer_b->size < peer_b->offset + num) 290 /* no ring buffer wrap-around for non-copying interface */ 291 num = peer_b->size - peer_b->offset; 292 assert(num > 0); 293 294 if (buf != NULL) 295 *buf = peer_b->buf + peer_b->offset; 296 return num; 297 } 298 299 static ssize_t 300 bio_nread(BIO *bio, char **buf, size_t num_) 301 { 302 struct bio_bio_st *b, *peer_b; 303 ssize_t num, available; 304 305 if (num_ > SSIZE_MAX) 306 num = SSIZE_MAX; 307 else 308 num = (ssize_t)num_; 309 310 available = bio_nread0(bio, buf); 311 if (num > available) 312 num = available; 313 if (num <= 0) 314 return num; 315 316 b = bio->ptr; 317 peer_b = b->peer->ptr; 318 319 peer_b->len -= num; 320 if (peer_b->len) { 321 peer_b->offset += num; 322 assert(peer_b->offset <= peer_b->size); 323 if (peer_b->offset == peer_b->size) 324 peer_b->offset = 0; 325 } else 326 peer_b->offset = 0; 327 328 return num; 329 } 330 331 332 static int 333 bio_write(BIO *bio, const char *buf, int num_) 334 { 335 size_t num = num_; 336 size_t rest; 337 struct bio_bio_st *b; 338 339 BIO_clear_retry_flags(bio); 340 341 if (!bio->init || buf == NULL || num == 0) 342 return 0; 343 344 b = bio->ptr; 345 346 assert(b != NULL); 347 assert(b->peer != NULL); 348 assert(b->buf != NULL); 349 350 b->request = 0; 351 if (b->closed) { 352 /* we already closed */ 353 BIOerror(BIO_R_BROKEN_PIPE); 354 return -1; 355 } 356 357 assert(b->len <= b->size); 358 359 if (b->len == b->size) { 360 BIO_set_retry_write(bio); /* buffer is full */ 361 return -1; 362 } 363 364 /* we can write */ 365 if (num > b->size - b->len) 366 num = b->size - b->len; 367 368 /* now write "num" bytes */ 369 370 rest = num; 371 372 assert(rest > 0); 373 do /* one or two iterations */ 374 { 375 size_t write_offset; 376 size_t chunk; 377 378 assert(b->len + rest <= b->size); 379 380 write_offset = b->offset + b->len; 381 if (write_offset >= b->size) 382 write_offset -= b->size; 383 /* b->buf[write_offset] is the first byte we can write to. */ 384 385 if (write_offset + rest <= b->size) 386 chunk = rest; 387 else 388 /* wrap around ring buffer */ 389 chunk = b->size - write_offset; 390 391 memcpy(b->buf + write_offset, buf, chunk); 392 393 b->len += chunk; 394 395 assert(b->len <= b->size); 396 397 rest -= chunk; 398 buf += chunk; 399 } while (rest); 400 401 return num; 402 } 403 404 /* non-copying interface: provide pointer to region to write to 405 * bio_nwrite0: check how much space is available 406 * bio_nwrite: also increase length 407 * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() 408 * or just bio_nwrite(), write to buffer) 409 */ 410 static ssize_t 411 bio_nwrite0(BIO *bio, char **buf) 412 { 413 struct bio_bio_st *b; 414 size_t num; 415 size_t write_offset; 416 417 BIO_clear_retry_flags(bio); 418 419 if (!bio->init) 420 return 0; 421 422 b = bio->ptr; 423 424 assert(b != NULL); 425 assert(b->peer != NULL); 426 assert(b->buf != NULL); 427 428 b->request = 0; 429 if (b->closed) { 430 BIOerror(BIO_R_BROKEN_PIPE); 431 return -1; 432 } 433 434 assert(b->len <= b->size); 435 436 if (b->len == b->size) { 437 BIO_set_retry_write(bio); 438 return -1; 439 } 440 441 num = b->size - b->len; 442 write_offset = b->offset + b->len; 443 if (write_offset >= b->size) 444 write_offset -= b->size; 445 if (write_offset + num > b->size) 446 /* no ring buffer wrap-around for non-copying interface 447 * (to fulfil the promise by BIO_ctrl_get_write_guarantee, 448 * BIO_nwrite may have to be called twice) */ 449 num = b->size - write_offset; 450 451 if (buf != NULL) 452 *buf = b->buf + write_offset; 453 assert(write_offset + num <= b->size); 454 455 return num; 456 } 457 458 static ssize_t 459 bio_nwrite(BIO *bio, char **buf, size_t num_) 460 { 461 struct bio_bio_st *b; 462 ssize_t num, space; 463 464 if (num_ > SSIZE_MAX) 465 num = SSIZE_MAX; 466 else 467 num = (ssize_t)num_; 468 469 space = bio_nwrite0(bio, buf); 470 if (num > space) 471 num = space; 472 if (num <= 0) 473 return num; 474 b = bio->ptr; 475 assert(b != NULL); 476 b->len += num; 477 assert(b->len <= b->size); 478 479 return num; 480 } 481 482 483 static long 484 bio_ctrl(BIO *bio, int cmd, long num, void *ptr) 485 { 486 long ret; 487 struct bio_bio_st *b = bio->ptr; 488 489 assert(b != NULL); 490 491 switch (cmd) { 492 /* specific CTRL codes */ 493 494 case BIO_C_SET_WRITE_BUF_SIZE: 495 if (b->peer) { 496 BIOerror(BIO_R_IN_USE); 497 ret = 0; 498 } else if (num == 0) { 499 BIOerror(BIO_R_INVALID_ARGUMENT); 500 ret = 0; 501 } else { 502 size_t new_size = num; 503 504 if (b->size != new_size) { 505 free(b->buf); 506 b->buf = NULL; 507 b->size = new_size; 508 } 509 ret = 1; 510 } 511 break; 512 513 case BIO_C_GET_WRITE_BUF_SIZE: 514 ret = (long) b->size; 515 break; 516 517 case BIO_C_MAKE_BIO_PAIR: 518 { 519 BIO *other_bio = ptr; 520 521 if (bio_make_pair(bio, other_bio)) 522 ret = 1; 523 else 524 ret = 0; 525 } 526 break; 527 528 case BIO_C_DESTROY_BIO_PAIR: 529 /* Affects both BIOs in the pair -- call just once! 530 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */ 531 bio_destroy_pair(bio); 532 ret = 1; 533 break; 534 535 case BIO_C_GET_WRITE_GUARANTEE: 536 /* How many bytes can the caller feed to the next write 537 * without having to keep any? */ 538 if (b->peer == NULL || b->closed) 539 ret = 0; 540 else 541 ret = (long) b->size - b->len; 542 break; 543 544 case BIO_C_GET_READ_REQUEST: 545 /* If the peer unsuccessfully tried to read, how many bytes 546 * were requested? (As with BIO_CTRL_PENDING, that number 547 * can usually be treated as boolean.) */ 548 ret = (long) b->request; 549 break; 550 551 case BIO_C_RESET_READ_REQUEST: 552 /* Reset request. (Can be useful after read attempts 553 * at the other side that are meant to be non-blocking, 554 * e.g. when probing SSL_read to see if any data is 555 * available.) */ 556 b->request = 0; 557 ret = 1; 558 break; 559 560 case BIO_C_SHUTDOWN_WR: 561 /* similar to shutdown(..., SHUT_WR) */ 562 b->closed = 1; 563 ret = 1; 564 break; 565 566 case BIO_C_NREAD0: 567 /* prepare for non-copying read */ 568 ret = (long) bio_nread0(bio, ptr); 569 break; 570 571 case BIO_C_NREAD: 572 /* non-copying read */ 573 ret = (long) bio_nread(bio, ptr, (size_t) num); 574 break; 575 576 case BIO_C_NWRITE0: 577 /* prepare for non-copying write */ 578 ret = (long) bio_nwrite0(bio, ptr); 579 break; 580 581 case BIO_C_NWRITE: 582 /* non-copying write */ 583 ret = (long) bio_nwrite(bio, ptr, (size_t) num); 584 break; 585 586 587 /* standard CTRL codes follow */ 588 589 case BIO_CTRL_RESET: 590 if (b->buf != NULL) { 591 b->len = 0; 592 b->offset = 0; 593 } 594 ret = 0; 595 break; 596 597 598 case BIO_CTRL_GET_CLOSE: 599 ret = bio->shutdown; 600 break; 601 602 case BIO_CTRL_SET_CLOSE: 603 bio->shutdown = (int) num; 604 ret = 1; 605 break; 606 607 case BIO_CTRL_PENDING: 608 if (b->peer != NULL) { 609 struct bio_bio_st *peer_b = b->peer->ptr; 610 611 ret = (long) peer_b->len; 612 } else 613 ret = 0; 614 break; 615 616 case BIO_CTRL_WPENDING: 617 if (b->buf != NULL) 618 ret = (long) b->len; 619 else 620 ret = 0; 621 break; 622 623 case BIO_CTRL_DUP: 624 /* See BIO_dup_chain for circumstances we have to expect. */ 625 { 626 BIO *other_bio = ptr; 627 struct bio_bio_st *other_b; 628 629 assert(other_bio != NULL); 630 other_b = other_bio->ptr; 631 assert(other_b != NULL); 632 633 assert(other_b->buf == NULL); /* other_bio is always fresh */ 634 635 other_b->size = b->size; 636 } 637 638 ret = 1; 639 break; 640 641 case BIO_CTRL_FLUSH: 642 ret = 1; 643 break; 644 645 case BIO_CTRL_EOF: 646 { 647 BIO *other_bio = ptr; 648 649 if (other_bio) { 650 struct bio_bio_st *other_b = other_bio->ptr; 651 652 assert(other_b != NULL); 653 ret = other_b->len == 0 && other_b->closed; 654 } else 655 ret = 1; 656 } 657 break; 658 659 default: 660 ret = 0; 661 } 662 return ret; 663 } 664 665 static int 666 bio_puts(BIO *bio, const char *str) 667 { 668 return bio_write(bio, str, strlen(str)); 669 } 670 671 672 static int 673 bio_make_pair(BIO *bio1, BIO *bio2) 674 { 675 struct bio_bio_st *b1, *b2; 676 677 assert(bio1 != NULL); 678 assert(bio2 != NULL); 679 680 b1 = bio1->ptr; 681 b2 = bio2->ptr; 682 683 if (b1->peer != NULL || b2->peer != NULL) { 684 BIOerror(BIO_R_IN_USE); 685 return 0; 686 } 687 688 if (b1->buf == NULL) { 689 b1->buf = malloc(b1->size); 690 if (b1->buf == NULL) { 691 BIOerror(ERR_R_MALLOC_FAILURE); 692 return 0; 693 } 694 b1->len = 0; 695 b1->offset = 0; 696 } 697 698 if (b2->buf == NULL) { 699 b2->buf = malloc(b2->size); 700 if (b2->buf == NULL) { 701 BIOerror(ERR_R_MALLOC_FAILURE); 702 return 0; 703 } 704 b2->len = 0; 705 b2->offset = 0; 706 } 707 708 b1->peer = bio2; 709 b1->closed = 0; 710 b1->request = 0; 711 b2->peer = bio1; 712 b2->closed = 0; 713 b2->request = 0; 714 715 bio1->init = 1; 716 bio2->init = 1; 717 718 return 1; 719 } 720 721 static void 722 bio_destroy_pair(BIO *bio) 723 { 724 struct bio_bio_st *b = bio->ptr; 725 726 if (b != NULL) { 727 BIO *peer_bio = b->peer; 728 729 if (peer_bio != NULL) { 730 struct bio_bio_st *peer_b = peer_bio->ptr; 731 732 assert(peer_b != NULL); 733 assert(peer_b->peer == bio); 734 735 peer_b->peer = NULL; 736 peer_bio->init = 0; 737 assert(peer_b->buf != NULL); 738 peer_b->len = 0; 739 peer_b->offset = 0; 740 741 b->peer = NULL; 742 bio->init = 0; 743 assert(b->buf != NULL); 744 b->len = 0; 745 b->offset = 0; 746 } 747 } 748 } 749 750 751 /* Exported convenience functions */ 752 int 753 BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p, size_t writebuf2) 754 { 755 BIO *bio1 = NULL, *bio2 = NULL; 756 long r; 757 int ret = 0; 758 759 bio1 = BIO_new(BIO_s_bio()); 760 if (bio1 == NULL) 761 goto err; 762 bio2 = BIO_new(BIO_s_bio()); 763 if (bio2 == NULL) 764 goto err; 765 766 if (writebuf1) { 767 r = BIO_set_write_buf_size(bio1, writebuf1); 768 if (!r) 769 goto err; 770 } 771 if (writebuf2) { 772 r = BIO_set_write_buf_size(bio2, writebuf2); 773 if (!r) 774 goto err; 775 } 776 777 r = BIO_make_bio_pair(bio1, bio2); 778 if (!r) 779 goto err; 780 ret = 1; 781 782 err: 783 if (ret == 0) { 784 if (bio1) { 785 BIO_free(bio1); 786 bio1 = NULL; 787 } 788 if (bio2) { 789 BIO_free(bio2); 790 bio2 = NULL; 791 } 792 } 793 794 *bio1_p = bio1; 795 *bio2_p = bio2; 796 return ret; 797 } 798 799 size_t 800 BIO_ctrl_get_write_guarantee(BIO *bio) 801 { 802 return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); 803 } 804 805 size_t 806 BIO_ctrl_get_read_request(BIO *bio) 807 { 808 return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); 809 } 810 811 int 812 BIO_ctrl_reset_read_request(BIO *bio) 813 { 814 return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); 815 } 816 817 818 /* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now 819 * (conceivably some other BIOs could allow non-copying reads and writes too.) 820 */ 821 int 822 BIO_nread0(BIO *bio, char **buf) 823 { 824 long ret; 825 826 if (!bio->init) { 827 BIOerror(BIO_R_UNINITIALIZED); 828 return -2; 829 } 830 831 ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); 832 if (ret > INT_MAX) 833 return INT_MAX; 834 else 835 return (int) ret; 836 } 837 838 int 839 BIO_nread(BIO *bio, char **buf, int num) 840 { 841 int ret; 842 843 if (!bio->init) { 844 BIOerror(BIO_R_UNINITIALIZED); 845 return -2; 846 } 847 848 ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf); 849 if (ret > 0) 850 bio->num_read += ret; 851 return ret; 852 } 853 854 int 855 BIO_nwrite0(BIO *bio, char **buf) 856 { 857 long ret; 858 859 if (!bio->init) { 860 BIOerror(BIO_R_UNINITIALIZED); 861 return -2; 862 } 863 864 ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); 865 if (ret > INT_MAX) 866 return INT_MAX; 867 else 868 return (int) ret; 869 } 870 871 int 872 BIO_nwrite(BIO *bio, char **buf, int num) 873 { 874 int ret; 875 876 if (!bio->init) { 877 BIOerror(BIO_R_UNINITIALIZED); 878 return -2; 879 } 880 881 ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); 882 if (ret > 0) 883 bio->num_write += ret; 884 return ret; 885 } 886