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 // |size| is bounded by the buffer size, which fits in |int|.
225 return (int)size;
226 }
227
bio_write(BIO * bio,const char * buf,int num_)228 static int bio_write(BIO *bio, const char *buf, int num_) {
229 size_t num = num_;
230 size_t rest;
231 struct bio_bio_st *b;
232
233 BIO_clear_retry_flags(bio);
234
235 if (!bio->init || buf == NULL || num == 0) {
236 return 0;
237 }
238
239 b = bio->ptr;
240 assert(b != NULL);
241 assert(b->peer != NULL);
242 assert(b->buf != NULL);
243
244 b->request = 0;
245 if (b->closed) {
246 // we already closed
247 OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
248 return -1;
249 }
250
251 assert(b->len <= b->size);
252
253 if (b->len == b->size) {
254 BIO_set_retry_write(bio); // buffer is full
255 return -1;
256 }
257
258 // we can write
259 if (num > b->size - b->len) {
260 num = b->size - b->len;
261 }
262
263 // now write "num" bytes
264 rest = num;
265
266 assert(rest > 0);
267 // one or two iterations
268 do {
269 size_t write_offset;
270 size_t chunk;
271
272 assert(b->len + rest <= b->size);
273
274 write_offset = b->offset + b->len;
275 if (write_offset >= b->size) {
276 write_offset -= b->size;
277 }
278 // b->buf[write_offset] is the first byte we can write to.
279
280 if (write_offset + rest <= b->size) {
281 chunk = rest;
282 } else {
283 // wrap around ring buffer
284 chunk = b->size - write_offset;
285 }
286
287 OPENSSL_memcpy(b->buf + write_offset, buf, chunk);
288
289 b->len += chunk;
290
291 assert(b->len <= b->size);
292
293 rest -= chunk;
294 buf += chunk;
295 } while (rest);
296
297 // |num| is bounded by the buffer size, which fits in |int|.
298 return (int)num;
299 }
300
bio_make_pair(BIO * bio1,BIO * bio2,size_t writebuf1_len,size_t writebuf2_len)301 static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len,
302 size_t writebuf2_len) {
303 struct bio_bio_st *b1, *b2;
304
305 assert(bio1 != NULL);
306 assert(bio2 != NULL);
307
308 b1 = bio1->ptr;
309 b2 = bio2->ptr;
310
311 if (b1->peer != NULL || b2->peer != NULL) {
312 OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE);
313 return 0;
314 }
315
316 if (b1->buf == NULL) {
317 if (writebuf1_len) {
318 b1->size = writebuf1_len;
319 }
320 b1->buf = OPENSSL_malloc(b1->size);
321 if (b1->buf == NULL) {
322 return 0;
323 }
324 b1->len = 0;
325 b1->offset = 0;
326 }
327
328 if (b2->buf == NULL) {
329 if (writebuf2_len) {
330 b2->size = writebuf2_len;
331 }
332 b2->buf = OPENSSL_malloc(b2->size);
333 if (b2->buf == NULL) {
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 (int)BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL);
483 }
484