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