Home | History | Annotate | Download | only in bio
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) cryptsoft.com).
      6  * The implementation was written so as to conform with Netscapes SSL.
      7  *
      8  * This library is free for commercial and non-commercial use as long as
      9  * the following conditions are aheared to.  The following conditions
     10  * apply to all code found in this distribution, be it the RC4, RSA,
     11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     12  * included with this distribution is covered by the same copyright terms
     13  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     14  *
     15  * Copyright remains Eric Young's, and as such any Copyright notices in
     16  * the code are not to be removed.
     17  * If this package is used in a product, Eric Young should be given attribution
     18  * as the author of the parts of the library used.
     19  * This can be in the form of a textual message at program startup or
     20  * in documentation (online or textual) provided with the package.
     21  *
     22  * Redistribution and use in source and binary forms, with or without
     23  * modification, are permitted provided that the following conditions
     24  * are met:
     25  * 1. Redistributions of source code must retain the copyright
     26  *    notice, this list of conditions and the following disclaimer.
     27  * 2. Redistributions in binary form must reproduce the above copyright
     28  *    notice, this list of conditions and the following disclaimer in the
     29  *    documentation and/or other materials provided with the distribution.
     30  * 3. All advertising materials mentioning features or use of this software
     31  *    must display the following acknowledgement:
     32  *    "This product includes cryptographic software written by
     33  *     Eric Young (eay (at) cryptsoft.com)"
     34  *    The word 'cryptographic' can be left out if the rouines from the library
     35  *    being used are not cryptographic related :-).
     36  * 4. If you include any Windows specific code (or a derivative thereof) from
     37  *    the apps directory (application code) you must include an acknowledgement:
     38  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     50  * SUCH DAMAGE.
     51  *
     52  * The licence and distribution terms for any publically available version or
     53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     54  * copied and put under another distribution licence
     55  * [including the GNU Public Licence.] */
     56 
     57 #include <openssl/bio.h>
     58 
     59 #include <assert.h>
     60 #include <errno.h>
     61 #include <limits.h>
     62 #include <string.h>
     63 
     64 #include <openssl/err.h>
     65 #include <openssl/mem.h>
     66 #include <openssl/thread.h>
     67 
     68 #include "../internal.h"
     69 
     70 
     71 BIO *BIO_new(const BIO_METHOD *method) {
     72   BIO *ret = OPENSSL_malloc(sizeof(BIO));
     73   if (ret == NULL) {
     74     OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
     75     return NULL;
     76   }
     77 
     78   OPENSSL_memset(ret, 0, sizeof(BIO));
     79   ret->method = method;
     80   ret->shutdown = 1;
     81   ret->references = 1;
     82 
     83   if (method->create != NULL && !method->create(ret)) {
     84     OPENSSL_free(ret);
     85     return NULL;
     86   }
     87 
     88   return ret;
     89 }
     90 
     91 int BIO_free(BIO *bio) {
     92   BIO *next_bio;
     93 
     94   for (; bio != NULL; bio = next_bio) {
     95     if (!CRYPTO_refcount_dec_and_test_zero(&bio->references)) {
     96       return 0;
     97     }
     98 
     99     if (bio->callback != NULL) {
    100       int i = (int)bio->callback(bio, BIO_CB_FREE, NULL, 0, 0, 1);
    101       if (i <= 0) {
    102         return i;
    103       }
    104     }
    105 
    106     next_bio = BIO_pop(bio);
    107 
    108     if (bio->method != NULL && bio->method->destroy != NULL) {
    109       bio->method->destroy(bio);
    110     }
    111 
    112     OPENSSL_free(bio);
    113   }
    114   return 1;
    115 }
    116 
    117 int BIO_up_ref(BIO *bio) {
    118   CRYPTO_refcount_inc(&bio->references);
    119   return 1;
    120 }
    121 
    122 void BIO_vfree(BIO *bio) {
    123   BIO_free(bio);
    124 }
    125 
    126 void BIO_free_all(BIO *bio) {
    127   BIO_free(bio);
    128 }
    129 
    130 static int bio_io(BIO *bio, void *buf, int len, size_t method_offset,
    131                   int callback_flags, size_t *num) {
    132   int i;
    133   typedef int (*io_func_t)(BIO *, char *, int);
    134   io_func_t io_func = NULL;
    135 
    136   if (bio != NULL && bio->method != NULL) {
    137     io_func =
    138         *((const io_func_t *)(((const uint8_t *)bio->method) + method_offset));
    139   }
    140 
    141   if (io_func == NULL) {
    142     OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
    143     return -2;
    144   }
    145 
    146   if (bio->callback != NULL) {
    147     i = (int) bio->callback(bio, callback_flags, buf, len, 0L, 1L);
    148     if (i <= 0) {
    149       return i;
    150     }
    151   }
    152 
    153   if (!bio->init) {
    154     OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
    155     return -2;
    156   }
    157 
    158   i = 0;
    159   if (buf != NULL && len > 0) {
    160     i = io_func(bio, buf, len);
    161   }
    162 
    163   if (i > 0) {
    164     *num += i;
    165   }
    166 
    167   if (bio->callback != NULL) {
    168     i = (int)(bio->callback(bio, callback_flags | BIO_CB_RETURN, buf, len, 0L,
    169                             (long)i));
    170   }
    171 
    172   return i;
    173 }
    174 
    175 int BIO_read(BIO *bio, void *buf, int len) {
    176   return bio_io(bio, buf, len, offsetof(BIO_METHOD, bread), BIO_CB_READ,
    177                 &bio->num_read);
    178 }
    179 
    180 int BIO_gets(BIO *bio, char *buf, int len) {
    181   return bio_io(bio, buf, len, offsetof(BIO_METHOD, bgets), BIO_CB_GETS,
    182                 &bio->num_read);
    183 }
    184 
    185 int BIO_write(BIO *bio, const void *in, int inl) {
    186   return bio_io(bio, (char *)in, inl, offsetof(BIO_METHOD, bwrite),
    187                 BIO_CB_WRITE, &bio->num_write);
    188 }
    189 
    190 int BIO_puts(BIO *bio, const char *in) {
    191   return BIO_write(bio, in, strlen(in));
    192 }
    193 
    194 int BIO_flush(BIO *bio) {
    195   return BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL);
    196 }
    197 
    198 long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) {
    199   long ret;
    200 
    201   if (bio == NULL) {
    202     return 0;
    203   }
    204 
    205   if (bio->method == NULL || bio->method->ctrl == NULL) {
    206     OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
    207     return -2;
    208   }
    209 
    210   if (bio->callback != NULL) {
    211     ret = bio->callback(bio, BIO_CB_CTRL, parg, cmd, larg, 1);
    212     if (ret <= 0) {
    213       return ret;
    214     }
    215   }
    216 
    217   ret = bio->method->ctrl(bio, cmd, larg, parg);
    218 
    219   if (bio->callback != NULL) {
    220     ret = bio->callback(bio, BIO_CB_CTRL | BIO_CB_RETURN, parg, cmd, larg, ret);
    221   }
    222 
    223   return ret;
    224 }
    225 
    226 char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) {
    227   char *p = NULL;
    228 
    229   if (BIO_ctrl(b, cmd, larg, (void *)&p) <= 0) {
    230     return NULL;
    231   }
    232 
    233   return p;
    234 }
    235 
    236 long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) {
    237   int i = iarg;
    238 
    239   return BIO_ctrl(b, cmd, larg, (void *)&i);
    240 }
    241 
    242 int BIO_reset(BIO *bio) {
    243   return BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL);
    244 }
    245 
    246 int BIO_eof(BIO *bio) {
    247   return BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL);
    248 }
    249 
    250 void BIO_set_flags(BIO *bio, int flags) {
    251   bio->flags |= flags;
    252 }
    253 
    254 int BIO_test_flags(const BIO *bio, int flags) {
    255   return bio->flags & flags;
    256 }
    257 
    258 int BIO_should_read(const BIO *bio) {
    259   return BIO_test_flags(bio, BIO_FLAGS_READ);
    260 }
    261 
    262 int BIO_should_write(const BIO *bio) {
    263   return BIO_test_flags(bio, BIO_FLAGS_WRITE);
    264 }
    265 
    266 int BIO_should_retry(const BIO *bio) {
    267   return BIO_test_flags(bio, BIO_FLAGS_SHOULD_RETRY);
    268 }
    269 
    270 int BIO_should_io_special(const BIO *bio) {
    271   return BIO_test_flags(bio, BIO_FLAGS_IO_SPECIAL);
    272 }
    273 
    274 int BIO_get_retry_reason(const BIO *bio) { return bio->retry_reason; }
    275 
    276 void BIO_clear_flags(BIO *bio, int flags) {
    277   bio->flags &= ~flags;
    278 }
    279 
    280 void BIO_set_retry_read(BIO *bio) {
    281   bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY;
    282 }
    283 
    284 void BIO_set_retry_write(BIO *bio) {
    285   bio->flags |= BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY;
    286 }
    287 
    288 static const int kRetryFlags = BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY;
    289 
    290 int BIO_get_retry_flags(BIO *bio) {
    291   return bio->flags & kRetryFlags;
    292 }
    293 
    294 void BIO_clear_retry_flags(BIO *bio) {
    295   bio->flags &= ~kRetryFlags;
    296   bio->retry_reason = 0;
    297 }
    298 
    299 int BIO_method_type(const BIO *bio) { return bio->method->type; }
    300 
    301 void BIO_copy_next_retry(BIO *bio) {
    302   BIO_clear_retry_flags(bio);
    303   BIO_set_flags(bio, BIO_get_retry_flags(bio->next_bio));
    304   bio->retry_reason = bio->next_bio->retry_reason;
    305 }
    306 
    307 long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
    308   long ret;
    309   bio_info_cb cb;
    310 
    311   if (bio == NULL) {
    312     return 0;
    313   }
    314 
    315   if (bio->method == NULL || bio->method->callback_ctrl == NULL) {
    316     OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
    317     return 0;
    318   }
    319 
    320   cb = bio->callback;
    321 
    322   if (cb != NULL) {
    323     ret = cb(bio, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L);
    324     if (ret <= 0) {
    325       return ret;
    326     }
    327   }
    328 
    329   ret = bio->method->callback_ctrl(bio, cmd, fp);
    330 
    331   if (cb != NULL) {
    332     ret = cb(bio, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, cmd, 0, ret);
    333   }
    334 
    335   return ret;
    336 }
    337 
    338 size_t BIO_pending(const BIO *bio) {
    339   const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_PENDING, 0, NULL);
    340   assert(r >= 0);
    341 
    342   if (r < 0) {
    343     return 0;
    344   }
    345   return r;
    346 }
    347 
    348 size_t BIO_ctrl_pending(const BIO *bio) {
    349   return BIO_pending(bio);
    350 }
    351 
    352 size_t BIO_wpending(const BIO *bio) {
    353   const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_WPENDING, 0, NULL);
    354   assert(r >= 0);
    355 
    356   if (r < 0) {
    357     return 0;
    358   }
    359   return r;
    360 }
    361 
    362 int BIO_set_close(BIO *bio, int close_flag) {
    363   return BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL);
    364 }
    365 
    366 void BIO_set_callback(BIO *bio, bio_info_cb callback_func) {
    367   bio->callback = callback_func;
    368 }
    369 
    370 void BIO_set_callback_arg(BIO *bio, char *arg) {
    371   bio->cb_arg = arg;
    372 }
    373 
    374 char *BIO_get_callback_arg(const BIO *bio) {
    375   return bio->cb_arg;
    376 }
    377 
    378 OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio) {
    379   return bio->num_read;
    380 }
    381 
    382 OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio) {
    383   return bio->num_write;
    384 }
    385 
    386 BIO *BIO_push(BIO *bio, BIO *appended_bio) {
    387   BIO *last_bio;
    388 
    389   if (bio == NULL) {
    390     return bio;
    391   }
    392 
    393   last_bio = bio;
    394   while (last_bio->next_bio != NULL) {
    395     last_bio = last_bio->next_bio;
    396   }
    397 
    398   last_bio->next_bio = appended_bio;
    399   return bio;
    400 }
    401 
    402 BIO *BIO_pop(BIO *bio) {
    403   BIO *ret;
    404 
    405   if (bio == NULL) {
    406     return NULL;
    407   }
    408   ret = bio->next_bio;
    409   bio->next_bio = NULL;
    410   return ret;
    411 }
    412 
    413 BIO *BIO_next(BIO *bio) {
    414   if (!bio) {
    415     return NULL;
    416   }
    417   return bio->next_bio;
    418 }
    419 
    420 BIO *BIO_find_type(BIO *bio, int type) {
    421   int method_type, mask;
    422 
    423   if (!bio) {
    424     return NULL;
    425   }
    426   mask = type & 0xff;
    427 
    428   do {
    429     if (bio->method != NULL) {
    430       method_type = bio->method->type;
    431 
    432       if (!mask) {
    433         if (method_type & type) {
    434           return bio;
    435         }
    436       } else if (method_type == type) {
    437         return bio;
    438       }
    439     }
    440     bio = bio->next_bio;
    441   } while (bio != NULL);
    442 
    443   return NULL;
    444 }
    445 
    446 int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent) {
    447   if (indent > max_indent) {
    448     indent = max_indent;
    449   }
    450 
    451   while (indent--) {
    452     if (BIO_puts(bio, " ") != 1) {
    453       return 0;
    454     }
    455   }
    456   return 1;
    457 }
    458 
    459 static int print_bio(const char *str, size_t len, void *bio) {
    460   return BIO_write((BIO *)bio, str, len);
    461 }
    462 
    463 void ERR_print_errors(BIO *bio) {
    464   ERR_print_errors_cb(print_bio, bio);
    465 }
    466 
    467 /* bio_read_all reads everything from |bio| and prepends |prefix| to it. On
    468  * success, |*out| is set to an allocated buffer (which should be freed with
    469  * |OPENSSL_free|), |*out_len| is set to its length and one is returned. The
    470  * buffer will contain |prefix| followed by the contents of |bio|. On failure,
    471  * zero is returned.
    472  *
    473  * The function will fail if the size of the output would equal or exceed
    474  * |max_len|. */
    475 static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len,
    476                         const uint8_t *prefix, size_t prefix_len,
    477                         size_t max_len) {
    478   static const size_t kChunkSize = 4096;
    479 
    480   size_t len = prefix_len + kChunkSize;
    481   if (len > max_len) {
    482     len = max_len;
    483   }
    484   if (len < prefix_len) {
    485     return 0;
    486   }
    487   *out = OPENSSL_malloc(len);
    488   if (*out == NULL) {
    489     return 0;
    490   }
    491   OPENSSL_memcpy(*out, prefix, prefix_len);
    492   size_t done = prefix_len;
    493 
    494   for (;;) {
    495     if (done == len) {
    496       OPENSSL_free(*out);
    497       return 0;
    498     }
    499     const size_t todo = len - done;
    500     assert(todo < INT_MAX);
    501     const int n = BIO_read(bio, *out + done, todo);
    502     if (n == 0) {
    503       *out_len = done;
    504       return 1;
    505     } else if (n == -1) {
    506       OPENSSL_free(*out);
    507       return 0;
    508     }
    509 
    510     done += n;
    511     if (len < max_len && len - done < kChunkSize / 2) {
    512       len += kChunkSize;
    513       if (len < kChunkSize || len > max_len) {
    514         len = max_len;
    515       }
    516       uint8_t *new_buf = OPENSSL_realloc(*out, len);
    517       if (new_buf == NULL) {
    518         OPENSSL_free(*out);
    519         return 0;
    520       }
    521       *out = new_buf;
    522     }
    523   }
    524 }
    525 
    526 int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
    527   uint8_t header[6];
    528 
    529   static const size_t kInitialHeaderLen = 2;
    530   if (BIO_read(bio, header, kInitialHeaderLen) != (int) kInitialHeaderLen) {
    531     return 0;
    532   }
    533 
    534   const uint8_t tag = header[0];
    535   const uint8_t length_byte = header[1];
    536 
    537   if ((tag & 0x1f) == 0x1f) {
    538     /* Long form tags are not supported. */
    539     return 0;
    540   }
    541 
    542   size_t len, header_len;
    543   if ((length_byte & 0x80) == 0) {
    544     /* Short form length. */
    545     len = length_byte;
    546     header_len = kInitialHeaderLen;
    547   } else {
    548     const size_t num_bytes = length_byte & 0x7f;
    549 
    550     if ((tag & 0x20 /* constructed */) != 0 && num_bytes == 0) {
    551       /* indefinite length. */
    552       return bio_read_all(bio, out, out_len, header, kInitialHeaderLen,
    553                           max_len);
    554     }
    555 
    556     if (num_bytes == 0 || num_bytes > 4) {
    557       return 0;
    558     }
    559 
    560     if (BIO_read(bio, header + kInitialHeaderLen, num_bytes) !=
    561         (int)num_bytes) {
    562       return 0;
    563     }
    564     header_len = kInitialHeaderLen + num_bytes;
    565 
    566     uint32_t len32 = 0;
    567     unsigned i;
    568     for (i = 0; i < num_bytes; i++) {
    569       len32 <<= 8;
    570       len32 |= header[kInitialHeaderLen + i];
    571     }
    572 
    573     if (len32 < 128) {
    574       /* Length should have used short-form encoding. */
    575       return 0;
    576     }
    577 
    578     if ((len32 >> ((num_bytes-1)*8)) == 0) {
    579       /* Length should have been at least one byte shorter. */
    580       return 0;
    581     }
    582 
    583     len = len32;
    584   }
    585 
    586   if (len + header_len < len ||
    587       len + header_len > max_len ||
    588       len > INT_MAX) {
    589     return 0;
    590   }
    591   len += header_len;
    592   *out_len = len;
    593 
    594   *out = OPENSSL_malloc(len);
    595   if (*out == NULL) {
    596     return 0;
    597   }
    598   OPENSSL_memcpy(*out, header, header_len);
    599   if (BIO_read(bio, (*out) + header_len, len - header_len) !=
    600       (int) (len - header_len)) {
    601     OPENSSL_free(*out);
    602     return 0;
    603   }
    604 
    605   return 1;
    606 }
    607 
    608 void BIO_set_retry_special(BIO *bio) {
    609   bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL;
    610 }
    611 
    612 int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; }
    613