diff options
author | beck <> | 2000-03-19 11:13:58 +0000 |
---|---|---|
committer | beck <> | 2000-03-19 11:13:58 +0000 |
commit | 796d609550df3a33fc11468741c5d2f6d3df4c11 (patch) | |
tree | 6c6d539061caa20372dad0ac4ddb1dfae2fbe7fe /src/lib/libcrypto/bio/bss_bio.c | |
parent | 5be3114c1fd7e0dfea1e38d3abb4cbba75244419 (diff) | |
download | openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.gz openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.bz2 openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.zip |
OpenSSL 0.9.5 merge
*warning* this bumps shared lib minors for libssl and libcrypto from 2.1 to 2.2
if you are using the ssl26 packages for ssh and other things to work you will
need to get new ones (see ~beck/libsslsnap/<arch>) on cvs or ~beck/src-patent.tar.gz on cvs
Diffstat (limited to 'src/lib/libcrypto/bio/bss_bio.c')
-rw-r--r-- | src/lib/libcrypto/bio/bss_bio.c | 256 |
1 files changed, 252 insertions, 4 deletions
diff --git a/src/lib/libcrypto/bio/bss_bio.c b/src/lib/libcrypto/bio/bss_bio.c index 562e9d8de2..0d0f9356f7 100644 --- a/src/lib/libcrypto/bio/bss_bio.c +++ b/src/lib/libcrypto/bio/bss_bio.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #endif | 13 | #endif |
14 | 14 | ||
15 | #include <assert.h> | 15 | #include <assert.h> |
16 | #include <limits.h> | ||
16 | #include <stdlib.h> | 17 | #include <stdlib.h> |
17 | #include <string.h> | 18 | #include <string.h> |
18 | 19 | ||
@@ -40,7 +41,8 @@ static BIO_METHOD methods_biop = | |||
40 | NULL /* no bio_gets */, | 41 | NULL /* no bio_gets */, |
41 | bio_ctrl, | 42 | bio_ctrl, |
42 | bio_new, | 43 | bio_new, |
43 | bio_free | 44 | bio_free, |
45 | NULL /* no bio_callback_ctrl */ | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | BIO_METHOD *BIO_s_bio(void) | 48 | BIO_METHOD *BIO_s_bio(void) |
@@ -64,7 +66,7 @@ struct bio_bio_st | |||
64 | 66 | ||
65 | size_t request; /* valid iff peer != NULL; 0 if len != 0, | 67 | size_t request; /* valid iff peer != NULL; 0 if len != 0, |
66 | * otherwise set by peer to number of bytes | 68 | * otherwise set by peer to number of bytes |
67 | * it (unsuccesfully) tried to read, | 69 | * it (unsuccessfully) tried to read, |
68 | * never more than buffer space (size-len) warrants. */ | 70 | * never more than buffer space (size-len) warrants. */ |
69 | }; | 71 | }; |
70 | 72 | ||
@@ -195,6 +197,81 @@ static int bio_read(BIO *bio, char *buf, int size_) | |||
195 | return size; | 197 | return size; |
196 | } | 198 | } |
197 | 199 | ||
200 | /* non-copying interface: provide pointer to available data in buffer | ||
201 | * bio_nread0: return number of available bytes | ||
202 | * bio_nread: also advance index | ||
203 | * (example usage: bio_nread0(), read from buffer, bio_nread() | ||
204 | * or just bio_nread(), read from buffer) | ||
205 | */ | ||
206 | /* WARNING: The non-copying interface is largely untested as of yet | ||
207 | * and may contain bugs. */ | ||
208 | static size_t bio_nread0(BIO *bio, char **buf) | ||
209 | { | ||
210 | struct bio_bio_st *b, *peer_b; | ||
211 | size_t num; | ||
212 | |||
213 | BIO_clear_retry_flags(bio); | ||
214 | |||
215 | if (!bio->init) | ||
216 | return 0; | ||
217 | |||
218 | b = bio->ptr; | ||
219 | assert(b != NULL); | ||
220 | assert(b->peer != NULL); | ||
221 | peer_b = b->peer->ptr; | ||
222 | assert(peer_b != NULL); | ||
223 | assert(peer_b->buf != NULL); | ||
224 | |||
225 | peer_b->request = 0; | ||
226 | |||
227 | if (peer_b->len == 0) | ||
228 | { | ||
229 | char dummy; | ||
230 | |||
231 | /* avoid code duplication -- nothing available for reading */ | ||
232 | return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ | ||
233 | } | ||
234 | |||
235 | num = peer_b->len; | ||
236 | if (peer_b->size < peer_b->offset + num) | ||
237 | /* no ring buffer wrap-around for non-copying interface */ | ||
238 | num = peer_b->size - peer_b->offset; | ||
239 | assert(num > 0); | ||
240 | |||
241 | if (buf != NULL) | ||
242 | *buf = peer_b->buf + peer_b->offset; | ||
243 | return num; | ||
244 | } | ||
245 | |||
246 | static size_t bio_nread(BIO *bio, char **buf, size_t num) | ||
247 | { | ||
248 | struct bio_bio_st *b, *peer_b; | ||
249 | size_t available; | ||
250 | |||
251 | available = bio_nread0(bio, buf); | ||
252 | if (num > available) | ||
253 | num = available; | ||
254 | if (num == 0) | ||
255 | return num; | ||
256 | |||
257 | b = bio->ptr; | ||
258 | peer_b = b->peer->ptr; | ||
259 | |||
260 | peer_b->len -= num; | ||
261 | if (peer_b->len) | ||
262 | { | ||
263 | peer_b->offset += num; | ||
264 | assert(peer_b->offset <= peer_b->size); | ||
265 | if (peer_b->offset == peer_b->size) | ||
266 | peer_b->offset = 0; | ||
267 | } | ||
268 | else | ||
269 | peer_b->offset = 0; | ||
270 | |||
271 | return num; | ||
272 | } | ||
273 | |||
274 | |||
198 | static int bio_write(BIO *bio, char *buf, int num_) | 275 | static int bio_write(BIO *bio, char *buf, int num_) |
199 | { | 276 | { |
200 | size_t num = num_; | 277 | size_t num = num_; |
@@ -268,6 +345,78 @@ static int bio_write(BIO *bio, char *buf, int num_) | |||
268 | return num; | 345 | return num; |
269 | } | 346 | } |
270 | 347 | ||
348 | /* non-copying interface: provide pointer to region to write to | ||
349 | * bio_nwrite0: check how much space is available | ||
350 | * bio_nwrite: also increase length | ||
351 | * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() | ||
352 | * or just bio_nwrite(), write to buffer) | ||
353 | */ | ||
354 | static size_t bio_nwrite0(BIO *bio, char **buf) | ||
355 | { | ||
356 | struct bio_bio_st *b; | ||
357 | size_t num; | ||
358 | size_t write_offset; | ||
359 | |||
360 | BIO_clear_retry_flags(bio); | ||
361 | |||
362 | if (!bio->init) | ||
363 | return 0; | ||
364 | |||
365 | b = bio->ptr; | ||
366 | assert(b != NULL); | ||
367 | assert(b->peer != NULL); | ||
368 | assert(b->buf != NULL); | ||
369 | |||
370 | b->request = 0; | ||
371 | if (b->closed) | ||
372 | { | ||
373 | BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); | ||
374 | return -1; | ||
375 | } | ||
376 | |||
377 | assert(b->len <= b->size); | ||
378 | |||
379 | if (b->len == b->size) | ||
380 | { | ||
381 | BIO_set_retry_write(bio); | ||
382 | return -1; | ||
383 | } | ||
384 | |||
385 | num = b->size - b->len; | ||
386 | write_offset = b->offset + b->len; | ||
387 | if (write_offset >= b->size) | ||
388 | write_offset -= b->size; | ||
389 | if (write_offset + num > b->size) | ||
390 | /* no ring buffer wrap-around for non-copying interface | ||
391 | * (to fulfil the promise by BIO_ctrl_get_write_guarantee, | ||
392 | * BIO_nwrite may have to be called twice) */ | ||
393 | num = b->size - write_offset; | ||
394 | |||
395 | if (buf != NULL) | ||
396 | *buf = b->buf + write_offset; | ||
397 | assert(write_offset + num <= b->size); | ||
398 | |||
399 | return num; | ||
400 | } | ||
401 | |||
402 | static size_t bio_nwrite(BIO *bio, char **buf, size_t num) | ||
403 | { | ||
404 | struct bio_bio_st *b; | ||
405 | size_t space; | ||
406 | |||
407 | space = bio_nwrite0(bio, buf); | ||
408 | if (num > space) | ||
409 | num = space; | ||
410 | if (num == 0) | ||
411 | return num; | ||
412 | b = bio->ptr; | ||
413 | assert(b != NULL); | ||
414 | b->len += num; | ||
415 | assert(b->len <= b->size); | ||
416 | |||
417 | return num; | ||
418 | } | ||
419 | |||
271 | 420 | ||
272 | static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | 421 | static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) |
273 | { | 422 | { |
@@ -331,7 +480,7 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
331 | 480 | ||
332 | case BIO_C_GET_WRITE_GUARANTEE: | 481 | case BIO_C_GET_WRITE_GUARANTEE: |
333 | /* How many bytes can the caller feed to the next write | 482 | /* How many bytes can the caller feed to the next write |
334 | * withouth having to keep any? */ | 483 | * without having to keep any? */ |
335 | if (b->peer == NULL || b->closed) | 484 | if (b->peer == NULL || b->closed) |
336 | ret = 0; | 485 | ret = 0; |
337 | else | 486 | else |
@@ -339,18 +488,42 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
339 | break; | 488 | break; |
340 | 489 | ||
341 | case BIO_C_GET_READ_REQUEST: | 490 | case BIO_C_GET_READ_REQUEST: |
342 | /* If the peer unsuccesfully tried to read, how many bytes | 491 | /* If the peer unsuccessfully tried to read, how many bytes |
343 | * were requested? (As with BIO_CTRL_PENDING, that number | 492 | * were requested? (As with BIO_CTRL_PENDING, that number |
344 | * can usually be treated as boolean.) */ | 493 | * can usually be treated as boolean.) */ |
345 | ret = (long) b->request; | 494 | ret = (long) b->request; |
346 | break; | 495 | break; |
347 | 496 | ||
497 | case BIO_C_RESET_READ_REQUEST: | ||
498 | /* Reset request. (Can be useful after read attempts | ||
499 | * at the other side that are meant to be non-blocking, | ||
500 | * e.g. when probing SSL_read to see if any data is | ||
501 | * available.) */ | ||
502 | b->request = 0; | ||
503 | ret = 1; | ||
504 | break; | ||
505 | |||
348 | case BIO_C_SHUTDOWN_WR: | 506 | case BIO_C_SHUTDOWN_WR: |
349 | /* similar to shutdown(..., SHUT_WR) */ | 507 | /* similar to shutdown(..., SHUT_WR) */ |
350 | b->closed = 1; | 508 | b->closed = 1; |
351 | ret = 1; | 509 | ret = 1; |
352 | break; | 510 | break; |
353 | 511 | ||
512 | case BIO_C_NREAD: | ||
513 | /* non-copying read */ | ||
514 | ret = (long) bio_nread(bio, ptr, (size_t) num); | ||
515 | break; | ||
516 | |||
517 | case BIO_C_NWRITE0: | ||
518 | /* prepare for non-copying write */ | ||
519 | ret = (long) bio_nwrite0(bio, ptr); | ||
520 | break; | ||
521 | |||
522 | case BIO_C_NWRITE: | ||
523 | /* non-copying write */ | ||
524 | ret = (long) bio_nwrite(bio, ptr, (size_t) num); | ||
525 | break; | ||
526 | |||
354 | 527 | ||
355 | /* standard CTRL codes follow */ | 528 | /* standard CTRL codes follow */ |
356 | 529 | ||
@@ -586,3 +759,78 @@ size_t BIO_ctrl_get_read_request(BIO *bio) | |||
586 | { | 759 | { |
587 | return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); | 760 | return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); |
588 | } | 761 | } |
762 | |||
763 | int BIO_ctrl_reset_read_request(BIO *bio) | ||
764 | { | ||
765 | return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); | ||
766 | } | ||
767 | |||
768 | |||
769 | /* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now | ||
770 | * (conceivably some other BIOs could allow non-copying reads and writes too.) | ||
771 | */ | ||
772 | int BIO_nread0(BIO *bio, char **buf) | ||
773 | { | ||
774 | long ret; | ||
775 | |||
776 | if (!bio->init) | ||
777 | { | ||
778 | BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); | ||
779 | return -2; | ||
780 | } | ||
781 | |||
782 | ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); | ||
783 | if (ret > INT_MAX) | ||
784 | return INT_MAX; | ||
785 | else | ||
786 | return (int) ret; | ||
787 | } | ||
788 | |||
789 | int BIO_nread(BIO *bio, char **buf, int num) | ||
790 | { | ||
791 | int ret; | ||
792 | |||
793 | if (!bio->init) | ||
794 | { | ||
795 | BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); | ||
796 | return -2; | ||
797 | } | ||
798 | |||
799 | ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf); | ||
800 | if (ret > 0) | ||
801 | bio->num_read += ret; | ||
802 | return ret; | ||
803 | } | ||
804 | |||
805 | int BIO_nwrite0(BIO *bio, char **buf) | ||
806 | { | ||
807 | long ret; | ||
808 | |||
809 | if (!bio->init) | ||
810 | { | ||
811 | BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); | ||
812 | return -2; | ||
813 | } | ||
814 | |||
815 | ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); | ||
816 | if (ret > INT_MAX) | ||
817 | return INT_MAX; | ||
818 | else | ||
819 | return (int) ret; | ||
820 | } | ||
821 | |||
822 | int BIO_nwrite(BIO *bio, char **buf, int num) | ||
823 | { | ||
824 | int ret; | ||
825 | |||
826 | if (!bio->init) | ||
827 | { | ||
828 | BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); | ||
829 | return -2; | ||
830 | } | ||
831 | |||
832 | ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); | ||
833 | if (ret > 0) | ||
834 | bio->num_read += ret; | ||
835 | return ret; | ||
836 | } | ||