summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bio/bss_bio.c
diff options
context:
space:
mode:
authorbeck <>2000-03-19 11:13:58 +0000
committerbeck <>2000-03-19 11:13:58 +0000
commit796d609550df3a33fc11468741c5d2f6d3df4c11 (patch)
tree6c6d539061caa20372dad0ac4ddb1dfae2fbe7fe /src/lib/libcrypto/bio/bss_bio.c
parent5be3114c1fd7e0dfea1e38d3abb4cbba75244419 (diff)
downloadopenbsd-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.c256
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
46BIO_METHOD *BIO_s_bio(void) 48BIO_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. */
208static 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
246static 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
198static int bio_write(BIO *bio, char *buf, int num_) 275static 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 */
354static 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
402static 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
272static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) 421static 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
763int 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 */
772int 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
789int 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
805int 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
822int 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 }