820cf8cf6a25982366004e138fa86d19e44f78de
[oweals/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         if (b->peer != NULL) {
631             struct bio_bio_st *peer_b = b->peer->ptr;
632
633             if (peer_b->len == 0 && peer_b->closed)
634                 ret = 1;
635             else
636                 ret = 0;
637         } else {
638             ret = 1;
639         }
640         break;
641
642     default:
643         ret = 0;
644     }
645     return ret;
646 }
647
648 static int bio_puts(BIO *bio, const char *str)
649 {
650     return bio_write(bio, str, strlen(str));
651 }
652
653 static int bio_make_pair(BIO *bio1, BIO *bio2)
654 {
655     struct bio_bio_st *b1, *b2;
656
657     assert(bio1 != NULL);
658     assert(bio2 != NULL);
659
660     b1 = bio1->ptr;
661     b2 = bio2->ptr;
662
663     if (b1->peer != NULL || b2->peer != NULL) {
664         BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
665         return 0;
666     }
667
668     if (b1->buf == NULL) {
669         b1->buf = OPENSSL_malloc(b1->size);
670         if (b1->buf == NULL) {
671             BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
672             return 0;
673         }
674         b1->len = 0;
675         b1->offset = 0;
676     }
677
678     if (b2->buf == NULL) {
679         b2->buf = OPENSSL_malloc(b2->size);
680         if (b2->buf == NULL) {
681             BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
682             return 0;
683         }
684         b2->len = 0;
685         b2->offset = 0;
686     }
687
688     b1->peer = bio2;
689     b1->closed = 0;
690     b1->request = 0;
691     b2->peer = bio1;
692     b2->closed = 0;
693     b2->request = 0;
694
695     bio1->init = 1;
696     bio2->init = 1;
697
698     return 1;
699 }
700
701 static void bio_destroy_pair(BIO *bio)
702 {
703     struct bio_bio_st *b = bio->ptr;
704
705     if (b != NULL) {
706         BIO *peer_bio = b->peer;
707
708         if (peer_bio != NULL) {
709             struct bio_bio_st *peer_b = peer_bio->ptr;
710
711             assert(peer_b != NULL);
712             assert(peer_b->peer == bio);
713
714             peer_b->peer = NULL;
715             peer_bio->init = 0;
716             assert(peer_b->buf != NULL);
717             peer_b->len = 0;
718             peer_b->offset = 0;
719
720             b->peer = NULL;
721             bio->init = 0;
722             assert(b->buf != NULL);
723             b->len = 0;
724             b->offset = 0;
725         }
726     }
727 }
728
729 /* Exported convenience functions */
730 int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
731                      BIO **bio2_p, size_t writebuf2)
732 {
733     BIO *bio1 = NULL, *bio2 = NULL;
734     long r;
735     int ret = 0;
736
737     bio1 = BIO_new(BIO_s_bio());
738     if (bio1 == NULL)
739         goto err;
740     bio2 = BIO_new(BIO_s_bio());
741     if (bio2 == NULL)
742         goto err;
743
744     if (writebuf1) {
745         r = BIO_set_write_buf_size(bio1, writebuf1);
746         if (!r)
747             goto err;
748     }
749     if (writebuf2) {
750         r = BIO_set_write_buf_size(bio2, writebuf2);
751         if (!r)
752             goto err;
753     }
754
755     r = BIO_make_bio_pair(bio1, bio2);
756     if (!r)
757         goto err;
758     ret = 1;
759
760  err:
761     if (ret == 0) {
762         BIO_free(bio1);
763         bio1 = NULL;
764         BIO_free(bio2);
765         bio2 = NULL;
766     }
767
768     *bio1_p = bio1;
769     *bio2_p = bio2;
770     return ret;
771 }
772
773 size_t BIO_ctrl_get_write_guarantee(BIO *bio)
774 {
775     return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
776 }
777
778 size_t BIO_ctrl_get_read_request(BIO *bio)
779 {
780     return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
781 }
782
783 int BIO_ctrl_reset_read_request(BIO *bio)
784 {
785     return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
786 }
787
788 /*
789  * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
790  * (conceivably some other BIOs could allow non-copying reads and writes
791  * too.)
792  */
793 int BIO_nread0(BIO *bio, char **buf)
794 {
795     long ret;
796
797     if (!bio->init) {
798         BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
799         return -2;
800     }
801
802     ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
803     if (ret > INT_MAX)
804         return INT_MAX;
805     else
806         return (int)ret;
807 }
808
809 int BIO_nread(BIO *bio, char **buf, int num)
810 {
811     int ret;
812
813     if (!bio->init) {
814         BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
815         return -2;
816     }
817
818     ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf);
819     if (ret > 0)
820         bio->num_read += ret;
821     return ret;
822 }
823
824 int BIO_nwrite0(BIO *bio, char **buf)
825 {
826     long ret;
827
828     if (!bio->init) {
829         BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
830         return -2;
831     }
832
833     ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
834     if (ret > INT_MAX)
835         return INT_MAX;
836     else
837         return (int)ret;
838 }
839
840 int BIO_nwrite(BIO *bio, char **buf, int num)
841 {
842     int ret;
843
844     if (!bio->init) {
845         BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
846         return -2;
847     }
848
849     ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
850     if (ret > 0)
851         bio->num_write += ret;
852     return ret;
853 }