xref: /freebsd/crypto/openssl/crypto/bio/bss_bio.c (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1 /*
2  * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 /*
11  * Special method for a BIO where the other endpoint is also a BIO of this
12  * kind, handled by the same thread (i.e. the "peer" is actually ourselves,
13  * wearing a different hat). Such "BIO pairs" are mainly for using the SSL
14  * library with I/O interfaces for which no specific BIO method is available.
15  * See ssl/ssltest.c for some hints on how this can be used.
16  */
17 
18 #include "e_os.h"
19 #include <assert.h>
20 #include <limits.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "bio_lcl.h"
25 #include <openssl/err.h>
26 #include <openssl/crypto.h>
27 
28 static int bio_new(BIO *bio);
29 static int bio_free(BIO *bio);
30 static int bio_read(BIO *bio, char *buf, int size);
31 static int bio_write(BIO *bio, const char *buf, int num);
32 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
33 static int bio_puts(BIO *bio, const char *str);
34 
35 static int bio_make_pair(BIO *bio1, BIO *bio2);
36 static void bio_destroy_pair(BIO *bio);
37 
38 static const BIO_METHOD methods_biop = {
39     BIO_TYPE_BIO,
40     "BIO pair",
41     /* TODO: Convert to new style write function */
42     bwrite_conv,
43     bio_write,
44     /* TODO: Convert to new style read function */
45     bread_conv,
46     bio_read,
47     bio_puts,
48     NULL /* no bio_gets */ ,
49     bio_ctrl,
50     bio_new,
51     bio_free,
52     NULL                        /* no bio_callback_ctrl */
53 };
54 
55 const BIO_METHOD *BIO_s_bio(void)
56 {
57     return &methods_biop;
58 }
59 
60 struct bio_bio_st {
61     BIO *peer;                  /* NULL if buf == NULL. If peer != NULL, then
62                                  * peer->ptr is also a bio_bio_st, and its
63                                  * "peer" member points back to us. peer !=
64                                  * NULL iff init != 0 in the BIO. */
65     /* This is for what we write (i.e. reading uses peer's struct): */
66     int closed;                 /* valid iff peer != NULL */
67     size_t len;                 /* valid iff buf != NULL; 0 if peer == NULL */
68     size_t offset;              /* valid iff buf != NULL; 0 if len == 0 */
69     size_t size;
70     char *buf;                  /* "size" elements (if != NULL) */
71     size_t request;             /* valid iff peer != NULL; 0 if len != 0,
72                                  * otherwise set by peer to number of bytes
73                                  * it (unsuccessfully) tried to read, never
74                                  * more than buffer space (size-len)
75                                  * warrants. */
76 };
77 
78 static int bio_new(BIO *bio)
79 {
80     struct bio_bio_st *b = OPENSSL_zalloc(sizeof(*b));
81 
82     if (b == NULL)
83         return 0;
84 
85     /* enough for one TLS record (just a default) */
86     b->size = 17 * 1024;
87 
88     bio->ptr = b;
89     return 1;
90 }
91 
92 static int bio_free(BIO *bio)
93 {
94     struct bio_bio_st *b;
95 
96     if (bio == NULL)
97         return 0;
98     b = bio->ptr;
99 
100     assert(b != NULL);
101 
102     if (b->peer)
103         bio_destroy_pair(bio);
104 
105     OPENSSL_free(b->buf);
106     OPENSSL_free(b);
107 
108     return 1;
109 }
110 
111 static int bio_read(BIO *bio, char *buf, int size_)
112 {
113     size_t size = size_;
114     size_t rest;
115     struct bio_bio_st *b, *peer_b;
116 
117     BIO_clear_retry_flags(bio);
118 
119     if (!bio->init)
120         return 0;
121 
122     b = bio->ptr;
123     assert(b != NULL);
124     assert(b->peer != NULL);
125     peer_b = b->peer->ptr;
126     assert(peer_b != NULL);
127     assert(peer_b->buf != NULL);
128 
129     peer_b->request = 0;        /* will be set in "retry_read" situation */
130 
131     if (buf == NULL || size == 0)
132         return 0;
133 
134     if (peer_b->len == 0) {
135         if (peer_b->closed)
136             return 0;           /* writer has closed, and no data is left */
137         else {
138             BIO_set_retry_read(bio); /* buffer is empty */
139             if (size <= peer_b->size)
140                 peer_b->request = size;
141             else
142                 /*
143                  * don't ask for more than the peer can deliver in one write
144                  */
145                 peer_b->request = peer_b->size;
146             return -1;
147         }
148     }
149 
150     /* we can read */
151     if (peer_b->len < size)
152         size = peer_b->len;
153 
154     /* now read "size" bytes */
155 
156     rest = size;
157 
158     assert(rest > 0);
159     do {                        /* one or two iterations */
160         size_t chunk;
161 
162         assert(rest <= peer_b->len);
163         if (peer_b->offset + rest <= peer_b->size)
164             chunk = rest;
165         else
166             /* wrap around ring buffer */
167             chunk = peer_b->size - peer_b->offset;
168         assert(peer_b->offset + chunk <= peer_b->size);
169 
170         memcpy(buf, peer_b->buf + peer_b->offset, chunk);
171 
172         peer_b->len -= chunk;
173         if (peer_b->len) {
174             peer_b->offset += chunk;
175             assert(peer_b->offset <= peer_b->size);
176             if (peer_b->offset == peer_b->size)
177                 peer_b->offset = 0;
178             buf += chunk;
179         } else {
180             /* buffer now empty, no need to advance "buf" */
181             assert(chunk == rest);
182             peer_b->offset = 0;
183         }
184         rest -= chunk;
185     }
186     while (rest);
187 
188     return size;
189 }
190 
191 /*-
192  * non-copying interface: provide pointer to available data in buffer
193  *    bio_nread0:  return number of available bytes
194  *    bio_nread:   also advance index
195  * (example usage:  bio_nread0(), read from buffer, bio_nread()
196  *  or just         bio_nread(), read from buffer)
197  */
198 /*
199  * WARNING: The non-copying interface is largely untested as of yet and may
200  * contain bugs.
201  */
202 static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
203 {
204     struct bio_bio_st *b, *peer_b;
205     ossl_ssize_t num;
206 
207     BIO_clear_retry_flags(bio);
208 
209     if (!bio->init)
210         return 0;
211 
212     b = bio->ptr;
213     assert(b != NULL);
214     assert(b->peer != NULL);
215     peer_b = b->peer->ptr;
216     assert(peer_b != NULL);
217     assert(peer_b->buf != NULL);
218 
219     peer_b->request = 0;
220 
221     if (peer_b->len == 0) {
222         char dummy;
223 
224         /* avoid code duplication -- nothing available for reading */
225         return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
226     }
227 
228     num = peer_b->len;
229     if (peer_b->size < peer_b->offset + num)
230         /* no ring buffer wrap-around for non-copying interface */
231         num = peer_b->size - peer_b->offset;
232     assert(num > 0);
233 
234     if (buf != NULL)
235         *buf = peer_b->buf + peer_b->offset;
236     return num;
237 }
238 
239 static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
240 {
241     struct bio_bio_st *b, *peer_b;
242     ossl_ssize_t num, available;
243 
244     if (num_ > OSSL_SSIZE_MAX)
245         num = OSSL_SSIZE_MAX;
246     else
247         num = (ossl_ssize_t) num_;
248 
249     available = bio_nread0(bio, buf);
250     if (num > available)
251         num = available;
252     if (num <= 0)
253         return num;
254 
255     b = bio->ptr;
256     peer_b = b->peer->ptr;
257 
258     peer_b->len -= num;
259     if (peer_b->len) {
260         peer_b->offset += num;
261         assert(peer_b->offset <= peer_b->size);
262         if (peer_b->offset == peer_b->size)
263             peer_b->offset = 0;
264     } else
265         peer_b->offset = 0;
266 
267     return num;
268 }
269 
270 static int bio_write(BIO *bio, const char *buf, int num_)
271 {
272     size_t num = num_;
273     size_t rest;
274     struct bio_bio_st *b;
275 
276     BIO_clear_retry_flags(bio);
277 
278     if (!bio->init || buf == NULL || num == 0)
279         return 0;
280 
281     b = bio->ptr;
282     assert(b != NULL);
283     assert(b->peer != NULL);
284     assert(b->buf != NULL);
285 
286     b->request = 0;
287     if (b->closed) {
288         /* we already closed */
289         BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
290         return -1;
291     }
292 
293     assert(b->len <= b->size);
294 
295     if (b->len == b->size) {
296         BIO_set_retry_write(bio); /* buffer is full */
297         return -1;
298     }
299 
300     /* we can write */
301     if (num > b->size - b->len)
302         num = b->size - b->len;
303 
304     /* now write "num" bytes */
305 
306     rest = num;
307 
308     assert(rest > 0);
309     do {                        /* one or two iterations */
310         size_t write_offset;
311         size_t chunk;
312 
313         assert(b->len + rest <= b->size);
314 
315         write_offset = b->offset + b->len;
316         if (write_offset >= b->size)
317             write_offset -= b->size;
318         /* b->buf[write_offset] is the first byte we can write to. */
319 
320         if (write_offset + rest <= b->size)
321             chunk = rest;
322         else
323             /* wrap around ring buffer */
324             chunk = b->size - write_offset;
325 
326         memcpy(b->buf + write_offset, buf, chunk);
327 
328         b->len += chunk;
329 
330         assert(b->len <= b->size);
331 
332         rest -= chunk;
333         buf += chunk;
334     }
335     while (rest);
336 
337     return num;
338 }
339 
340 /*-
341  * non-copying interface: provide pointer to region to write to
342  *   bio_nwrite0:  check how much space is available
343  *   bio_nwrite:   also increase length
344  * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
345  *  or just         bio_nwrite(), write to buffer)
346  */
347 static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
348 {
349     struct bio_bio_st *b;
350     size_t num;
351     size_t write_offset;
352 
353     BIO_clear_retry_flags(bio);
354 
355     if (!bio->init)
356         return 0;
357 
358     b = bio->ptr;
359     assert(b != NULL);
360     assert(b->peer != NULL);
361     assert(b->buf != NULL);
362 
363     b->request = 0;
364     if (b->closed) {
365         BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
366         return -1;
367     }
368 
369     assert(b->len <= b->size);
370 
371     if (b->len == b->size) {
372         BIO_set_retry_write(bio);
373         return -1;
374     }
375 
376     num = b->size - b->len;
377     write_offset = b->offset + b->len;
378     if (write_offset >= b->size)
379         write_offset -= b->size;
380     if (write_offset + num > b->size)
381         /*
382          * no ring buffer wrap-around for non-copying interface (to fulfil
383          * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have
384          * to be called twice)
385          */
386         num = b->size - write_offset;
387 
388     if (buf != NULL)
389         *buf = b->buf + write_offset;
390     assert(write_offset + num <= b->size);
391 
392     return num;
393 }
394 
395 static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
396 {
397     struct bio_bio_st *b;
398     ossl_ssize_t num, space;
399 
400     if (num_ > OSSL_SSIZE_MAX)
401         num = OSSL_SSIZE_MAX;
402     else
403         num = (ossl_ssize_t) num_;
404 
405     space = bio_nwrite0(bio, buf);
406     if (num > space)
407         num = space;
408     if (num <= 0)
409         return num;
410     b = bio->ptr;
411     assert(b != NULL);
412     b->len += num;
413     assert(b->len <= b->size);
414 
415     return num;
416 }
417 
418 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
419 {
420     long ret;
421     struct bio_bio_st *b = bio->ptr;
422 
423     assert(b != NULL);
424 
425     switch (cmd) {
426         /* specific CTRL codes */
427 
428     case BIO_C_SET_WRITE_BUF_SIZE:
429         if (b->peer) {
430             BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
431             ret = 0;
432         } else if (num == 0) {
433             BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
434             ret = 0;
435         } else {
436             size_t new_size = num;
437 
438             if (b->size != new_size) {
439                 OPENSSL_free(b->buf);
440                 b->buf = NULL;
441                 b->size = new_size;
442             }
443             ret = 1;
444         }
445         break;
446 
447     case BIO_C_GET_WRITE_BUF_SIZE:
448         ret = (long)b->size;
449         break;
450 
451     case BIO_C_MAKE_BIO_PAIR:
452         {
453             BIO *other_bio = ptr;
454 
455             if (bio_make_pair(bio, other_bio))
456                 ret = 1;
457             else
458                 ret = 0;
459         }
460         break;
461 
462     case BIO_C_DESTROY_BIO_PAIR:
463         /*
464          * Affects both BIOs in the pair -- call just once! Or let
465          * BIO_free(bio1); BIO_free(bio2); do the job.
466          */
467         bio_destroy_pair(bio);
468         ret = 1;
469         break;
470 
471     case BIO_C_GET_WRITE_GUARANTEE:
472         /*
473          * How many bytes can the caller feed to the next write without
474          * having to keep any?
475          */
476         if (b->peer == NULL || b->closed)
477             ret = 0;
478         else
479             ret = (long)b->size - b->len;
480         break;
481 
482     case BIO_C_GET_READ_REQUEST:
483         /*
484          * If the peer unsuccessfully tried to read, how many bytes were
485          * requested? (As with BIO_CTRL_PENDING, that number can usually be
486          * treated as boolean.)
487          */
488         ret = (long)b->request;
489         break;
490 
491     case BIO_C_RESET_READ_REQUEST:
492         /*
493          * Reset request.  (Can be useful after read attempts at the other
494          * side that are meant to be non-blocking, e.g. when probing SSL_read
495          * to see if any data is available.)
496          */
497         b->request = 0;
498         ret = 1;
499         break;
500 
501     case BIO_C_SHUTDOWN_WR:
502         /* similar to shutdown(..., SHUT_WR) */
503         b->closed = 1;
504         ret = 1;
505         break;
506 
507     case BIO_C_NREAD0:
508         /* prepare for non-copying read */
509         ret = (long)bio_nread0(bio, ptr);
510         break;
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 
527         /* standard CTRL codes follow */
528 
529     case BIO_CTRL_RESET:
530         if (b->buf != NULL) {
531             b->len = 0;
532             b->offset = 0;
533         }
534         ret = 0;
535         break;
536 
537     case BIO_CTRL_GET_CLOSE:
538         ret = bio->shutdown;
539         break;
540 
541     case BIO_CTRL_SET_CLOSE:
542         bio->shutdown = (int)num;
543         ret = 1;
544         break;
545 
546     case BIO_CTRL_PENDING:
547         if (b->peer != NULL) {
548             struct bio_bio_st *peer_b = b->peer->ptr;
549 
550             ret = (long)peer_b->len;
551         } else
552             ret = 0;
553         break;
554 
555     case BIO_CTRL_WPENDING:
556         if (b->buf != NULL)
557             ret = (long)b->len;
558         else
559             ret = 0;
560         break;
561 
562     case BIO_CTRL_DUP:
563         /* See BIO_dup_chain for circumstances we have to expect. */
564         {
565             BIO *other_bio = ptr;
566             struct bio_bio_st *other_b;
567 
568             assert(other_bio != NULL);
569             other_b = other_bio->ptr;
570             assert(other_b != NULL);
571 
572             assert(other_b->buf == NULL); /* other_bio is always fresh */
573 
574             other_b->size = b->size;
575         }
576 
577         ret = 1;
578         break;
579 
580     case BIO_CTRL_FLUSH:
581         ret = 1;
582         break;
583 
584     case BIO_CTRL_EOF:
585         if (b->peer != NULL) {
586             struct bio_bio_st *peer_b = b->peer->ptr;
587 
588             if (peer_b->len == 0 && peer_b->closed)
589                 ret = 1;
590             else
591                 ret = 0;
592         } else {
593             ret = 1;
594         }
595         break;
596 
597     default:
598         ret = 0;
599     }
600     return ret;
601 }
602 
603 static int bio_puts(BIO *bio, const char *str)
604 {
605     return bio_write(bio, str, strlen(str));
606 }
607 
608 static int bio_make_pair(BIO *bio1, BIO *bio2)
609 {
610     struct bio_bio_st *b1, *b2;
611 
612     assert(bio1 != NULL);
613     assert(bio2 != NULL);
614 
615     b1 = bio1->ptr;
616     b2 = bio2->ptr;
617 
618     if (b1->peer != NULL || b2->peer != NULL) {
619         BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
620         return 0;
621     }
622 
623     if (b1->buf == NULL) {
624         b1->buf = OPENSSL_malloc(b1->size);
625         if (b1->buf == NULL) {
626             BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
627             return 0;
628         }
629         b1->len = 0;
630         b1->offset = 0;
631     }
632 
633     if (b2->buf == NULL) {
634         b2->buf = OPENSSL_malloc(b2->size);
635         if (b2->buf == NULL) {
636             BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
637             return 0;
638         }
639         b2->len = 0;
640         b2->offset = 0;
641     }
642 
643     b1->peer = bio2;
644     b1->closed = 0;
645     b1->request = 0;
646     b2->peer = bio1;
647     b2->closed = 0;
648     b2->request = 0;
649 
650     bio1->init = 1;
651     bio2->init = 1;
652 
653     return 1;
654 }
655 
656 static void bio_destroy_pair(BIO *bio)
657 {
658     struct bio_bio_st *b = bio->ptr;
659 
660     if (b != NULL) {
661         BIO *peer_bio = b->peer;
662 
663         if (peer_bio != NULL) {
664             struct bio_bio_st *peer_b = peer_bio->ptr;
665 
666             assert(peer_b != NULL);
667             assert(peer_b->peer == bio);
668 
669             peer_b->peer = NULL;
670             peer_bio->init = 0;
671             assert(peer_b->buf != NULL);
672             peer_b->len = 0;
673             peer_b->offset = 0;
674 
675             b->peer = NULL;
676             bio->init = 0;
677             assert(b->buf != NULL);
678             b->len = 0;
679             b->offset = 0;
680         }
681     }
682 }
683 
684 /* Exported convenience functions */
685 int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
686                      BIO **bio2_p, size_t writebuf2)
687 {
688     BIO *bio1 = NULL, *bio2 = NULL;
689     long r;
690     int ret = 0;
691 
692     bio1 = BIO_new(BIO_s_bio());
693     if (bio1 == NULL)
694         goto err;
695     bio2 = BIO_new(BIO_s_bio());
696     if (bio2 == NULL)
697         goto err;
698 
699     if (writebuf1) {
700         r = BIO_set_write_buf_size(bio1, writebuf1);
701         if (!r)
702             goto err;
703     }
704     if (writebuf2) {
705         r = BIO_set_write_buf_size(bio2, writebuf2);
706         if (!r)
707             goto err;
708     }
709 
710     r = BIO_make_bio_pair(bio1, bio2);
711     if (!r)
712         goto err;
713     ret = 1;
714 
715  err:
716     if (ret == 0) {
717         BIO_free(bio1);
718         bio1 = NULL;
719         BIO_free(bio2);
720         bio2 = NULL;
721     }
722 
723     *bio1_p = bio1;
724     *bio2_p = bio2;
725     return ret;
726 }
727 
728 size_t BIO_ctrl_get_write_guarantee(BIO *bio)
729 {
730     return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
731 }
732 
733 size_t BIO_ctrl_get_read_request(BIO *bio)
734 {
735     return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
736 }
737 
738 int BIO_ctrl_reset_read_request(BIO *bio)
739 {
740     return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
741 }
742 
743 /*
744  * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
745  * (conceivably some other BIOs could allow non-copying reads and writes
746  * too.)
747  */
748 int BIO_nread0(BIO *bio, char **buf)
749 {
750     long ret;
751 
752     if (!bio->init) {
753         BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
754         return -2;
755     }
756 
757     ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
758     if (ret > INT_MAX)
759         return INT_MAX;
760     else
761         return (int)ret;
762 }
763 
764 int BIO_nread(BIO *bio, char **buf, int num)
765 {
766     int ret;
767 
768     if (!bio->init) {
769         BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
770         return -2;
771     }
772 
773     ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf);
774     if (ret > 0)
775         bio->num_read += ret;
776     return ret;
777 }
778 
779 int BIO_nwrite0(BIO *bio, char **buf)
780 {
781     long ret;
782 
783     if (!bio->init) {
784         BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
785         return -2;
786     }
787 
788     ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
789     if (ret > INT_MAX)
790         return INT_MAX;
791     else
792         return (int)ret;
793 }
794 
795 int BIO_nwrite(BIO *bio, char **buf, int num)
796 {
797     int ret;
798 
799     if (!bio->init) {
800         BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
801         return -2;
802     }
803 
804     ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
805     if (ret > 0)
806         bio->num_write += ret;
807     return ret;
808 }
809