GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/bio/bss_bio.c Lines: 224 312 71.8 %
Date: 2017-11-13 Branches: 89 171 52.0 %

Line Branch Exec Source
1
/* $OpenBSD: bss_bio.c,v 1.23 2017/01/29 17:49:22 beck 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
static int bio_new(BIO *bio);
88
static int bio_free(BIO *bio);
89
static int bio_read(BIO *bio, char *buf, int size);
90
static int bio_write(BIO *bio, const char *buf, int num);
91
static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
92
static int bio_puts(BIO *bio, const char *str);
93
94
static int bio_make_pair(BIO *bio1, BIO *bio2);
95
static void bio_destroy_pair(BIO *bio);
96
97
static BIO_METHOD methods_biop = {
98
	.type = BIO_TYPE_BIO,
99
	.name = "BIO pair",
100
	.bwrite = bio_write,
101
	.bread = bio_read,
102
	.bputs = bio_puts,
103
	.ctrl = bio_ctrl,
104
	.create = bio_new,
105
	.destroy = bio_free
106
};
107
108
BIO_METHOD *
109
BIO_s_bio(void)
110
{
111
576
	return &methods_biop;
112
}
113
114
struct bio_bio_st {
115
	BIO *peer;	/* NULL if buf == NULL.
116
			 * If peer != NULL, then peer->ptr is also a bio_bio_st,
117
			 * and its "peer" member points back to us.
118
			 * peer != NULL iff init != 0 in the BIO. */
119
120
	/* This is for what we write (i.e. reading uses peer's struct): */
121
	int closed;	/* valid iff peer != NULL */
122
	size_t len;	/* valid iff buf != NULL; 0 if peer == NULL */
123
	size_t offset;	/* valid iff buf != NULL; 0 if len == 0 */
124
	size_t size;
125
	char *buf;      /* "size" elements (if != NULL) */
126
127
	size_t request; /* valid iff peer != NULL; 0 if len != 0,
128
			 * otherwise set by peer to number of bytes
129
			 * it (unsuccessfully) tried to read,
130
	                 * never more than buffer space (size-len) warrants. */
131
};
132
133
static int
134
bio_new(BIO *bio)
135
{
136
	struct bio_bio_st *b;
137
138
576
	b = malloc(sizeof *b);
139
288
	if (b == NULL)
140
		return 0;
141
142
288
	b->peer = NULL;
143
288
	b->size = 17 * 1024; /* enough for one TLS record (just a default) */
144
288
	b->buf = NULL;
145
146
288
	bio->ptr = b;
147
288
	return 1;
148
288
}
149
150
static int
151
bio_free(BIO *bio)
152
{
153
	struct bio_bio_st *b;
154
155
576
	if (bio == NULL)
156
		return 0;
157
288
	b = bio->ptr;
158
159
	assert(b != NULL);
160
161
288
	if (b->peer)
162
144
		bio_destroy_pair(bio);
163
164
288
	free(b->buf);
165
288
	free(b);
166
288
	return 1;
167
288
}
168
169
170
171
static int
172
bio_read(BIO *bio, char *buf, int size_)
173
{
174
23892
	size_t size = size_;
175
	size_t rest;
176
	struct bio_bio_st *b, *peer_b;
177
178
11946
	BIO_clear_retry_flags(bio);
179
180
11946
	if (!bio->init)
181
		return 0;
182
183
11946
	b = bio->ptr;
184
	assert(b != NULL);
185
	assert(b->peer != NULL);
186
11946
	peer_b = b->peer->ptr;
187
	assert(peer_b != NULL);
188
	assert(peer_b->buf != NULL);
189
190
11946
	peer_b->request = 0; /* will be set in "retry_read" situation */
191
192
11946
	if (buf == NULL || size == 0)
193
		return 0;
194
195
11946
	if (peer_b->len == 0) {
196
6570
		if (peer_b->closed)
197
			return 0; /* writer has closed, and no data is left */
198
		else {
199
6570
			BIO_set_retry_read(bio); /* buffer is empty */
200
6570
			if (size <= peer_b->size)
201
5808
				peer_b->request = size;
202
			else
203
				/* don't ask for more than the peer can
204
				 * deliver in one write */
205
				peer_b->request = peer_b->size;
206
6570
			return -1;
207
		}
208
	}
209
210
	/* we can read */
211
5376
	if (peer_b->len < size)
212
1458
		size = peer_b->len;
213
214
	/* now read "size" bytes */
215
216
	rest = size;
217
218
	assert(rest > 0);
219
5376
	do /* one or two iterations */
220
	{
221
		size_t chunk;
222
223
		assert(rest <= peer_b->len);
224
5547
		if (peer_b->offset + rest <= peer_b->size)
225
5376
			chunk = rest;
226
		else
227
			/* wrap around ring buffer */
228
171
			chunk = peer_b->size - peer_b->offset;
229
		assert(peer_b->offset + chunk <= peer_b->size);
230
231
5547
		memcpy(buf, peer_b->buf + peer_b->offset, chunk);
232
233
5547
		peer_b->len -= chunk;
234
5547
		if (peer_b->len) {
235
2865
			peer_b->offset += chunk;
236
			assert(peer_b->offset <= peer_b->size);
237
2865
			if (peer_b->offset == peer_b->size)
238
180
				peer_b->offset = 0;
239
2865
			buf += chunk;
240
2865
		} else {
241
			/* buffer now empty, no need to advance "buf" */
242
			assert(chunk == rest);
243
2682
			peer_b->offset = 0;
244
		}
245
5547
		rest -= chunk;
246
5547
	} while (rest);
247
248
5376
	return size;
249
11946
}
250
251
/* non-copying interface: provide pointer to available data in buffer
252
 *    bio_nread0:  return number of available bytes
253
 *    bio_nread:   also advance index
254
 * (example usage:  bio_nread0(), read from buffer, bio_nread()
255
 *  or just         bio_nread(), read from buffer)
256
 */
