1 /* 2 * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 #include <stdio.h> 10 #include <string.h> 11 #include <openssl/bio.h> 12 13 #include "testutil.h" 14 15 #define MAXCOUNT 5 16 static int my_param_count; 17 static BIO *my_param_b[MAXCOUNT]; 18 static int my_param_oper[MAXCOUNT]; 19 static const char *my_param_argp[MAXCOUNT]; 20 static int my_param_argi[MAXCOUNT]; 21 static long my_param_argl[MAXCOUNT]; 22 static long my_param_ret[MAXCOUNT]; 23 24 static long my_bio_callback(BIO *b, int oper, const char *argp, int argi, 25 long argl, long ret) 26 { 27 if (my_param_count >= MAXCOUNT) 28 return -1; 29 my_param_b[my_param_count] = b; 30 my_param_oper[my_param_count] = oper; 31 my_param_argp[my_param_count] = argp; 32 my_param_argi[my_param_count] = argi; 33 my_param_argl[my_param_count] = argl; 34 my_param_ret[my_param_count] = ret; 35 my_param_count++; 36 return ret; 37 } 38 39 static int test_bio_callback(void) 40 { 41 int ok = 0; 42 BIO *bio; 43 int i; 44 char test1[] = "test"; 45 const int test1len = sizeof(test1) - 1; 46 char test2[] = "hello"; 47 const int test2len = sizeof(test2) - 1; 48 char buf[16]; 49 50 my_param_count = 0; 51 52 bio = BIO_new(BIO_s_mem()); 53 if (bio == NULL) 54 goto err; 55 56 BIO_set_callback(bio, my_bio_callback); 57 i = BIO_write(bio, test1, test1len); 58 if (!TEST_int_eq(i, test1len) 59 || !TEST_int_eq(my_param_count, 2) 60 || !TEST_ptr_eq(my_param_b[0], bio) 61 || !TEST_int_eq(my_param_oper[0], BIO_CB_WRITE) 62 || !TEST_ptr_eq(my_param_argp[0], test1) 63 || !TEST_int_eq(my_param_argi[0], test1len) 64 || !TEST_long_eq(my_param_argl[0], 0L) 65 || !TEST_long_eq(my_param_ret[0], 1L) 66 || !TEST_ptr_eq(my_param_b[1], bio) 67 || !TEST_int_eq(my_param_oper[1], BIO_CB_WRITE | BIO_CB_RETURN) 68 || !TEST_ptr_eq(my_param_argp[1], test1) 69 || !TEST_int_eq(my_param_argi[1], test1len) 70 || !TEST_long_eq(my_param_argl[1], 0L) 71 || !TEST_long_eq(my_param_ret[1], (long)test1len)) 72 goto err; 73 74 my_param_count = 0; 75 i = BIO_read(bio, buf, sizeof(buf)); 76 if (!TEST_mem_eq(buf, i, test1, test1len) 77 || !TEST_int_eq(my_param_count, 2) 78 || !TEST_ptr_eq(my_param_b[0], bio) 79 || !TEST_int_eq(my_param_oper[0], BIO_CB_READ) 80 || !TEST_ptr_eq(my_param_argp[0], buf) 81 || !TEST_int_eq(my_param_argi[0], sizeof(buf)) 82 || !TEST_long_eq(my_param_argl[0], 0L) 83 || !TEST_long_eq(my_param_ret[0], 1L) 84 || !TEST_ptr_eq(my_param_b[1], bio) 85 || !TEST_int_eq(my_param_oper[1], BIO_CB_READ | BIO_CB_RETURN) 86 || !TEST_ptr_eq(my_param_argp[1], buf) 87 || !TEST_int_eq(my_param_argi[1], sizeof(buf)) 88 || !TEST_long_eq(my_param_argl[1], 0L) 89 || !TEST_long_eq(my_param_ret[1], (long)test1len)) 90 goto err; 91 92 /* By default a mem bio returns -1 if it has run out of data */ 93 my_param_count = 0; 94 i = BIO_read(bio, buf, sizeof(buf)); 95 if (!TEST_int_eq(i, -1) 96 || !TEST_int_eq(my_param_count, 2) 97 || !TEST_ptr_eq(my_param_b[0], bio) 98 || !TEST_int_eq(my_param_oper[0], BIO_CB_READ) 99 || !TEST_ptr_eq(my_param_argp[0], buf) 100 || !TEST_int_eq(my_param_argi[0], sizeof(buf)) 101 || !TEST_long_eq(my_param_argl[0], 0L) 102 || !TEST_long_eq(my_param_ret[0], 1L) 103 || !TEST_ptr_eq(my_param_b[1], bio) 104 || !TEST_int_eq(my_param_oper[1], BIO_CB_READ | BIO_CB_RETURN) 105 || !TEST_ptr_eq(my_param_argp[1], buf) 106 || !TEST_int_eq(my_param_argi[1], sizeof(buf)) 107 || !TEST_long_eq(my_param_argl[1], 0L) 108 || !TEST_long_eq(my_param_ret[1], -1L)) 109 goto err; 110 111 /* Force the mem bio to return 0 if it has run out of data */ 112 BIO_set_mem_eof_return(bio, 0); 113 my_param_count = 0; 114 i = BIO_read(bio, buf, sizeof(buf)); 115 if (!TEST_int_eq(i, 0) 116 || !TEST_int_eq(my_param_count, 2) 117 || !TEST_ptr_eq(my_param_b[0], bio) 118 || !TEST_int_eq(my_param_oper[0], BIO_CB_READ) 119 || !TEST_ptr_eq(my_param_argp[0], buf) 120 || !TEST_int_eq(my_param_argi[0], sizeof(buf)) 121 || !TEST_long_eq(my_param_argl[0], 0L) 122 || !TEST_long_eq(my_param_ret[0], 1L) 123 || !TEST_ptr_eq(my_param_b[1], bio) 124 || !TEST_int_eq(my_param_oper[1], BIO_CB_READ | BIO_CB_RETURN) 125 || !TEST_ptr_eq(my_param_argp[1], buf) 126 || !TEST_int_eq(my_param_argi[1], sizeof(buf)) 127 || !TEST_long_eq(my_param_argl[1], 0L) 128 || !TEST_long_eq(my_param_ret[1], 0L)) 129 goto err; 130 131 my_param_count = 0; 132 i = BIO_puts(bio, test2); 133 if (!TEST_int_eq(i, 5) 134 || !TEST_int_eq(my_param_count, 2) 135 || !TEST_ptr_eq(my_param_b[0], bio) 136 || !TEST_int_eq(my_param_oper[0], BIO_CB_PUTS) 137 || !TEST_ptr_eq(my_param_argp[0], test2) 138 || !TEST_int_eq(my_param_argi[0], 0) 139 || !TEST_long_eq(my_param_argl[0], 0L) 140 || !TEST_long_eq(my_param_ret[0], 1L) 141 || !TEST_ptr_eq(my_param_b[1], bio) 142 || !TEST_int_eq(my_param_oper[1], BIO_CB_PUTS | BIO_CB_RETURN) 143 || !TEST_ptr_eq(my_param_argp[1], test2) 144 || !TEST_int_eq(my_param_argi[1], 0) 145 || !TEST_long_eq(my_param_argl[1], 0L) 146 || !TEST_long_eq(my_param_ret[1], (long)test2len)) 147 goto err; 148 149 my_param_count = 0; 150 i = BIO_free(bio); 151 if (!TEST_int_eq(i, 1) 152 || !TEST_int_eq(my_param_count, 1) 153 || !TEST_ptr_eq(my_param_b[0], bio) 154 || !TEST_int_eq(my_param_oper[0], BIO_CB_FREE) 155 || !TEST_ptr_eq(my_param_argp[0], NULL) 156 || !TEST_int_eq(my_param_argi[0], 0) 157 || !TEST_long_eq(my_param_argl[0], 0L) 158 || !TEST_long_eq(my_param_ret[0], 1L)) 159 goto finish; 160 161 ok = 1; 162 goto finish; 163 164 err: 165 BIO_free(bio); 166 167 finish: 168 /* This helps finding memory leaks with ASAN */ 169 memset(my_param_b, 0, sizeof(my_param_b)); 170 memset(my_param_argp, 0, sizeof(my_param_argp)); 171 return ok; 172 } 173 174 int setup_tests(void) 175 { 176 ADD_TEST(test_bio_callback); 177 return 1; 178 } 179