summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bio/bss_bio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bio/bss_bio.c')
-rw-r--r--src/lib/libcrypto/bio/bss_bio.c884
1 files changed, 0 insertions, 884 deletions
diff --git a/src/lib/libcrypto/bio/bss_bio.c b/src/lib/libcrypto/bio/bss_bio.c
deleted file mode 100644
index 26ae962aeb..0000000000
--- a/src/lib/libcrypto/bio/bss_bio.c
+++ /dev/null
@@ -1,884 +0,0 @@
1/* $OpenBSD: bss_bio.c,v 1.20 2014/06/12 15:49:28 deraadt 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
82#include <openssl/bio.h>
83#include <openssl/err.h>
84#include <openssl/crypto.h>
85
86static int bio_new(BIO *bio);
87static int bio_free(BIO *bio);
88static int bio_read(BIO *bio, char *buf, int size);
89static int bio_write(BIO *bio, const char *buf, int num);
90static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
91static int bio_puts(BIO *bio, const char *str);
92
93static int bio_make_pair(BIO *bio1, BIO *bio2);
94static void bio_destroy_pair(BIO *bio);
95
96static BIO_METHOD methods_biop = {
97 .type = BIO_TYPE_BIO,
98 .name = "BIO pair",
99 .bwrite = bio_write,
100 .bread = bio_read,
101 .bputs = bio_puts,
102 .ctrl = bio_ctrl,
103 .create = bio_new,
104 .destroy = bio_free
105};
106
107BIO_METHOD *
108BIO_s_bio(void)
109{
110 return &methods_biop;
111}
112
113struct bio_bio_st {
114 BIO *peer; /* NULL if buf == NULL.
115 * If peer != NULL, then peer->ptr is also a bio_bio_st,
116 * and its "peer" member points back to us.
117 * peer != NULL iff init != 0 in the BIO. */
118
119 /* This is for what we write (i.e. reading uses peer's struct): */
120 int closed; /* valid iff peer != NULL */
121 size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
122 size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
123 size_t size;
124 char *buf; /* "size" elements (if != NULL) */
125
126 size_t request; /* valid iff peer != NULL; 0 if len != 0,
127 * otherwise set by peer to number of bytes
128 * it (unsuccessfully) tried to read,
129 * never more than buffer space (size-len) warrants. */
130};
131
132static int
133bio_new(BIO *bio)
134{
135 struct bio_bio_st *b;
136
137 b = malloc(sizeof *b);
138 if (b == NULL)
139 return 0;
140
141 b->peer = NULL;
142 b->size = 17 * 1024; /* enough for one TLS record (just a default) */
143 b->buf = NULL;
144
145 bio->ptr = b;
146 return 1;
147}
148
149static int
150bio_free(BIO *bio)
151{
152 struct bio_bio_st *b;
153
154 if (bio == NULL)
155 return 0;
156 b = bio->ptr;
157
158 assert(b != NULL);
159
160 if (b->peer)
161 bio_destroy_pair(bio);
162
163 free(b->buf);
164 free(b);
165 return 1;
166}
167
168
169
170static int
171bio_read(BIO *bio, char *buf, int size_)
172{
173 size_t size = size_;
174 size_t rest;
175 struct bio_bio_st *b, *peer_b;
176
177 BIO_clear_retry_flags(bio);
178
179 if (!bio->init)
180 return 0;
181
182 b = bio->ptr;
183 assert(b != NULL);
184 assert(b->peer != NULL);
185 peer_b = b->peer->ptr;
186 assert(peer_b != NULL);
187 assert(peer_b->buf != NULL);
188
189 peer_b->request = 0; /* will be set in "retry_read" situation */
190
191 if (buf == NULL || size == 0)
192 return 0;
193
194 if (peer_b->len == 0) {
195 if (peer_b->closed)
196 return 0; /* writer has closed, and no data is left */
197 else {
198 BIO_set_retry_read(bio); /* buffer is empty */
199 if (size <= peer_b->size)
200 peer_b->request = size;
201 else
202 /* don't ask for more than the peer can
203 * deliver in one write */
204 peer_b->request = peer_b->size;
205 return -1;
206 }
207 }
208
209 /* we can read */
210 if (peer_b->len < size)
211 size = peer_b->len;
212
213 /* now read "size" bytes */
214
215 rest = size;
216
217 assert(rest > 0);
218 do /* one or two iterations */
219 {
220 size_t chunk;
221
222 assert(rest <= peer_b->len);
223 if (peer_b->offset + rest <= peer_b->size)
224 chunk = rest;
225 else
226 /* wrap around ring buffer */
227 chunk = peer_b->size - peer_b->offset;
228 assert(peer_b->offset + chunk <= peer_b->size);
229
230 memcpy(buf, peer_b->buf + peer_b->offset, chunk);
231
232 peer_b->len -= chunk;
233 if (peer_b->len) {
234 peer_b->offset += chunk;
235 assert(peer_b->offset <= peer_b->size);
236 if (peer_b->offset == peer_b->size)
237 peer_b->offset = 0;
238 buf += chunk;
239 } else {
240 /* buffer now empty, no need to advance "buf" */
241 assert(chunk == rest);
242 peer_b->offset = 0;
243 }
244 rest -= chunk;
245 } while (rest);
246
247 return size;
248}
249
250/* non-copying interface: provide pointer to available data in buffer
251 * bio_nread0: return number of available bytes
252 * bio_nread: also advance index
253 * (example usage: bio_nread0(), read from buffer, bio_nread()
254 * or just bio_nread(), read from buffer)
255 */
256/* WARNING: The non-copying interface is largely untested as of yet
257 * and may contain bugs. */
258static ssize_t
259bio_nread0(BIO *bio, char **buf)
260{
261 struct bio_bio_st *b, *peer_b;
262 ssize_t num;
263
264 BIO_clear_retry_flags(bio);
265
266 if (!bio->init)
267 return 0;
268
269 b = bio->ptr;
270 assert(b != NULL);
271 assert(b->peer != NULL);
272 peer_b = b->peer->ptr;
273 assert(peer_b != NULL);
274 assert(peer_b->buf != NULL);
275
276 peer_b->request = 0;
277
278 if (peer_b->len == 0) {
279 char dummy;
280
281 /* avoid code duplication -- nothing available for reading */
282 return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
283 }
284
285 num = peer_b->len;
286 if (peer_b->size < peer_b->offset + num)
287 /* no ring buffer wrap-around for non-copying interface */
288 num = peer_b->size - peer_b->offset;
289 assert(num > 0);
290
291 if (buf != NULL)
292 *buf = peer_b->buf + peer_b->offset;
293 return num;
294}
295
296static ssize_t
297bio_nread(BIO *bio, char **buf, size_t num_)
298{
299 struct bio_bio_st *b, *peer_b;
300 ssize_t num, available;
301
302 if (num_ > SSIZE_MAX)
303 num = SSIZE_MAX;
304 else
305 num = (ssize_t)num_;
306
307 available = bio_nread0(bio, buf);
308 if (num > available)
309 num = available;
310 if (num <= 0)
311 return num;
312
313 b = bio->ptr;
314 peer_b = b->peer->ptr;
315
316 peer_b->len -= num;
317 if (peer_b->len) {
318 peer_b->offset += num;
319 assert(peer_b->offset <= peer_b->size);
320 if (peer_b->offset == peer_b->size)
321 peer_b->offset = 0;
322 } else
323 peer_b->offset = 0;
324
325 return num;
326}
327
328
329static int
330bio_write(BIO *bio, const char *buf, int num_)
331{
332 size_t num = num_;
333 size_t rest;
334 struct bio_bio_st *b;
335
336 BIO_clear_retry_flags(bio);
337
338 if (!bio->init || buf == NULL || num == 0)
339 return 0;
340
341 b = bio->ptr;
342
343 assert(b != NULL);
344 assert(b->peer != NULL);
345 assert(b->buf != NULL);
346
347 b->request = 0;
348 if (b->closed) {
349 /* we already closed */
350 BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
351 return -1;
352 }
353
354 assert(b->len <= b->size);
355
356 if (b->len == b->size) {
357 BIO_set_retry_write(bio); /* buffer is full */
358 return -1;
359 }
360
361 /* we can write */
362 if (num > b->size - b->len)
363 num = b->size - b->len;
364
365 /* now write "num" bytes */
366
367 rest = num;
368
369 assert(rest > 0);
370 do /* one or two iterations */
371 {
372 size_t write_offset;
373 size_t chunk;
374
375 assert(b->len + rest <= b->size);
376
377 write_offset = b->offset + b->len;
378 if (write_offset >= b->size)
379 write_offset -= b->size;
380 /* b->buf[write_offset] is the first byte we can write to. */
381
382 if (write_offset + rest <= b->size)
383 chunk = rest;
384 else
385 /* wrap around ring buffer */
386 chunk = b->size - write_offset;
387
388 memcpy(b->buf + write_offset, buf, chunk);
389
390 b->len += chunk;
391
392 assert(b->len <= b->size);
393
394 rest -= chunk;
395 buf += chunk;
396 } while (rest);
397
398 return num;
399}
400
401/* non-copying interface: provide pointer to region to write to
402 * bio_nwrite0: check how much space is available
403 * bio_nwrite: also increase length
404 * (example usage: bio_nwrite0(), write to buffer, bio_nwrite()
405 * or just bio_nwrite(), write to buffer)
406 */
407static ssize_t
408bio_nwrite0(BIO *bio, char **buf)
409{
410 struct bio_bio_st *b;
411 size_t num;
412 size_t write_offset;
413
414 BIO_clear_retry_flags(bio);
415
416 if (!bio->init)
417 return 0;
418
419 b = bio->ptr;
420
421 assert(b != NULL);
422 assert(b->peer != NULL);
423 assert(b->buf != NULL);
424
425 b->request = 0;
426 if (b->closed) {
427 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
428 return -1;
429 }
430
431 assert(b->len <= b->size);
432
433 if (b->len == b->size) {
434 BIO_set_retry_write(bio);
435 return -1;
436 }
437
438 num = b->size - b->len;
439 write_offset = b->offset + b->len;
440 if (write_offset >= b->size)
441 write_offset -= b->size;
442 if (write_offset + num > b->size)
443 /* no ring buffer wrap-around for non-copying interface
444 * (to fulfil the promise by BIO_ctrl_get_write_guarantee,
445 * BIO_nwrite may have to be called twice) */
446 num = b->size - write_offset;
447
448 if (buf != NULL)
449 *buf = b->buf + write_offset;
450 assert(write_offset + num <= b->size);
451
452 return num;
453}
454
455static ssize_t
456bio_nwrite(BIO *bio, char **buf, size_t num_)
457{
458 struct bio_bio_st *b;
459 ssize_t num, space;
460
461 if (num_ > SSIZE_MAX)
462 num = SSIZE_MAX;
463 else
464 num = (ssize_t)num_;
465
466 space = bio_nwrite0(bio, buf);
467 if (num > space)
468 num = space;
469 if (num <= 0)
470 return num;
471 b = bio->ptr;
472 assert(b != NULL);
473 b->len += num;
474 assert(b->len <= b->size);
475
476 return num;
477}
478
479
480static long
481bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
482{
483 long ret;
484 struct bio_bio_st *b = bio->ptr;
485
486 assert(b != NULL);
487
488 switch (cmd) {
489 /* specific CTRL codes */
490
491 case BIO_C_SET_WRITE_BUF_SIZE:
492 if (b->peer) {
493 BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
494 ret = 0;
495 } else if (num == 0) {
496 BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
497 ret = 0;
498 } else {
499 size_t new_size = num;
500
501 if (b->size != new_size) {
502 if (b->buf) {
503 free(b->buf);
504 b->buf = NULL;
505 }
506 b->size = new_size;
507 }
508 ret = 1;
509 }
510 break;
511
512 case BIO_C_GET_WRITE_BUF_SIZE:
513 ret = (long) b->size;
514 break;
515
516 case BIO_C_MAKE_BIO_PAIR:
517 {
518 BIO *other_bio = ptr;
519
520 if (bio_make_pair(bio, other_bio))
521 ret = 1;
522 else
523 ret = 0;
524 }
525 break;
526
527 case BIO_C_DESTROY_BIO_PAIR:
528 /* Affects both BIOs in the pair -- call just once!
529 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */
530 bio_destroy_pair(bio);
531 ret = 1;
532 break;
533
534 case BIO_C_GET_WRITE_GUARANTEE:
535 /* How many bytes can the caller feed to the next write
536 * without having to keep any? */
537 if (b->peer == NULL || b->closed)
538 ret = 0;
539 else
540 ret = (long) b->size - b->len;
541 break;
542
543 case BIO_C_GET_READ_REQUEST:
544 /* If the peer unsuccessfully tried to read, how many bytes
545 * were requested? (As with BIO_CTRL_PENDING, that number
546 * can usually be treated as boolean.) */
547 ret = (long) b->request;
548 break;
549
550 case BIO_C_RESET_READ_REQUEST:
551 /* Reset request. (Can be useful after read attempts
552 * at the other side that are meant to be non-blocking,
553 * e.g. when probing SSL_read to see if any data is
554 * available.) */
555 b->request = 0;
556 ret = 1;
557 break;
558
559 case BIO_C_SHUTDOWN_WR:
560 /* similar to shutdown(..., SHUT_WR) */
561 b->closed = 1;
562 ret = 1;
563 break;
564
565 case BIO_C_NREAD0:
566 /* prepare for non-copying read */
567 ret = (long) bio_nread0(bio, ptr);
568 break;
569
570 case BIO_C_NREAD:
571 /* non-copying read */
572 ret = (long) bio_nread(bio, ptr, (size_t) num);
573 break;
574
575 case BIO_C_NWRITE0:
576 /* prepare for non-copying write */
577 ret = (long) bio_nwrite0(bio, ptr);
578 break;
579
580 case BIO_C_NWRITE:
581 /* non-copying write */
582 ret = (long) bio_nwrite(bio, ptr, (size_t) num);
583 break;
584
585
586 /* standard CTRL codes follow */
587
588 case BIO_CTRL_RESET:
589 if (b->buf != NULL) {
590 b->len = 0;
591 b->offset = 0;
592 }
593 ret = 0;
594 break;
595
596
597 case BIO_CTRL_GET_CLOSE:
598 ret = bio->shutdown;
599 break;
600
601 case BIO_CTRL_SET_CLOSE:
602 bio->shutdown = (int) num;
603 ret = 1;
604 break;
605
606 case BIO_CTRL_PENDING:
607 if (b->peer != NULL) {
608 struct bio_bio_st *peer_b = b->peer->ptr;
609
610 ret = (long) peer_b->len;
611 } else
612 ret = 0;
613 break;
614
615 case BIO_CTRL_WPENDING:
616 if (b->buf != NULL)
617 ret = (long) b->len;
618 else
619 ret = 0;
620 break;
621
622 case BIO_CTRL_DUP:
623 /* See BIO_dup_chain for circumstances we have to expect. */
624 {
625 BIO *other_bio = ptr;
626 struct bio_bio_st *other_b;
627
628 assert(other_bio != NULL);
629 other_b = other_bio->ptr;
630 assert(other_b != NULL);
631
632 assert(other_b->buf == NULL); /* other_bio is always fresh */
633
634 other_b->size = b->size;
635 }
636
637 ret = 1;
638 break;
639
640 case BIO_CTRL_FLUSH:
641 ret = 1;
642 break;
643
644 case BIO_CTRL_EOF:
645 {
646 BIO *other_bio = ptr;
647
648 if (other_bio) {
649 struct bio_bio_st *other_b = other_bio->ptr;
650
651 assert(other_b != NULL);
652 ret = other_b->len == 0 && other_b->closed;
653 } else
654 ret = 1;
655 }
656 break;
657
658 default:
659 ret = 0;
660 }
661 return ret;
662}
663
664static int
665bio_puts(BIO *bio, const char *str)
666{
667 return bio_write(bio, str, strlen(str));
668}
669
670
671static int
672bio_make_pair(BIO *bio1, BIO *bio2)
673{
674 struct bio_bio_st *b1, *b2;
675
676 assert(bio1 != NULL);
677 assert(bio2 != NULL);
678
679 b1 = bio1->ptr;
680 b2 = bio2->ptr;
681
682 if (b1->peer != NULL || b2->peer != NULL) {
683 BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
684 return 0;
685 }
686
687 if (b1->buf == NULL) {
688 b1->buf = malloc(b1->size);
689 if (b1->buf == NULL) {
690 BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
691 return 0;
692 }
693 b1->len = 0;
694 b1->offset = 0;
695 }
696
697 if (b2->buf == NULL) {
698 b2->buf = malloc(b2->size);
699 if (b2->buf == NULL) {
700 BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
701 return 0;
702 }
703 b2->len = 0;
704 b2->offset = 0;
705 }
706
707 b1->peer = bio2;
708 b1->closed = 0;
709 b1->request = 0;
710 b2->peer = bio1;
711 b2->closed = 0;
712 b2->request = 0;
713
714 bio1->init = 1;
715 bio2->init = 1;
716
717 return 1;
718}
719
720static void
721bio_destroy_pair(BIO *bio)
722{
723 struct bio_bio_st *b = bio->ptr;
724
725 if (b != NULL) {
726 BIO *peer_bio = b->peer;
727
728 if (peer_bio != NULL) {
729 struct bio_bio_st *peer_b = peer_bio->ptr;
730
731 assert(peer_b != NULL);
732 assert(peer_b->peer == bio);
733
734 peer_b->peer = NULL;
735 peer_bio->init = 0;
736 assert(peer_b->buf != NULL);
737 peer_b->len = 0;
738 peer_b->offset = 0;
739
740 b->peer = NULL;
741 bio->init = 0;
742 assert(b->buf != NULL);
743 b->len = 0;
744 b->offset = 0;
745 }
746 }
747}
748
749
750/* Exported convenience functions */
751int
752BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p, size_t writebuf2)
753{
754 BIO *bio1 = NULL, *bio2 = NULL;
755 long r;
756 int ret = 0;
757
758 bio1 = BIO_new(BIO_s_bio());
759 if (bio1 == NULL)
760 goto err;
761 bio2 = BIO_new(BIO_s_bio());
762 if (bio2 == NULL)
763 goto err;
764
765 if (writebuf1) {
766 r = BIO_set_write_buf_size(bio1, writebuf1);
767 if (!r)
768 goto err;
769 }
770 if (writebuf2) {
771 r = BIO_set_write_buf_size(bio2, writebuf2);
772 if (!r)
773 goto err;
774 }
775
776 r = BIO_make_bio_pair(bio1, bio2);
777 if (!r)
778 goto err;
779 ret = 1;
780
781 err:
782 if (ret == 0) {
783 if (bio1) {
784 BIO_free(bio1);
785 bio1 = NULL;
786 }
787 if (bio2) {
788 BIO_free(bio2);
789 bio2 = NULL;
790 }
791 }
792
793 *bio1_p = bio1;
794 *bio2_p = bio2;
795 return ret;
796}
797
798size_t
799BIO_ctrl_get_write_guarantee(BIO *bio)
800{
801 return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
802}
803
804size_t
805BIO_ctrl_get_read_request(BIO *bio)
806{
807 return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
808}
809
810int
811BIO_ctrl_reset_read_request(BIO *bio)
812{
813 return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
814}
815
816
817/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
818 * (conceivably some other BIOs could allow non-copying reads and writes too.)
819 */
820int
821BIO_nread0(BIO *bio, char **buf)
822{
823 long ret;
824
825 if (!bio->init) {
826 BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
827 return -2;
828 }
829
830 ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
831 if (ret > INT_MAX)
832 return INT_MAX;
833 else
834 return (int) ret;
835}
836
837int
838BIO_nread(BIO *bio, char **buf, int num)
839{
840 int ret;
841
842 if (!bio->init) {
843 BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
844 return -2;
845 }
846
847 ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
848 if (ret > 0)
849 bio->num_read += ret;
850 return ret;
851}
852
853int
854BIO_nwrite0(BIO *bio, char **buf)
855{
856 long ret;
857
858 if (!bio->init) {
859 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
860 return -2;
861 }
862
863 ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
864 if (ret > INT_MAX)
865 return INT_MAX;
866 else
867 return (int) ret;
868}
869
870int
871BIO_nwrite(BIO *bio, char **buf, int num)
872{
873 int ret;
874
875 if (!bio->init) {
876 BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
877 return -2;
878 }
879
880 ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
881 if (ret > 0)
882 bio->num_write += ret;
883 return ret;
884}