Home | History | Annotate | Line # | Download | only in test
      1      1.1  christos /*
      2      1.1  christos  * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos  *
      4      1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5      1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6      1.1  christos  * in the file LICENSE in the source distribution or at
      7      1.1  christos  * https://www.openssl.org/source/license.html
      8      1.1  christos  */
      9      1.1  christos #include <stdio.h>
     10      1.1  christos #include <string.h>
     11      1.1  christos #include <openssl/buffer.h>
     12      1.1  christos #include <openssl/bio.h>
     13      1.1  christos 
     14      1.1  christos #include "testutil.h"
     15      1.1  christos 
     16      1.1  christos static int test_bio_memleak(void)
     17      1.1  christos {
     18      1.1  christos     int ok = 0;
     19      1.1  christos     BIO *bio;
     20      1.1  christos     BUF_MEM bufmem;
     21      1.1  christos     static const char str[] = "BIO test\n";
     22      1.1  christos     char buf[100];
     23      1.1  christos 
     24      1.1  christos     bio = BIO_new(BIO_s_mem());
     25      1.1  christos     if (!TEST_ptr(bio))
     26      1.1  christos         goto finish;
     27      1.1  christos     bufmem.length = sizeof(str);
     28  1.1.1.2  christos     bufmem.data = (char *)str;
     29      1.1  christos     bufmem.max = bufmem.length;
     30      1.1  christos     BIO_set_mem_buf(bio, &bufmem, BIO_NOCLOSE);
     31      1.1  christos     BIO_set_flags(bio, BIO_FLAGS_MEM_RDONLY);
     32      1.1  christos     if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(str)))
     33      1.1  christos         goto finish;
     34      1.1  christos     if (!TEST_mem_eq(buf, sizeof(str), str, sizeof(str)))
     35      1.1  christos         goto finish;
     36      1.1  christos     ok = 1;
     37      1.1  christos 
     38  1.1.1.2  christos finish:
     39      1.1  christos     BIO_free(bio);
     40      1.1  christos     return ok;
     41      1.1  christos }
     42      1.1  christos 
     43      1.1  christos static int test_bio_get_mem(void)
     44      1.1  christos {
     45      1.1  christos     int ok = 0;
     46      1.1  christos     BIO *bio = NULL;
     47      1.1  christos     BUF_MEM *bufmem = NULL;
     48      1.1  christos 
     49      1.1  christos     bio = BIO_new(BIO_s_mem());
     50      1.1  christos     if (!TEST_ptr(bio))
     51      1.1  christos         goto finish;
     52      1.1  christos     if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
     53      1.1  christos         goto finish;
     54      1.1  christos     BIO_get_mem_ptr(bio, &bufmem);
     55      1.1  christos     if (!TEST_ptr(bufmem))
     56      1.1  christos         goto finish;
     57      1.1  christos     if (!TEST_int_gt(BIO_set_close(bio, BIO_NOCLOSE), 0))
     58      1.1  christos         goto finish;
     59      1.1  christos     BIO_free(bio);
     60      1.1  christos     bio = NULL;
     61      1.1  christos     if (!TEST_mem_eq(bufmem->data, bufmem->length, "Hello World\n", 12))
     62      1.1  christos         goto finish;
     63      1.1  christos     ok = 1;
     64      1.1  christos 
     65  1.1.1.2  christos finish:
     66      1.1  christos     BIO_free(bio);
     67      1.1  christos     BUF_MEM_free(bufmem);
     68      1.1  christos     return ok;
     69      1.1  christos }
     70      1.1  christos 
     71      1.1  christos static int test_bio_new_mem_buf(void)
     72      1.1  christos {
     73      1.1  christos     int ok = 0;
     74      1.1  christos     BIO *bio;
     75      1.1  christos     BUF_MEM *bufmem;
     76      1.1  christos     char data[16];
     77      1.1  christos 
     78      1.1  christos     bio = BIO_new_mem_buf("Hello World\n", 12);
     79      1.1  christos     if (!TEST_ptr(bio))
     80      1.1  christos         goto finish;
     81      1.1  christos     if (!TEST_int_eq(BIO_read(bio, data, 5), 5))
     82      1.1  christos         goto finish;
     83      1.1  christos     if (!TEST_mem_eq(data, 5, "Hello", 5))
     84      1.1  christos         goto finish;
     85      1.1  christos     if (!TEST_int_gt(BIO_get_mem_ptr(bio, &bufmem), 0))
     86      1.1  christos         goto finish;
     87      1.1  christos     if (!TEST_int_lt(BIO_write(bio, "test", 4), 0))
     88      1.1  christos         goto finish;
     89      1.1  christos     if (!TEST_int_eq(BIO_read(bio, data, 16), 7))
     90      1.1  christos         goto finish;
     91      1.1  christos     if (!TEST_mem_eq(data, 7, " World\n", 7))
     92      1.1  christos         goto finish;
     93      1.1  christos     if (!TEST_int_gt(BIO_reset(bio), 0))
     94      1.1  christos         goto finish;
     95      1.1  christos     if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
     96      1.1  christos         goto finish;
     97      1.1  christos     if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
     98      1.1  christos         goto finish;
     99      1.1  christos     ok = 1;
    100      1.1  christos 
    101  1.1.1.2  christos finish:
    102      1.1  christos     BIO_free(bio);
    103      1.1  christos     return ok;
    104      1.1  christos }
    105      1.1  christos 
    106      1.1  christos static int test_bio_rdonly_mem_buf(void)
    107      1.1  christos {
    108      1.1  christos     int ok = 0;
    109      1.1  christos     BIO *bio, *bio2 = NULL;
    110      1.1  christos     BUF_MEM *bufmem;
    111      1.1  christos     char data[16];
    112      1.1  christos 
    113      1.1  christos     bio = BIO_new_mem_buf("Hello World\n", 12);
    114      1.1  christos     if (!TEST_ptr(bio))
    115      1.1  christos         goto finish;
    116      1.1  christos     if (!TEST_int_eq(BIO_read(bio, data, 5), 5))
    117      1.1  christos         goto finish;
    118      1.1  christos     if (!TEST_mem_eq(data, 5, "Hello", 5))
    119      1.1  christos         goto finish;
    120      1.1  christos     if (!TEST_int_gt(BIO_get_mem_ptr(bio, &bufmem), 0))
    121      1.1  christos         goto finish;
    122      1.1  christos     (void)BIO_set_close(bio, BIO_NOCLOSE);
    123      1.1  christos 
    124      1.1  christos     bio2 = BIO_new(BIO_s_mem());
    125      1.1  christos     if (!TEST_ptr(bio2))
    126      1.1  christos         goto finish;
    127      1.1  christos     BIO_set_mem_buf(bio2, bufmem, BIO_CLOSE);
    128      1.1  christos     BIO_set_flags(bio2, BIO_FLAGS_MEM_RDONLY);
    129      1.1  christos 
    130      1.1  christos     if (!TEST_int_eq(BIO_read(bio2, data, 16), 7))
    131      1.1  christos         goto finish;
    132      1.1  christos     if (!TEST_mem_eq(data, 7, " World\n", 7))
    133      1.1  christos         goto finish;
    134      1.1  christos     if (!TEST_int_gt(BIO_reset(bio2), 0))
    135      1.1  christos         goto finish;
    136      1.1  christos     if (!TEST_int_eq(BIO_read(bio2, data, 16), 7))
    137      1.1  christos         goto finish;
    138      1.1  christos     if (!TEST_mem_eq(data, 7, " World\n", 7))
    139      1.1  christos         goto finish;
    140      1.1  christos     ok = 1;
    141      1.1  christos 
    142  1.1.1.2  christos finish:
    143      1.1  christos     BIO_free(bio);
    144      1.1  christos     BIO_free(bio2);
    145      1.1  christos     return ok;
    146      1.1  christos }
    147      1.1  christos 
    148      1.1  christos static int test_bio_rdwr_rdonly(void)
    149      1.1  christos {
    150      1.1  christos     int ok = 0;
    151      1.1  christos     BIO *bio = NULL;
    152      1.1  christos     char data[16];
    153      1.1  christos 
    154      1.1  christos     bio = BIO_new(BIO_s_mem());
    155      1.1  christos     if (!TEST_ptr(bio))
    156      1.1  christos         goto finish;
    157      1.1  christos     if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
    158      1.1  christos         goto finish;
    159      1.1  christos 
    160      1.1  christos     BIO_set_flags(bio, BIO_FLAGS_MEM_RDONLY);
    161      1.1  christos     if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
    162      1.1  christos         goto finish;
    163      1.1  christos     if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
    164      1.1  christos         goto finish;
    165      1.1  christos     if (!TEST_int_gt(BIO_reset(bio), 0))
    166      1.1  christos         goto finish;
    167      1.1  christos 
    168      1.1  christos     BIO_clear_flags(bio, BIO_FLAGS_MEM_RDONLY);
    169      1.1  christos     if (!TEST_int_eq(BIO_puts(bio, "Hi!\n"), 4))
    170      1.1  christos         goto finish;
    171      1.1  christos     if (!TEST_int_eq(BIO_read(bio, data, 16), 16))
    172      1.1  christos         goto finish;
    173      1.1  christos 
    174      1.1  christos     if (!TEST_mem_eq(data, 16, "Hello World\nHi!\n", 16))
    175      1.1  christos         goto finish;
    176      1.1  christos 
    177      1.1  christos     ok = 1;
    178      1.1  christos 
    179  1.1.1.2  christos finish:
    180      1.1  christos     BIO_free(bio);
    181      1.1  christos     return ok;
    182      1.1  christos }
    183      1.1  christos 
    184      1.1  christos static int test_bio_nonclear_rst(void)
    185      1.1  christos {
    186      1.1  christos     int ok = 0;
    187      1.1  christos     BIO *bio = NULL;
    188      1.1  christos     char data[16];
    189      1.1  christos 
    190      1.1  christos     bio = BIO_new(BIO_s_mem());
    191      1.1  christos     if (!TEST_ptr(bio))
    192      1.1  christos         goto finish;
    193      1.1  christos     if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
    194      1.1  christos         goto finish;
    195      1.1  christos 
    196      1.1  christos     BIO_set_flags(bio, BIO_FLAGS_NONCLEAR_RST);
    197      1.1  christos 
    198      1.1  christos     if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
    199      1.1  christos         goto finish;
    200      1.1  christos     if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
    201      1.1  christos         goto finish;
    202      1.1  christos     if (!TEST_int_gt(BIO_reset(bio), 0))
    203      1.1  christos         goto finish;
    204      1.1  christos 
    205      1.1  christos     if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
    206      1.1  christos         goto finish;
    207      1.1  christos     if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
    208      1.1  christos         goto finish;
    209      1.1  christos 
    210      1.1  christos     BIO_clear_flags(bio, BIO_FLAGS_NONCLEAR_RST);
    211      1.1  christos     if (!TEST_int_gt(BIO_reset(bio), 0))
    212      1.1  christos         goto finish;
    213      1.1  christos 
    214      1.1  christos     if (!TEST_int_lt(BIO_read(bio, data, 16), 1))
    215      1.1  christos         goto finish;
    216      1.1  christos 
    217      1.1  christos     ok = 1;
    218      1.1  christos 
    219  1.1.1.2  christos finish:
    220      1.1  christos     BIO_free(bio);
    221      1.1  christos     return ok;
    222      1.1  christos }
    223      1.1  christos 
    224      1.1  christos static int error_callback_fired;
    225      1.1  christos static long BIO_error_callback(BIO *bio, int cmd, const char *argp,
    226  1.1.1.2  christos     size_t len, int argi,
    227  1.1.1.2  christos     long argl, int ret, size_t *processed)
    228      1.1  christos {
    229      1.1  christos     if ((cmd & (BIO_CB_READ | BIO_CB_RETURN)) != 0) {
    230      1.1  christos         error_callback_fired = 1;
    231  1.1.1.2  christos         ret = 0; /* fail for read operations to simulate error in input BIO */
    232      1.1  christos     }
    233      1.1  christos     return ret;
    234      1.1  christos }
    235      1.1  christos 
    236      1.1  christos /* Checks i2d_ASN1_bio_stream() is freeing all memory when input BIO ends unexpectedly. */
    237      1.1  christos static int test_bio_i2d_ASN1_mime(void)
    238      1.1  christos {
    239      1.1  christos     int ok = 0;
    240      1.1  christos     BIO *bio = NULL, *out = NULL;
    241      1.1  christos     BUF_MEM bufmem;
    242      1.1  christos     static const char str[] = "BIO mime test\n";
    243      1.1  christos     PKCS7 *p7 = NULL;
    244      1.1  christos 
    245      1.1  christos     if (!TEST_ptr(bio = BIO_new(BIO_s_mem())))
    246      1.1  christos         goto finish;
    247      1.1  christos 
    248      1.1  christos     bufmem.length = sizeof(str);
    249  1.1.1.2  christos     bufmem.data = (char *)str;
    250      1.1  christos     bufmem.max = bufmem.length;
    251      1.1  christos     BIO_set_mem_buf(bio, &bufmem, BIO_NOCLOSE);
    252      1.1  christos     BIO_set_flags(bio, BIO_FLAGS_MEM_RDONLY);
    253      1.1  christos     BIO_set_callback_ex(bio, BIO_error_callback);
    254      1.1  christos 
    255      1.1  christos     if (!TEST_ptr(out = BIO_new(BIO_s_mem())))
    256      1.1  christos         goto finish;
    257      1.1  christos     if (!TEST_ptr(p7 = PKCS7_new()))
    258      1.1  christos         goto finish;
    259      1.1  christos     if (!TEST_true(PKCS7_set_type(p7, NID_pkcs7_data)))
    260      1.1  christos         goto finish;
    261      1.1  christos 
    262      1.1  christos     error_callback_fired = 0;
    263      1.1  christos 
    264  1.1.1.2  christos     if (!TEST_false(i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, bio,
    265  1.1.1.2  christos             SMIME_STREAM | SMIME_BINARY,
    266  1.1.1.2  christos             ASN1_ITEM_rptr(PKCS7))))
    267      1.1  christos         goto finish;
    268      1.1  christos 
    269      1.1  christos     if (!TEST_int_eq(error_callback_fired, 1))
    270      1.1  christos         goto finish;
    271      1.1  christos 
    272      1.1  christos     ok = 1;
    273      1.1  christos 
    274  1.1.1.2  christos finish:
    275      1.1  christos     BIO_free(bio);
    276      1.1  christos     BIO_free(out);
    277      1.1  christos     PKCS7_free(p7);
    278      1.1  christos     return ok;
    279      1.1  christos }
    280      1.1  christos 
    281      1.1  christos int setup_tests(void)
    282      1.1  christos {
    283      1.1  christos     ADD_TEST(test_bio_memleak);
    284      1.1  christos     ADD_TEST(test_bio_get_mem);
    285      1.1  christos     ADD_TEST(test_bio_new_mem_buf);
    286      1.1  christos     ADD_TEST(test_bio_rdonly_mem_buf);
    287      1.1  christos     ADD_TEST(test_bio_rdwr_rdonly);
    288      1.1  christos     ADD_TEST(test_bio_nonclear_rst);
    289      1.1  christos     ADD_TEST(test_bio_i2d_ASN1_mime);
    290      1.1  christos     return 1;
    291      1.1  christos }
    292