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 = bio->ptr;
131
132 assert(b != NULL);
133
134 if (b->peer) {
135 bio_destroy_pair(bio);
136 }
137
138 OPENSSL_free(b->buf);
139 OPENSSL_free(b);
140
141 return 1;
142 }
143
bio_read(BIO * bio,char * buf,int size_)144 static int bio_read(BIO *bio, char *buf, int size_) {
145 size_t size = size_;
146 size_t rest;
147 struct bio_bio_st *b, *peer_b;
148
149 BIO_clear_retry_flags(bio);
150
151 if (!bio->init) {
152 return 0;
153 }
154
155 b = bio->ptr;
156 assert(b != NULL);
157 assert(b->peer != NULL);
158 peer_b = b->peer->ptr;
159 assert(peer_b != NULL);
160 assert(peer_b->buf != NULL);
161
162 peer_b->request = 0; // will be set in "retry_read" situation
163
164 if (buf == NULL || size == 0) {
165 return 0;
166 }
167
168 if (peer_b->len == 0) {
169 if (peer_b->closed) {
170 return 0; // writer has closed, and no data is left
171 } else {
172 BIO_set_retry_read(bio); // buffer is empty
173 if (size <= peer_b->size) {
174 peer_b->request = size;
175 } else {
176 // don't ask for more than the peer can
177 // deliver in one write
178 peer_b->request = peer_b->size;
179 }
180 return -1;
181 }
182 }
183
184 // we can read
185 if (peer_b->len < size) {
186 size = peer_b->len;
187 }
188
189 // now read "size" bytes
190 rest = size;
191
192 assert(rest > 0);
193 // one or two iterations
194 do {
195 size_t chunk;
196
197 assert(rest <= peer_b->len);
198 if (peer_b->offset + rest <= peer_b->size) {
199 chunk = rest;
200 } else {
201 // wrap around ring buffer
202 chunk = peer_b->size - peer_b->offset;
203 }
204 assert(peer_b->offset + chunk <= peer_b->size);
205
206 OPENSSL_memcpy(buf, peer_b->buf + peer_b->offset, chunk);
207
208 peer_b->len -= chunk;
209 if (peer_b->len) {
210 peer_b->offset += chunk;
211 assert(peer_b->offset <= peer_b->size);
212 if (peer_b->offset == peer_b->size) {
213 peer_b->offset = 0;
214 }
215 buf += chunk;
216 } else {
217 // buffer now empty, no need to advance "buf"
218 assert(chunk == rest);
219 peer_b->offset = 0;
220 }
221 rest -= chunk;
222 } while (rest);
223
224 return size;
225 }
226
bio_write(BIO * bio,const char * buf,int num_)227 static int bio_write(BIO *bio, const char *buf, int num_) {
228 size_t num = num_;
229 size_t rest;
230 struct bio_bio_st *b;
231
232 BIO_clear_retry_flags(bio);
233
234 if (!bio->init || buf == NULL || num == 0) {
235 return 0;
236 }
237
238 b = bio->ptr;
239 assert(b != NULL);
240 assert(b->peer != NULL);
241 assert(b->buf != NULL);
242
243 b->request = 0;
244 if (b->closed) {
245 // we already closed
246 OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
247 return -1;
248 }
249
250 assert(b->len <= b->size);
251
252 if (b->len == b->size) {
253 BIO_set_retry_write(bio); // buffer is full
254 return -1;
255 }
256
257 // we can write
258 if (num > b->size - b->len) {
259 num = b->size - b->len;
260 }
261
262 // now write "num" bytes
263 rest = num;
264
265 assert(rest > 0);
266 // one or two iterations
267 do {
268 size_t write_offset;
269 size_t chunk;
270
271 assert(b->len + rest <= b->size);
272
273 write_offset = b->offset + b->len;
274 if (write_offset >= b->size) {
275 write_offset -= b->size;
276 }
277 // b->buf[write_offset] is the first byte we can write to.
278
279 if (write_offset + rest <= b->size) {
280 chunk = rest;
281 } else {
282 // wrap around ring buffer
283 chunk = b->size - write_offset;
284 }
285
286 OPENSSL_memcpy(b->buf + write_offset, buf, chunk);
287
288 b->len += chunk;
289
290 assert(b->len <= b->size);
291
292 rest -= chunk;
293 buf += chunk;
294 } while (rest);
295
296 return num;
297 }
298
bio_make_pair(BIO * bio1,BIO * bio2,size_t writebuf1_len,size_t writebuf2_len)299 static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len,
300 size_t writebuf2_len) {
301 struct bio_bio_st *b1, *b2;
302
303 assert(bio1 != NULL);
304 assert(bio2 != NULL);
305
306 b1 = bio1->ptr;
307 b2 = bio2->ptr;
308
309 if (b1->peer != NULL || b2->peer != NULL) {
310 OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE);
311 return 0;
312 }
313
314 if (b1->buf == NULL) {
315 if (writebuf1_len) {
316 b1->size = writebuf1_len;
317 }
318 b1->buf = OPENSSL_malloc(b1->size);
319 if (b1->buf == NULL) {
320 OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
321 return 0;
322 }
323 b1->len = 0;
324 b1->offset = 0;
325 }
326
327 if (b2->buf == NULL) {
328 if (writebuf2_len) {
329 b2->size = writebuf2_len;
330 }
331 b2->buf = OPENSSL_malloc(b2->size);
332 if (b2->buf == NULL) {
333 OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
334 return 0;
335 }
336 b2->len = 0;
337 b2->offset = 0;
338 }
339
340 b1->peer = bio2;
341 b1->closed = 0;
342 b1->request = 0;
343 b2->peer = bio1;
344 b2->closed = 0;
345 b2->request = 0;
346
347 bio1->init = 1;
348 bio2->init = 1;
349
350 return 1;
351 }
352
bio_ctrl(BIO * bio,int cmd,long num,void * ptr)353 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
354 long ret;
355 struct bio_bio_st *b = bio->ptr;
356
357 assert(b != NULL);
358
359 switch (cmd) {
360 // specific CTRL codes
361
362 case BIO_C_GET_WRITE_BUF_SIZE:
363 ret = (long)b->size;
364 break;
365
366 case BIO_C_GET_WRITE_GUARANTEE:
367 // How many bytes can the caller feed to the next write
368 // without having to keep any?
369 if (b->peer == NULL || b->closed) {
370 ret = 0;
371 } else {
372 ret = (long)b->size - b->len;
373 }
374 break;
375
376 case BIO_C_GET_READ_REQUEST:
377 // If the peer unsuccessfully tried to read, how many bytes
378 // were requested? (As with BIO_CTRL_PENDING, that number
379 // can usually be treated as boolean.)
380 ret = (long)b->request;
381 break;
382
383 case BIO_C_RESET_READ_REQUEST:
384 // Reset request. (Can be useful after read attempts
385 // at the other side that are meant to be non-blocking,
386 // e.g. when probing SSL_read to see if any data is
387 // available.)
388 b->request = 0;
389 ret = 1;
390 break;
391
392 case BIO_C_SHUTDOWN_WR:
393 // similar to shutdown(..., SHUT_WR)
394 b->closed = 1;
395 ret = 1;
396 break;
397
398 // standard CTRL codes follow
399
400 case BIO_CTRL_GET_CLOSE:
401 ret = bio->shutdown;
402 break;
403
404 case BIO_CTRL_SET_CLOSE:
405 bio->shutdown = (int)num;
406 ret = 1;
407 break;
408
409 case BIO_CTRL_PENDING:
410 if (b->peer != NULL) {
411 struct bio_bio_st *peer_b = b->peer->ptr;
412 ret = (long)peer_b->len;
413 } else {
414 ret = 0;
415 }
416 break;
417
418 case BIO_CTRL_WPENDING:
419 ret = 0;
420 if (b->buf != NULL) {
421 ret = (long)b->len;
422 }
423 break;
424
425 case BIO_CTRL_FLUSH:
426 ret = 1;
427 break;
428
429 case BIO_CTRL_EOF: {
430 BIO *other_bio = ptr;
431
432 if (other_bio) {
433 struct bio_bio_st *other_b = other_bio->ptr;
434 assert(other_b != NULL);
435 ret = other_b->len == 0 && other_b->closed;
436 } else {
437 ret = 1;
438 }
439 } break;
440
441 default:
442 ret = 0;
443 }
444 return ret;
445 }
446
447
448 static const BIO_METHOD methods_biop = {
449 BIO_TYPE_BIO, "BIO pair", bio_write, bio_read, NULL /* puts */,
450 NULL /* gets */, bio_ctrl, bio_new, bio_free, NULL /* callback_ctrl */,
451 };
452
bio_s_bio(void)453 static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
454
BIO_new_bio_pair(BIO ** bio1_p,size_t writebuf1_len,BIO ** bio2_p,size_t writebuf2_len)455 int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1_len,
456 BIO** bio2_p, size_t writebuf2_len) {
457 BIO *bio1 = BIO_new(bio_s_bio());
458 BIO *bio2 = BIO_new(bio_s_bio());
459 if (bio1 == NULL || bio2 == NULL ||
460 !bio_make_pair(bio1, bio2, writebuf1_len, writebuf2_len)) {
461 BIO_free(bio1);
462 BIO_free(bio2);
463 *bio1_p = NULL;
464 *bio2_p = NULL;
465 return 0;
466 }
467
468 *bio1_p = bio1;
469 *bio2_p = bio2;
470 return 1;
471 }
472
BIO_ctrl_get_read_request(BIO * bio)473 size_t BIO_ctrl_get_read_request(BIO *bio) {
474 return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
475 }
476
BIO_ctrl_get_write_guarantee(BIO * bio)477 size_t BIO_ctrl_get_write_guarantee(BIO *bio) {
478 return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
479 }
480
BIO_shutdown_wr(BIO * bio)481 int BIO_shutdown_wr(BIO *bio) {
482 return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL);
483 }
484