Fix migration guide mappings for i2o/o2i_ECPublicKey
[openssl.git] / test / errtest.c
1 /*
2  * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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
10 #include <string.h>
11 #include <openssl/opensslconf.h>
12 #include <openssl/err.h>
13 #include <openssl/macros.h>
14
15 #include "testutil.h"
16
17 #if defined(OPENSSL_SYS_WINDOWS)
18 # include <windows.h>
19 #else
20 # include <errno.h>
21 #endif
22
23 #ifndef OPENSSL_NO_DEPRECATED_3_0
24 # define IS_HEX(ch) ((ch >= '0' && ch <='9') || (ch >= 'A' && ch <='F'))
25
26 static int test_print_error_format(void)
27 {
28     /* Variables used to construct an error line */
29     char *lib;
30     const char *func = OPENSSL_FUNC;
31     char *reason;
32 # ifdef OPENSSL_NO_ERR
33     char reasonbuf[255];
34 # endif
35 # ifndef OPENSSL_NO_FILENAMES
36     const char *file = OPENSSL_FILE;
37     const int line = OPENSSL_LINE;
38 # else
39     const char *file = "";
40     const int line = 0;
41 # endif
42     /* The format for OpenSSL error lines */
43     const char *expected_format = ":error:%08lX:%s:%s:%s:%s:%d";
44     /*-
45      *                                          ^^ ^^ ^^ ^^ ^^
46      * "library" name --------------------------++ || || || ||
47      * function name ------------------------------++ || || ||
48      * reason string (system error string) -----------++ || ||
49      * file name ----------------------------------------++ ||
50      * line number -----------------------------------------++
51      */
52     char expected[512];
53
54     char *out = NULL, *p = NULL;
55     int ret = 0, len;
56     BIO *bio = NULL;
57     const int syserr = EPERM;
58     unsigned long errorcode;
59     unsigned long reasoncode;
60
61     /*
62      * We set a mark here so we can clear the system error that we generate
63      * with ERR_PUT_error().  That is, after all, just a simulation to verify
64      * ERR_print_errors() output, not a real error.
65      */
66     ERR_set_mark();
67
68     ERR_PUT_error(ERR_LIB_SYS, 0, syserr, file, line);
69     errorcode = ERR_peek_error();
70     reasoncode = ERR_GET_REASON(errorcode);
71
72     if (!TEST_int_eq(reasoncode, syserr)) {
73         ERR_pop_to_mark();
74         goto err;
75     }
76
77 # ifndef OPENSSL_NO_ERR
78     lib = "system library";
79     reason = strerror(syserr);
80 # else
81     lib = "lib(2)";
82     BIO_snprintf(reasonbuf, sizeof(reasonbuf), "reason(%lu)", reasoncode);
83     reason = reasonbuf;
84 # endif
85
86     BIO_snprintf(expected, sizeof(expected), expected_format,
87                  errorcode, lib, func, reason, file, line);
88
89     if (!TEST_ptr(bio = BIO_new(BIO_s_mem())))
90         goto err;
91
92     ERR_print_errors(bio);
93
94     if (!TEST_int_gt(len = BIO_get_mem_data(bio, &out), 0))
95         goto err;
96     /* Skip over the variable thread id at the start of the string */
97     for (p = out; *p != ':' && *p != 0; ++p) {
98         if (!TEST_true(IS_HEX(*p)))
99             goto err;
100     }
101     if (!TEST_true(*p != 0)
102         || !TEST_strn_eq(expected, p, strlen(expected)))
103         goto err;
104
105     ret = 1;
106 err:
107     BIO_free(bio);
108     return ret;
109 }
110 #endif
111
112 /* Test that querying the error queue preserves the OS error. */
113 static int preserves_system_error(void)
114 {
115 #if defined(OPENSSL_SYS_WINDOWS)
116     SetLastError(ERROR_INVALID_FUNCTION);
117     ERR_get_error();
118     return TEST_int_eq(GetLastError(), ERROR_INVALID_FUNCTION);
119 #else
120     errno = EINVAL;
121     ERR_get_error();
122     return TEST_int_eq(errno, EINVAL);
123 #endif
124 }
125
126 /* Test that calls to ERR_add_error_[v]data append */
127 static int vdata_appends(void)
128 {
129     const char *data;
130
131     ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
132     ERR_add_error_data(1, "hello ");
133     ERR_add_error_data(1, "world");
134     ERR_peek_error_data(&data, NULL);
135     return TEST_str_eq(data, "hello world");
136 }
137
138 static int raised_error(void)
139 {
140     const char *f, *data;
141     int l;
142     unsigned long e;
143
144     /*
145      * When OPENSSL_NO_ERR or OPENSSL_NO_FILENAMES, no file name or line
146      * number is saved, so no point checking them.
147      */
148 #if !defined(OPENSSL_NO_FILENAMES) && !defined(OPENSSL_NO_ERR)
149     const char *file;
150     int line;
151
152     file = __FILE__;
153     line = __LINE__ + 2; /* The error is generated on the ERR_raise_data line */
154 #endif
155     ERR_raise_data(ERR_LIB_NONE, ERR_R_INTERNAL_ERROR,
156                    "calling exit()");
157     if (!TEST_ulong_ne(e = ERR_get_error_all(&f, &l, NULL, &data, NULL), 0)
158             || !TEST_int_eq(ERR_GET_REASON(e), ERR_R_INTERNAL_ERROR)
159 #if !defined(OPENSSL_NO_FILENAMES) && !defined(OPENSSL_NO_ERR)
160             || !TEST_int_eq(l, line)
161             || !TEST_str_eq(f, file)
162 #endif
163             || !TEST_str_eq(data, "calling exit()"))
164         return 0;
165     return 1;
166 }
167
168 static int test_marks(void)
169 {
170     unsigned long mallocfail, shouldnot;
171
172     /* Set an initial error */
173     ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
174     mallocfail = ERR_peek_last_error();
175     if (!TEST_ulong_gt(mallocfail, 0))
176         return 0;
177
178     /* Setting and clearing a mark should not affect the error */
179     if (!TEST_true(ERR_set_mark())
180             || !TEST_true(ERR_pop_to_mark())
181             || !TEST_ulong_eq(mallocfail, ERR_peek_last_error())
182             || !TEST_true(ERR_set_mark())
183             || !TEST_true(ERR_clear_last_mark())
184             || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()))
185         return 0;
186
187     /* Test popping errors */
188     if (!TEST_true(ERR_set_mark()))
189         return 0;
190     ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
191     if (!TEST_ulong_ne(mallocfail, ERR_peek_last_error())
192             || !TEST_true(ERR_pop_to_mark())
193             || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()))
194         return 0;
195
196     /* Nested marks should also work */
197     if (!TEST_true(ERR_set_mark())
198             || !TEST_true(ERR_set_mark()))
199         return 0;
200     ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
201     if (!TEST_ulong_ne(mallocfail, ERR_peek_last_error())
202             || !TEST_true(ERR_pop_to_mark())
203             || !TEST_true(ERR_pop_to_mark())
204             || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()))
205         return 0;
206
207     if (!TEST_true(ERR_set_mark()))
208         return 0;
209     ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
210     shouldnot = ERR_peek_last_error();
211     if (!TEST_ulong_ne(mallocfail, shouldnot)
212             || !TEST_true(ERR_set_mark()))
213         return 0;
214     ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
215     if (!TEST_ulong_ne(shouldnot, ERR_peek_last_error())
216             || !TEST_true(ERR_pop_to_mark())
217             || !TEST_ulong_eq(shouldnot, ERR_peek_last_error())
218             || !TEST_true(ERR_pop_to_mark())
219             || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()))
220         return 0;
221
222     /* Setting and clearing a mark should not affect the errors on the stack */
223     if (!TEST_true(ERR_set_mark()))
224         return 0;
225     ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
226     if (!TEST_true(ERR_clear_last_mark())
227             || !TEST_ulong_eq(shouldnot, ERR_peek_last_error()))
228         return 0;
229
230     /*
231      * Popping where no mark has been set should pop everything - but return
232      * a failure result
233      */
234     if (!TEST_false(ERR_pop_to_mark())
235             || !TEST_ulong_eq(0, ERR_peek_last_error()))
236         return 0;
237
238     /* Clearing where there is no mark should fail */
239     ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
240     if (!TEST_false(ERR_clear_last_mark())
241                 /* "get" the last error to remove it */
242             || !TEST_ulong_eq(mallocfail, ERR_get_error())
243             || !TEST_ulong_eq(0, ERR_peek_last_error()))
244         return 0;
245
246     /*
247      * Setting a mark where there are no errors in the stack should fail.
248      * NOTE: This is somewhat surprising behaviour but is historically how this
249      * function behaves. In practice we typically set marks without first
250      * checking whether there is anything on the stack - but we also don't
251      * tend to check the success of this function. It turns out to work anyway
252      * because although setting a mark with no errors fails, a subsequent call
253      * to ERR_pop_to_mark() or ERR_clear_last_mark() will do the right thing
254      * anyway (even though they will report a failure result).
255      */
256     if (!TEST_false(ERR_set_mark()))
257         return 0;
258
259     ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
260     if (!TEST_true(ERR_set_mark()))
261         return 0;
262     ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
263     ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
264
265     /* Should be able to "pop" past 2 errors */
266     if (!TEST_true(ERR_pop_to_mark())
267             || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()))
268         return 0;
269
270     if (!TEST_true(ERR_set_mark()))
271         return 0;
272     ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
273     ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
274
275     /* Should be able to "clear" past 2 errors */
276     if (!TEST_true(ERR_clear_last_mark())
277             || !TEST_ulong_eq(shouldnot, ERR_peek_last_error()))
278         return 0;
279
280     /* Clear remaining errors from last test */
281     ERR_clear_error();
282
283     return 1;
284 }
285
286 int setup_tests(void)
287 {
288     ADD_TEST(preserves_system_error);
289     ADD_TEST(vdata_appends);
290     ADD_TEST(raised_error);
291 #ifndef OPENSSL_NO_DEPRECATED_3_0
292     ADD_TEST(test_print_error_format);
293 #endif
294     ADD_TEST(test_marks);
295     return 1;
296 }