Module: sip-router Branch: andrei/tcp_tls_changes Commit: d13629b64226ba665bf9ed2d8211189215bb5157 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d13629b64226ba665bf9ed2d8211189215bb5157
Author: Andrei Pelinescu-Onciul <[email protected]> Committer: Andrei Pelinescu-Onciul <[email protected]> Date: Thu Mar 25 20:30:57 2010 +0100 tls: added custom memory based bio Added a custom memory based BIO, that reads and writes in some memory buffers. It will be used to replace the direct socket access. --- modules/tls/tls_bio.c | 246 +++++++++++++++++++++++++++++++++++++++++++++++++ modules/tls/tls_bio.h | 54 +++++++++++ 2 files changed, 300 insertions(+), 0 deletions(-) diff --git a/modules/tls/tls_bio.c b/modules/tls/tls_bio.c new file mode 100644 index 0000000..a7ba50d --- /dev/null +++ b/modules/tls/tls_bio.c @@ -0,0 +1,246 @@ +/* + * $Id$ + * + * Copyright (C) 2010 iptelorg GmbH + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/** openssl BIOs for reading/writing via a fixed memory buffer. + * @file /home/andrei/sr.git/modules/tls/tls_bio.c + * @ingroup tls + * @Module: @ref tls + */ +/* + * History: + * -------- + * 2010-03-25 initial version (andrei) +*/ + +#include "tls_bio.h" +#include "../../compiler_opt.h" +#include "../../dprint.h" +#include "../../ut.h" + +/* 0xf2 should be unused (as of openssl 1.0.0 max. + internal defined BIO is 23) */ +#define BIO_TYPE_TLS_MBUF (BIO_TYPE_SOURCE_SINK | 0xf2) + + +static int tls_bio_mbuf_new(BIO* b); +static int tls_bio_mbuf_free(BIO* b); +static int tls_bio_mbuf_write(BIO* b, const char* buf, int num); +static int tls_bio_mbuf_read(BIO* b, char* buf, int num); +static int tls_bio_mbuf_puts(BIO* b, const char* s); +static long tls_bio_mbuf_ctrl(BIO* b, int cmd, long arg1, void* arg2); + + +static BIO_METHOD tls_mbuf_method = { + BIO_TYPE_TLS_MBUF, /* type */ + "sr_tls_mbuf", /* name */ + tls_bio_mbuf_write, /* write function */ + tls_bio_mbuf_read, /* read function */ + tls_bio_mbuf_puts, /* puts function */ + 0, /* gets function */ + tls_bio_mbuf_ctrl, /* ctrl function */ + tls_bio_mbuf_new, /* create(new) function */ + tls_bio_mbuf_free, /* destroy(free) function */ + 0 /* ctrl callback */ +}; + + +/** returns a custom tls_mbuf BIO. */ +BIO_METHOD* tls_BIO_mbuf(void) +{ + return &tls_mbuf_method; +} + + + +/** create an initialize a new tls_BIO_mbuf. + * @return new BIO on success (!=0), 0 on error. + */ +BIO* tls_BIO_new_mbuf(struct tls_mbuf* rd, struct tls_mbuf* wr) +{ + BIO* ret; + + ret = BIO_new(tls_BIO_mbuf()); + if (unlikely(ret == 0)) + return 0; + if (unlikely(tls_BIO_mbuf_set(ret, rd, wr) == 0)) { + BIO_free(ret); + return 0; + } + return ret; +} + + + +/** sets the read and write mbuf for an mbuf BIO. + * @return 1 on success, 0 on error (openssl BIO convention). + */ +int tls_BIO_mbuf_set(BIO* b, struct tls_mbuf* rd, struct tls_mbuf* wr) +{ + struct tls_bio_mbuf_data* d; + + if (unlikely(b->ptr == 0)){ + BUG("null BIO ptr\n"); + return 0; + } + d = b->ptr; + d->rd = rd; + d->wr = wr; + b->init = 1; + return 1; +} + + + +/** create a new BIO. + * (internal openssl use via the tls_mbuf method) + * @return 1 on success, 0 on error. + */ +static int tls_bio_mbuf_new(BIO* b) +{ + struct tls_bio_mbuf_data* d; + + b->init = 0; /* not initialized yet */ + b->num = 0; + b->ptr = 0; + b->flags = 0; + d = OPENSSL_malloc(sizeof(*d)); + if (unlikely(d == 0)) + return 0; + d->rd = 0; + d->wr = 0; + b->ptr = d; + return 1; +} + + + +/** destroy a tls mbuf BIO. + * (internal openssl use via the tls_mbuf method) + * @return 1 on success, 0 on error. + */ +static int tls_bio_mbuf_free(BIO* b) +{ + if (unlikely( b == 0)) + return 0; + if (likely(b->ptr)){ + OPENSSL_free(b->ptr); + b->ptr = 0; + b->init = 0; + } + return 1; +} + + + +/** read from a mbuf. + * (internal openssl use via the tls_mbuf method) + * @return bytes read on success (0< ret <=dst_len), -1 on empty buffer & sets + * should_retry_read, -1 on some other errors (w/o should_retry_read set). + */ +static int tls_bio_mbuf_read(BIO* b, char* dst, int dst_len) +{ + struct tls_bio_mbuf_data* d; + struct tls_mbuf* rd; + int ret; + + ret = 0; + if (likely(dst)) { + d= b->ptr; + BIO_clear_retry_flags(b); + if (unlikely(d == 0 || d->rd->buf == 0)) { + if (d == 0) + BUG("tls_BIO_mbuf %p: read called with null b->ptr\n", b); + else + BUG("tls_BIO_mbuf %p: read called with null read buffer\n", b); + return -1; + } + rd = d->rd; + if (unlikely(rd->used == rd->pos && dst_len)) { + /* mimic non-blocking read behaviour */ + BIO_set_retry_read(b); + return -1; + } + ret = MIN_int(rd->used - rd->pos, dst_len); + /* copy data from rd.buf into dst */ + memcpy(rd->buf+rd->pos, dst, ret); + rd->pos += ret; +/* if (unlikely(rd->pos < rd->used)) + BIO_set_retry_read(b); +*/ + } + return ret; +} + + + +/** write to a mbuf. + * (internal openssl use via the tls_mbuf method) + * @return bytes written on success (0<= ret <=src_len), -1 on error or buffer + * full (in this case sets should_retry_write). + */ +static int tls_bio_mbuf_write(BIO* b, const char* src, int src_len) +{ + struct tls_bio_mbuf_data* d; + struct tls_mbuf* wr; + int ret; + + ret = 0; + d= b->ptr; + BIO_clear_retry_flags(b); + if (unlikely(d == 0 || d->wr->buf == 0)) { + if (d == 0) + BUG("tls_BIO_mbuf %p: write called with null b->ptr\n", b); + else + BUG("tls_BIO_mbuf %p: write called with null read buffer\n", b); + return -1; + } + wr = d->wr; + if (unlikely(wr->size == wr->used && src_len)) { + /* mimic non-blocking socket behaviour */ + BIO_set_retry_write(b); + return -1; + } + ret = MIN_int(wr->size - wr->used, src_len); + memcpy(wr->buf + wr->used, src, ret); + wr->used += ret; +/* if (unlikely(ret < src_len)) + BIO_set_retry_write(); +*/ + return ret; +} + + + +static long tls_bio_mbuf_ctrl(BIO* b, int cmd, long arg1, void* arg2) +{ + /* no cmd supported */ + return 0; +} + + + +static int tls_bio_mbuf_puts(BIO* b, const char* s) +{ + int len; + + len=strlen(s); + return tls_bio_mbuf_write(b, s, len); +} + + + +/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ diff --git a/modules/tls/tls_bio.h b/modules/tls/tls_bio.h new file mode 100644 index 0000000..78d5a47 --- /dev/null +++ b/modules/tls/tls_bio.h @@ -0,0 +1,54 @@ +/* + * $Id$ + * + * Copyright (C) 2010 iptelorg GmbH + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/** openssl BIOs for reading/writing via a fixed memory buffer. + * @file modules/tls/tls_bio.h + * @ingroup tls + * @Module: @ref tls + */ +/* + * History: + * -------- + * 2010-03-25 initial version (andrei) +*/ + +#ifndef __tls_bio_h +#define __tls_bio_h + +#include <openssl/bio.h> + +/* memory buffer used for tls I/O */ +struct tls_mbuf { + unsigned char* buf; + int pos; /* current position in the buffer while reading*/ + int used; /* how much it's used */ + int size; /* total buffer size (fixed) */ +}; + +struct tls_bio_mbuf_data { + struct tls_mbuf* rd; + struct tls_mbuf* wr; +}; + + +BIO_METHOD* tls_BIO_mbuf(void); +BIO* tls_BIO_new_mbuf(struct tls_mbuf* rd, struct tls_mbuf* wr); +int tls_BIO_mbuf_set(BIO* b, struct tls_mbuf* rd, struct tls_mbuf* wr); + +#endif /*__tls_bio_h*/ + +/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ _______________________________________________ sr-dev mailing list [email protected] http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
