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