Home | History | Annotate | Download | only in bio
      1 /* ====================================================================
      2  * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in
     13  *    the documentation and/or other materials provided with the
     14  *    distribution.
     15  *
     16  * 3. All advertising materials mentioning features or use of this
     17  *    software must display the following acknowledgment:
     18  *    "This product includes software developed by the OpenSSL Project
     19  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
     20  *
     21  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     22  *    endorse or promote products derived from this software without
     23  *    prior written permission. For written permission, please contact
     24  *    openssl-core (at) openssl.org.
     25  *
     26  * 5. Products derived from this software may not be called "OpenSSL"
     27  *    nor may "OpenSSL" appear in their names without prior written
     28  *    permission of the OpenSSL Project.
     29  *
     30  * 6. Redistributions of any form whatsoever must retain the following
     31  *    acknowledgment:
     32  *    "This product includes software developed by the OpenSSL Project
     33  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
     34  *
     35  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     46  * OF THE POSSIBILITY OF SUCH DAMAGE.
     47  * ====================================================================
     48  *
     49  * This product includes cryptographic software written by Eric Young
     50  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     51  * Hudson (tjh (at) cryptsoft.com). */
     52 
     53 #include <openssl/bio.h>
     54 
     55 #include <assert.h>
     56 
     57 #include <openssl/buf.h>
     58 #include <openssl/err.h>
     59 #include <openssl/mem.h>
     60 
     61 
     62 struct bio_bio_st {
     63   BIO *peer; /* NULL if buf == NULL.
     64               * If peer != NULL, then peer->ptr is also a bio_bio_st,
     65               * and its "peer" member points back to us.
     66               * peer != NULL iff init != 0 in the BIO. */
     67 
     68   /* This is for what we write (i.e. reading uses peer's struct): */
     69   int closed;    /* valid iff peer != NULL */
     70   size_t len;    /* valid iff buf != NULL; 0 if peer == NULL */
     71   size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
     72   size_t size;
     73   char *buf; /* "size" elements (if != NULL) */
     74 
     75   size_t request; /* valid iff peer != NULL; 0 if len != 0,
     76                    * otherwise set by peer to number of bytes
     77                    * it (unsuccessfully) tried to read,
     78                    * never more than buffer space (size-len) warrants. */
     79 };
     80 
     81 static int bio_new(BIO *bio) {
     82   struct bio_bio_st *b;
     83 
     84   b = OPENSSL_malloc(sizeof *b);
     85   if (b == NULL) {
     86     return 0;
     87   }
     88 
     89   b->peer = NULL;
     90   b->size = 17 * 1024; /* enough for one TLS record (just a default) */
     91   b->buf = NULL;
     92 
     93   bio->ptr = b;
     94   return 1;
     95 }
     96 
     97 static void bio_destroy_pair(BIO *bio) {
     98   struct bio_bio_st *b = bio->ptr;
     99   BIO *peer_bio;
    100   struct bio_bio_st *peer_b;
    101 
    102   if (b == NULL) {
    103     return;
    104   }
    105 
    106   peer_bio = b->peer;
    107   if (peer_bio == NULL) {
    108     return;
    109   }
    110 
    111   peer_b = peer_bio->ptr;
    112 
    113   assert(peer_b != NULL);
    114   assert(peer_b->peer == bio);
    115 
    116   peer_b->peer = NULL;
    117   peer_bio->init = 0;
    118   assert(peer_b->buf != NULL);
    119   peer_b->len = 0;
    120   peer_b->offset = 0;
    121 
    122   b->peer = NULL;
    123   bio->init = 0;
    124   assert(b->buf != NULL);
    125   b->len = 0;
    126   b->offset = 0;
    127 }
    128 
    129 static int bio_free(BIO *bio) {
    130   struct bio_bio_st *b;
    131 
    132   if (bio == NULL) {
    133     return 0;
    134   }
    135   b = bio->ptr;
    136 
    137   assert(b != NULL);
    138 
    139   if (b->peer) {
    140     bio_destroy_pair(bio);
    141   }
    142 
    143   if (b->buf != NULL) {
    144     OPENSSL_free(b->buf);
    145   }
    146 
    147   OPENSSL_free(b);
    148 
    149   return 1;
    150 }
    151 
    152 static int bio_read(BIO *bio, char *buf, int size_) {
    153   size_t size = size_;
    154   size_t rest;
    155   struct bio_bio_st *b, *peer_b;
    156 
    157   BIO_clear_retry_flags(bio);
    158 
    159   if (!bio->init) {
    160     return 0;
    161   }
    162 
    163   b = bio->ptr;
    164   assert(b != NULL);
    165   assert(b->peer != NULL);
    166   peer_b = b->peer->ptr;
    167   assert(peer_b != NULL);
    168   assert(peer_b->buf != NULL);
    169 
    170   peer_b->request = 0; /* will be set in "retry_read" situation */
    171 
    172   if (buf == NULL || size == 0) {
    173     return 0;
    174   }
    175 
    176   if (peer_b->len == 0) {
    177     if (peer_b->closed) {
    178       return 0; /* writer has closed, and no data is left */
    179     } else {
    180       BIO_set_retry_read(bio); /* buffer is empty */
    181       if (size <= peer_b->size) {
    182         peer_b->request = size;
    183       } else {
    184         /* don't ask for more than the peer can
    185          * deliver in one write */
    186         peer_b->request = peer_b->size;
    187       }
    188       return -1;
    189     }
    190   }
    191 
    192   /* we can read */
    193   if (peer_b->len < size) {
    194     size = peer_b->len;
    195   }
    196 
    197   /* now read "size" bytes */
    198   rest = size;
    199 
    200   assert(rest > 0);
    201   /* one or two iterations */
    202   do {
    203     size_t chunk;
    204 
    205     assert(rest <= peer_b->len);
    206     if (peer_b->offset + rest <= peer_b->size) {
    207       chunk = rest;
    208     } else {
    209       /* wrap around ring buffer */
    210       chunk = peer_b->size - peer_b->offset;
    211     }
    212     assert(peer_b->offset + chunk <= peer_b->size);
    213 
    214     memcpy(buf, peer_b->buf + peer_b->offset, chunk);
    215 
    216     peer_b->len -= chunk;
    217     if (peer_b->len) {
    218       peer_b->offset += chunk;
    219       assert(peer_b->offset <= peer_b->size);
    220       if (peer_b->offset == peer_b->size) {
    221         peer_b->offset = 0;
    222       }
    223       buf += chunk;
    224     } else {
    225       /* buffer now empty, no need to advance "buf" */
    226       assert(chunk == rest);
    227       peer_b->offset = 0;
    228     }
    229     rest -= chunk;
    230   } while (rest);
    231 
    232   return size;
    233 }
    234 
    235 static int bio_write(BIO *bio, const char *buf, int num_) {
    236   size_t num = num_;
    237   size_t rest;
    238   struct bio_bio_st *b;
    239 
    240   BIO_clear_retry_flags(bio);
    241 
    242   if (!bio->init || buf == NULL || num == 0) {
    243     return 0;
    244   }
    245 
    246   b = bio->ptr;
    247   assert(b != NULL);
    248   assert(b->peer != NULL);
    249   assert(b->buf != NULL);
    250 
    251   b->request = 0;
    252   if (b->closed) {
    253     /* we already closed */
    254     OPENSSL_PUT_ERROR(BIO, bio_write, BIO_R_BROKEN_PIPE);
    255     return -1;
    256   }
    257 
    258   assert(b->len <= b->size);
    259 
    260   if (b->len == b->size) {
    261     BIO_set_retry_write(bio); /* buffer is full */
    262     return -1;
    263   }
    264 
    265   /* we can write */
    266   if (num > b->size - b->len) {
    267     num = b->size - b->len;
    268   }
    269 
    270   /* now write "num" bytes */
    271   rest = num;
    272 
    273   assert(rest > 0);
    274   /* one or two iterations */
    275   do {
    276     size_t write_offset;
    277     size_t chunk;
    278 
    279     assert(b->len + rest <= b->size);
    280 
    281     write_offset = b->offset + b->len;
    282     if (write_offset >= b->size) {
    283       write_offset -= b->size;
    284     }
    285     /* b->buf[write_offset] is the first byte we can write to. */
    286 
    287     if (write_offset + rest <= b->size) {
    288       chunk = rest;
    289     } else {
    290       /* wrap around ring buffer */
    291       chunk = b->size - write_offset;
    292     }
    293 
    294     memcpy(b->buf + write_offset, buf, chunk);
    295 
    296     b->len += chunk;
    297 
    298     assert(b->len <= b->size);
    299 
    300     rest -= chunk;
    301     buf += chunk;
    302   } while (rest);
    303 
    304   return num;
    305 }
    306 
    307 static int bio_make_pair(BIO *bio1, BIO *bio2) {
    308   struct bio_bio_st *b1, *b2;
    309 
    310   assert(bio1 != NULL);
    311   assert(bio2 != NULL);
    312 
    313   b1 = bio1->ptr;
    314   b2 = bio2->ptr;
    315 
    316   if (b1->peer != NULL || b2->peer != NULL) {
    317     OPENSSL_PUT_ERROR(BIO, bio_make_pair, BIO_R_IN_USE);
    318     return 0;
    319   }
    320 
    321   if (b1->buf == NULL) {
    322     b1->buf = OPENSSL_malloc(b1->size);
    323     if (b1->buf == NULL) {
    324       OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
    325       return 0;
    326     }
    327     b1->len = 0;
    328     b1->offset = 0;
    329   }
    330 
    331   if (b2->buf == NULL) {
    332     b2->buf = OPENSSL_malloc(b2->size);
    333     if (b2->buf == NULL) {
    334       OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
    335       return 0;
    336     }
    337     b2->len = 0;
    338     b2->offset = 0;
    339   }
    340 
    341   b1->peer = bio2;
    342   b1->closed = 0;
    343   b1->request = 0;
    344   b2->peer = bio1;
    345   b2->closed = 0;
    346   b2->request = 0;
    347 
    348   bio1->init = 1;
    349   bio2->init = 1;
    350 
    351   return 1;
    352 }
    353 
    354 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
    355   long ret;
    356   struct bio_bio_st *b = bio->ptr;
    357 
    358   assert(b != NULL);
    359 
    360   switch (cmd) {
    361     /* specific CTRL codes */
    362 
    363     case BIO_C_SET_BUFF_SIZE:
    364       if (b->peer) {
    365         OPENSSL_PUT_ERROR(BIO, bio_ctrl, BIO_R_IN_USE);
    366         ret = 0;
    367       } else if (num == 0) {
    368         OPENSSL_PUT_ERROR(BIO, bio_ctrl, BIO_R_INVALID_ARGUMENT);
    369         ret = 0;
    370       } else {
    371         size_t new_size = num;
    372 
    373         if (b->size != new_size) {
    374           if (b->buf) {
    375             OPENSSL_free(b->buf);
    376             b->buf = NULL;
    377           }
    378           b->size = new_size;
    379         }
    380         ret = 1;
    381       }
    382       break;
    383 
    384     case BIO_C_GET_WRITE_BUF_SIZE:
    385       ret = (long)b->size;
    386       break;
    387 
    388     case BIO_C_GET_WRITE_GUARANTEE:
    389       /* How many bytes can the caller feed to the next write
    390        * without having to keep any? */
    391       if (b->peer == NULL || b->closed) {
    392         ret = 0;
    393       } else {
    394         ret = (long)b->size - b->len;
    395       }
    396       break;
    397 
    398     case BIO_C_GET_READ_REQUEST:
    399       /* If the peer unsuccessfully tried to read, how many bytes
    400        * were requested?  (As with BIO_CTRL_PENDING, that number
    401        * can usually be treated as boolean.) */
    402       ret = (long)b->request;
    403       break;
    404 
    405     case BIO_C_RESET_READ_REQUEST:
    406       /* Reset request.  (Can be useful after read attempts
    407        * at the other side that are meant to be non-blocking,
    408        * e.g. when probing SSL_read to see if any data is
    409        * available.) */
    410       b->request = 0;
    411       ret = 1;
    412       break;
    413 
    414     case BIO_C_SHUTDOWN_WR:
    415       /* similar to shutdown(..., SHUT_WR) */
    416       b->closed = 1;
    417       ret = 1;
    418       break;
    419 
    420     /* standard CTRL codes follow */
    421 
    422     case BIO_CTRL_RESET:
    423       if (b->buf != NULL) {
    424         b->len = 0;
    425         b->offset = 0;
    426       }
    427       ret = 0;
    428       break;
    429 
    430     case BIO_CTRL_GET_CLOSE:
    431       ret = bio->shutdown;
    432       break;
    433 
    434     case BIO_CTRL_SET_CLOSE:
    435       bio->shutdown = (int)num;
    436       ret = 1;
    437       break;
    438 
    439     case BIO_CTRL_PENDING:
    440       if (b->peer != NULL) {
    441         struct bio_bio_st *peer_b = b->peer->ptr;
    442         ret = (long)peer_b->len;
    443       } else {
    444         ret = 0;
    445       }
    446       break;
    447 
    448     case BIO_CTRL_WPENDING:
    449       ret = 0;
    450       if (b->buf != NULL) {
    451         ret = (long)b->len;
    452       }
    453       break;
    454 
    455     case BIO_CTRL_FLUSH:
    456       ret = 1;
    457       break;
    458 
    459     case BIO_CTRL_EOF: {
    460       BIO *other_bio = ptr;
    461 
    462       if (other_bio) {
    463         struct bio_bio_st *other_b = other_bio->ptr;
    464         assert(other_b != NULL);
    465         ret = other_b->len == 0 && other_b->closed;
    466       } else {
    467         ret = 1;
    468       }
    469     } break;
    470 
    471     default:
    472       ret = 0;
    473   }
    474   return ret;
    475 }
    476 
    477 static int bio_puts(BIO *bio, const char *str) {
    478   return bio_write(bio, str, strlen(str));
    479 }
    480 
    481 int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p,
    482                      size_t writebuf2) {
    483   BIO *bio1 = NULL, *bio2 = NULL;
    484   long r;
    485   int ret = 0;
    486 
    487   bio1 = BIO_new(BIO_s_bio());
    488   if (bio1 == NULL) {
    489     goto err;
    490   }
    491   bio2 = BIO_new(BIO_s_bio());
    492   if (bio2 == NULL) {
    493     goto err;
    494   }
    495 
    496   if (writebuf1) {
    497     r = BIO_set_write_buffer_size(bio1, writebuf1);
    498     if (!r) {
    499       goto err;
    500     }
    501   }
    502   if (writebuf2) {
    503     r = BIO_set_write_buffer_size(bio2, writebuf2);
    504     if (!r) {
    505       goto err;
    506     }
    507   }
    508 
    509   if (!bio_make_pair(bio1, bio2)) {
    510     goto err;
    511   }
    512   ret = 1;
    513 
    514 err:
    515   if (ret == 0) {
    516     if (bio1) {
    517       BIO_free(bio1);
    518       bio1 = NULL;
    519     }
    520     if (bio2) {
    521       BIO_free(bio2);
    522       bio2 = NULL;
    523     }
    524   }
    525 
    526   *bio1_p = bio1;
    527   *bio2_p = bio2;
    528   return ret;
    529 }
    530 
    531 static const BIO_METHOD methods_biop = {
    532     BIO_TYPE_BIO, "BIO pair",             bio_write, bio_read,
    533     bio_puts,     NULL /* no bio_gets */, bio_ctrl,  bio_new,
    534     bio_free,     NULL /* no bio_callback_ctrl */
    535 };
    536 
    537 const BIO_METHOD *BIO_s_bio(void) { return &methods_biop; }
    538 
    539 size_t BIO_ctrl_get_read_request(BIO *bio) {
    540   return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
    541 }
    542 
    543 size_t BIO_ctrl_get_write_guarantee(BIO *bio) {
    544   return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
    545 }
    546 
    547 int BIO_shutdown_wr(BIO *bio) {
    548   return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL);
    549 }
    550