summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bio/bss_bio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bio/bss_bio.c')
-rw-r--r--src/lib/libcrypto/bio/bss_bio.c318
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
23static int bio_new(BIO *bio); 44static int bio_new(BIO *bio);
24static int bio_free(BIO *bio); 45static int bio_free(BIO *bio);
25static int bio_read(BIO *bio, char *buf, int size); 46static int bio_read(BIO *bio, char *buf, int size);
26static int bio_write(BIO *bio, char *buf, int num); 47static int bio_write(BIO *bio, const char *buf, int num);
27static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); 48static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
28static int bio_puts(BIO *bio, char *str); 49static int bio_puts(BIO *bio, const char *str);
29 50
30static int bio_make_pair(BIO *bio1, BIO *bio2); 51static int bio_make_pair(BIO *bio1, BIO *bio2);
31static void bio_destroy_pair(BIO *bio); 52static 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
46BIO_METHOD *BIO_s_bio(void) 68BIO_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
198static 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. */
228static 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
266static 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
300static 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 */
379static 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
427static 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
272static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) 451static 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
437static int bio_puts(BIO *bio, char *str) 646static 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
799int 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 */
808int 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
825int 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
841int 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
858int 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 }