bss_bio.c revision 55714
122347Spst/* crypto/bio/bss_bio.c  -*- Mode: C; c-file-style: "eay" -*- */
222347Spst
329964Sache/* Special method for a BIO where the other endpoint is also a BIO
429964Sache * of this kind, handled by the same thread (i.e. the "peer" is actually
522347Spst * ourselves, wearing a different hat).
622347Spst * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
722347Spst * for which no specific BIO method is available.
822347Spst * See ssl/ssltest.c for some hints on how this can be used. */
922347Spst
1022347Spst#ifndef BIO_PAIR_DEBUG
1122347Spst# undef NDEBUG /* avoid conflicting definitions */
1222347Spst# define NDEBUG
1322347Spst#endif
1422347Spst
1522347Spst#include <assert.h>
1622347Spst#include <stdlib.h>
1729964Sache#include <string.h>
1829964Sache
1922347Spst#include <openssl/bio.h>
2022347Spst#include <openssl/err.h>
2122347Spst#include <openssl/crypto.h>
2222347Spst
2322347Spststatic int bio_new(BIO *bio);
2422347Spststatic int bio_free(BIO *bio);
2522347Spststatic int bio_read(BIO *bio, char *buf, int size);
2622347Spststatic int bio_write(BIO *bio, char *buf, int num);
2722347Spststatic long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
2822347Spststatic int bio_puts(BIO *bio, char *str);
2922347Spst
3022347Spststatic int bio_make_pair(BIO *bio1, BIO *bio2);
3122347Spststatic void bio_destroy_pair(BIO *bio);
3222347Spst
3322347Spststatic BIO_METHOD methods_biop =
3422347Spst{
3522347Spst	BIO_TYPE_BIO,
3622347Spst	"BIO pair",
3722347Spst	bio_write,
3822347Spst	bio_read,
3922347Spst	bio_puts,
4022347Spst	NULL /* no bio_gets */,
4122347Spst	bio_ctrl,
4222347Spst	bio_new,
4322347Spst	bio_free
4422347Spst};
4522347Spst
4622347SpstBIO_METHOD *BIO_s_bio(void)
4722347Spst	{
4822347Spst	return &methods_biop;
4922347Spst	}
5022347Spst
5122347Spststruct bio_bio_st
5222347Spst{
5322347Spst	BIO *peer;     /* NULL if buf == NULL.
5422347Spst	                * If peer != NULL, then peer->ptr is also a bio_bio_st,
5522347Spst	                * and its "peer" member points back to us.
5622347Spst	                * peer != NULL iff init != 0 in the BIO. */
5722347Spst
5822347Spst	/* This is for what we write (i.e. reading uses peer's struct): */
5922347Spst	int closed;     /* valid iff peer != NULL */
6022347Spst	size_t len;     /* valid iff buf != NULL; 0 if peer == NULL */
6122347Spst	size_t offset;  /* valid iff buf != NULL; 0 if len == 0 */
6222347Spst	size_t size;
6322347Spst	char *buf;      /* "size" elements (if != NULL) */
6422347Spst
6522347Spst	size_t request; /* valid iff peer != NULL; 0 if len != 0,
6622347Spst	                 * otherwise set by peer to number of bytes
6722347Spst	                 * it (unsuccesfully) tried to read,
6822347Spst	                 * never more than buffer space (size-len) warrants. */
6922347Spst};
7022347Spst
7122347Spststatic int bio_new(BIO *bio)
7222347Spst	{
7322347Spst	struct bio_bio_st *b;
7422347Spst
7522347Spst	b = Malloc(sizeof *b);
7622347Spst	if (b == NULL)
7722347Spst		return 0;
7822347Spst
7922347Spst	b->peer = NULL;
8022347Spst	b->size = 17*1024; /* enough for one TLS record (just a default) */
8122347Spst	b->buf = NULL;
8222347Spst
8322347Spst	bio->ptr = b;
8422347Spst	return 1;
8522347Spst	}
8622347Spst
8722347Spst
8822347Spststatic int bio_free(BIO *bio)
8922347Spst	{
9022347Spst	struct bio_bio_st *b;
9122347Spst
9222347Spst	if (bio == NULL)
9322347Spst		return 0;
9422347Spst	b = bio->ptr;
9522347Spst
9622347Spst	assert(b != NULL);
9722347Spst
9822347Spst	if (b->peer)
9922347Spst		bio_destroy_pair(bio);
10022347Spst
10122347Spst	if (b->buf != NULL)
10222347Spst		{
10322347Spst		Free(b->buf);
10422347Spst		}
10522347Spst
10622347Spst	Free(b);
10722347Spst
10822347Spst	return 1;
10922347Spst	}
11022347Spst
11122347Spst
11222347Spst
11322347Spststatic int bio_read(BIO *bio, char *buf, int size_)
11422347Spst	{
11522347Spst	size_t size = size_;
11622347Spst	size_t rest;
11722347Spst	struct bio_bio_st *b, *peer_b;
11822347Spst
11922347Spst	BIO_clear_retry_flags(bio);
12022347Spst
12122347Spst	if (!bio->init)
12222347Spst		return 0;
12322347Spst
12422347Spst	b = bio->ptr;
12522347Spst	assert(b != NULL);
12622347Spst	assert(b->peer != NULL);
12722347Spst	peer_b = b->peer->ptr;
12822347Spst	assert(peer_b != NULL);
12922347Spst	assert(peer_b->buf != NULL);
13022347Spst
13122347Spst	peer_b->request = 0; /* will be set in "retry_read" situation */
13222347Spst
13322347Spst	if (buf == NULL || size == 0)
13422347Spst		return 0;
13522347Spst
13622347Spst	if (peer_b->len == 0)
13722347Spst		{
13822347Spst		if (peer_b->closed)
13922347Spst			return 0; /* writer has closed, and no data is left */
14022347Spst		else
14122347Spst			{
14222347Spst			BIO_set_retry_read(bio); /* buffer is empty */
14322347Spst			if (size <= peer_b->size)
14422347Spst				peer_b->request = size;
14522347Spst			else
14622347Spst				/* don't ask for more than the peer can
14722347Spst				 * deliver in one write */
14822347Spst				peer_b->request = peer_b->size;
14922347Spst			return -1;
15022347Spst			}
15122347Spst		}
15222347Spst
15322347Spst	/* we can read */
15422347Spst	if (peer_b->len < size)
15522347Spst		size = peer_b->len;
15622347Spst
15722347Spst	/* now read "size" bytes */
15822347Spst
15922347Spst	rest = size;
16022347Spst
16122347Spst	assert(rest > 0);
16222347Spst	do /* one or two iterations */
16322347Spst		{
16422347Spst		size_t chunk;
16522347Spst
16622347Spst		assert(rest <= peer_b->len);
16722347Spst		if (peer_b->offset + rest <= peer_b->size)
16822347Spst			chunk = rest;
16922347Spst		else
17022347Spst			/* wrap around ring buffer */
17122347Spst			chunk = peer_b->size - peer_b->offset;
17222347Spst		assert(peer_b->offset + chunk <= peer_b->size);
17322347Spst
17422347Spst		memcpy(buf, peer_b->buf + peer_b->offset, chunk);
17522347Spst
17622347Spst		peer_b->len -= chunk;
17722347Spst		if (peer_b->len)
17822347Spst			{
17922347Spst			peer_b->offset += chunk;
18022347Spst			assert(peer_b->offset <= peer_b->size);
18122347Spst			if (peer_b->offset == peer_b->size)
18222347Spst				peer_b->offset = 0;
18322347Spst			buf += chunk;
18422347Spst			}
18522347Spst		else
18622347Spst			{
18722347Spst			/* buffer now empty, no need to advance "buf" */
18822347Spst			assert(chunk == rest);
18922347Spst			peer_b->offset = 0;
19022347Spst			}
19122347Spst		rest -= chunk;
19222347Spst		}
19322347Spst	while (rest);
19422347Spst
19522347Spst	return size;
19622347Spst	}
19722347Spst
19822347Spststatic int bio_write(BIO *bio, char *buf, int num_)
19922347Spst	{
20022347Spst	size_t num = num_;
20122347Spst	size_t rest;
20222347Spst	struct bio_bio_st *b;
20322347Spst
20422347Spst	BIO_clear_retry_flags(bio);
20522347Spst
20622347Spst	if (!bio->init || buf == NULL || num == 0)
20722347Spst		return 0;
20822347Spst
20922347Spst	b = bio->ptr;
21022347Spst	assert(b != NULL);
21122347Spst	assert(b->peer != NULL);
21222347Spst	assert(b->buf != NULL);
21322347Spst
21422347Spst	b->request = 0;
21522347Spst	if (b->closed)
21622347Spst		{
21722347Spst		/* we already closed */
21822347Spst		BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
21922347Spst		return -1;
22022347Spst		}
22122347Spst
22222347Spst	assert(b->len <= b->size);
22322347Spst
22422347Spst	if (b->len == b->size)
22522347Spst		{
22622347Spst		BIO_set_retry_write(bio); /* buffer is full */
22722347Spst		return -1;
22822347Spst		}
22922347Spst
23022347Spst	/* we can write */
23122347Spst	if (num > b->size - b->len)
23222347Spst		num = b->size - b->len;
23329964Sache
23422347Spst	/* now write "num" bytes */
23522347Spst
23622347Spst	rest = num;
23722347Spst
23822347Spst	assert(rest > 0);
23922347Spst	do /* one or two iterations */
24022347Spst		{
24122347Spst		size_t write_offset;
24222347Spst		size_t chunk;
24329964Sache
24422347Spst		assert(b->len + rest <= b->size);
24522347Spst
24622347Spst		write_offset = b->offset + b->len;
24722347Spst		if (write_offset >= b->size)
24822347Spst			write_offset -= b->size;
24922347Spst		/* b->buf[write_offset] is the first byte we can write to. */
25022347Spst
25122347Spst		if (write_offset + rest <= b->size)
25222347Spst			chunk = rest;
25322347Spst		else
25422347Spst			/* wrap around ring buffer */
25522347Spst			chunk = b->size - write_offset;
25622347Spst
25722347Spst		memcpy(b->buf + write_offset, buf, chunk);
25822347Spst
25922347Spst		b->len += chunk;
26022347Spst
26122347Spst		assert(b->len <= b->size);
26222347Spst
26322347Spst		rest -= chunk;
26422347Spst		buf += chunk;
26522347Spst		}
26622347Spst	while (rest);
26722347Spst
26822347Spst	return num;
26922347Spst	}
27022347Spst
27122347Spst
27222347Spststatic long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
27322347Spst	{
27422347Spst	long ret;
27522347Spst	struct bio_bio_st *b = bio->ptr;
27622347Spst
27722347Spst	assert(b != NULL);
27822347Spst
27922347Spst	switch (cmd)
28022347Spst		{
28122347Spst	/* specific CTRL codes */
28222347Spst
28322347Spst	case BIO_C_SET_WRITE_BUF_SIZE:
28422347Spst		if (b->peer)
28522347Spst			{
28622347Spst			BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
28722347Spst			ret = 0;
28822347Spst			}
28922347Spst		else if (num == 0)
29022347Spst			{
29122347Spst			BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
29222347Spst			ret = 0;
29322347Spst			}
29422347Spst		else
29522347Spst			{
29622347Spst			size_t new_size = num;
29722347Spst
29822347Spst			if (b->size != new_size)
29922347Spst				{
30022347Spst				if (b->buf)
30122347Spst					{
30222347Spst					Free(b->buf);
30322347Spst					b->buf = NULL;
30422347Spst					}
30529964Sache				b->size = new_size;
30629964Sache				}
30729964Sache			ret = 1;
30829964Sache			}
30929964Sache		break;
31029964Sache
31129964Sache	case BIO_C_GET_WRITE_BUF_SIZE:
31229964Sache		num = (long) b->size;
31329964Sache
31429964Sache	case BIO_C_MAKE_BIO_PAIR:
31529964Sache		{
31629964Sache		BIO *other_bio = ptr;
31729964Sache
31829964Sache		if (bio_make_pair(bio, other_bio))
31922347Spst			ret = 1;
32022347Spst		else
32122347Spst			ret = 0;
32222347Spst		}
32322347Spst		break;
32422347Spst
32522347Spst	case BIO_C_DESTROY_BIO_PAIR:
32622347Spst		/* Effects both BIOs in the pair -- call just once!
32722347Spst		 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */
32822347Spst		bio_destroy_pair(bio);
32922347Spst		ret = 1;
33022347Spst		break;
33122347Spst
33222347Spst	case BIO_C_GET_WRITE_GUARANTEE:
33322347Spst		/* How many bytes can the caller feed to the next write
33422347Spst		 * withouth having to keep any? */
33522347Spst		if (b->peer == NULL || b->closed)
33622347Spst			ret = 0;
33722347Spst		else
33822347Spst			ret = (long) b->size - b->len;
33922347Spst		break;
34022347Spst
34122347Spst	case BIO_C_GET_READ_REQUEST:
34222347Spst		/* If the peer unsuccesfully tried to read, how many bytes
34322347Spst		 * were requested?  (As with BIO_CTRL_PENDING, that number
34422347Spst		 * can usually be treated as boolean.) */
34522347Spst		ret = (long) b->request;
34622347Spst		break;
34722347Spst
34822347Spst	case BIO_C_SHUTDOWN_WR:
34922347Spst		/* similar to shutdown(..., SHUT_WR) */
35022347Spst		b->closed = 1;
35122347Spst		ret = 1;
35222347Spst		break;
35322347Spst
35422347Spst
35522347Spst	/* standard CTRL codes follow */
35622347Spst
35722347Spst	case BIO_CTRL_RESET:
35822347Spst		if (b->buf != NULL)
35922347Spst			{
36022347Spst			b->len = 0;
36122347Spst			b->offset = 0;
36222347Spst			}
36322347Spst		ret = 0;
36422347Spst		break;
36522347Spst
36622347Spst	case BIO_CTRL_GET_CLOSE:
36722347Spst		ret = bio->shutdown;
36822347Spst		break;
36922347Spst
37022347Spst	case BIO_CTRL_SET_CLOSE:
37122347Spst		bio->shutdown = (int) num;
37222347Spst		ret = 1;
37322347Spst		break;
37422347Spst
37522347Spst	case BIO_CTRL_PENDING:
37622347Spst		if (b->peer != NULL)
37722347Spst			{
37822347Spst			struct bio_bio_st *peer_b = b->peer->ptr;
37922347Spst
38022347Spst			ret = (long) peer_b->len;
38122347Spst			}
38222347Spst		else
38322347Spst			ret = 0;
38422347Spst		break;
38522347Spst
38622347Spst	case BIO_CTRL_WPENDING:
38722347Spst		if (b->buf != NULL)
38822347Spst			ret = (long) b->len;
38922347Spst		else
39022347Spst			ret = 0;
39122347Spst		break;
39222347Spst
39322347Spst	case BIO_CTRL_DUP:
39422347Spst		/* See BIO_dup_chain for circumstances we have to expect. */
39522347Spst		{
39622347Spst		BIO *other_bio = ptr;
39722347Spst		struct bio_bio_st *other_b;
39822347Spst
39922347Spst		assert(other_bio != NULL);
40022347Spst		other_b = other_bio->ptr;
40122347Spst		assert(other_b != NULL);
40222347Spst
40322347Spst		assert(other_b->buf == NULL); /* other_bio is always fresh */
40422347Spst
40522347Spst		other_b->size = b->size;
40622347Spst		}
40722347Spst
40822347Spst		ret = 1;
40922347Spst		break;
41022347Spst
41122347Spst	case BIO_CTRL_FLUSH:
41222347Spst		ret = 1;
41322347Spst		break;
41422347Spst
41522347Spst	case BIO_CTRL_EOF:
41622347Spst		{
41722347Spst		BIO *other_bio = ptr;
41822347Spst
41922347Spst		if (other_bio)
42022347Spst			{
42122347Spst			struct bio_bio_st *other_b = other_bio->ptr;
42222347Spst
42322347Spst			assert(other_b != NULL);
42429964Sache			ret = other_b->len == 0 && other_b->closed;
42529964Sache			}
42622347Spst		else
42722347Spst			ret = 1;
42822347Spst		}
42922347Spst		break;
43022347Spst
43122347Spst	default:
43222347Spst		ret = 0;
43322347Spst		}
43422347Spst	return ret;
43522347Spst	}
43629964Sache
43722347Spststatic int bio_puts(BIO *bio, char *str)
43822347Spst	{
43922347Spst	return bio_write(bio, str, strlen(str));
44022347Spst	}
44122347Spst
44222347Spst
44322347Spststatic int bio_make_pair(BIO *bio1, BIO *bio2)
44422347Spst	{
44522347Spst	struct bio_bio_st *b1, *b2;
44622347Spst
44722347Spst	assert(bio1 != NULL);
44822347Spst	assert(bio2 != NULL);
44922347Spst
45022347Spst	b1 = bio1->ptr;
45122347Spst	b2 = bio2->ptr;
45222347Spst
45322347Spst	if (b1->peer != NULL || b2->peer != NULL)
45422347Spst		{
45522347Spst		BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
45622347Spst		return 0;
45722347Spst		}
45822347Spst
45922347Spst	if (b1->buf == NULL)
46022347Spst		{
46122347Spst		b1->buf = Malloc(b1->size);
46222347Spst		if (b1->buf == NULL)
46322347Spst			{
46422347Spst			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
46522347Spst			return 0;
46622347Spst			}
46722347Spst		b1->len = 0;
46822347Spst		b1->offset = 0;
46922347Spst		}
47022347Spst
47122347Spst	if (b2->buf == NULL)
47222347Spst		{
47322347Spst		b2->buf = Malloc(b2->size);
47422347Spst		if (b2->buf == NULL)
47522347Spst			{
47622347Spst			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
47722347Spst			return 0;
47822347Spst			}
47922347Spst		b2->len = 0;
48022347Spst		b2->offset = 0;
48122347Spst		}
48222347Spst
48322347Spst	b1->peer = bio2;
48422347Spst	b1->closed = 0;
48522347Spst	b1->request = 0;
48622347Spst	b2->peer = bio1;
48722347Spst	b2->closed = 0;
48822347Spst	b2->request = 0;
48922347Spst
49029964Sache	bio1->init = 1;
49129964Sache	bio2->init = 1;
49222347Spst
49329964Sache	return 1;
49422347Spst	}
49522347Spst
49622347Spststatic void bio_destroy_pair(BIO *bio)
49722347Spst	{
49822347Spst	struct bio_bio_st *b = bio->ptr;
49922347Spst
50022347Spst	if (b != NULL)
50122347Spst		{
50222347Spst		BIO *peer_bio = b->peer;
50322347Spst
50422347Spst		if (peer_bio != NULL)
50522347Spst			{
50629964Sache			struct bio_bio_st *peer_b = peer_bio->ptr;
50722347Spst
50822347Spst			assert(peer_b != NULL);
50922347Spst			assert(peer_b->peer == bio);
51029964Sache
51122347Spst			peer_b->peer = NULL;
51222347Spst			peer_bio->init = 0;
51322347Spst			assert(peer_b->buf != NULL);
51422347Spst			peer_b->len = 0;
51522347Spst			peer_b->offset = 0;
51629964Sache
51722347Spst			b->peer = NULL;
51822347Spst			bio->init = 0;
51922347Spst			assert(b->buf != NULL);
52022347Spst			b->len = 0;
52122347Spst			b->offset = 0;
52222347Spst			}
52322347Spst		}
52422347Spst	}
52522347Spst
52622347Spst
52722347Spst/* Exported convenience functions */
52822347Spstint BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
52922347Spst	BIO **bio2_p, size_t writebuf2)
53022347Spst	 {
53122347Spst	 BIO *bio1 = NULL, *bio2 = NULL;
53222347Spst	 long r;
53322347Spst	 int ret = 0;
53422347Spst
53522347Spst	 bio1 = BIO_new(BIO_s_bio());
53622347Spst	 if (bio1 == NULL)
53722347Spst		 goto err;
53822347Spst	 bio2 = BIO_new(BIO_s_bio());
53922347Spst	 if (bio2 == NULL)
54022347Spst		 goto err;
54122347Spst
54222347Spst	 if (writebuf1)
54322347Spst		 {
54422347Spst		 r = BIO_set_write_buf_size(bio1, writebuf1);
54522347Spst		 if (!r)
54622347Spst			 goto err;
54729964Sache		 }
54829964Sache	 if (writebuf2)
54929964Sache		 {
55029964Sache		 r = BIO_set_write_buf_size(bio2, writebuf2);
55129964Sache		 if (!r)
55229964Sache			 goto err;
55322347Spst		 }
55422347Spst
55529964Sache	 r = BIO_make_bio_pair(bio1, bio2);
55629964Sache	 if (!r)
55729964Sache		 goto err;
55829964Sache	 ret = 1;
55929964Sache
56022347Spst err:
56122347Spst	 if (ret == 0)
56222347Spst		 {
56322347Spst		 if (bio1)
56429964Sache			 {
56522347Spst			 BIO_free(bio1);
56622347Spst			 bio1 = NULL;
56722347Spst			 }
56822347Spst		 if (bio2)
56922347Spst			 {
57022347Spst			 BIO_free(bio2);
57122347Spst			 bio2 = NULL;
57222347Spst			 }
57322347Spst		 }
57422347Spst
57522347Spst	 *bio1_p = bio1;
57622347Spst	 *bio2_p = bio2;
57722347Spst	 return ret;
57822347Spst	 }
57922347Spst
58022347Spstsize_t BIO_ctrl_get_write_guarantee(BIO *bio)
58122347Spst	{
58222347Spst	return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
58322347Spst	}
58422347Spst
58522347Spstsize_t BIO_ctrl_get_read_request(BIO *bio)
58622347Spst	{
58722347Spst	return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
58822347Spst	}
58922347Spst