Browse code

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.

Andrei Pelinescu-Onciul authored on 25/03/2010 19:30:57
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,246 @@
1
+/* 
2
+ * $Id$
3
+ * 
4
+ * Copyright (C) 2010 iptelorg GmbH
5
+ *
6
+ * Permission to use, copy, modify, and distribute this software for any
7
+ * purpose with or without fee is hereby granted, provided that the above
8
+ * copyright notice and this permission notice appear in all copies.
9
+ *
10
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
+ */
18
+/** openssl BIOs for reading/writing via a fixed memory buffer.
19
+ * @file /home/andrei/sr.git/modules/tls/tls_bio.c
20
+ * @ingroup tls
21
+ * @Module: @ref tls
22
+ */
23
+/*
24
+ * History:
25
+ * --------
26
+ *  2010-03-25  initial version (andrei)
27
+*/
28
+
29
+#include "tls_bio.h"
30
+#include "../../compiler_opt.h"
31
+#include "../../dprint.h"
32
+#include "../../ut.h"
33
+
34
+/* 0xf2 should be unused (as of openssl 1.0.0 max.
35
+   internal defined BIO is 23) */
36
+#define BIO_TYPE_TLS_MBUF	(BIO_TYPE_SOURCE_SINK | 0xf2)
37
+
38
+
39
+static int tls_bio_mbuf_new(BIO* b);
40
+static int tls_bio_mbuf_free(BIO* b);
41
+static int tls_bio_mbuf_write(BIO* b, const char* buf, int num);
42
+static int tls_bio_mbuf_read(BIO* b, char* buf, int num);
43
+static int tls_bio_mbuf_puts(BIO* b, const char* s);
44
+static long tls_bio_mbuf_ctrl(BIO* b, int cmd, long arg1, void* arg2);
45
+
46
+
47
+static BIO_METHOD tls_mbuf_method = {
48
+	BIO_TYPE_TLS_MBUF,	/* type */
49
+	"sr_tls_mbuf",		/* name */
50
+	tls_bio_mbuf_write,	/* write function */
51
+	tls_bio_mbuf_read,	/* read function */
52
+	tls_bio_mbuf_puts,	/* puts function */
53
+	0,					/* gets function */
54
+	tls_bio_mbuf_ctrl,	/* ctrl function */
55
+	tls_bio_mbuf_new,	/* create(new) function */
56
+	tls_bio_mbuf_free,	/* destroy(free) function */
57
+	0					/* ctrl callback */
58
+};
59
+
60
+
61
+/** returns a custom tls_mbuf BIO. */
62
+BIO_METHOD* tls_BIO_mbuf(void)
63
+{
64
+	return &tls_mbuf_method;
65
+}
66
+
67
+
68
+
69
+/** create an initialize a new tls_BIO_mbuf.
70
+ * @return new BIO on success (!=0), 0 on error.
71
+ */
72
+BIO* tls_BIO_new_mbuf(struct tls_mbuf* rd, struct tls_mbuf* wr)
73
+{
74
+	BIO* ret;
75
+	
76
+	ret = BIO_new(tls_BIO_mbuf());
77
+	if (unlikely(ret == 0))
78
+		return 0;
79
+	if (unlikely(tls_BIO_mbuf_set(ret, rd, wr) == 0)) {
80
+		BIO_free(ret);
81
+		return 0;
82
+	}
83
+	return ret;
84
+}
85
+
86
+
87
+
88
+/** sets the read and write mbuf for an  mbuf BIO.
89
+ * @return 1 on success, 0 on error (openssl BIO convention).
90
+ */
91
+int tls_BIO_mbuf_set(BIO* b, struct tls_mbuf* rd, struct tls_mbuf* wr)
92
+{
93
+	struct tls_bio_mbuf_data* d;
94
+	
95
+	if (unlikely(b->ptr == 0)){
96
+		BUG("null BIO ptr\n");
97
+		return 0;
98
+	}
99
+	d = b->ptr;
100
+	d->rd = rd;
101
+	d->wr = wr;
102
+	b->init = 1;
103
+	return 1;
104
+}
105
+
106
+
107
+
108
+/** create a new BIO.
109
+ * (internal openssl use via the tls_mbuf method)
110
+ * @return 1 on success, 0 on error.
111
+ */
112
+static int tls_bio_mbuf_new(BIO* b)
113
+{
114
+	struct tls_bio_mbuf_data* d;
115
+	
116
+	b->init = 0; /* not initialized yet */
117
+	b->num = 0;
118
+	b->ptr = 0;
119
+	b->flags = 0;
120
+	d = OPENSSL_malloc(sizeof(*d));
121
+	if (unlikely(d == 0))
122
+		return 0;
123
+	d->rd = 0;
124
+	d->wr = 0;
125
+	b->ptr = d;
126
+	return 1;
127
+}
128
+
129
+
130
+
131
+/** destroy a tls mbuf BIO.
132
+ * (internal openssl use via the tls_mbuf method)
133
+ * @return 1 on success, 0 on error.
134
+ */
135
+static int tls_bio_mbuf_free(BIO* b)
136
+{
137
+	if (unlikely( b == 0))
138
+			return 0;
139
+	if (likely(b->ptr)){
140
+		OPENSSL_free(b->ptr);
141
+		b->ptr = 0;
142
+		b->init = 0;
143
+	}
144
+	return 1;
145
+}
146
+
147
+
148
+
149
+/** read from a mbuf.
150
+ * (internal openssl use via the tls_mbuf method)
151
+ * @return bytes read on success (0< ret <=dst_len), -1 on empty buffer & sets
152
+ *  should_retry_read, -1 on some other errors (w/o should_retry_read set).
153
+ */
154
+static int tls_bio_mbuf_read(BIO* b, char* dst, int dst_len)
155
+{
156
+	struct tls_bio_mbuf_data* d;
157
+	struct tls_mbuf* rd;
158
+	int ret;
159
+	
160
+	ret = 0;
161
+	if (likely(dst)) {
162
+		d= b->ptr;
163
+		BIO_clear_retry_flags(b);
164
+		if (unlikely(d == 0 || d->rd->buf == 0)) {
165
+			if (d == 0)
166
+				BUG("tls_BIO_mbuf %p: read called with null b->ptr\n", b);
167
+			else
168
+				BUG("tls_BIO_mbuf %p: read called with null read buffer\n", b);
169
+			return -1;
170
+		}
171
+		rd = d->rd;
172
+		if (unlikely(rd->used == rd->pos && dst_len)) {
173
+			/* mimic non-blocking read behaviour */
174
+			BIO_set_retry_read(b);
175
+			return -1;
176
+		}
177
+		ret = MIN_int(rd->used - rd->pos, dst_len);
178
+		/* copy data from rd.buf into dst */
179
+		memcpy(rd->buf+rd->pos, dst, ret);
180
+		rd->pos += ret;
181
+/*		if (unlikely(rd->pos < rd->used))
182
+			BIO_set_retry_read(b);
183
+*/
184
+	}
185
+	return ret;
186
+}
187
+
188
+
189
+
190
+/** write to a mbuf.
191
+ * (internal openssl use via the tls_mbuf method)
192
+ * @return bytes written on success (0<= ret <=src_len), -1 on error or buffer
193
+ * full (in this case sets should_retry_write).
194
+ */
195
+static int tls_bio_mbuf_write(BIO* b, const char* src, int src_len)
196
+{
197
+	struct tls_bio_mbuf_data* d;
198
+	struct tls_mbuf* wr;
199
+	int ret;
200
+	
201
+	ret = 0;
202
+	d= b->ptr;
203
+	BIO_clear_retry_flags(b);
204
+	if (unlikely(d == 0 || d->wr->buf == 0)) {
205
+		if (d == 0)
206
+			BUG("tls_BIO_mbuf %p: write called with null b->ptr\n", b);
207
+		else
208
+			BUG("tls_BIO_mbuf %p: write called with null read buffer\n", b);
209
+		return -1;
210
+	}
211
+	wr = d->wr;
212
+	if (unlikely(wr->size == wr->used && src_len)) {
213
+		/* mimic non-blocking socket behaviour */
214
+		BIO_set_retry_write(b);
215
+		return -1;
216
+	}
217
+	ret = MIN_int(wr->size - wr->used, src_len);
218
+	memcpy(wr->buf + wr->used, src, ret);
219
+	wr->used += ret;
220
+/*	if (unlikely(ret < src_len))
221
+		BIO_set_retry_write();
222
+*/
223
+	return ret;
224
+}
225
+
226
+
227
+
228
+static long tls_bio_mbuf_ctrl(BIO* b, int cmd, long arg1, void* arg2)
229
+{
230
+	/* no cmd supported */
231
+	return 0;
232
+}
233
+
234
+
235
+
236
+static int tls_bio_mbuf_puts(BIO* b, const char* s)
237
+{
238
+	int len;
239
+	
240
+	len=strlen(s);
241
+	return tls_bio_mbuf_write(b, s, len);
242
+}
243
+
244
+
245
+
246
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */
0 247
new file mode 100644
... ...
@@ -0,0 +1,54 @@
1
+/* 
2
+ * $Id$
3
+ * 
4
+ * Copyright (C) 2010 iptelorg GmbH
5
+ *
6
+ * Permission to use, copy, modify, and distribute this software for any
7
+ * purpose with or without fee is hereby granted, provided that the above
8
+ * copyright notice and this permission notice appear in all copies.
9
+ *
10
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
+ */
18
+/** openssl BIOs for reading/writing via a fixed memory buffer.
19
+ * @file modules/tls/tls_bio.h
20
+ * @ingroup tls
21
+ * @Module: @ref tls
22
+ */
23
+/*
24
+ * History:
25
+ * --------
26
+ *  2010-03-25  initial version (andrei)
27
+*/
28
+
29
+#ifndef __tls_bio_h
30
+#define __tls_bio_h
31
+
32
+#include <openssl/bio.h>
33
+
34
+/* memory buffer used for tls I/O */
35
+struct tls_mbuf {
36
+	unsigned char* buf;
37
+	int pos;  /* current position in the buffer while reading*/
38
+	int used; /* how much it's used */
39
+	int size; /* total buffer size (fixed) */
40
+};
41
+
42
+struct tls_bio_mbuf_data {
43
+	struct tls_mbuf* rd;
44
+	struct tls_mbuf* wr;
45
+};
46
+
47
+
48
+BIO_METHOD* tls_BIO_mbuf(void);
49
+BIO* tls_BIO_new_mbuf(struct tls_mbuf* rd, struct tls_mbuf* wr);
50
+int tls_BIO_mbuf_set(BIO* b, struct tls_mbuf* rd, struct tls_mbuf* wr);
51
+
52
+#endif /*__tls_bio_h*/
53
+
54
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */