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