257
/* WARNING: The non-copying interface is largely untested as of yet
258
 * and may contain bugs. */
259
static ssize_t
260
bio_nread0(BIO *bio, char **buf)
261
{
262
	struct bio_bio_st *b, *peer_b;
263
	ssize_t num;
264
265
1260
	BIO_clear_retry_flags(bio);
266
267
630
	if (!bio->init)
268
		return 0;
269
270
630
	b = bio->ptr;
271
	assert(b != NULL);
272
	assert(b->peer != NULL);
273
630
	peer_b = b->peer->ptr;
274
	assert(peer_b != NULL);
275
	assert(peer_b->buf != NULL);
276
277
630
	peer_b->request = 0;
278
279
630
	if (peer_b->len == 0) {
280
		char dummy;
281
282
		/* avoid code duplication -- nothing available for reading */
283
		return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
284
	}
285
286
	num = peer_b->len;
287
630
	if (peer_b->size < peer_b->offset + num)
288
		/* no ring buffer wrap-around for non-copying interface */
289
		num = peer_b->size - peer_b->offset;
290
	assert(num > 0);
291
292
630
	if (buf != NULL)
293
630
		*buf = peer_b->buf + peer_b->offset;
294
630
	return num;
295
630
}
296
297
static ssize_t
298
bio_nread(BIO *bio, char **buf, size_t num_)
299
{
300
	struct bio_bio_st *b, *peer_b;
301
	ssize_t num, available;
302
303
1260
	if (num_ > SSIZE_MAX)
304
		num = SSIZE_MAX;
305
	else
306
		num = (ssize_t)num_;
307
308
630
	available = bio_nread0(bio, buf);
309
630
	if (num > available)
310
		num = available;
311
630
	if (num <= 0)
312
		return num;
313
314
630
	b = bio->ptr;
315
630
	peer_b = b->peer->ptr;
316
317
630
	peer_b->len -= num;
318
630
	if (peer_b->len) {
319
		peer_b->offset += num;
320
		assert(peer_b->offset <= peer_b->size);
321
		if (peer_b->offset == peer_b->size)
322
			peer_b->offset = 0;
323
	} else
324
		peer_b->offset = 0;
325
326
1260
	return num;
327
630
}
328
329
330
static int
331
bio_write(BIO *bio, const char *buf, int num_)
332
{
333
7704
	size_t num = num_;
334
	size_t rest;
335
	struct bio_bio_st *b;
336
337
3852
	BIO_clear_retry_flags(bio);
338
339
3852
	if (!bio->init || buf == NULL || num == 0)
340
		return 0;
341
342
3852
	b = bio->ptr;
343
344
	assert(b != NULL);
345
	assert(b->peer != NULL);
346
	assert(b->buf != NULL);
347
348
3852
	b->request = 0;
349
3852
	if (b->closed) {
350
		/* we already closed */
351
		BIOerror(BIO_R_BROKEN_PIPE);
352
		return -1;
353
	}
354
355
	assert(b->len <= b->size);
356
357
3852
	if (b->len == b->size) {
358
1674
		BIO_set_retry_write(bio); /* buffer is full */
359
1674
		return -1;
360
	}
361
362
	/* we can write */
363
2178
	if (num > b->size - b->len)
364
1116
		num = b->size - b->len;
365
366
	/* now write "num" bytes */
367
368
	rest = num;
369
370
	assert(rest > 0);
371
2178
	do /* one or two iterations */
372
	{
373
		size_t write_offset;
374
		size_t chunk;
375
376
		assert(b->len + rest <= b->size);
377
378
2268
		write_offset = b->offset + b->len;
379
2268
		if (write_offset >= b->size)
380
540
			write_offset -= b->size;
381
		/* b->buf[write_offset] is the first byte we can write to. */
382
383
2268
		if (write_offset + rest <= b->size)
384
2178
			chunk = rest;
385
		else
386
			/* wrap around ring buffer */
387
90
			chunk = b->size - write_offset;
388
389
2268
		memcpy(b->buf + write_offset, buf, chunk);
390
391
2268
		b->len += chunk;
392
393
		assert(b->len <= b->size);
394
395
2268
		rest -= chunk;
396
2268
		buf += chunk;
397
2268
	} while (rest);
398
399
2178
	return num;
400
3852
}
401
402
/* non-copying interface: provide pointer to region to write to
403
 *   bio_nwrite0:  check how much space is available
404
 *   bio_nwrite:   also increase length
405
 * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
406
 *  or just         bio_nwrite(), write to buffer)
407
 */
