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