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