/*
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
#include "output.h"
#include "tu_local.h"
+#include <errno.h>
#include <string.h>
#include <ctype.h>
-#include "../../e_os.h"
+#include "internal/nelem.h"
+#include <openssl/asn1.h>
-/* The size of memory buffers to display on failure */
-#define MEM_BUFFER_SIZE (33)
-#define MAX_STRING_WIDTH (80)
-
-/* Output a failed test first line */
-static void test_fail_message_prefix(const char *prefix, const char *file,
- int line, const char *type,
- const char *left, const char *right,
- const char *op)
+/*
+ * Output a failed test first line.
+ * All items are optional are generally not preinted if passed as NULL.
+ * The special cases are for prefix where "ERROR" is assumed and for left
+ * and right where a non-failure message is produced if either is NULL.
+ */
+void test_fail_message_prefix(const char *prefix, const char *file,
+ int line, const char *type,
+ const char *left, const char *right,
+ const char *op)
{
- test_printf_stderr("%*s# %s: ", subtest_level(), "",
- prefix != NULL ? prefix : "ERROR");
+ test_printf_stderr("%s: ", prefix != NULL ? prefix : "ERROR");
if (type)
test_printf_stderr("(%s) ", type);
- if (op != NULL)
- test_printf_stderr("%s %s %s", left, op, right);
+ if (op != NULL) {
+ if (left != NULL && right != NULL)
+ test_printf_stderr("'%s %s %s' failed", left, op, right);
+ else
+ test_printf_stderr("'%s'", op);
+ }
if (file != NULL) {
test_printf_stderr(" @ %s:%d", file, line);
}
{
test_fail_message_prefix(prefix, file, line, type, left, right, op);
if (fmt != NULL) {
- test_printf_stderr("%*s# ", subtest_level(), "");
test_vprintf_stderr(fmt, ap);
test_printf_stderr("\n");
}
- test_printf_stderr("\n");
- test_flush_stderr();
-}
-
-static void test_fail_string_message(const char *prefix, const char *file,
- int line, const char *type,
- const char *left, const char *right,
- const char *op, const char *m1, size_t l1,
- const char *m2, size_t l2)
-{
- const int indent = subtest_level();
- const size_t width = (MAX_STRING_WIDTH - indent - 12) / 16 * 16;
- char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1];
- char bdiff[MAX_STRING_WIDTH + 1];
- size_t n1, n2, i;
- unsigned int cnt = 0, diff;
-
- test_fail_message_prefix(prefix, file, line, type, left, right, op);
- if (m1 == NULL)
- l1 = 0;
- if (m2 == NULL)
- l2 = 0;
- if (l1 == 0 && l2 == 0) {
- if ((m1 == NULL) == (m2 == NULL)) {
- test_printf_stderr("%*s# % 4s %s\n", indent, "", "",
- m1 == NULL ? "NULL" : "''");
- } else {
- test_printf_stderr("%*s# % 4s - %s\n", indent, "", "",
- m1 == NULL ? "NULL" : "''");
- test_printf_stderr("%*s# % 4s + %s\n", indent, "", "",
- m2 == NULL ? "NULL" : "''");
- }
- goto fin;
- }
-
- while (l1 > 0 || l2 > 0) {
- n1 = n2 = 0;
- if (l1 > 0) {
- b1[n1 = l1 > width ? width : l1] = 0;
- for (i = 0; i < n1; i++)
- b1[i] = isprint(m1[i]) ? m1[i] : '.';
- }
- if (l2 > 0) {
- b2[n2 = l2 > width ? width : l2] = 0;
- for (i = 0; i < n2; i++)
- b2[i] = isprint(m2[i]) ? m2[i] : '.';
- }
- diff = n1 != n2;
- i = 0;
- if (n1 > 0 && n2 > 0) {
- const size_t j = n1 < n2 ? n1 : n2;
- const size_t k = n1 > n2 ? n1 : n2;
-
- for (; i < j; i++)
- if (m1[i] == m2[i]) {
- bdiff[i] = ' ';
- } else {
- bdiff[i] = '^';
- diff = 1;
- }
- for (; i < k; i++)
- bdiff[i] = '^';
- bdiff[i] = '\0';
- }
- if (!diff) {
- test_printf_stderr("%*s# % 4u: '%s'\n", indent, "", cnt, b1);
- } else {
- if (cnt == 0 && m1 == NULL)
- test_printf_stderr("%*s# % 4s - NULL\n", indent, "", "");
- else if (cnt == 0 && *m1 == '\0')
- test_printf_stderr("%*s# % 4s - ''\n", indent, "", "");
- else if (n1 > 0)
- test_printf_stderr("%*s# % 4u:- '%s'\n", indent, "", cnt, b1);
- if (cnt == 0 && m2 == NULL)
- test_printf_stderr("%*s# % 4s + NULL\n", indent, "", "");
- else if (cnt == 0 && *m2 == '\0')
- test_printf_stderr("%*s# % 4s + ''\n", indent, "", "");
- else if (n2 > 0)
- test_printf_stderr("%*s# % 4u:+ '%s'\n", indent, "", cnt, b2);
- if (i > 0)
- test_printf_stderr("%*s# % 4s %s\n", indent, "", "", bdiff);
- }
- m1 += n1;
- m2 += n2;
- l1 -= n1;
- l2 -= n2;
- cnt += width;
- }
-fin:
- test_printf_stderr("\n");
- test_flush_stderr();
-}
-
-static void hex_convert_memory(const char *m, size_t n, char *b)
-{
- size_t i;
-
- for (i = 0; i < n; i++) {
- const unsigned char c = *m++;
-
- *b++ = "0123456789abcdef"[c >> 4];
- *b++ = "0123456789abcdef"[c & 15];
- if ((i % 8) == 7 && i != n - 1)
- *b++ = ' ';
- }
- *b = '\0';
-}
-
-static void test_fail_memory_message(const char *prefix, const char *file,
- int line, const char *type,
- const char *left, const char *right,
- const char *op, const char *m1, size_t l1,
- const char *m2, size_t l2)
-{
- const int indent = subtest_level();
- const size_t bytes = (MAX_STRING_WIDTH - 9) / 17 * 8;
- char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1];
- char *p, bdiff[MAX_STRING_WIDTH + 1];
- size_t n1, n2, i;
- unsigned int cnt = 0, diff;
-
- test_fail_message_prefix(prefix, file, line, type, left, right, op);
- if (m1 == NULL)
- l1 = 0;
- if (m2 == NULL)
- l2 = 0;
- if (l1 == 0 && l2 == 0) {
- if ((m1 == NULL) == (m2 == NULL)) {
- test_printf_stderr("%*s# %04s %s\n", indent, "", "",
- m1 == NULL ? "NULL" : "empty");
- } else {
- test_printf_stderr("%*s# %04s -%s\n", indent, "", "",
- m1 == NULL ? "NULL" : "empty");
- test_printf_stderr("%*s# %04s +%s\n", indent, "", "",
- m2 == NULL ? "NULL" : "empty");
- }
- goto fin;
- }
-
- while (l1 > 0 || l2 > 0) {
- n1 = n2 = 0;
- if (l1 > 0) {
- n1 = l1 > bytes ? bytes : l1;
- hex_convert_memory(m1, n1, b1);
- }
- if (l2 > 0) {
- n2 = l2 > bytes ? bytes : l2;
- hex_convert_memory(m2, n2, b2);
- }
-
- diff = n1 != n2;
- i = 0;
- p = bdiff;
- if (n1 > 0 && n2 > 0) {
- const size_t j = n1 < n2 ? n1 : n2;
- const size_t k = n1 > n2 ? n1 : n2;
-
- for (; i < j; i++) {
- if (m1[i] == m2[i]) {
- *p++ = ' ';
- *p++ = ' ';
- } else {
- *p++ = '^';
- *p++ = '^';
- diff = 1;
- }
- if ((i % 8) == 7 && (i != j - 1 || j != k))
- *p++ = ' ';
- }
-
- for (; i < k; i++) {
- *p++ = '^';
- *p++ = '^';
- if ((i % 8) == 7 && i != k - 1)
- *p++ = ' ';
- }
- *p++ = '\0';
- }
-
- if (!diff) {
- test_printf_stderr("%*s# %04x: %s\n", indent, "", cnt, b1);
- } else {
- if (cnt == 0 && m1 == NULL)
- test_printf_stderr("%*s# %04s -NULL\n", indent, "", "");
- else if (cnt == 0 && l1 == 0)
- test_printf_stderr("%*s# %04s -empty\n", indent, "", "");
- else if (n1 > 0)
- test_printf_stderr("%*s# %04x:-%s\n", indent, "", cnt, b1);
- if (cnt == 0 && m2 == NULL)
- test_printf_stderr("%*s# %04s +NULL\n", indent, "", "");
- else if (cnt == 0 && l2 == 0)
- test_printf_stderr("%*s# %04s +empty\n", indent, "", "");
- else if (n2 > 0)
- test_printf_stderr("%*s# %04x:+%s\n", indent, "", cnt, b2);
- if (i > 0)
- test_printf_stderr("%*s# % 4s %s\n", indent, "", "", bdiff);
- }
- m1 += n1;
- m2 += n2;
- l1 -= n1;
- l2 -= n2;
- cnt += bytes;
- }
-fin:
- test_printf_stderr("\n");
test_flush_stderr();
}
va_list ap;
va_start(ap, desc);
- test_fail_message(NULL, NULL, -1, NULL, NULL, NULL, NULL, desc, ap);
+ test_fail_message_va(NULL, NULL, -1, NULL, NULL, NULL, NULL, desc, ap);
va_end(ap);
+ test_printf_stderr("\n");
}
void test_error(const char *file, int line, const char *desc, ...)
va_start(ap, desc);
test_fail_message_va(NULL, file, line, NULL, NULL, NULL, NULL, desc, ap);
va_end(ap);
+ test_printf_stderr("\n");
+}
+
+void test_perror(const char *s)
+{
+ /*
+ * Using openssl_strerror_r causes linking issues since it isn't
+ * exported from libcrypto.so
+ */
+ TEST_error("%s: %s", s, strerror(errno));
+}
+
+void test_note(const char *fmt, ...)
+{
+ if (fmt != NULL) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ test_vprintf_stderr(fmt, ap);
+ va_end(ap);
+ test_printf_stderr("\n");
+ }
+ test_flush_stderr();
+}
+
+
+int test_skip(const char *file, int line, const char *desc, ...)
+{
+ va_list ap;
+
+ va_start(ap, desc);
+ test_fail_message_va("SKIP", file, line, NULL, NULL, NULL, NULL, desc, ap);
+ va_end(ap);
+ return TEST_SKIP_CODE;
+}
+
+int test_skip_c90(const char *desc, ...)
+{
+ va_list ap;
+
+ va_start(ap, desc);
+ test_fail_message_va("SKIP", NULL, -1, NULL, NULL, NULL, NULL, desc, ap);
+ va_end(ap);
+ test_printf_stderr("\n");
+ return TEST_SKIP_CODE;
}
+
void test_openssl_errors(void)
{
ERR_print_errors_cb(openssl_error_cb, NULL);
+ ERR_clear_error();
}
/*
DEFINE_COMPARISONS(long, long, "%ld")
DEFINE_COMPARISONS(unsigned long, ulong, "%lu")
DEFINE_COMPARISONS(size_t, size_t, "%zu")
+DEFINE_COMPARISONS(double, double, "%g")
DEFINE_COMPARISON(void *, ptr, eq, ==, "%p")
DEFINE_COMPARISON(void *, ptr, ne, !=, "%p")
}
return 1;
}
+
+#define DEFINE_BN_COMPARISONS(opname, op, zero_cond) \
+ int test_BN_ ## opname(const char *file, int line, \
+ const char *s1, const char *s2, \
+ const BIGNUM *t1, const BIGNUM *t2) \
+ { \
+ if (BN_cmp(t1, t2) op 0) \
+ return 1; \
+ test_fail_bignum_message(NULL, file, line, "BIGNUM", s1, s2, \
+ #op, t1, t2); \
+ return 0; \
+ } \
+ int test_BN_ ## opname ## _zero(const char *file, int line, \
+ const char *s, const BIGNUM *a) \
+ { \
+ if (a != NULL &&(zero_cond)) \
+ return 1; \
+ test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", \
+ s, "0", #op, a); \
+ return 0; \
+ }
+
+DEFINE_BN_COMPARISONS(eq, ==, BN_is_zero(a))
+DEFINE_BN_COMPARISONS(ne, !=, !BN_is_zero(a))
+DEFINE_BN_COMPARISONS(gt, >, !BN_is_negative(a) && !BN_is_zero(a))
+DEFINE_BN_COMPARISONS(ge, >=, !BN_is_negative(a) || BN_is_zero(a))
+DEFINE_BN_COMPARISONS(lt, <, BN_is_negative(a) && !BN_is_zero(a))
+DEFINE_BN_COMPARISONS(le, <=, BN_is_negative(a) || BN_is_zero(a))
+
+int test_BN_eq_one(const char *file, int line, const char *s, const BIGNUM *a)
+{
+ if (a != NULL && BN_is_one(a))
+ return 1;
+ test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", s, "1", "==", a);
+ return 0;
+}
+
+int test_BN_odd(const char *file, int line, const char *s, const BIGNUM *a)
+{
+ if (a != NULL && BN_is_odd(a))
+ return 1;
+ test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "ODD(", ")", s, a);
+ return 0;
+}
+
+int test_BN_even(const char *file, int line, const char *s, const BIGNUM *a)
+{
+ if (a != NULL && !BN_is_odd(a))
+ return 1;
+ test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "EVEN(", ")", s,
+ a);
+ return 0;
+}
+
+int test_BN_eq_word(const char *file, int line, const char *bns, const char *ws,
+ const BIGNUM *a, BN_ULONG w)
+{
+ BIGNUM *bw;
+
+ if (a != NULL && BN_is_word(a, w))
+ return 1;
+ bw = BN_new();
+ BN_set_word(bw, w);
+ test_fail_bignum_message(NULL, file, line, "BIGNUM", bns, ws, "==", a, bw);
+ BN_free(bw);
+ return 0;
+}
+
+int test_BN_abs_eq_word(const char *file, int line, const char *bns,
+ const char *ws, const BIGNUM *a, BN_ULONG w)
+{
+ BIGNUM *bw, *aa;
+
+ if (a != NULL && BN_abs_is_word(a, w))
+ return 1;
+ bw = BN_new();
+ aa = BN_dup(a);
+ BN_set_negative(aa, 0);
+ BN_set_word(bw, w);
+ test_fail_bignum_message(NULL, file, line, "BIGNUM", bns, ws, "abs==",
+ aa, bw);
+ BN_free(bw);
+ BN_free(aa);
+ return 0;
+}
+
+static const char *print_time(const ASN1_TIME *t)
+{
+ return t == NULL ? "<null>" : (const char *)ASN1_STRING_get0_data(t);
+}
+
+#define DEFINE_TIME_T_COMPARISON(opname, op) \
+ int test_time_t_ ## opname(const char *file, int line, \
+ const char *s1, const char *s2, \
+ const time_t t1, const time_t t2) \
+ { \
+ ASN1_TIME *at1 = ASN1_TIME_set(NULL, t1); \
+ ASN1_TIME *at2 = ASN1_TIME_set(NULL, t2); \
+ int r = at1 != NULL && at2 != NULL \
+ && ASN1_TIME_compare(at1, at2) op 0; \
+ if (!r) \
+ test_fail_message(NULL, file, line, "time_t", s1, s2, #op, \
+ "[%s] compared to [%s]", \
+ print_time(at1), print_time(at2)); \
+ ASN1_STRING_free(at1); \
+ ASN1_STRING_free(at2); \
+ return r; \
+ }
+DEFINE_TIME_T_COMPARISON(eq, ==)
+DEFINE_TIME_T_COMPARISON(ne, !=)
+DEFINE_TIME_T_COMPARISON(gt, >)
+DEFINE_TIME_T_COMPARISON(ge, >=)
+DEFINE_TIME_T_COMPARISON(lt, <)
+DEFINE_TIME_T_COMPARISON(le, <=)