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