xref: /openbsd-src/regress/lib/libcrypto/err/err_test.c (revision 41cc39b37c84044448ddbe83239da4f54545e23f)
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