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 #include <string.h>
     57 
     58 #include <openssl/buf.h>
     59 #include <openssl/err.h>
     60 #include <openssl/mem.h>
     61 
     62 #include "../internal.h"
     63 
     64 
     65 struct bio_bio_st {
     66   BIO *peer;  // NULL if buf == NULL.
     67               // If peer != NULL, then peer->ptr is also a bio_bio_st,
     68               // and its "peer" member points back to us.
     69               // peer != NULL iff init != 0 in the BIO.
     70 
     71   // This is for what we write (i.e. reading uses peer's struct):
     72   int closed;     // valid iff peer != NULL
     73   size_t len;     // valid iff buf != NULL; 0 if peer == NULL
     74   size_t offset;  // valid iff buf != NULL; 0 if len == 0
     75   size_t size;
     76   uint8_t *buf;  // "size" elements (if != NULL)
     77 
     78   size_t request;  // valid iff peer != NULL; 0 if len != 0,
     79                    // otherwise set by peer to number of bytes
     80                    // it (unsuccessfully) tried to read,
     81                    // never more than buffer space (size-len) warrants.
     82 };
     83 
     84 static int bio_new(BIO *bio) {
     85   struct bio_bio_st *b;
     86 
     87   b = OPENSSL_malloc(sizeof *b);
     88   if (b == NULL) {
     89     return 0;
     90   }
     91   OPENSSL_memset(b, 0, sizeof(struct bio_bio_st));
     92 
     93   b->size = 17 * 1024;  // enough for one TLS record (just a default)
     94   bio->ptr = b;
     95   return 1;
     96 }
     97 
     98 static void bio_destroy_pair(BIO *bio) {
     99   struct bio_bio_st *b = bio->ptr;
    100   BIO *peer_bio;
    101   struct bio_bio_st *peer_b;
    102 
    103   if (b == NULL) {
    104     return;
    105   }
    106 
    107   peer_bio = b->peer;
    108   if (peer_bio == NULL) {
    109     return;
    110   }
    111 
    112   peer_b = peer_bio->ptr;
    113 
    114   assert(peer_b != NULL);
    115   assert(peer_b->peer == bio);
    116 
    117   peer_b->peer = NULL;
    118   peer_bio->init = 0;
    119   assert(peer_b->buf != NULL);
    120   peer_b->len = 0;
    121   peer_b->offset = 0;
    122 
    123   b->peer = NULL;
    124   bio->init = 0;
    125   assert(b->buf != NULL);
    126   b->len = 0;
    127   b->offset = 0;
    128 }
    129 
    130 static int bio_free(BIO *bio) {
    131   struct bio_bio_st *b;
    132 
    133   if (bio == NULL) {
    134     return 0;
    135   }
    136   b = bio->ptr;
    137 
    138   assert(b != NULL);
    139 
    140   if (b->peer) {
    141     bio_destroy_pair(bio);
    142   }
    143 
    144   OPENSSL_free(b->buf);
    145   OPENSSL_free(b);
    146 
    147   return 1;
    148 }
    149 
    150 static int bio_read(BIO *bio, char *buf, int size_) {
    151   size_t size = size_;
    152   size_t rest;
    153   struct bio_bio_st *b, *peer_b;
    154 
    155   BIO_clear_retry_flags(bio);
    156 
    157   if (!bio->init) {
    158     return 0;
    159   }
    160 
    161   b = bio->ptr;
    162   assert(b != NULL);
    163   assert(b->peer != NULL);
    164   peer_b = b->peer->ptr;
    165   assert(peer_b != NULL);
    166   assert(peer_b->buf != NULL);
    167 
    168   peer_b->request = 0;  // will be set in "retry_read" situation
    169 
    170   if (buf == NULL || size == 0) {
    171     return 0;
    172   }
    173 
    174   if (peer_b->len == 0) {
    175     if (peer_b->closed) {
    176       return 0;  // writer has closed, and no data is left
    177     } else {
    178       BIO_set_retry_read(bio);  // buffer is empty
    179       if (size <= peer_b->size) {
    180         peer_b->request = size;
    181       } else {
    182         // don't ask for more than the peer can
    183         // deliver in one write
    184         peer_b->request = peer_b->size;
    185       }
    186       return -1;
    187     }
    188   }
    189 
    190   // we can read
    191   if (peer_b->len < size) {
    192     size = peer_b->len;
    193   }
    194 
    195   // now read "size" bytes
    196   rest = size;
    197 
    198   assert(rest > 0);
    199   // one or two iterations
    200   do {
    201     size_t chunk;
    202 
    203     assert(rest <= peer_b->len);
    204     if (peer_b->offset + rest <= peer_b->size) {
    205       chunk = rest;
    206     } else {
    207       // wrap around ring buffer
    208       chunk = peer_b->size - peer_b->offset;
    209     }
    210     assert(peer_b->offset + chunk <= peer_b->size);
    211 
    212     OPENSSL_memcpy(buf, peer_b->buf + peer_b->offset, chunk);
    213 
    214     peer_b->len -= chunk;
    215     if (peer_b->len) {
    216       peer_b->offset += chunk;
    217       assert(peer_b->offset <= peer_b->size);
    218       if (peer_b->offset == peer_b->size) {
    219         peer_b->offset = 0;
    220       }
    221       buf += chunk;
    222     } else {
    223       // buffer now empty, no need to advance "buf"
    224       assert(chunk == rest);
    225       peer_b->offset = 0;
    226     }
    227     rest -= chunk;
    228   } while (rest);
    229 
    230   return size;
    231 }
    232 
    233 static int bio_write(BIO *bio, const char *buf, int num_) {
    234   size_t num = num_;
    235   size_t rest;
    236   struct bio_bio_st *b;
    237 
    238   BIO_clear_retry_flags(bio);
    239 
    240   if (!bio->init || buf == NULL || num == 0) {
    241     return 0;
    242   }
    243 
    244   b = bio->ptr;
    245   assert(b != NULL);
    246   assert(b->peer != NULL);
    247   assert(b->buf != NULL);
    248 
    249   b->request = 0;
    250   if (b->closed) {
    251     // we already closed
    252     OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
    253     return -1;
    254   }
    255 
    256   assert(b->len <= b->size);
    257 
    258   if (b->len == b->size) {
    259     BIO_set_retry_write(bio);  // buffer is full
    260     return -1;
    261   }
    262 
    263   // we can write
    264   if (num > b->size - b->len) {
    265     num = b->size - b->len;
    266   }
    267 
    268   // now write "num" bytes
    269   rest = num;
    270 
    271   assert(rest > 0);
    272   // one or two iterations
    273   do {
    274     size_t write_offset;
    275     size_t chunk;
    276 
    277     assert(b->len + rest <= b->size);
    278 
    279     write_offset = b->offset + b->len;
    280     if (write_offset >= b->size) {
    281       write_offset -= b->size;
    282     }
    283     // b->buf[write_offset] is the first byte we can write to.
    284 
    285     if (write_offset + rest <= b->size) {
    286       chunk = rest;
    287     } else {
    288       // wrap around ring buffer
    289       chunk = b->size - write_offset;
    290     }
    291 
    292     OPENSSL_memcpy(b->buf + write_offset, buf, chunk);
    293 
    294     b->len += chunk;
    295 
    296     assert(b->len <= b->size);
    297 
    298     rest -= chunk;
    299     buf += chunk;
    300   } while (rest);
    301 
    302   return num;
    303 }
    304 
    305 static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len,
    306                          size_t writebuf2_len) {
    307   struct bio_bio_st *b1, *b2;
    308 
    309   assert(bio1 != NULL);
    310   assert(bio2 != NULL);
    311 
    312   b1 = bio1->ptr;
    313   b2 = bio2->ptr;
    314 
    315   if (b1->peer != NULL || b2->peer != NULL) {
    316     OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE);
    317     return 0;
    318   }
    319 
    320   if (b1->buf == NULL) {
    321     if (writebuf1_len) {
    322       b1->size = writebuf1_len;
    323     }
    324     b1->buf = OPENSSL_malloc(b1->size);
    325     if (b1->buf == NULL) {
    326       OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
    327       return 0;
    328     }
    329     b1->len = 0;
    330     b1->offset = 0;
    331   }
    332 
    333   if (b2->buf == NULL) {
    334     if (writebuf2_len) {
    335       b2->size = writebuf2_len;
    336     }
    337     b2->buf = OPENSSL_malloc(b2->size);
    338     if (b2->buf == NULL) {
    339       OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
    340       return 0;
    341     }
    342     b2->len = 0;
    343     b2->offset = 0;
    344   }
    345 
    346   b1->peer = bio2;
    347   b1->closed = 0;
    348   b1->request = 0;
    349   b2->peer = bio1;
    350   b2->closed = 0;
    351   b2->request = 0;
    352 
    353   bio1->init = 1;
    354   bio2->init = 1;
    355 
    356   return 1;
    357 }
    358 
    359 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
    360   long ret;
    361   struct bio_bio_st *b = bio->ptr;
    362 
    363   assert(b != NULL);
    364 
    365   switch (cmd) {
    366     // specific CTRL codes
    367 
    368     case BIO_C_GET_WRITE_BUF_SIZE:
    369       ret = (long)b->size;
    370       break;
    371 
    372     case BIO_C_GET_WRITE_GUARANTEE:
    373       // How many bytes can the caller feed to the next write
    374       // without having to keep any?
    375       if (b->peer == NULL || b->closed) {
    376         ret = 0;
    377       } else {
    378         ret = (long)b->size - b->len;
    379       }
    380       break;
    381 
    382     case BIO_C_GET_READ_REQUEST:
    383       // If the peer unsuccessfully tried to read, how many bytes
    384       // were requested?  (As with BIO_CTRL_PENDING, that number
    385       // can usually be treated as boolean.)
    386       ret = (long)b->request;
    387       break;
    388 
    389     case BIO_C_RESET_READ_REQUEST:
    390       // Reset request.  (Can be useful after read attempts
    391       // at the other side that are meant to be non-blocking,
    392       // e.g. when probing SSL_read to see if any data is
    393       // available.)
    394       b->request = 0;
    395       ret = 1;
    396       break;
    397 
    398     case BIO_C_SHUTDOWN_WR:
    399       // similar to shutdown(..., SHUT_WR)
    400       b->closed = 1;
    401       ret = 1;
    402       break;
    403 
    404     // standard CTRL codes follow
    405 
    406     case BIO_CTRL_GET_CLOSE:
    407       ret = bio->shutdown;
    408       break;
    409 
    410     case BIO_CTRL_SET_CLOSE:
    411       bio->shutdown = (int)num;
    412       ret = 1;
    413       break;
    414 
    415     case BIO_CTRL_PENDING:
    416       if (b->peer != NULL) {
    417         struct bio_bio_st *peer_b = b->peer->ptr;
    418         ret = (long)peer_b->len;
    419       } else {
    420         ret = 0;
    421       }
    422       break;
    423 
    424     case BIO_CTRL_WPENDING:
    425       ret = 0;
    426       if (b->buf != NULL) {
    427         ret = (long)b->len;
    428       }
    429       break;
    430 
    431     case BIO_CTRL_FLUSH:
    432       ret = 1;
    433       break;
    434 
    435     case BIO_CTRL_EOF: {
    436       BIO *other_bio = ptr;
    437 
    438       if (other_bio) {
    439         struct bio_bio_st *other_b = other_bio->ptr;
    440         assert(other_b != NULL);
    441         ret = other_b->len == 0 && other_b->closed;
    442       } else {
    443         ret = 1;
    444       }
    445     } break;
    446 
    447     default:
    448       ret = 0;
    449   }
    450   return ret;
    451 }
    452 
    453 
    454 static const BIO_METHOD methods_biop = {
    455     BIO_TYPE_BIO,    "BIO pair", bio_write, bio_read, NULL /* puts */,
    456     NULL /* gets */, bio_ctrl,   bio_new,   bio_free, NULL /* callback_ctrl */,
    457 };
    458 
    459 static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
    460 
    461 int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1_len,
    462                      BIO** bio2_p, size_t writebuf2_len) {
    463   BIO *bio1 = BIO_new(bio_s_bio());
    464   BIO *bio2 = BIO_new(bio_s_bio());
    465   if (bio1 == NULL || bio2 == NULL ||
    466       !bio_make_pair(bio1, bio2, writebuf1_len, writebuf2_len)) {
    467     BIO_free(bio1);
    468     BIO_free(bio2);
    469     *bio1_p = NULL;
    470     *bio2_p = NULL;
    471     return 0;
    472   }
    473 
    474   *bio1_p = bio1;
    475   *bio2_p = bio2;
    476   return 1;
    477 }
    478 
    479 size_t BIO_ctrl_get_read_request(BIO *bio) {
    480   return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
    481 }
    482 
    483 size_t BIO_ctrl_get_write_guarantee(BIO *bio) {
    484   return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
    485 }
    486 
    487 int BIO_shutdown_wr(BIO *bio) {
    488   return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL);
    489 }
    490