1 /* $OpenBSD: err_test.c,v 1.2 2024/10/11 07:54:22 jsing Exp $ */ 2 /* 3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <string.h> 19 20 #include <openssl/bn.h> 21 #include <openssl/crypto.h> 22 #include <openssl/err.h> 23 24 /* 25 * This should also test: 26 * - error handling with more than ERR_NUM_ERRORS. 27 * - multi-threaded use. 28 */ 29 30 static int 31 err_test(void) 32 { 33 const char *file, *s; 34 char buf[2048]; 35 unsigned long err; 36 int line; 37 int failed = 1; 38 39 ERR_load_crypto_strings(); 40 41 ERR_remove_state(0); 42 43 ERR_clear_error(); 44 45 if ((err = ERR_peek_error()) != 0) { 46 fprintf(stderr, "FAIL: ERR_peek_error() = %lx, want " 47 "0x0\n", err); 48 goto failure; 49 } 50 if ((err = ERR_get_error()) != 0) { 51 fprintf(stderr, "FAIL: ERR_get_error() = %lx, want " 52 "0x0\n", err); 53 goto failure; 54 } 55 56 ERR_put_error(ERR_LIB_SYS, SYS_F_SOCKET, ERR_R_MALLOC_FAILURE, 57 "sys.c", 100); 58 ERR_put_error(ERR_LIB_BN, BN_F_BN_USUB, BN_R_DIV_BY_ZERO, 59 "bn.c", 200); 60 61 if ((err = ERR_peek_error()) != 0x2004041UL) { 62 fprintf(stderr, "FAIL: ERR_peek_error() = %lx, want " 63 "0x2004041UL\n", err); 64 goto failure; 65 } 66 if ((err = ERR_peek_error_line(&file, &line)) != 0x2004041UL) { 67 fprintf(stderr, "FAIL: ERR_peek_error_line() = %lx, want " 68 "0x2004041\n", err); 69 goto failure; 70 } 71 if (strcmp(file, "sys.c") != 0) { 72 fprintf(stderr, "FAIL: got file '%s', want 'sys.c'", file); 73 goto failure; 74 } 75 if (line != 100) { 76 fprintf(stderr, "FAIL: line = %d, want 100", line); 77 goto failure; 78 } 79 80 if ((err = ERR_peek_last_error()) != 0x3073067UL) { 81 fprintf(stderr, "FAIL: ERR_peek_error() = %lx, want " 82 "0x3073067\n", err); 83 goto failure; 84 } 85 if ((err = ERR_peek_last_error_line(&file, &line)) != 0x3073067UL) { 86 fprintf(stderr, "FAIL: ERR_peek_last_error_line() = %lx, want " 87 "0x3073067\n", err); 88 goto failure; 89 } 90 if (strcmp(file, "bn.c") != 0) { 91 fprintf(stderr, "FAIL: got file '%s', want 'bn.c'", file); 92 goto failure; 93 } 94 if (line != 200) { 95 fprintf(stderr, "FAIL: line = %d, want 200", line); 96 goto failure; 97 } 98 99 if ((err = ERR_get_error()) != 0x2004041UL) { 100 fprintf(stderr, "FAIL: ERR_get_error() = %lx, want " 101 "0x2004041\n", err); 102 goto failure; 103 } 104 105 if ((err = ERR_peek_error()) != 0x3073067UL) { 106 fprintf(stderr, "FAIL: ERR_peek_error() = %lx, want " 107 "0x3073067\n", err); 108 goto failure; 109 } 110 111 if ((err = ERR_get_error_line(&file, &line)) != 0x3073067UL) { 112 fprintf(stderr, "FAIL: ERR_get_error_line() = %lx, want " 113 "0x3073067\n", err); 114 goto failure; 115 } 116 if (strcmp(file, "bn.c") != 0) { 117 fprintf(stderr, "FAIL: got file '%s', want 'bn.c'", file); 118 goto failure; 119 } 120 if (line != 200) { 121 fprintf(stderr, "FAIL: line = %d, want 200", line); 122 goto failure; 123 } 124 125 if ((err = ERR_get_error()) != 0) { 126 fprintf(stderr, "FAIL: ERR_get_error() = %lx, want " 127 "0x0\n", err); 128 goto failure; 129 } 130 131 ERR_clear_error(); 132 133 /* 134 * Check SYSerror() reasons, which are dynamically populated from 135 * strerror(). 136 */ 137 ERR_put_error(ERR_LIB_SYS, 0xfff, 1, "err.c", 300); 138 139 if ((err = ERR_get_error()) != 0x2fff001UL) { 140 fprintf(stderr, "FAIL: ERR_get_error() = %lx, want " 141 "0x2fff001UL\n", err); 142 goto failure; 143 } 144 s = ERR_reason_error_string(err); 145 if (strcmp(s, strerror(ERR_GET_REASON(err))) != 0) { 146 fprintf(stderr, "FAIL: ERR_reason_error_string() = '%s', " 147 "want '%s'\n", s, strerror(ERR_GET_REASON(err))); 148 goto failure; 149 } 150 151 s = ERR_lib_error_string(0x3fff067UL); 152 if (strcmp(s, "bignum routines") != 0) { 153 fprintf(stderr, "FAIL: ERR_lib_error_string() = '%s', " 154 "want 'bignum routines'\n", s); 155 goto failure; 156 } 157 158 s = ERR_func_error_string(0x3fff067UL); 159 if (strcmp(s, "CRYPTO_internal") != 0) { 160 fprintf(stderr, "FAIL: ERR_func_error_string() = '%s', " 161 "want 'CRYPTO_internal'\n", s); 162 goto failure; 163 } 164 165 s = ERR_reason_error_string(0x3fff067UL); 166 if (strcmp(s, "div by zero") != 0) { 167 fprintf(stderr, "FAIL: ERR_reason_error_string() = '%s', " 168 "want 'div by zero'\n", s); 169 goto failure; 170 } 171 172 ERR_remove_state(0); 173 174 s = ERR_error_string(0x3fff067UL, NULL); 175 if (strcmp(s, "error:03FFF067:bignum routines:CRYPTO_internal:div by zero") != 0) { 176 fprintf(stderr, "FAIL: ERR_error_string() = '%s', " 177 "want 'error:03FFF067:bignum routines:CRYPTO_internal:div by zero'\n", s); 178 goto failure; 179 } 180 memset(buf, 0xdb, sizeof(buf)); 181 s = ERR_error_string(0x3fff067UL, buf); 182 if (s != buf) { 183 fprintf(stderr, "FAIL: ERR_error_string() did not " 184 "return buffer\n"); 185 goto failure; 186 } 187 if (strcmp(s, "error:03FFF067:bignum routines:CRYPTO_internal:div by zero") != 0) { 188 fprintf(stderr, "FAIL: ERR_error_string() = '%s', " 189 "want 'error:03FFF067:bignum routines:CRYPTO_internal:div by zero'\n", s); 190 goto failure; 191 } 192 193 memset(buf, 0xdb, sizeof(buf)); 194 ERR_error_string_n(0x3fff067UL, buf, sizeof(buf)); 195 if (strcmp(s, "error:03FFF067:bignum routines:CRYPTO_internal:div by zero") != 0) { 196 fprintf(stderr, "FAIL: ERR_error_string() = '%s', " 197 "want 'error:03FFF067:bignum routines:CRYPTO_internal:div by zero'\n", s); 198 goto failure; 199 } 200 201 failed = 0; 202 203 failure: 204 205 return failed; 206 } 207 208 int 209 main(int argc, char **argv) 210 { 211 int failed = 0; 212 213 failed |= err_test(); 214 215 /* Force a clean up. */ 216 OPENSSL_cleanup(); 217 218 return failed; 219 } 220