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