]>
Commit | Line | Data |
---|---|---|
440e5d80 | 1 | /* |
556009c5 | 2 | * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. |
5e3de8e6 | 3 | * |
909f1a2e | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
440e5d80 RS |
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 | |
5e3de8e6 MB |
8 | */ |
9 | ||
4db40c94 | 10 | #include "../testutil.h" |
579d0fab | 11 | #include "output.h" |
c5657cb7 | 12 | #include "tu_local.h" |
5e3de8e6 | 13 | |
8fe3127c | 14 | #include <errno.h> |
ce2cdac2 | 15 | #include <string.h> |
516decae | 16 | #include <ctype.h> |
b7af3f14 | 17 | #include <openssl/asn1.h> |
6ec327ee | 18 | |
37916462 P |
19 | /* |
20 | * Output a failed test first line. | |
10fe5e29 | 21 | * All items are optional are generally not printed if passed as NULL. |
37916462 P |
22 | * The special cases are for prefix where "ERROR" is assumed and for left |
23 | * and right where a non-failure message is produced if either is NULL. | |
24 | */ | |
25 | void test_fail_message_prefix(const char *prefix, const char *file, | |
26 | int line, const char *type, | |
27 | const char *left, const char *right, | |
28 | const char *op) | |
516decae | 29 | { |
a69de3f2 | 30 | test_printf_stderr("%s: ", prefix != NULL ? prefix : "ERROR"); |
516decae P |
31 | if (type) |
32 | test_printf_stderr("(%s) ", type); | |
37916462 P |
33 | if (op != NULL) { |
34 | if (left != NULL && right != NULL) | |
35 | test_printf_stderr("'%s %s %s' failed", left, op, right); | |
36 | else | |
37 | test_printf_stderr("'%s'", op); | |
38 | } | |
516decae P |
39 | if (file != NULL) { |
40 | test_printf_stderr(" @ %s:%d", file, line); | |
41 | } | |
42 | test_printf_stderr("\n"); | |
43 | } | |
2fae041d | 44 | |
2fae041d P |
45 | /* |
46 | * A common routine to output test failure messages. Generally this should not | |
47 | * be called directly, rather it should be called by the following functions. | |
48 | * | |
49 | * |desc| is a printf formatted description with arguments |args| that is | |
50 | * supplied by the user and |desc| can be NULL. |type| is the data type | |
51 | * that was tested (int, char, ptr, ...). |fmt| is a system provided | |
52 | * printf format with following arguments that spell out the failure | |
53 | * details i.e. the actual values compared and the operator used. | |
54 | * | |
55 | * The typical use for this is from an utility test function: | |
56 | * | |
57 | * int test6(const char *file, int line, int n) { | |
58 | * if (n != 6) { | |
59 | * test_fail_message(1, file, line, "int", "value %d is not %d", n, 6); | |
60 | * return 0; | |
61 | * } | |
62 | * return 1; | |
63 | * } | |
64 | * | |
65 | * calling test6(3, "oops") will return 0 and produce out along the lines of: | |
66 | * FAIL oops: (int) value 3 is not 6\n | |
2fae041d P |
67 | */ |
68 | static void test_fail_message(const char *prefix, const char *file, int line, | |
516decae P |
69 | const char *type, const char *left, |
70 | const char *right, const char *op, | |
71 | const char *fmt, ...) | |
72 | PRINTF_FORMAT(8, 9); | |
73 | ||
74 | static void test_fail_message_va(const char *prefix, const char *file, | |
75 | int line, const char *type, | |
76 | const char *left, const char *right, | |
77 | const char *op, const char *fmt, va_list ap) | |
2fae041d | 78 | { |
516decae | 79 | test_fail_message_prefix(prefix, file, line, type, left, right, op); |
2fae041d | 80 | if (fmt != NULL) { |
4db40c94 | 81 | test_vprintf_stderr(fmt, ap); |
516decae | 82 | test_printf_stderr("\n"); |
2fae041d | 83 | } |
516decae P |
84 | test_flush_stderr(); |
85 | } | |
86 | ||
87 | static void test_fail_message(const char *prefix, const char *file, | |
88 | int line, const char *type, | |
89 | const char *left, const char *right, | |
90 | const char *op, const char *fmt, ...) | |
2fae041d P |
91 | { |
92 | va_list ap; | |
4db40c94 | 93 | |
2fae041d | 94 | va_start(ap, fmt); |
516decae | 95 | test_fail_message_va(prefix, file, line, type, left, right, op, fmt, ap); |
2fae041d P |
96 | va_end(ap); |
97 | } | |
98 | ||
99 | void test_info_c90(const char *desc, ...) | |
100 | { | |
101 | va_list ap; | |
102 | ||
103 | va_start(ap, desc); | |
516decae | 104 | test_fail_message_va("INFO", NULL, -1, NULL, NULL, NULL, NULL, desc, ap); |
2fae041d P |
105 | va_end(ap); |
106 | } | |
107 | ||
108 | void test_info(const char *file, int line, const char *desc, ...) | |
109 | { | |
110 | va_list ap; | |
111 | ||
112 | va_start(ap, desc); | |
516decae | 113 | test_fail_message_va("INFO", file, line, NULL, NULL, NULL, NULL, desc, ap); |
2fae041d P |
114 | va_end(ap); |
115 | } | |
116 | ||
117 | void test_error_c90(const char *desc, ...) | |
118 | { | |
119 | va_list ap; | |
120 | ||
121 | va_start(ap, desc); | |
dd591877 | 122 | test_fail_message_va(NULL, NULL, -1, NULL, NULL, NULL, NULL, desc, ap); |
2fae041d | 123 | va_end(ap); |
37916462 | 124 | test_printf_stderr("\n"); |
2fae041d P |
125 | } |
126 | ||
127 | void test_error(const char *file, int line, const char *desc, ...) | |
128 | { | |
129 | va_list ap; | |
130 | ||
131 | va_start(ap, desc); | |
516decae | 132 | test_fail_message_va(NULL, file, line, NULL, NULL, NULL, NULL, desc, ap); |
2fae041d | 133 | va_end(ap); |
37916462 P |
134 | test_printf_stderr("\n"); |
135 | } | |
136 | ||
8fe3127c P |
137 | void test_perror(const char *s) |
138 | { | |
139 | /* | |
140 | * Using openssl_strerror_r causes linking issues since it isn't | |
141 | * exported from libcrypto.so | |
142 | */ | |
143 | TEST_error("%s: %s", s, strerror(errno)); | |
144 | } | |
145 | ||
37916462 P |
146 | void test_note(const char *fmt, ...) |
147 | { | |
37916462 | 148 | if (fmt != NULL) { |
7b4d3230 RL |
149 | va_list ap; |
150 | ||
7b4d3230 | 151 | va_start(ap, fmt); |
37916462 | 152 | test_vprintf_stderr(fmt, ap); |
7b4d3230 | 153 | va_end(ap); |
37916462 P |
154 | test_printf_stderr("\n"); |
155 | } | |
156 | test_flush_stderr(); | |
2fae041d P |
157 | } |
158 | ||
c5f7a996 P |
159 | |
160 | int test_skip(const char *file, int line, const char *desc, ...) | |
161 | { | |
162 | va_list ap; | |
163 | ||
164 | va_start(ap, desc); | |
165 | test_fail_message_va("SKIP", file, line, NULL, NULL, NULL, NULL, desc, ap); | |
166 | va_end(ap); | |
167 | return TEST_SKIP_CODE; | |
168 | } | |
169 | ||
170 | int test_skip_c90(const char *desc, ...) | |
171 | { | |
172 | va_list ap; | |
173 | ||
174 | va_start(ap, desc); | |
175 | test_fail_message_va("SKIP", NULL, -1, NULL, NULL, NULL, NULL, desc, ap); | |
176 | va_end(ap); | |
177 | test_printf_stderr("\n"); | |
178 | return TEST_SKIP_CODE; | |
179 | } | |
180 | ||
181 | ||
68e49bf2 RL |
182 | void test_openssl_errors(void) |
183 | { | |
184 | ERR_print_errors_cb(openssl_error_cb, NULL); | |
8fe3127c | 185 | ERR_clear_error(); |
68e49bf2 RL |
186 | } |
187 | ||
2fae041d P |
188 | /* |
189 | * Define some comparisons between pairs of various types. | |
190 | * These functions return 1 if the test is true. | |
191 | * Otherwise, they return 0 and pretty-print diagnostics. | |
192 | * | |
193 | * In each case the functions produced are: | |
194 | * int test_name_eq(const type t1, const type t2, const char *desc, ...); | |
195 | * int test_name_ne(const type t1, const type t2, const char *desc, ...); | |
196 | * int test_name_lt(const type t1, const type t2, const char *desc, ...); | |
197 | * int test_name_le(const type t1, const type t2, const char *desc, ...); | |
198 | * int test_name_gt(const type t1, const type t2, const char *desc, ...); | |
199 | * int test_name_ge(const type t1, const type t2, const char *desc, ...); | |
200 | * | |
201 | * The t1 and t2 arguments are to be compared for equality, inequality, | |
202 | * less than, less than or equal to, greater than and greater than or | |
203 | * equal to respectively. If the specified condition holds, the functions | |
204 | * return 1. If the condition does not hold, the functions print a diagnostic | |
205 | * message and return 0. | |
206 | * | |
207 | * The desc argument is a printf format string followed by its arguments and | |
208 | * this is included in the output if the condition being tested for is false. | |
209 | */ | |
416d0a63 | 210 | #define DEFINE_COMPARISON(type, name, opname, op, fmt, cast) \ |
2fae041d P |
211 | int test_ ## name ## _ ## opname(const char *file, int line, \ |
212 | const char *s1, const char *s2, \ | |
213 | const type t1, const type t2) \ | |
214 | { \ | |
215 | if (t1 op t2) \ | |
216 | return 1; \ | |
516decae P |
217 | test_fail_message(NULL, file, line, #type, s1, s2, #op, \ |
218 | "[" fmt "] compared to [" fmt "]", \ | |
416d0a63 | 219 | (cast)t1, (cast)t2); \ |
2fae041d P |
220 | return 0; \ |
221 | } | |
222 | ||
416d0a63 HL |
223 | #define DEFINE_COMPARISONS(type, name, fmt, cast) \ |
224 | DEFINE_COMPARISON(type, name, eq, ==, fmt, cast) \ | |
225 | DEFINE_COMPARISON(type, name, ne, !=, fmt, cast) \ | |
226 | DEFINE_COMPARISON(type, name, lt, <, fmt, cast) \ | |
227 | DEFINE_COMPARISON(type, name, le, <=, fmt, cast) \ | |
228 | DEFINE_COMPARISON(type, name, gt, >, fmt, cast) \ | |
229 | DEFINE_COMPARISON(type, name, ge, >=, fmt, cast) | |
230 | ||
231 | DEFINE_COMPARISONS(int, int, "%d", int) | |
232 | DEFINE_COMPARISONS(unsigned int, uint, "%u", unsigned int) | |
233 | DEFINE_COMPARISONS(char, char, "%c", char) | |
234 | DEFINE_COMPARISONS(unsigned char, uchar, "%u", unsigned char) | |
235 | DEFINE_COMPARISONS(long, long, "%ld", long) | |
236 | DEFINE_COMPARISONS(unsigned long, ulong, "%lu", unsigned long) | |
237 | DEFINE_COMPARISONS(int64_t, int64_t, "%lld", long long) | |
238 | DEFINE_COMPARISONS(uint64_t, uint64_t, "%llu", unsigned long long) | |
239 | DEFINE_COMPARISONS(size_t, size_t, "%zu", size_t) | |
240 | DEFINE_COMPARISONS(double, double, "%g", double) | |
241 | ||
242 | DEFINE_COMPARISON(void *, ptr, eq, ==, "%p", void *) | |
243 | DEFINE_COMPARISON(void *, ptr, ne, !=, "%p", void *) | |
2fae041d P |
244 | |
245 | int test_ptr_null(const char *file, int line, const char *s, const void *p) | |
246 | { | |
247 | if (p == NULL) | |
248 | return 1; | |
516decae | 249 | test_fail_message(NULL, file, line, "ptr", s, "NULL", "==", "%p", p); |
2fae041d P |
250 | return 0; |
251 | } | |
252 | ||
253 | int test_ptr(const char *file, int line, const char *s, const void *p) | |
254 | { | |
255 | if (p != NULL) | |
256 | return 1; | |
516decae | 257 | test_fail_message(NULL, file, line, "ptr", s, "NULL", "!=", "%p", p); |
2fae041d P |
258 | return 0; |
259 | } | |
260 | ||
261 | int test_true(const char *file, int line, const char *s, int b) | |
262 | { | |
263 | if (b) | |
264 | return 1; | |
516decae | 265 | test_fail_message(NULL, file, line, "bool", s, "true", "==", "false"); |
2fae041d P |
266 | return 0; |
267 | } | |
268 | ||
269 | int test_false(const char *file, int line, const char *s, int b) | |
270 | { | |
271 | if (!b) | |
272 | return 1; | |
516decae | 273 | test_fail_message(NULL, file, line, "bool", s, "false", "==", "true"); |
2fae041d P |
274 | return 0; |
275 | } | |
276 | ||
2fae041d P |
277 | int test_str_eq(const char *file, int line, const char *st1, const char *st2, |
278 | const char *s1, const char *s2) | |
ce2cdac2 EK |
279 | { |
280 | if (s1 == NULL && s2 == NULL) | |
281 | return 1; | |
282 | if (s1 == NULL || s2 == NULL || strcmp(s1, s2) != 0) { | |
516decae P |
283 | test_fail_string_message(NULL, file, line, "string", st1, st2, "==", |
284 | s1, s1 == NULL ? 0 : strlen(s1), | |
285 | s2, s2 == NULL ? 0 : strlen(s2)); | |
2fae041d P |
286 | return 0; |
287 | } | |
288 | return 1; | |
289 | } | |
290 | ||
291 | int test_str_ne(const char *file, int line, const char *st1, const char *st2, | |
292 | const char *s1, const char *s2) | |
293 | { | |
294 | if ((s1 == NULL) ^ (s2 == NULL)) | |
295 | return 1; | |
296 | if (s1 == NULL || strcmp(s1, s2) == 0) { | |
516decae P |
297 | test_fail_string_message(NULL, file, line, "string", st1, st2, "!=", |
298 | s1, s1 == NULL ? 0 : strlen(s1), | |
299 | s2, s2 == NULL ? 0 : strlen(s2)); | |
2fae041d P |
300 | return 0; |
301 | } | |
302 | return 1; | |
303 | } | |
304 | ||
adcd8e37 | 305 | int test_strn_eq(const char *file, int line, const char *st1, const char *st2, |
319d0b2b | 306 | const char *s1, size_t n1, const char *s2, size_t n2) |
adcd8e37 | 307 | { |
adcd8e37 RS |
308 | if (s1 == NULL && s2 == NULL) |
309 | return 1; | |
319d0b2b | 310 | if (n1 != n2 || s1 == NULL || s2 == NULL || strncmp(s1, s2, n1) != 0) { |
516decae | 311 | test_fail_string_message(NULL, file, line, "string", st1, st2, "==", |
319d0b2b RL |
312 | s1, s1 == NULL ? 0 : OPENSSL_strnlen(s1, n1), |
313 | s2, s2 == NULL ? 0 : OPENSSL_strnlen(s2, n2)); | |
adcd8e37 RS |
314 | return 0; |
315 | } | |
316 | return 1; | |
317 | } | |
318 | ||
319 | int test_strn_ne(const char *file, int line, const char *st1, const char *st2, | |
319d0b2b | 320 | const char *s1, size_t n1, const char *s2, size_t n2) |
adcd8e37 | 321 | { |
adcd8e37 RS |
322 | if ((s1 == NULL) ^ (s2 == NULL)) |
323 | return 1; | |
319d0b2b | 324 | if (n1 != n2 || s1 == NULL || strncmp(s1, s2, n1) == 0) { |
516decae | 325 | test_fail_string_message(NULL, file, line, "string", st1, st2, "!=", |
319d0b2b RL |
326 | s1, s1 == NULL ? 0 : OPENSSL_strnlen(s1, n1), |
327 | s2, s2 == NULL ? 0 : OPENSSL_strnlen(s2, n2)); | |
adcd8e37 RS |
328 | return 0; |
329 | } | |
330 | return 1; | |
331 | } | |
332 | ||
2fae041d P |
333 | int test_mem_eq(const char *file, int line, const char *st1, const char *st2, |
334 | const void *s1, size_t n1, const void *s2, size_t n2) | |
335 | { | |
2fae041d P |
336 | if (s1 == NULL && s2 == NULL) |
337 | return 1; | |
ee6b68ce | 338 | if (n1 != n2 || s1 == NULL || s2 == NULL || memcmp(s1, s2, n1) != 0) { |
516decae P |
339 | test_fail_memory_message(NULL, file, line, "memory", st1, st2, "==", |
340 | s1, n1, s2, n2); | |
2fae041d P |
341 | return 0; |
342 | } | |
343 | return 1; | |
344 | } | |
345 | ||
346 | int test_mem_ne(const char *file, int line, const char *st1, const char *st2, | |
347 | const void *s1, size_t n1, const void *s2, size_t n2) | |
348 | { | |
2fae041d | 349 | if ((s1 == NULL) ^ (s2 == NULL)) |
ee6b68ce | 350 | return 1; |
2fae041d P |
351 | if (n1 != n2) |
352 | return 1; | |
353 | if (s1 == NULL || memcmp(s1, s2, n1) == 0) { | |
516decae P |
354 | test_fail_memory_message(NULL, file, line, "memory", st1, st2, "!=", |
355 | s1, n1, s2, n2); | |
ce2cdac2 EK |
356 | return 0; |
357 | } | |
358 | return 1; | |
359 | } | |
dc352c19 P |
360 | |
361 | #define DEFINE_BN_COMPARISONS(opname, op, zero_cond) \ | |
362 | int test_BN_ ## opname(const char *file, int line, \ | |
363 | const char *s1, const char *s2, \ | |
364 | const BIGNUM *t1, const BIGNUM *t2) \ | |
365 | { \ | |
366 | if (BN_cmp(t1, t2) op 0) \ | |
367 | return 1; \ | |
368 | test_fail_bignum_message(NULL, file, line, "BIGNUM", s1, s2, \ | |
369 | #op, t1, t2); \ | |
370 | return 0; \ | |
371 | } \ | |
372 | int test_BN_ ## opname ## _zero(const char *file, int line, \ | |
373 | const char *s, const BIGNUM *a) \ | |
374 | { \ | |
375 | if (a != NULL &&(zero_cond)) \ | |
376 | return 1; \ | |
377 | test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", \ | |
378 | s, "0", #op, a); \ | |
379 | return 0; \ | |
380 | } | |
381 | ||
382 | DEFINE_BN_COMPARISONS(eq, ==, BN_is_zero(a)) | |
383 | DEFINE_BN_COMPARISONS(ne, !=, !BN_is_zero(a)) | |
384 | DEFINE_BN_COMPARISONS(gt, >, !BN_is_negative(a) && !BN_is_zero(a)) | |
385 | DEFINE_BN_COMPARISONS(ge, >=, !BN_is_negative(a) || BN_is_zero(a)) | |
386 | DEFINE_BN_COMPARISONS(lt, <, BN_is_negative(a) && !BN_is_zero(a)) | |
387 | DEFINE_BN_COMPARISONS(le, <=, BN_is_negative(a) || BN_is_zero(a)) | |
388 | ||
389 | int test_BN_eq_one(const char *file, int line, const char *s, const BIGNUM *a) | |
390 | { | |
391 | if (a != NULL && BN_is_one(a)) | |
392 | return 1; | |
393 | test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", s, "1", "==", a); | |
394 | return 0; | |
395 | } | |
396 | ||
397 | int test_BN_odd(const char *file, int line, const char *s, const BIGNUM *a) | |
398 | { | |
399 | if (a != NULL && BN_is_odd(a)) | |
400 | return 1; | |
ffbaf06a | 401 | test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "ODD(", ")", s, a); |
dc352c19 P |
402 | return 0; |
403 | } | |
404 | ||
405 | int test_BN_even(const char *file, int line, const char *s, const BIGNUM *a) | |
406 | { | |
407 | if (a != NULL && !BN_is_odd(a)) | |
408 | return 1; | |
409 | test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "EVEN(", ")", s, | |
410 | a); | |
411 | return 0; | |
412 | } | |
413 | ||
414 | int test_BN_eq_word(const char *file, int line, const char *bns, const char *ws, | |
415 | const BIGNUM *a, BN_ULONG w) | |
416 | { | |
417 | BIGNUM *bw; | |
418 | ||
419 | if (a != NULL && BN_is_word(a, w)) | |
420 | return 1; | |
d99004fe | 421 | if ((bw = BN_new()) != NULL) |
422 | BN_set_word(bw, w); | |
dc352c19 P |
423 | test_fail_bignum_message(NULL, file, line, "BIGNUM", bns, ws, "==", a, bw); |
424 | BN_free(bw); | |
425 | return 0; | |
426 | } | |
427 | ||
428 | int test_BN_abs_eq_word(const char *file, int line, const char *bns, | |
429 | const char *ws, const BIGNUM *a, BN_ULONG w) | |
430 | { | |
431 | BIGNUM *bw, *aa; | |
432 | ||
433 | if (a != NULL && BN_abs_is_word(a, w)) | |
434 | return 1; | |
d99004fe | 435 | if ((aa = BN_dup(a)) != NULL) |
436 | BN_set_negative(aa, 0); | |
437 | if ((bw = BN_new()) != NULL) | |
438 | BN_set_word(bw, w); | |
dc352c19 P |
439 | test_fail_bignum_message(NULL, file, line, "BIGNUM", bns, ws, "abs==", |
440 | aa, bw); | |
441 | BN_free(bw); | |
442 | BN_free(aa); | |
443 | return 0; | |
444 | } | |
b7af3f14 P |
445 | |
446 | static const char *print_time(const ASN1_TIME *t) | |
447 | { | |
8343229b | 448 | return t == NULL ? "<null>" : (const char *)ASN1_STRING_get0_data(t); |
b7af3f14 P |
449 | } |
450 | ||
451 | #define DEFINE_TIME_T_COMPARISON(opname, op) \ | |
452 | int test_time_t_ ## opname(const char *file, int line, \ | |
453 | const char *s1, const char *s2, \ | |
454 | const time_t t1, const time_t t2) \ | |
455 | { \ | |
456 | ASN1_TIME *at1 = ASN1_TIME_set(NULL, t1); \ | |
457 | ASN1_TIME *at2 = ASN1_TIME_set(NULL, t2); \ | |
458 | int r = at1 != NULL && at2 != NULL \ | |
459 | && ASN1_TIME_compare(at1, at2) op 0; \ | |
460 | if (!r) \ | |
461 | test_fail_message(NULL, file, line, "time_t", s1, s2, #op, \ | |
462 | "[%s] compared to [%s]", \ | |
463 | print_time(at1), print_time(at2)); \ | |
464 | ASN1_STRING_free(at1); \ | |
465 | ASN1_STRING_free(at2); \ | |
466 | return r; \ | |
467 | } | |
468 | DEFINE_TIME_T_COMPARISON(eq, ==) | |
469 | DEFINE_TIME_T_COMPARISON(ne, !=) | |
470 | DEFINE_TIME_T_COMPARISON(gt, >) | |
471 | DEFINE_TIME_T_COMPARISON(ge, >=) | |
472 | DEFINE_TIME_T_COMPARISON(lt, <) | |
473 | DEFINE_TIME_T_COMPARISON(le, <=) |