408
static ssize_t
409
bio_nwrite0(BIO *bio, char **buf)
410
{
411
	struct bio_bio_st *b;
412
	size_t num;
413
	size_t write_offset;
414
415
7344
	BIO_clear_retry_flags(bio);
416
417
3672
	if (!bio->init)
418
		return 0;
419
420
3672
	b = bio->ptr;
421
422
	assert(b != NULL);
423
	assert(b->peer != NULL);
424
	assert(b->buf != NULL);
425
426
3672
	b->request = 0;
427
3672
	if (b->closed) {
428
		BIOerror(BIO_R_BROKEN_PIPE);
429
		return -1;
430
	}
431
432
	assert(b->len <= b->size);
433
434
3672
	if (b->len == b->size) {
435
		BIO_set_retry_write(bio);
436
		return -1;
437
	}
438
439
3672
	num = b->size - b->len;
440
3672
	write_offset = b->offset + b->len;
441
3672
	if (write_offset >= b->size)
442
		write_offset -= b->size;
443
3672
	if (write_offset + num > b->size)
444
		/* no ring buffer wrap-around for non-copying interface
445
		 * (to fulfil the promise by BIO_ctrl_get_write_guarantee,
446
		 * BIO_nwrite may have to be called twice) */
447
		num = b->size - write_offset;
448
449
3672
	if (buf != NULL)
450
3672
		*buf = b->buf + write_offset;
451
	assert(write_offset + num <= b->size);
452
453
3672
	return num;
454
3672
}
455
456
static ssize_t
457
bio_nwrite(BIO *bio, char **buf, size_t num_)
458
{
459
	struct bio_bio_st *b;
460
	ssize_t num, space;
461
462
3672
	if (num_ > SSIZE_MAX)
463
		num = SSIZE_MAX;
464
	else
465
		num = (ssize_t)num_;
466
467
1836
	space = bio_nwrite0(bio, buf);
468
1836
	if (num > space)
469
		num = space;
470
1836
	if (num <= 0)
471
		return num;
472
1836
	b = bio->ptr;
473
	assert(b != NULL);
474
1836
	b->len += num;
475
	assert(b->len <= b->size);
476
477
1836
	return num;
478
1836
}
479
480
481
static long
482
bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
483
{
484
	long ret;
485
32292
	struct bio_bio_st *b = bio->ptr;
486
487
	assert(b != NULL);
488
489





16146
	switch (cmd) {
490
		/* specific CTRL codes */
491
492
	case BIO_C_SET_WRITE_BUF_SIZE:
493
288
		if (b->peer) {
494
			BIOerror(BIO_R_IN_USE);
495
			ret = 0;
496
288
		} else if (num == 0) {
497
			BIOerror(BIO_R_INVALID_ARGUMENT);
498
			ret = 0;
499
		} else {
500
			size_t new_size = num;
501
502
288
			if (b->size != new_size) {
503
288
				free(b->buf);
504
288
				b->buf = NULL;
505
288
				b->size = new_size;
506
288
			}
507
			ret = 1;
508
		}
509
		break;
510
511
	case BIO_C_GET_WRITE_BUF_SIZE:
512
		ret = (long) b->size;
513
		break;
514
515
	case BIO_C_MAKE_BIO_PAIR:
516
		{
517
144
			BIO *other_bio = ptr;
518
519
144
			if (bio_make_pair(bio, other_bio))
520
144
				ret = 1;
521
			else
522
				ret = 0;
523
		}
524
144
		break;
525
526
	case BIO_C_DESTROY_BIO_PAIR:
527
		/* Affects both BIOs in the pair -- call just once!
528
		 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */
529
		bio_destroy_pair(bio);
530
		ret = 1;
531
		break;
532
533
	case BIO_C_GET_WRITE_GUARANTEE:
534
		/* How many bytes can the caller feed to the next write
535
		 * without having to keep any? */
536

6084
		if (b->peer == NULL || b->closed)
537
			ret = 0;
538
		else
539
3042
			ret = (long) b->size - b->len;
540
		break;
541
542
	case BIO_C_GET_READ_REQUEST:
543
		/* If the peer unsuccessfully tried to read, how many bytes
544
		 * were requested?  (As with BIO_CTRL_PENDING, that number
545
		 * can usually be treated as boolean.) */
546
2412
		ret = (long) b->request;
547
2412
		break;
548
549
	case BIO_C_RESET_READ_REQUEST:
550
		/* Reset request.  (Can be useful after read attempts
551
		 * at the other side that are meant to be non-blocking,
552
		 * e.g. when probing SSL_read to see if any data is
553
		 * available.) */
554
		b->request = 0;
555
		ret = 1;
556
		break;
557
558
	case BIO_C_SHUTDOWN_WR:
559
		/* similar to shutdown(..., SHUT_WR) */
560
		b->closed = 1;
561
		ret = 1;
562
		break;
563
564
	case BIO_C_NREAD0:
565
		/* prepare for non-copying read */
566
		ret = (long) bio_nread0(bio, ptr);
567
		break;
568
569
	case BIO_C_NREAD:
570
		/* non-copying read */
571
630
		ret = (long) bio_nread(bio, ptr, (size_t) num);
572
630
		break;
573
574
	case BIO_C_NWRITE0:
575
		/* prepare for non-copying write */
576
1836
		ret = (long) bio_nwrite0(bio, ptr);
577
1836
		break;
578
579
	case BIO_C_NWRITE:
580
		/* non-copying write */
581
1836
		ret = (long) bio_nwrite(bio, ptr, (size_t) num);
582
1836
		break;
583
584
585
		/* standard CTRL codes follow */
586
587
	case BIO_CTRL_RESET:
588
		if (b->buf != NULL) {
589
			b->len = 0;
590
			b->offset = 0;
591
		}
592
		ret = 0;
593
		break;
594
595
596
	case BIO_CTRL_GET_CLOSE:
597
		ret = bio->shutdown;
598
		break;
599
600
	case BIO_CTRL_SET_CLOSE:
601
		bio->shutdown = (int) num;
602
		ret = 1;
603
		break;
604
605
	case BIO_CTRL_PENDING:
606
5454
		if (b->peer != NULL) {
607
5454
			struct bio_bio_st *peer_b = b->peer->ptr;
608
609
5454
			ret = (long) peer_b->len;
610
5454
		} else
611
			ret = 0;
612
		break;
613
614
	case BIO_CTRL_WPENDING:
615
		if (b->buf != NULL)
616
			ret = (long) b->len;
617
		else
618
			ret = 0;
619
		break;
620
621
	case BIO_CTRL_DUP:
622
		/* See BIO_dup_chain for circumstances we have to expect. */
623
		{
624
			BIO *other_bio = ptr;
625
			struct bio_bio_st *other_b;
626
627
			assert(other_bio != NULL);
628
			other_b = other_bio->ptr;
629
			assert(other_b != NULL);
630
631
			assert(other_b->buf == NULL); /* other_bio is always fresh */
632
633
			other_b->size = b->size;
634
		}
635
636
		ret = 1;
637
		break;
638
639
	case BIO_CTRL_FLUSH:
640
		ret = 1;
641
216
		break;
642
643
	case BIO_CTRL_EOF:
644
		{
645
			BIO *other_bio = ptr;
646
647
			if (other_bio) {
648
				struct bio_bio_st *other_b = other_bio->ptr;
649
650
				assert(other_b != NULL);
651
				ret = other_b->len == 0 && other_b->closed;
652
			} else
653
				ret = 1;
654
		}
655
		break;
656
657
	default:
658
		ret = 0;
659
288
	}
660
16146
	return ret;
661
}
662
663
static int
664
bio_puts(BIO *bio, const char *str)
665
{
666
	return bio_write(bio, str, strlen(str));
667
}
668
669
670
static int
671
bio_make_pair(BIO *bio1, BIO *bio2)
672
{
673
	struct bio_bio_st *b1, *b2;
674
675
	assert(bio1 != NULL);
676
	assert(bio2 != NULL);
677
678
288
	b1 = bio1->ptr;
679
144
	b2 = bio2->ptr;
680
681

288
	if (b1->peer != NULL || b2->peer != NULL) {
682
		BIOerror(BIO_R_IN_USE);
683
		return 0;
684
	}
685
686
144
	if (b1->buf == NULL) {
687
144
		b1->buf = malloc(b1->size);
688
144
		if (b1->buf == NULL) {
689
			BIOerror(ERR_R_MALLOC_FAILURE);
690
			return 0;
691
		}
692
144
		b1->len = 0;
693
144
		b1->offset = 0;
694
144
	}
695
696
144
	if (b2->buf == NULL) {
697
144
		b2->buf = malloc(b2->size);
698
144
		if (b2->buf == NULL) {
699
			BIOerror(ERR_R_MALLOC_FAILURE);
700
			return 0;
701
		}
702
144
		b2->len = 0;
703
144
		b2->offset = 0;
704
144
	}
705
706
144
	b1->peer = bio2;
707
144
	b1->closed = 0;
708
144
	b1->request = 0;
709
144
	b2->peer = bio1;
710
144
	b2->closed = 0;
711
144
	b2->request = 0;
712
713
144
	bio1->init = 1;
714
144
	bio2->init = 1;
715
716
144
	return 1;
717
144
}
718
719
static void
720
bio_destroy_pair(BIO *bio)
721
{
722
288
	struct bio_bio_st *b = bio->ptr;
723
724
144
	if (b != NULL) {
725
144
		BIO *peer_bio = b->peer;
726
727
144
		if (peer_bio != NULL) {
728
144
			struct bio_bio_st *peer_b = peer_bio->ptr;
729
730
			assert(peer_b != NULL);
731
			assert(peer_b->peer == bio);
732
733
144
			peer_b->peer = NULL;
734
144
			peer_bio->init = 0;
735
			assert(peer_b->buf != NULL);
736
144
			peer_b->len = 0;
737
144
			peer_b->offset = 0;
738
739
144
			b->peer = NULL;
740
144
			bio->init = 0;
741
			assert(b->buf != NULL);
742
144
			b->len = 0;
743
144
			b->offset = 0;
744
144
		}
745
144
	}
746
144
}
747
748
749
/* Exported convenience functions */
750
int
751
BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p, size_t writebuf2)
752
{
753
	BIO *bio1 = NULL, *bio2 = NULL;
754
	long r;
755
	int ret = 0;
756
757
288
	bio1 = BIO_new(BIO_s_bio());
758
144
	if (bio1 == NULL)
759
		goto err;
760
144
	bio2 = BIO_new(BIO_s_bio());
761
144
	if (bio2 == NULL)
762
		goto err;
763
764
144
	if (writebuf1) {
765
144
		r = BIO_set_write_buf_size(bio1, writebuf1);
766
144
		if (!r)
767
			goto err;
768
	}
769
144
	if (writebuf2) {
770
144
		r = BIO_set_write_buf_size(bio2, writebuf2);
771
144
		if (!r)
772
			goto err;
773
	}
774
775
144
	r = BIO_make_bio_pair(bio1, bio2);
776
144
	if (!r)
777
		goto err;
778
144
	ret = 1;
779
780
	err:
781
144
	if (ret == 0) {
782
		if (bio1) {
783
			BIO_free(bio1);
784
			bio1 = NULL;
785
		}
786
		if (bio2) {
787
			BIO_free(bio2);
788
			bio2 = NULL;
789
		}
790
	}
791
792
144
	*bio1_p = bio1;
793
144
	*bio2_p = bio2;
794
144
	return ret;
795
}
796
797
size_t
798
BIO_ctrl_get_write_guarantee(BIO *bio)
799
{
800
6084
	return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
801
}
802
803
size_t
804
BIO_ctrl_get_read_request(BIO *bio)
805
{
806
4824
	return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
807
}
808
809
int
810
BIO_ctrl_reset_read_request(BIO *bio)
811
{
812
	return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
813
}
814
815
816
/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
817
 * (conceivably some other BIOs could allow non-copying reads and writes too.)
