From 9e06f6f6019198e3f84cbfc9ff5d561400db4d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bodo=20M=C3=B6ller?= Date: Mon, 7 Jun 1999 16:04:45 +0000 Subject: Introduce "BIO pairs", which (when finished) will relay data so that the SSL library can be used for applications that have to handle all the actual I/O themselves. --- crypto/bio/Makefile.ssl | 6 +- crypto/bio/bio.h | 6 +- crypto/bio/bio_err.c | 2 + crypto/bio/bss_bio.c | 258 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 crypto/bio/bss_bio.c (limited to 'crypto/bio') diff --git a/crypto/bio/Makefile.ssl b/crypto/bio/Makefile.ssl index fbdded5d52..433f44ff6e 100644 --- a/crypto/bio/Makefile.ssl +++ b/crypto/bio/Makefile.ssl @@ -26,12 +26,12 @@ LIBSRC= bio_lib.c bio_cb.c bio_err.c \ bss_mem.c bss_null.c bss_fd.c \ bss_file.c bss_sock.c bss_conn.c \ bf_null.c bf_buff.c b_print.c b_dump.c \ - b_sock.c bss_acpt.c bf_nbio.c bss_log.c + b_sock.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c LIBOBJ= bio_lib.o bio_cb.o bio_err.o \ bss_mem.o bss_null.o bss_fd.o \ bss_file.o bss_sock.o bss_conn.o \ bf_null.o bf_buff.o b_print.o b_dump.o \ - b_sock.o bss_acpt.o bf_nbio.o bss_log.o + b_sock.o bss_acpt.o bf_nbio.o bss_log.o bss_bio.o SRC= $(LIBSRC) @@ -166,6 +166,8 @@ bss_acpt.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h bss_acpt.o: ../../include/openssl/opensslconf.h bss_acpt.o: ../../include/openssl/opensslv.h ../../include/openssl/stack.h bss_acpt.o: ../cryptlib.h +bss_bio.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +bss_bio.o: ../../include/openssl/opensslv.h ../../include/openssl/stack.h bss_conn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h bss_conn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os.h bss_conn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h index c41db123a5..8e5b7b5280 100644 --- a/crypto/bio/bio.h +++ b/crypto/bio/bio.h @@ -86,6 +86,7 @@ extern "C" { #define BIO_TYPE_NBIO_TEST (16|0x0200) /* server proxy BIO */ #define BIO_TYPE_NULL_FILTER (17|0x0200) #define BIO_TYPE_BER (18|0x0200) /* BER -> bin filter */ +#define BIO_TYPE_BIO (19|0x0400) /* (half a) BIO pair */ #define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ #define BIO_TYPE_FILTER 0x0200 @@ -240,7 +241,7 @@ typedef struct bio_st int flags; /* extra storage */ int retry_reason; int num; - char *ptr; + void *ptr; struct bio_st *next_bio; /* used by filter BIOs */ struct bio_st *prev_bio; /* used by filter BIOs */ int references; @@ -497,6 +498,7 @@ BIO_METHOD *BIO_s_connect(void); BIO_METHOD *BIO_s_accept(void); BIO_METHOD *BIO_s_fd(void); BIO_METHOD *BIO_s_log(void); +BIO_METHOD *BIO_s_bio(void); BIO_METHOD *BIO_s_null(void); BIO_METHOD *BIO_f_null(void); BIO_METHOD *BIO_f_buffer(void); @@ -551,6 +553,7 @@ int BIO_printf(BIO *bio, ...); #define BIO_F_BIO_GET_ACCEPT_SOCKET 105 #define BIO_F_BIO_GET_HOST_IP 106 #define BIO_F_BIO_GET_PORT 107 +#define BIO_F_BIO_MAKE_PAIR 121 #define BIO_F_BIO_NEW 108 #define BIO_F_BIO_NEW_FILE 109 #define BIO_F_BIO_PUTS 110 @@ -574,6 +577,7 @@ int BIO_printf(BIO *bio, ...); #define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106 #define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 #define BIO_R_INVALID_IP_ADDRESS 108 +#define BIO_R_IN_USE 123 #define BIO_R_KEEPALIVE 109 #define BIO_R_NBIO_CONNECT_ERROR 110 #define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111 diff --git a/crypto/bio/bio_err.c b/crypto/bio/bio_err.c index d88f978b55..badbfc1919 100644 --- a/crypto/bio/bio_err.c +++ b/crypto/bio/bio_err.c @@ -74,6 +74,7 @@ static ERR_STRING_DATA BIO_str_functs[]= {ERR_PACK(0,BIO_F_BIO_GET_ACCEPT_SOCKET,0), "BIO_get_accept_socket"}, {ERR_PACK(0,BIO_F_BIO_GET_HOST_IP,0), "BIO_get_host_ip"}, {ERR_PACK(0,BIO_F_BIO_GET_PORT,0), "BIO_get_port"}, +{ERR_PACK(0,BIO_F_BIO_MAKE_PAIR,0), "BIO_MAKE_PAIR"}, {ERR_PACK(0,BIO_F_BIO_NEW,0), "BIO_new"}, {ERR_PACK(0,BIO_F_BIO_NEW_FILE,0), "BIO_new_file"}, {ERR_PACK(0,BIO_F_BIO_PUTS,0), "BIO_puts"}, @@ -100,6 +101,7 @@ static ERR_STRING_DATA BIO_str_reasons[]= {BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET,"error setting nbio on accept socket"}, {BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET ,"gethostbyname addr is not af inet"}, {BIO_R_INVALID_IP_ADDRESS ,"invalid ip address"}, +{BIO_R_IN_USE ,"in use"}, {BIO_R_KEEPALIVE ,"keepalive"}, {BIO_R_NBIO_CONNECT_ERROR ,"nbio connect error"}, {BIO_R_NO_ACCEPT_PORT_SPECIFIED ,"no accept port specified"}, diff --git a/crypto/bio/bss_bio.c b/crypto/bio/bss_bio.c new file mode 100644 index 0000000000..5b60f541a1 --- /dev/null +++ b/crypto/bio/bss_bio.c @@ -0,0 +1,258 @@ +/* crypto/bio/bss_bio.c -*- Mode: C; c-file-style: "eay" -*- */ + +/* *** Not yet finished (or even tested). *** */ + +/* Special method for a BIO where the other endpoint is also a BIO + * of this kind, handled by the same thread. + * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces + * for which no specific BIO method is available. */ + +#include +#include + +#include +#include +#include + +static int bio_new(BIO *bio); +static int bio_free(BIO *bio); +static int bio_read(BIO *bio, char *buf, int size); +static int bio_write(BIO *bio, char *buf, int num); +static long bio_ctrl(BIO *bio, int cmd, long num, char *ptr); +static int bio_puts(BIO *bio, char *str); + +static int bio_make_pair(BIO *bio1, BIO *bio2); +static void bio_destroy_pair(BIO *bio); + +static BIO_METHOD methods_biop = +{ + BIO_TYPE_BIO, + "BIO pair", + bio_write, + bio_read, + bio_puts, + NULL /* no bio_gets */, + bio_ctrl, + bio_new, + bio_free +}; + +BIO_METHOD *BIO_s_bio(void) + { + return &methods_biop; + } + +struct bio_bio_st +{ + BIO *peer; /* NULL if buf == NULL. + * If peer != NULL, then peer->ptr is also a bio_bio_st, + * and its "peer" member points back to us. */ + + /* This is for what we write (i.e. reading uses peer's struct): */ + int closed; /* valid iff peer != NULL */ + size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ + size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ + size_t size; + char *buf; /* "size" elements (if != NULL) */ +}; + +static int bio_new(BIO *bio) + { + struct bio_bio_st *b; + + b = Malloc(sizeof *b); + if (b == NULL) + return 0; + + b->peer = NULL; + b->size = 17*1024; /* enough for one TLS record (just a default) */ + b->buf = NULL; + + return 1; + } + + +static int bio_free(BIO *bio) + { + struct bio_bio_st *b; + + if (bio == NULL) + return 0; + b = bio->ptr; + + assert(b != NULL); + + if (b->peer) + bio_destroy_pair(bio); + + if (b->buf != NULL) + { + Free(b->buf); + } + + Free(b); + + return 1; + } + + + +static int bio_read(BIO *bio, char *buf, int size) + { + /* XXX */ + return -1; + } + +static int bio_write(BIO *bio, char *buf, int num) + { + /* XXX */ + return -1; + } + +static long bio_ctrl(BIO *bio, int cmd, long num, char *ptr) + { + long ret; + struct bio_bio_st *b = bio->ptr; + + assert(b != NULL); + + switch (cmd) + { + /* XXX Additional commands: */ + /* - Set buffer size */ + /* - make pair */ + /* - destroy pair */ + /* - get number of bytes that the next write will accept */ + /* - send "close" */ + + case BIO_CTRL_RESET: + if (b->buf != NULL) + { + b->len = 0; + b->offset = 0; + } + ret = 0; + break; + + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int) num; + ret = 1; + break; + + case BIO_CTRL_PENDING: + if (b->peer != NULL) + { + struct bio_bio_st *peer_b =b->peer->ptr; + + ret = (long) peer_b->len; + } + else + ret = 0; + break; + + case BIO_CTRL_WPENDING: + if (b->buf != NULL) + ret = (long) b->len; + else + ret = 0; + break; + + case BIO_CTRL_DUP: + /* XXX */ + + case BIO_CTRL_FLUSH: + ret = 1; + break; + + default: + ret = 0; + } + return ret; + } + +static int bio_puts(BIO *bio, char *str) + { + return bio_write(bio, str, strlen(str)); + } + + + +static int bio_make_pair(BIO *bio1, BIO *bio2) + { + struct bio_bio_st *b1, *b2; + + assert(bio1 != NULL); + assert(bio2 != NULL); + + b1 = bio1->ptr; + b2 = bio2->ptr; + + if (b1->peer != NULL || b2->peer != NULL) + { + BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); + return 0; + } + + if (b1->buf != NULL) + { + b1->buf = Malloc(b1->size); + if (b1->buf == NULL) + { + BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); + return 0; + } + b1->len = 0; + b1->offset = 0; + } + + if (b2->buf != NULL) + { + b2->buf = Malloc(b2->size); + if (b2->buf == NULL) + { + BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); + return 0; + } + b2->len = 0; + b2->offset = 0; + } + + b1->peer = bio2; + b2->peer = bio1; + + return 1; + } + +static void bio_destroy_pair(BIO *bio) + { + struct bio_bio_st *b = bio->ptr; + + if (b != NULL) + { + BIO *peer_bio = b->peer; + + if (peer_bio != NULL) + { + struct bio_bio_st *peer_b = peer_bio->ptr; + + assert(peer_b != NULL); + assert(peer_b->peer == bio); + + peer_b->peer = NULL; + peer_bio->init = 0; + assert(peer_b->buf != NULL); + peer_b->len = 0; + peer_b->offset = 0; + + b->peer = NULL; + bio->init = 0; + assert(b->buf != NULL); + b->len = 0; + b->offset = 0; + } + } + } -- cgit v1.2.3