diff options
Diffstat (limited to 'src/lib/libcrypto/bio/bss_bio.c')
-rw-r--r-- | src/lib/libcrypto/bio/bss_bio.c | 318 |
1 files changed, 301 insertions, 17 deletions
diff --git a/src/lib/libcrypto/bio/bss_bio.c b/src/lib/libcrypto/bio/bss_bio.c index 562e9d8de2..1c485a4479 100644 --- a/src/lib/libcrypto/bio/bss_bio.c +++ b/src/lib/libcrypto/bio/bss_bio.c | |||
@@ -7,25 +7,46 @@ | |||
7 | * for which no specific BIO method is available. | 7 | * for which no specific BIO method is available. |
8 | * See ssl/ssltest.c for some hints on how this can be used. */ | 8 | * See ssl/ssltest.c for some hints on how this can be used. */ |
9 | 9 | ||
10 | /* BIO_DEBUG implies BIO_PAIR_DEBUG */ | ||
11 | #ifdef BIO_DEBUG | ||
12 | # ifndef BIO_PAIR_DEBUG | ||
13 | # define BIO_PAIR_DEBUG | ||
14 | # endif | ||
15 | #endif | ||
16 | |||
17 | /* disable assert() unless BIO_PAIR_DEBUG has been defined */ | ||
10 | #ifndef BIO_PAIR_DEBUG | 18 | #ifndef BIO_PAIR_DEBUG |
11 | # undef NDEBUG /* avoid conflicting definitions */ | 19 | # ifndef NDEBUG |
12 | # define NDEBUG | 20 | # define NDEBUG |
21 | # endif | ||
13 | #endif | 22 | #endif |
14 | 23 | ||
15 | #include <assert.h> | 24 | #include <assert.h> |
25 | #include <limits.h> | ||
16 | #include <stdlib.h> | 26 | #include <stdlib.h> |
17 | #include <string.h> | 27 | #include <string.h> |
18 | 28 | ||
19 | #include <openssl/bio.h> | 29 | #include <openssl/bio.h> |
20 | #include <openssl/err.h> | 30 | #include <openssl/err.h> |
31 | #include <openssl/err.h> | ||
21 | #include <openssl/crypto.h> | 32 | #include <openssl/crypto.h> |
22 | 33 | ||
34 | #include "e_os.h" | ||
35 | |||
36 | /* VxWorks defines SSIZE_MAX with an empty value causing compile errors */ | ||
37 | #if defined(OPENSSL_SYS_VSWORKS) | ||
38 | # undef SSIZE_MAX | ||
39 | #endif | ||
40 | #ifndef SSIZE_MAX | ||
41 | # define SSIZE_MAX INT_MAX | ||
42 | #endif | ||
43 | |||
23 | static int bio_new(BIO *bio); | 44 | static int bio_new(BIO *bio); |
24 | static int bio_free(BIO *bio); | 45 | static int bio_free(BIO *bio); |
25 | static int bio_read(BIO *bio, char *buf, int size); | 46 | static int bio_read(BIO *bio, char *buf, int size); |
26 | static int bio_write(BIO *bio, char *buf, int num); | 47 | static int bio_write(BIO *bio, const char *buf, int num); |
27 | static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); | 48 | static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); |
28 | static int bio_puts(BIO *bio, char *str); | 49 | static int bio_puts(BIO *bio, const char *str); |
29 | 50 | ||
30 | static int bio_make_pair(BIO *bio1, BIO *bio2); | 51 | static int bio_make_pair(BIO *bio1, BIO *bio2); |
31 | static void bio_destroy_pair(BIO *bio); | 52 | static void bio_destroy_pair(BIO *bio); |
@@ -40,7 +61,8 @@ static BIO_METHOD methods_biop = | |||
40 | NULL /* no bio_gets */, | 61 | NULL /* no bio_gets */, |
41 | bio_ctrl, | 62 | bio_ctrl, |
42 | bio_new, | 63 | bio_new, |
43 | bio_free | 64 | bio_free, |
65 | NULL /* no bio_callback_ctrl */ | ||
44 | }; | 66 | }; |
45 | 67 | ||
46 | BIO_METHOD *BIO_s_bio(void) | 68 | BIO_METHOD *BIO_s_bio(void) |
@@ -64,7 +86,7 @@ struct bio_bio_st | |||
64 | 86 | ||
65 | size_t request; /* valid iff peer != NULL; 0 if len != 0, | 87 | size_t request; /* valid iff peer != NULL; 0 if len != 0, |
66 | * otherwise set by peer to number of bytes | 88 | * otherwise set by peer to number of bytes |
67 | * it (unsuccesfully) tried to read, | 89 | * it (unsuccessfully) tried to read, |
68 | * never more than buffer space (size-len) warrants. */ | 90 | * never more than buffer space (size-len) warrants. */ |
69 | }; | 91 | }; |
70 | 92 | ||
@@ -72,7 +94,7 @@ static int bio_new(BIO *bio) | |||
72 | { | 94 | { |
73 | struct bio_bio_st *b; | 95 | struct bio_bio_st *b; |
74 | 96 | ||
75 | b = Malloc(sizeof *b); | 97 | b = OPENSSL_malloc(sizeof *b); |
76 | if (b == NULL) | 98 | if (b == NULL) |
77 | return 0; | 99 | return 0; |
78 | 100 | ||
@@ -100,10 +122,10 @@ static int bio_free(BIO *bio) | |||
100 | 122 | ||
101 | if (b->buf != NULL) | 123 | if (b->buf != NULL) |
102 | { | 124 | { |
103 | Free(b->buf); | 125 | OPENSSL_free(b->buf); |
104 | } | 126 | } |
105 | 127 | ||
106 | Free(b); | 128 | OPENSSL_free(b); |
107 | 129 | ||
108 | return 1; | 130 | return 1; |
109 | } | 131 | } |
@@ -195,7 +217,87 @@ static int bio_read(BIO *bio, char *buf, int size_) | |||
195 | return size; | 217 | return size; |
196 | } | 218 | } |
197 | 219 | ||
198 | static int bio_write(BIO *bio, char *buf, int num_) | 220 | /* non-copying interface: provide pointer to available data in buffer |
221 | * bio_nread0: return number of available bytes | ||
222 | * bio_nread: also advance index | ||
223 | * (example usage: bio_nread0(), read from buffer, bio_nread() | ||
224 | * or just bio_nread(), read from buffer) | ||
225 | */ | ||
226 | /* WARNING: The non-copying interface is largely untested as of yet | ||
227 | * and may contain bugs. */ | ||
228 | static ssize_t bio_nread0(BIO *bio, char **buf) | ||
229 | { | ||
230 | struct bio_bio_st *b, *peer_b; | ||
231 | ssize_t num; | ||
232 | |||
233 | BIO_clear_retry_flags(bio); | ||
234 | |||
235 | if (!bio->init) | ||
236 | return 0; | ||
237 | |||
238 | b = bio->ptr; | ||
239 | assert(b != NULL); | ||
240 | assert(b->peer != NULL); | ||
241 | peer_b = b->peer->ptr; | ||
242 | assert(peer_b != NULL); | ||
243 | assert(peer_b->buf != NULL); | ||
244 | |||
245 | peer_b->request = 0; | ||
246 | |||
247 | if (peer_b->len == 0) | ||
248 | { | ||
249 | char dummy; | ||
250 | |||
251 | /* avoid code duplication -- nothing available for reading */ | ||
252 | return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ | ||
253 | } | ||
254 | |||
255 | num = peer_b->len; | ||
256 | if (peer_b->size < peer_b->offset + num) | ||
257 | /* no ring buffer wrap-around for non-copying interface */ | ||
258 | num = peer_b->size - peer_b->offset; | ||
259 | assert(num > 0); | ||
260 | |||
261 | if (buf != NULL) | ||
262 | *buf = peer_b->buf + peer_b->offset; | ||
263 | return num; | ||
264 | } | ||
265 | |||
266 | static ssize_t bio_nread(BIO *bio, char **buf, size_t num_) | ||
267 | { | ||
268 | struct bio_bio_st *b, *peer_b; | ||
269 | ssize_t num, available; | ||
270 | |||
271 | if (num_ > SSIZE_MAX) | ||
272 | num = SSIZE_MAX; | ||
273 | else | ||
274 | num = (ssize_t)num_; | ||
275 | |||
276 | available = bio_nread0(bio, buf); | ||
277 | if (num > available) | ||
278 | num = available; | ||
279 | if (num <= 0) | ||
280 | return num; | ||
281 | |||
282 | b = bio->ptr; | ||
283 | peer_b = b->peer->ptr; | ||
284 | |||
285 | peer_b->len -= num; | ||
286 | if (peer_b->len) | ||
287 | { | ||
288 | peer_b->offset += num; | ||
289 | assert(peer_b->offset <= peer_b->size); | ||
290 | if (peer_b->offset == peer_b->size) | ||
291 | peer_b->offset = 0; | ||
292 | } | ||
293 | else | ||
294 | peer_b->offset = 0; | ||
295 | |||
296 | return num; | ||
297 | } | ||
298 | |||
299 | |||
300 | static int bio_write(BIO *bio, const char *buf, int num_) | ||
199 | { | 301 | { |
200 | size_t num = num_; | 302 | size_t num = num_; |
201 | size_t rest; | 303 | size_t rest; |
@@ -268,6 +370,83 @@ static int bio_write(BIO *bio, char *buf, int num_) | |||
268 | return num; | 370 | return num; |
269 | } | 371 | } |
270 | 372 | ||
373 | /* non-copying interface: provide pointer to region to write to | ||
374 | * bio_nwrite0: check how much space is available | ||
375 | * bio_nwrite: also increase length | ||
376 | * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() | ||
377 | * or just bio_nwrite(), write to buffer) | ||
378 | */ | ||
379 | static ssize_t bio_nwrite0(BIO *bio, char **buf) | ||
380 | { | ||
381 | struct bio_bio_st *b; | ||
382 | size_t num; | ||
383 | size_t write_offset; | ||
384 | |||
385 | BIO_clear_retry_flags(bio); | ||
386 | |||
387 | if (!bio->init) | ||
388 | return 0; | ||
389 | |||
390 | b = bio->ptr; | ||
391 | assert(b != NULL); | ||
392 | assert(b->peer != NULL); | ||
393 | assert(b->buf != NULL); | ||
394 | |||
395 | b->request = 0; | ||
396 | if (b->closed) | ||
397 | { | ||
398 | BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); | ||
399 | return -1; | ||
400 | } | ||
401 | |||
402 | assert(b->len <= b->size); | ||
403 | |||
404 | if (b->len == b->size) | ||
405 | { | ||
406 | BIO_set_retry_write(bio); | ||
407 | return -1; | ||
408 | } | ||
409 | |||
410 | num = b->size - b->len; | ||
411 | write_offset = b->offset + b->len; | ||
412 | if (write_offset >= b->size) | ||
413 | write_offset -= b->size; | ||
414 | if (write_offset + num > b->size) | ||
415 | /* no ring buffer wrap-around for non-copying interface | ||
416 | * (to fulfil the promise by BIO_ctrl_get_write_guarantee, | ||
417 | * BIO_nwrite may have to be called twice) */ | ||
418 | num = b->size - write_offset; | ||
419 | |||
420 | if (buf != NULL) | ||
421 | *buf = b->buf + write_offset; | ||
422 | assert(write_offset + num <= b->size); | ||
423 | |||
424 | return num; | ||
425 | } | ||
426 | |||
427 | static ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) | ||
428 | { | ||
429 | struct bio_bio_st *b; | ||
430 | ssize_t num, space; | ||
431 | |||
432 | if (num_ > SSIZE_MAX) | ||
433 | num = SSIZE_MAX; | ||
434 | else | ||
435 | num = (ssize_t)num_; | ||
436 | |||
437 | space = bio_nwrite0(bio, buf); | ||
438 | if (num > space) | ||
439 | num = space; | ||
440 | if (num <= 0) | ||
441 | return num; | ||
442 | b = bio->ptr; | ||
443 | assert(b != NULL); | ||
444 | b->len += num; | ||
445 | assert(b->len <= b->size); | ||
446 | |||
447 | return num; | ||
448 | } | ||
449 | |||
271 | 450 | ||
272 | static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | 451 | static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) |
273 | { | 452 | { |
@@ -299,7 +478,7 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
299 | { | 478 | { |
300 | if (b->buf) | 479 | if (b->buf) |
301 | { | 480 | { |
302 | Free(b->buf); | 481 | OPENSSL_free(b->buf); |
303 | b->buf = NULL; | 482 | b->buf = NULL; |
304 | } | 483 | } |
305 | b->size = new_size; | 484 | b->size = new_size; |
@@ -309,7 +488,8 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
309 | break; | 488 | break; |
310 | 489 | ||
311 | case BIO_C_GET_WRITE_BUF_SIZE: | 490 | case BIO_C_GET_WRITE_BUF_SIZE: |
312 | num = (long) b->size; | 491 | ret = (long) b->size; |
492 | break; | ||
313 | 493 | ||
314 | case BIO_C_MAKE_BIO_PAIR: | 494 | case BIO_C_MAKE_BIO_PAIR: |
315 | { | 495 | { |
@@ -331,7 +511,7 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
331 | 511 | ||
332 | case BIO_C_GET_WRITE_GUARANTEE: | 512 | case BIO_C_GET_WRITE_GUARANTEE: |
333 | /* How many bytes can the caller feed to the next write | 513 | /* How many bytes can the caller feed to the next write |
334 | * withouth having to keep any? */ | 514 | * without having to keep any? */ |
335 | if (b->peer == NULL || b->closed) | 515 | if (b->peer == NULL || b->closed) |
336 | ret = 0; | 516 | ret = 0; |
337 | else | 517 | else |
@@ -339,18 +519,47 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
339 | break; | 519 | break; |
340 | 520 | ||
341 | case BIO_C_GET_READ_REQUEST: | 521 | case BIO_C_GET_READ_REQUEST: |
342 | /* If the peer unsuccesfully tried to read, how many bytes | 522 | /* If the peer unsuccessfully tried to read, how many bytes |
343 | * were requested? (As with BIO_CTRL_PENDING, that number | 523 | * were requested? (As with BIO_CTRL_PENDING, that number |
344 | * can usually be treated as boolean.) */ | 524 | * can usually be treated as boolean.) */ |
345 | ret = (long) b->request; | 525 | ret = (long) b->request; |
346 | break; | 526 | break; |
347 | 527 | ||
528 | case BIO_C_RESET_READ_REQUEST: | ||
529 | /* Reset request. (Can be useful after read attempts | ||
530 | * at the other side that are meant to be non-blocking, | ||
531 | * e.g. when probing SSL_read to see if any data is | ||
532 | * available.) */ | ||
533 | b->request = 0; | ||
534 | ret = 1; | ||
535 | break; | ||
536 | |||
348 | case BIO_C_SHUTDOWN_WR: | 537 | case BIO_C_SHUTDOWN_WR: |
349 | /* similar to shutdown(..., SHUT_WR) */ | 538 | /* similar to shutdown(..., SHUT_WR) */ |
350 | b->closed = 1; | 539 | b->closed = 1; |
351 | ret = 1; | 540 | ret = 1; |
352 | break; | 541 | break; |
353 | 542 | ||
543 | case BIO_C_NREAD0: | ||
544 | /* prepare for non-copying read */ | ||
545 | ret = (long) bio_nread0(bio, ptr); | ||
546 | break; | ||
547 | |||
548 | case BIO_C_NREAD: | ||
549 | /* non-copying read */ | ||
550 | ret = (long) bio_nread(bio, ptr, (size_t) num); | ||
551 | break; | ||
552 | |||
553 | case BIO_C_NWRITE0: | ||
554 | /* prepare for non-copying write */ | ||
555 | ret = (long) bio_nwrite0(bio, ptr); | ||
556 | break; | ||
557 | |||
558 | case BIO_C_NWRITE: | ||
559 | /* non-copying write */ | ||
560 | ret = (long) bio_nwrite(bio, ptr, (size_t) num); | ||
561 | break; | ||
562 | |||
354 | 563 | ||
355 | /* standard CTRL codes follow */ | 564 | /* standard CTRL codes follow */ |
356 | 565 | ||
@@ -434,7 +643,7 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
434 | return ret; | 643 | return ret; |
435 | } | 644 | } |
436 | 645 | ||
437 | static int bio_puts(BIO *bio, char *str) | 646 | static int bio_puts(BIO *bio, const char *str) |
438 | { | 647 | { |
439 | return bio_write(bio, str, strlen(str)); | 648 | return bio_write(bio, str, strlen(str)); |
440 | } | 649 | } |
@@ -458,7 +667,7 @@ static int bio_make_pair(BIO *bio1, BIO *bio2) | |||
458 | 667 | ||
459 | if (b1->buf == NULL) | 668 | if (b1->buf == NULL) |
460 | { | 669 | { |
461 | b1->buf = Malloc(b1->size); | 670 | b1->buf = OPENSSL_malloc(b1->size); |
462 | if (b1->buf == NULL) | 671 | if (b1->buf == NULL) |
463 | { | 672 | { |
464 | BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); | 673 | BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); |
@@ -470,7 +679,7 @@ static int bio_make_pair(BIO *bio1, BIO *bio2) | |||
470 | 679 | ||
471 | if (b2->buf == NULL) | 680 | if (b2->buf == NULL) |
472 | { | 681 | { |
473 | b2->buf = Malloc(b2->size); | 682 | b2->buf = OPENSSL_malloc(b2->size); |
474 | if (b2->buf == NULL) | 683 | if (b2->buf == NULL) |
475 | { | 684 | { |
476 | BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); | 685 | BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); |
@@ -586,3 +795,78 @@ size_t BIO_ctrl_get_read_request(BIO *bio) | |||
586 | { | 795 | { |
587 | return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); | 796 | return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); |
588 | } | 797 | } |
798 | |||
799 | int BIO_ctrl_reset_read_request(BIO *bio) | ||
800 | { | ||
801 | return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); | ||
802 | } | ||
803 | |||
804 | |||
805 | /* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now | ||
806 | * (conceivably some other BIOs could allow non-copying reads and writes too.) | ||
807 | */ | ||
808 | int BIO_nread0(BIO *bio, char **buf) | ||
809 | { | ||
810 | long ret; | ||
811 | |||
812 | if (!bio->init) | ||
813 | { | ||
814 | BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); | ||
815 | return -2; | ||
816 | } | ||
817 | |||
818 | ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); | ||
819 | if (ret > INT_MAX) | ||
820 | return INT_MAX; | ||
821 | else | ||
822 | return (int) ret; | ||
823 | } | ||
824 | |||
825 | int BIO_nread(BIO *bio, char **buf, int num) | ||
826 | { | ||
827 | int ret; | ||
828 | |||
829 | if (!bio->init) | ||
830 | { | ||
831 | BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); | ||
832 | return -2; | ||
833 | } | ||
834 | |||
835 | ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf); | ||
836 | if (ret > 0) | ||
837 | bio->num_read += ret; | ||
838 | return ret; | ||
839 | } | ||
840 | |||
841 | int BIO_nwrite0(BIO *bio, char **buf) | ||
842 | { | ||
843 | long ret; | ||
844 | |||
845 | if (!bio->init) | ||
846 | { | ||
847 | BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); | ||
848 | return -2; | ||
849 | } | ||
850 | |||
851 | ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); | ||
852 | if (ret > INT_MAX) | ||
853 | return INT_MAX; | ||
854 | else | ||
855 | return (int) ret; | ||
856 | } | ||
857 | |||
858 | int BIO_nwrite(BIO *bio, char **buf, int num) | ||
859 | { | ||
860 | int ret; | ||
861 | |||
862 | if (!bio->init) | ||
863 | { | ||
864 | BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); | ||
865 | return -2; | ||
866 | } | ||
867 | |||
868 | ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); | ||
869 | if (ret > 0) | ||
870 | bio->num_read += ret; | ||
871 | return ret; | ||
872 | } | ||