1 /* ====================================================================
2 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com). */
52
53 #include <openssl/bio.h>
54
55 #include <assert.h>
56 #include <string.h>
57
58 #include <openssl/err.h>
59 #include <openssl/mem.h>
60
61 #include "../internal.h"
62
63
64 struct bio_bio_st {
65 BIO *peer; // NULL if buf == NULL.
66 // If peer != NULL, then peer->ptr is also a bio_bio_st,
67 // and its "peer" member points back to us.
68 // peer != NULL iff init != 0 in the BIO.
69
70 // This is for what we write (i.e. reading uses peer's struct):
71 int closed; // valid iff peer != NULL
72 size_t len; // valid iff buf != NULL; 0 if peer == NULL
73 size_t offset; // valid iff buf != NULL; 0 if len == 0
74 size_t size;
75 uint8_t *buf; // "size" elements (if != NULL)
76
77 size_t request; // valid iff peer != NULL; 0 if len != 0,
78 // otherwise set by peer to number of bytes
79 // it (unsuccessfully) tried to read,
80 // never more than buffer space (size-len) warrants.
81 };
82
bio_new(BIO * bio)83 static int bio_new(BIO *bio) {
84 struct bio_bio_st *b;
85
86 b = OPENSSL_malloc(sizeof *b);
87 if (b == NULL) {
88 return 0;
89 }
90 OPENSSL_memset(b, 0, sizeof(struct bio_bio_st));
91
92 b->size = 17 * 1024; // enough for one TLS record (just a default)
93 bio->ptr = b;
94 return 1;
95 }
96
bio_destroy_pair(BIO * bio)97 static void bio_destroy_pair(BIO *bio) {
98 struct bio_bio_st *b = bio->ptr;
99 BIO *peer_bio;
100 struct bio_bio_st *peer_b;
101
102 if (b == NULL) {
103 return;
104 }
105
106 peer_bio = b->peer;
107 if (peer_bio == NULL) {
108 return;
109 }
110
111 peer_b = peer_bio->ptr;
112
113 assert(peer_b != NULL);
114 assert(peer_b->peer == bio);
115
116 peer_b->peer = NULL;
117 peer_bio->init = 0;
118 assert(peer_b->buf != NULL);
119 peer_b->len = 0;
120 peer_b->offset = 0;
121
122 b->peer = NULL;
123 bio->init = 0;
124 assert(b->buf != NULL);
125 b->len = 0;
126 b->offset = 0;
127 }
128
bio_free(BIO * bio)129 static int bio_free(BIO *bio) {
130 struct bio_bio_st *b;
131
132 if (bio == NULL) {
133 return 0;
134 }
135 b = bio->ptr;
136
137 assert(b != NULL);
138
139 if (b->peer) {
140 bio_destroy_pair(bio);
141 }
142
143 OPENSSL_free(b->buf);
144 OPENSSL_free(b);
145
146 return 1;
147 }
148
bio_read(BIO * bio,char * buf,int size_)149 static int bio_read(BIO *bio, char *buf, int size_) {
150 size_t size = size_;
151 size_t rest;
152 struct bio_bio_st *b, *peer_b;
153
154 BIO_clear_retry_flags(bio);
155
156 if (!bio->init) {
157 return 0;
158 }
159
160 b = bio->ptr;
161 assert(b != NULL);
162 assert(b->peer != NULL);
163 peer_b = b->peer->ptr;
164 assert(peer_b != NULL);
165 assert(peer_b->buf != NULL);
166
167 peer_b->request = 0; // will be set in "retry_read" situation
168
169 if (buf == NULL || size == 0) {
170 return 0;
171 }
172
173 if (peer_b->len == 0) {
174 if (peer_b->closed) {
175 return 0; // writer has closed, and no data is left
176 } else {
177 BIO_set_retry_read(bio); // buffer is empty
178 if (size <= peer_b->size) {
179 peer_b->request = size;
180 } else {
181 // don't ask for more than the peer can
182 // deliver in one write
183 peer_b->request = peer_b->size;
184 }
185 return -1;
186 }
187 }
188
189 // we can read
190 if (peer_b->len < size) {
191 size = peer_b->len;
192 }
193
194 // now read "size" bytes
195 rest = size;
196
197 assert(rest > 0);
198 // one or two iterations
199 do {
200 size_t chunk;
201
202 assert(rest <= peer_b->len);
203 if (peer_b->offset + rest <= peer_b->size) {
204 chunk = rest;
205 } else {
206 // wrap around ring buffer
207 chunk = peer_b->size - peer_b->offset;
208 }
209 assert(peer_b->offset + chunk <= peer_b->size);
210
211 OPENSSL_memcpy(buf, peer_b->buf + peer_b->offset, chunk);
212
213 peer_b->len -= chunk;
214 if (peer_b->len) {
215 peer_b->offset += chunk;
216 assert(peer_b->offset <= peer_b->size);
217 if (peer_b->offset == peer_b->size) {
218 peer_b->offset = 0;
219 }
220 buf += chunk;
221 } else {
222 // buffer now empty, no need to advance "buf"
223 assert(chunk == rest);
224 peer_b->offset = 0;
225 }
226 rest -= chunk;
227 } while (rest);
228
229 return size;
230 }
231
bio_write(BIO * bio,const char * buf,int num_)232 static int bio_write(BIO *bio, const char *buf, int num_) {
233 size_t num = num_;
234 size_t rest;
235 struct bio_bio_st *b;
236
237 BIO_clear_retry_flags(bio);
238
239 if (!bio->init || buf == NULL || num == 0) {
240 return 0;
241 }
242
243 b = bio->ptr;
244 assert(b != NULL);
245 assert(b->peer != NULL);
246 assert(b->buf != NULL);
247
248 b->request = 0;
249 if (b->closed) {
250 // we already closed
251 OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
252 return -1;
253 }
254
255 assert(b->len <= b->size);
256
257 if (b->len == b->size) {
258 BIO_set_retry_write(bio); // buffer is full
259 return -1;
260 }
261
262 // we can write
263 if (num > b->size - b->len) {
264 num = b->size - b->len;
265 }
266
267 // now write "num" bytes
268 rest = num;
269
270 assert(rest > 0);
271 // one or two iterations
272 do {
273 size_t write_offset;
274 size_t chunk;
275
276 assert(b->len + rest <= b->size);
277
278 write_offset = b->offset + b->len;
279 if (write_offset >= b->size) {
280 write_offset -= b->size;
281 }
282 // b->buf[write_offset] is the first byte we can write to.
283
284 if (write_offset + rest <= b->size) {
285 chunk = rest;
286 } else {
287 // wrap around ring buffer
288 chunk = b->size - write_offset;
289 }
290
291 OPENSSL_memcpy(b->buf + write_offset, buf, chunk);
292
293 b->len += chunk;
294
295 assert(b->len <= b->size);
296
297 rest -= chunk;
298 buf += chunk;
299 } while (rest);
300
301 return num;
302 }
303
bio_make_pair(BIO * bio1,BIO * bio2,size_t writebuf1_len,size_t writebuf2_len)304 static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len,
305 size_t writebuf2_len) {
306 struct bio_bio_st *b1, *b2;
307
308 assert(bio1 != NULL);
309 assert(bio2 != NULL);
310
311 b1 = bio1->ptr;
312 b2 = bio2->ptr;
313
314 if (b1->peer != NULL || b2->peer != NULL) {
315 OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE);
316 return 0;
317 }
318
319 if (b1->buf == NULL) {
320 if (writebuf1_len) {
321 b1->size = writebuf1_len;
322 }
323 b1->buf = OPENSSL_malloc(b1->size);
324 if (b1->buf == NULL) {
325 OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
326 return 0;
327 }
328 b1->len = 0;
329 b1->offset = 0;
330 }
331
332 if (b2->buf == NULL) {
333 if (writebuf2_len) {
334 b2->size = writebuf2_len;
335 }
336 b2->buf = OPENSSL_malloc(b2->size);
337 if (b2->buf == NULL) {
338 OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
339 return 0;
340 }
341 b2->len = 0;
342 b2->offset = 0;
343 }
344
345 b1->peer = bio2;
346 b1->closed = 0;
347 b1->request = 0;
348 b2->peer = bio1;
349 b2->closed = 0;
350 b2->request = 0;
351
352 bio1->init = 1;
353 bio2->init = 1;
354
355 return 1;
356 }
357
bio_ctrl(BIO * bio,int cmd,long num,void * ptr)358 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
359 long ret;
360 struct bio_bio_st *b = bio->ptr;
361
362 assert(b != NULL);
363
364 switch (cmd) {
365 // specific CTRL codes
366
367 case BIO_C_GET_WRITE_BUF_SIZE:
368 ret = (long)b->size;
369 break;
370
371 case BIO_C_GET_WRITE_GUARANTEE:
372 // How many bytes can the caller feed to the next write
373 // without having to keep any?
374 if (b->peer == NULL || b->closed) {
375 ret = 0;
376 } else {
377 ret = (long)b->size - b->len;
378 }
379 break;
380
381 case BIO_C_GET_READ_REQUEST:
382 // If the peer unsuccessfully tried to read, how many bytes
383 // were requested? (As with BIO_CTRL_PENDING, that number
384 // can usually be treated as boolean.)
385 ret = (long)b->request;
386 break;
387
388 case BIO_C_RESET_READ_REQUEST:
389 // Reset request. (Can be useful after read attempts
390 // at the other side that are meant to be non-blocking,
391 // e.g. when probing SSL_read to see if any data is
392 // available.)
393 b->request = 0;
394 ret = 1;
395 break;
396
397 case BIO_C_SHUTDOWN_WR:
398 // similar to shutdown(..., SHUT_WR)
399 b->closed = 1;
400 ret = 1;
401 break;
402
403 // standard CTRL codes follow
404
405 case BIO_CTRL_GET_CLOSE:
406 ret = bio->shutdown;
407 break;
408
409 case BIO_CTRL_SET_CLOSE:
410 bio->shutdown = (int)num;
411 ret = 1;
412 break;
413
414 case BIO_CTRL_PENDING:
415 if (b->peer != NULL) {
416 struct bio_bio_st *peer_b = b->peer->ptr;
417 ret = (long)peer_b->len;
418 } else {
419 ret = 0;
420 }
421 break;
422
423 case BIO_CTRL_WPENDING:
424 ret = 0;
425 if (b->buf != NULL) {
426 ret = (long)b->len;
427 }
428 break;
429
430 case BIO_CTRL_FLUSH:
431 ret = 1;
432 break;
433
434 case BIO_CTRL_EOF: {
435 BIO *other_bio = ptr;
436
437 if (other_bio) {
438 struct bio_bio_st *other_b = other_bio->ptr;
439 assert(other_b != NULL);
440 ret = other_b->len == 0 && other_b->closed;
441 } else {
442 ret = 1;
443 }
444 } break;
445
446 default:
447 ret = 0;
448 }
449 return ret;
450 }
451
452
453 static const BIO_METHOD methods_biop = {
454 BIO_TYPE_BIO, "BIO pair", bio_write, bio_read, NULL /* puts */,
455 NULL /* gets */, bio_ctrl, bio_new, bio_free, NULL /* callback_ctrl */,
456 };
457
bio_s_bio(void)458 static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
459
BIO_new_bio_pair(BIO ** bio1_p,size_t writebuf1_len,BIO ** bio2_p,size_t writebuf2_len)460 int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1_len,
461 BIO** bio2_p, size_t writebuf2_len) {
462 BIO *bio1 = BIO_new(bio_s_bio());
463 BIO *bio2 = BIO_new(bio_s_bio());
464 if (bio1 == NULL || bio2 == NULL ||
465 !bio_make_pair(bio1, bio2, writebuf1_len, writebuf2_len)) {
466 BIO_free(bio1);
467 BIO_free(bio2);
468 *bio1_p = NULL;
469 *bio2_p = NULL;
470 return 0;
471 }
472
473 *bio1_p = bio1;
474 *bio2_p = bio2;
475 return 1;
476 }
477
BIO_ctrl_get_read_request(BIO * bio)478 size_t BIO_ctrl_get_read_request(BIO *bio) {
479 return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
480 }
481
BIO_ctrl_get_write_guarantee(BIO * bio)482 size_t BIO_ctrl_get_write_guarantee(BIO *bio) {
483 return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
484 }
485
BIO_shutdown_wr(BIO * bio)486 int BIO_shutdown_wr(BIO *bio) {
487 return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL);
488 }
489