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