[sr-dev] git:andrei/tcp_tls_changes: tls: added custom memory based bio

Andrei Pelinescu-Onciul andrei at iptel.org
Thu May 20 16:19:02 CEST 2010


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 <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
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: */




More information about the sr-dev mailing list