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