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