818
 */
819
int
820
BIO_nread0(BIO *bio, char **buf)
821
{
822
	long ret;
823
824
	if (!bio->init) {
825
		BIOerror(BIO_R_UNINITIALIZED);
826
		return -2;
827
	}
828
829
	ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
830
	if (ret > INT_MAX)
831
		return INT_MAX;
832
	else
833
		return (int) ret;
834
}
835
836
int
837
BIO_nread(BIO *bio, char **buf, int num)
838
{
839
	int ret;
840
841
1260
	if (!bio->init) {
842
		BIOerror(BIO_R_UNINITIALIZED);
843
		return -2;
844
	}
845
846
630
	ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
847
630
	if (ret > 0)
848
630
		bio->num_read += ret;
849
630
	return ret;
850
630
}
851
852
int
853
BIO_nwrite0(BIO *bio, char **buf)
854
{
855
	long ret;
856
857
3672
	if (!bio->init) {
858
		BIOerror(BIO_R_UNINITIALIZED);
859
		return -2;
860
	}
861
862
1836
	ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
863
1836
	if (ret > INT_MAX)
864
		return INT_MAX;
865
	else
866
1836
		return (int) ret;
867
1836
}
868
869
int
870
BIO_nwrite(BIO *bio, char **buf, int num)
871
{
872
	int ret;
873
874
3672
	if (!bio->init) {
875
		BIOerror(BIO_R_UNINITIALIZED);
876
		return -2;
877
	}
878
879
1836
	ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
880
1836
	if (ret > 0)
881
1836
		bio->num_write += ret;
882
1836
	return ret;
883
1836
}