Imported OpenSSL 1.1.1a

This commit is contained in:
Steve Dower
2019-02-08 14:45:21 -08:00
parent 66bc075dac
commit d6b2cd4920
3033 changed files with 1039677 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 "../testutil.h"
#include "output.h"
#include "tu_local.h"
#include <openssl/crypto.h>
#include <openssl/bio.h>
BIO *bio_out = NULL;
BIO *bio_err = NULL;
void test_open_streams(void)
{
bio_out = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT);
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
#ifdef __VMS
bio_out = BIO_push(BIO_new(BIO_f_linebuffer()), bio_out);
bio_err = BIO_push(BIO_new(BIO_f_linebuffer()), bio_err);
#endif
bio_err = BIO_push(BIO_new(BIO_f_tap()), bio_err);
OPENSSL_assert(bio_out != NULL);
OPENSSL_assert(bio_err != NULL);
}
void test_close_streams(void)
{
BIO_free_all(bio_out);
BIO_free_all(bio_err);
}
int test_vprintf_stdout(const char *fmt, va_list ap)
{
return BIO_vprintf(bio_out, fmt, ap);
}
int test_vprintf_stderr(const char *fmt, va_list ap)
{
return BIO_vprintf(bio_err, fmt, ap);
}
int test_flush_stdout(void)
{
return BIO_flush(bio_out);
}
int test_flush_stderr(void)
{
return BIO_flush(bio_err);
}

16
test/testutil/cb.c Normal file
View File

@@ -0,0 +1,16 @@
/*
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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"
int openssl_error_cb(const char *str, size_t len, void *u)
{
return test_printf_stderr("%s", str);
}

299
test/testutil/driver.c Normal file
View File

@@ -0,0 +1,299 @@
/*
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 "../testutil.h"
#include "output.h"
#include "tu_local.h"
#include <string.h>
#include <assert.h>
#include "internal/nelem.h"
#include <openssl/bio.h>
#ifdef _WIN32
# define strdup _strdup
#endif
/*
* Declares the structures needed to register each test case function.
*/
typedef struct test_info {
const char *test_case_name;
int (*test_fn) (void);
int (*param_test_fn)(int idx);
int num;
/* flags */
int subtest:1;
} TEST_INFO;
static TEST_INFO all_tests[1024];
static int num_tests = 0;
static int seed = 0;
/*
* A parameterised tests runs a loop of test cases.
* |num_test_cases| counts the total number of test cases
* across all tests.
*/
static int num_test_cases = 0;
void add_test(const char *test_case_name, int (*test_fn) (void))
{
assert(num_tests != OSSL_NELEM(all_tests));
all_tests[num_tests].test_case_name = test_case_name;
all_tests[num_tests].test_fn = test_fn;
all_tests[num_tests].num = -1;
++num_tests;
++num_test_cases;
}
void add_all_tests(const char *test_case_name, int(*test_fn)(int idx),
int num, int subtest)
{
assert(num_tests != OSSL_NELEM(all_tests));
all_tests[num_tests].test_case_name = test_case_name;
all_tests[num_tests].param_test_fn = test_fn;
all_tests[num_tests].num = num;
all_tests[num_tests].subtest = subtest;
++num_tests;
num_test_cases += num;
}
static int level = 0;
int subtest_level(void)
{
return level;
}
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
static int should_report_leaks(void)
{
/*
* When compiled with enable-crypto-mdebug, OPENSSL_DEBUG_MEMORY=0
* can be used to disable leak checking at runtime.
* Note this only works when running the test binary manually;
* the test harness always enables OPENSSL_DEBUG_MEMORY.
*/
char *mem_debug_env = getenv("OPENSSL_DEBUG_MEMORY");
return mem_debug_env == NULL
|| (strcmp(mem_debug_env, "0") && strcmp(mem_debug_env, ""));
}
#endif
static int gcd(int a, int b)
{
while (b != 0) {
int t = b;
b = a % b;
a = t;
}
return a;
}
void setup_test_framework()
{
char *TAP_levels = getenv("HARNESS_OSSL_LEVEL");
char *test_seed = getenv("OPENSSL_TEST_RAND_ORDER");
level = TAP_levels != NULL ? 4 * atoi(TAP_levels) : 0;
if (test_seed != NULL) {
seed = atoi(test_seed);
if (seed <= 0)
seed = (int)time(NULL);
test_printf_stdout("%*s# RAND SEED %d\n", subtest_level(), "", seed);
test_flush_stdout();
srand(seed);
}
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
if (should_report_leaks()) {
CRYPTO_set_mem_debug(1);
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
}
#endif
}
int pulldown_test_framework(int ret)
{
set_test_title(NULL);
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
if (should_report_leaks()
&& CRYPTO_mem_leaks_cb(openssl_error_cb, NULL) <= 0)
return EXIT_FAILURE;
#endif
return ret;
}
static void finalize(int success)
{
if (success)
ERR_clear_error();
else
ERR_print_errors_cb(openssl_error_cb, NULL);
}
static char *test_title = NULL;
void set_test_title(const char *title)
{
free(test_title);
test_title = title == NULL ? NULL : strdup(title);
}
PRINTF_FORMAT(2, 3) static void test_verdict(int pass, const char *extra, ...)
{
va_list ap;
test_flush_stdout();
test_flush_stderr();
test_printf_stdout("%*s%s", level, "", pass ? "ok" : "not ok");
if (extra != NULL) {
test_printf_stdout(" ");
va_start(ap, extra);
test_vprintf_stdout(extra, ap);
va_end(ap);
}
test_printf_stdout("\n");
test_flush_stdout();
}
int run_tests(const char *test_prog_name)
{
int num_failed = 0;
int verdict = 1;
int ii, i, jj, j, jstep;
int permute[OSSL_NELEM(all_tests)];
if (num_tests < 1) {
test_printf_stdout("%*s1..0 # Skipped: %s\n", level, "",
test_prog_name);
} else {
if (level > 0)
test_printf_stdout("%*s# Subtest: %s\n", level, "", test_prog_name);
test_printf_stdout("%*s1..%d\n", level, "", num_tests);
}
test_flush_stdout();
for (i = 0; i < num_tests; i++)
permute[i] = i;
if (seed != 0)
for (i = num_tests - 1; i >= 1; i--) {
j = rand() % (1 + i);
ii = permute[j];
permute[j] = permute[i];
permute[i] = ii;
}
for (ii = 0; ii != num_tests; ++ii) {
i = permute[ii];
if (all_tests[i].num == -1) {
int ret = 0;
set_test_title(all_tests[i].test_case_name);
ret = all_tests[i].test_fn();
verdict = 1;
if (!ret) {
verdict = 0;
++num_failed;
}
test_verdict(verdict, "%d - %s", ii + 1, test_title);
finalize(ret);
} else {
int num_failed_inner = 0;
level += 4;
if (all_tests[i].subtest) {
test_printf_stdout("%*s# Subtest: %s\n", level, "",
all_tests[i].test_case_name);
test_printf_stdout("%*s%d..%d\n", level, "", 1,
all_tests[i].num);
test_flush_stdout();
}
j = -1;
if (seed == 0 || all_tests[i].num < 3)
jstep = 1;
else
do
jstep = rand() % all_tests[i].num;
while (jstep == 0 || gcd(all_tests[i].num, jstep) != 1);
for (jj = 0; jj < all_tests[i].num; jj++) {
int ret;
j = (j + jstep) % all_tests[i].num;
set_test_title(NULL);
ret = all_tests[i].param_test_fn(j);
if (!ret)
++num_failed_inner;
finalize(ret);
if (all_tests[i].subtest) {
verdict = 1;
if (!ret) {
verdict = 0;
++num_failed_inner;
}
if (test_title != NULL)
test_verdict(verdict, "%d - %s", jj + 1, test_title);
else
test_verdict(verdict, "%d - iteration %d",
jj + 1, j + 1);
}
}
level -= 4;
verdict = 1;
if (num_failed_inner) {
verdict = 0;
++num_failed;
}
test_verdict(verdict, "%d - %s", ii + 1,
all_tests[i].test_case_name);
}
}
if (num_failed != 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
/*
* Glue an array of strings together and return it as an allocated string.
* Optionally return the whole length of this string in |out_len|
*/
char *glue_strings(const char *list[], size_t *out_len)
{
size_t len = 0;
char *p, *ret;
int i;
for (i = 0; list[i] != NULL; i++)
len += strlen(list[i]);
if (out_len != NULL)
*out_len = len;
if (!TEST_ptr(ret = p = OPENSSL_malloc(len + 1)))
return NULL;
for (i = 0; list[i] != NULL; i++)
p += strlen(strcpy(p, list[i]));
return ret;
}

View File

@@ -0,0 +1,529 @@
/*
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 "../testutil.h"
#include "output.h"
#include "tu_local.h"
#include <string.h>
#include <ctype.h>
#include "internal/nelem.h"
/* The size of memory buffers to display on failure */
#define MEM_BUFFER_SIZE (2000)
#define MAX_STRING_WIDTH (80)
#define BN_OUTPUT_SIZE (8)
/* Output a diff header */
static void test_diff_header(const char *left, const char *right)
{
test_printf_stderr("--- %s\n", left);
test_printf_stderr("+++ %s\n", right);
}
/* Formatted string output routines */
static void test_string_null_empty(const char *m, char c)
{
if (m == NULL)
test_printf_stderr("% 4s %c NULL\n", "", c);
else
test_printf_stderr("% 4u:%c ''\n", 0u, c);
}
static void test_fail_string_common(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 size_t width = (MAX_STRING_WIDTH - subtest_level() - 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_string_null_empty(m1, ' ');
} else {
test_diff_header(left, right);
test_string_null_empty(m1, '-');
test_string_null_empty(m2, '+');
}
goto fin;
}
if (l1 != l2 || strcmp(m1, m2) != 0)
test_diff_header(left, right);
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((unsigned char)m1[i]) ? m1[i] : '.';
}
if (l2 > 0) {
b2[n2 = l2 > width ? width : l2] = 0;
for (i = 0; i < n2; i++)
b2[i] = isprint((unsigned char)m2[i]) ? m2[i] : '.';
}
diff = 0;
i = 0;
if (n1 > 0 && n2 > 0) {
const size_t j = n1 < n2 ? n1 : n2;
for (; i < j; i++)
if (m1[i] == m2[i]) {
bdiff[i] = ' ';
} else {
bdiff[i] = '^';
diff = 1;
}
bdiff[i] = '\0';
}
if (n1 == n2 && !diff) {
test_printf_stderr("% 4u: '%s'\n", cnt, n2 > n1 ? b2 : b1);
} else {
if (cnt == 0 && (m1 == NULL || *m1 == '\0'))
test_string_null_empty(m1, '-');
else if (n1 > 0)
test_printf_stderr("% 4u:- '%s'\n", cnt, b1);
if (cnt == 0 && (m2 == NULL || *m2 == '\0'))
test_string_null_empty(m2, '+');
else if (n2 > 0)
test_printf_stderr("% 4u:+ '%s'\n", cnt, b2);
if (diff && i > 0)
test_printf_stderr("% 4s %s\n", "", bdiff);
}
m1 += n1;
m2 += n2;
l1 -= n1;
l2 -= n2;
cnt += width;
}
fin:
test_flush_stderr();
}
/*
* Wrapper routines so that the underlying code can be shared.
* The first is the call from inside the test utilities when a conditional
* fails. The second is the user's call to dump a string.
*/
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)
{
test_fail_string_common(prefix, file, line, type, left, right, op,
m1, l1, m2, l2);
test_printf_stderr("\n");
}
void test_output_string(const char *name, const char *m, size_t l)
{
test_fail_string_common("string", NULL, 0, NULL, NULL, NULL, name,
m, l, m, l);
}
/* BIGNUM formatted output routines */
/*
* A basic memory byte to hex digit converter with allowance for spacing
* every so often.
*/
static void hex_convert_memory(const unsigned char *m, size_t n, char *b,
size_t width)
{
size_t i;
for (i = 0; i < n; i++) {
const unsigned char c = *m++;
*b++ = "0123456789abcdef"[c >> 4];
*b++ = "0123456789abcdef"[c & 15];
if (i % width == width - 1 && i != n - 1)
*b++ = ' ';
}
*b = '\0';
}
/*
* Constants to define the number of bytes to display per line and the number
* of characters these take.
*/
static const int bn_bytes = (MAX_STRING_WIDTH - 9) / (BN_OUTPUT_SIZE * 2 + 1)
* BN_OUTPUT_SIZE;
static const int bn_chars = (MAX_STRING_WIDTH - 9) / (BN_OUTPUT_SIZE * 2 + 1)
* (BN_OUTPUT_SIZE * 2 + 1) - 1;
/*
* Output the header line for the bignum
*/
static void test_bignum_header_line(void)
{
test_printf_stderr(" %*s\n", bn_chars + 6, "bit position");
}
static const char *test_bignum_zero_null(const BIGNUM *bn)
{
if (bn != NULL)
return BN_is_negative(bn) ? "-0" : "0";
return "NULL";
}
/*
* Print a bignum zero taking care to include the correct sign.
* This routine correctly deals with a NULL bignum pointer as input.
*/
static void test_bignum_zero_print(const BIGNUM *bn, char sep)
{
const char *v = test_bignum_zero_null(bn);
const char *suf = bn != NULL ? ": 0" : "";
test_printf_stderr("%c%*s%s\n", sep, bn_chars, v, suf);
}
/*
* Convert a section of memory from inside a bignum into a displayable
* string with appropriate visual aid spaces inserted.
*/
static int convert_bn_memory(const unsigned char *in, size_t bytes,
char *out, int *lz, const BIGNUM *bn)
{
int n = bytes * 2, i;
char *p = out, *q = NULL;
if (bn != NULL && !BN_is_zero(bn)) {
hex_convert_memory(in, bytes, out, BN_OUTPUT_SIZE);
if (*lz) {
for (; *p == '0' || *p == ' '; p++)
if (*p == '0') {
q = p;
*p = ' ';
n--;
}
if (*p == '\0') {
/*
* in[bytes] is defined because we're converting a non-zero
* number and we've not seen a non-zero yet.
*/
if ((in[bytes] & 0xf0) != 0 && BN_is_negative(bn)) {
*lz = 0;
*q = '-';
n++;
}
} else {
*lz = 0;
if (BN_is_negative(bn)) {
/*
* This is valid because we always convert more digits than
* the number holds.
*/
*q = '-';
n++;
}
}
}
return n;
}
for (i = 0; i < n; i++) {
*p++ = ' ';
if (i % (2 * BN_OUTPUT_SIZE) == 2 * BN_OUTPUT_SIZE - 1 && i != n - 1)
*p++ = ' ';
}
*p = '\0';
if (bn == NULL)
q = "NULL";
else
q = BN_is_negative(bn) ? "-0" : "0";
strcpy(p - strlen(q), q);
return 0;
}
/*
* Common code to display either one or two bignums, including the diff
* pointers for changes (only when there are two).
*/
static void test_fail_bignum_common(const char *prefix, const char *file,
int line, const char *type,
const char *left, const char *right,
const char *op,
const BIGNUM *bn1, const BIGNUM *bn2)
{
const size_t bytes = bn_bytes;
char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1];
char *p, bdiff[MAX_STRING_WIDTH + 1];
size_t l1, l2, n1, n2, i, len;
unsigned int cnt, diff, real_diff;
unsigned char *m1 = NULL, *m2 = NULL;
int lz1 = 1, lz2 = 1;
unsigned char buffer[MEM_BUFFER_SIZE * 2], *bufp = buffer;
test_fail_message_prefix(prefix, file, line, type, left, right, op);
l1 = bn1 == NULL ? 0 : (BN_num_bytes(bn1) + (BN_is_negative(bn1) ? 1 : 0));
l2 = bn2 == NULL ? 0 : (BN_num_bytes(bn2) + (BN_is_negative(bn2) ? 1 : 0));
if (l1 == 0 && l2 == 0) {
if ((bn1 == NULL) == (bn2 == NULL)) {
test_bignum_header_line();
test_bignum_zero_print(bn1, ' ');
} else {
test_diff_header(left, right);
test_bignum_header_line();
test_bignum_zero_print(bn1, '-');
test_bignum_zero_print(bn2, '+');
}
goto fin;
}
if (l1 != l2 || bn1 == NULL || bn2 == NULL || BN_cmp(bn1, bn2) != 0)
test_diff_header(left, right);
test_bignum_header_line();
len = ((l1 > l2 ? l1 : l2) + bytes - 1) / bytes * bytes;
if (len > MEM_BUFFER_SIZE && (bufp = OPENSSL_malloc(len * 2)) == NULL) {
bufp = buffer;
len = MEM_BUFFER_SIZE;
test_printf_stderr("WARNING: these BIGNUMs have been truncated\n");
}
if (bn1 != NULL) {
m1 = bufp;
BN_bn2binpad(bn1, m1, len);
}
if (bn2 != NULL) {
m2 = bufp + len;
BN_bn2binpad(bn2, m2, len);
}
while (len > 0) {
cnt = 8 * (len - bytes);
n1 = convert_bn_memory(m1, bytes, b1, &lz1, bn1);
n2 = convert_bn_memory(m2, bytes, b2, &lz2, bn2);
diff = real_diff = 0;
i = 0;
p = bdiff;
for (i=0; b1[i] != '\0'; i++)
if (b1[i] == b2[i] || b1[i] == ' ' || b2[i] == ' ') {
*p++ = ' ';
diff |= b1[i] != b2[i];
} else {
*p++ = '^';
real_diff = diff = 1;
}
*p++ = '\0';
if (!diff) {
test_printf_stderr(" %s:% 5d\n", n2 > n1 ? b2 : b1, cnt);
} else {
if (cnt == 0 && bn1 == NULL)
test_printf_stderr("-%s\n", b1);
else if (cnt == 0 || n1 > 0)
test_printf_stderr("-%s:% 5d\n", b1, cnt);
if (cnt == 0 && bn2 == NULL)
test_printf_stderr("+%s\n", b2);
else if (cnt == 0 || n2 > 0)
test_printf_stderr("+%s:% 5d\n", b2, cnt);
if (real_diff && (cnt == 0 || (n1 > 0 && n2 > 0))
&& bn1 != NULL && bn2 != NULL)
test_printf_stderr(" %s\n", bdiff);
}
if (m1 != NULL)
m1 += bytes;
if (m2 != NULL)
m2 += bytes;
len -= bytes;
}
fin:
test_flush_stderr();
if (bufp != buffer)
OPENSSL_free(bufp);
}
/*
* Wrapper routines so that the underlying code can be shared.
* The first two are calls from inside the test utilities when a conditional
* fails. The third is the user's call to dump a bignum.
*/
void test_fail_bignum_message(const char *prefix, const char *file,
int line, const char *type,
const char *left, const char *right,
const char *op,
const BIGNUM *bn1, const BIGNUM *bn2)
{
test_fail_bignum_common(prefix, file, line, type, left, right, op, bn1, bn2);
test_printf_stderr("\n");
}
void test_fail_bignum_mono_message(const char *prefix, const char *file,
int line, const char *type,
const char *left, const char *right,
const char *op, const BIGNUM *bn)
{
test_fail_bignum_common(prefix, file, line, type, left, right, op, bn, bn);
test_printf_stderr("\n");
}
void test_output_bignum(const char *name, const BIGNUM *bn)
{
if (bn == NULL || BN_is_zero(bn)) {
test_printf_stderr("bignum: '%s' = %s\n", name,
test_bignum_zero_null(bn));
} else if (BN_num_bytes(bn) <= BN_OUTPUT_SIZE) {
unsigned char buf[BN_OUTPUT_SIZE];
char out[2 * sizeof(buf) + 1];
char *p = out;
int n = BN_bn2bin(bn, buf);
hex_convert_memory(buf, n, p, BN_OUTPUT_SIZE);
while (*p == '0' && *++p != '\0')
;
test_printf_stderr("bignum: '%s' = %s0x%s\n", name,
BN_is_negative(bn) ? "-" : "", p);
} else {
test_fail_bignum_common("bignum", NULL, 0, NULL, NULL, NULL, name,
bn, bn);
}
}
/* Memory output routines */
/*
* Handle zero length blocks of memory or NULL pointers to memory
*/
static void test_memory_null_empty(const unsigned char *m, char c)
{
if (m == NULL)
test_printf_stderr("% 4s %c%s\n", "", c, "NULL");
else
test_printf_stderr("%04x %c%s\n", 0u, c, "empty");
}
/*
* Common code to display one or two blocks of memory.
*/
static void test_fail_memory_common(const char *prefix, const char *file,
int line, const char *type,
const char *left, const char *right,
const char *op,
const unsigned char *m1, size_t l1,
const unsigned char *m2, size_t l2)
{
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_memory_null_empty(m1, ' ');
} else {
test_diff_header(left, right);
test_memory_null_empty(m1, '-');
test_memory_null_empty(m2, '+');
}
goto fin;
}
if (l1 != l2 || (m1 != m2 && memcmp(m1, m2, l1) != 0))
test_diff_header(left, right);
while (l1 > 0 || l2 > 0) {
n1 = n2 = 0;
if (l1 > 0) {
n1 = l1 > bytes ? bytes : l1;
hex_convert_memory(m1, n1, b1, 8);
}
if (l2 > 0) {
n2 = l2 > bytes ? bytes : l2;
hex_convert_memory(m2, n2, b2, 8);
}
diff = 0;
i = 0;
p = bdiff;
if (n1 > 0 && n2 > 0) {
const size_t j = 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)
*p++ = ' ';
}
*p++ = '\0';
}
if (n1 == n2 && !diff) {
test_printf_stderr("%04x: %s\n", cnt, b1);
} else {
if (cnt == 0 && (m1 == NULL || l1 == 0))
test_memory_null_empty(m1, '-');
else if (n1 > 0)
test_printf_stderr("%04x:-%s\n", cnt, b1);
if (cnt == 0 && (m2 == NULL || l2 == 0))
test_memory_null_empty(m2, '+');
else if (n2 > 0)
test_printf_stderr("%04x:+%s\n", cnt, b2);
if (diff && i > 0)
test_printf_stderr("% 4s %s\n", "", bdiff);
}
m1 += n1;
m2 += n2;
l1 -= n1;
l2 -= n2;
cnt += bytes;
}
fin:
test_flush_stderr();
}
/*
* Wrapper routines so that the underlying code can be shared.
* The first is the call from inside the test utilities when a conditional
* fails. The second is the user's call to dump memory.
*/
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 unsigned char *m1, size_t l1,
const unsigned char *m2, size_t l2)
{
test_fail_memory_common(prefix, file, line, type, left, right, op,
m1, l1, m2, l2);
test_printf_stderr("\n");
}
void test_output_memory(const char *name, const unsigned char *m, size_t l)
{
test_fail_memory_common("memory", NULL, 0, NULL, NULL, NULL, name,
m, l, m, l);
}

15
test/testutil/init.c Normal file
View File

@@ -0,0 +1,15 @@
/*
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 "../testutil.h"
int global_init(void)
{
return 1;
}

106
test/testutil/main.c Normal file
View File

@@ -0,0 +1,106 @@
/*
* Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 "../testutil.h"
#include "internal/nelem.h"
#include "output.h"
#include "tu_local.h"
#include <string.h>
static size_t arg_count;
static char **args;
static unsigned char arg_used[1000];
static void check_arg_usage(void)
{
size_t i, n = arg_count < OSSL_NELEM(arg_used) ? arg_count
: OSSL_NELEM(arg_used);
for (i = 0; i < n; i++)
if (!arg_used[i+1])
test_printf_stderr("Warning ignored command-line argument %d: %s\n",
i, args[i+1]);
if (i < arg_count)
test_printf_stderr("Warning arguments %zu and later unchecked\n", i);
}
int main(int argc, char *argv[])
{
int ret = EXIT_FAILURE;
test_open_streams();
if (!global_init()) {
test_printf_stderr("Global init failed - aborting\n");
return ret;
}
arg_count = argc - 1;
args = argv;
setup_test_framework();
if (setup_tests())
ret = run_tests(argv[0]);
cleanup_tests();
check_arg_usage();
ret = pulldown_test_framework(ret);
test_close_streams();
return ret;
}
const char *test_get_program_name(void)
{
return args[0];
}
char *test_get_argument(size_t n)
{
if (n > arg_count)
return NULL;
if (n + 1 < OSSL_NELEM(arg_used))
arg_used[n + 1] = 1;
return args[n + 1];
}
size_t test_get_argument_count(void)
{
return arg_count;
}
int test_has_option(const char *option)
{
size_t i;
for (i = 1; i <= arg_count; i++)
if (strcmp(args[i], option) == 0) {
arg_used[i] = 1;
return 1;
}
return 0;
}
const char *test_get_option_argument(const char *option)
{
size_t i, n = strlen(option);
for (i = 1; i <= arg_count; i++)
if (strncmp(args[i], option, n) == 0) {
arg_used[i] = 1;
if (args[i][n] == '\0' && i + 1 < arg_count) {
arg_used[++i] = 1;
return args[i];
}
return args[i] + n;
}
return NULL;
}

32
test/testutil/output.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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
*/
#ifndef HEADER_TU_OUTPUT_H
# define HEADER_TU_OUTPUT_H
#include <stdarg.h>
/*
* The basic I/O functions used internally by the test framework. These
* can be overridden when needed. Note that if one is, then all must be.
*/
void test_open_streams(void);
void test_close_streams(void);
/* The following ALL return the number of characters written */
int test_vprintf_stdout(const char *fmt, va_list ap);
int test_vprintf_stderr(const char *fmt, va_list ap);
/* These return failure or success */
int test_flush_stdout(void);
int test_flush_stderr(void);
/* Commodity functions. There's no need to override these */
int test_printf_stdout(const char *fmt, ...);
int test_printf_stderr(const char *fmt, ...);
#endif /* HEADER_TU_OUTPUT_H */

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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"
int test_printf_stdout(const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = test_vprintf_stdout(fmt, ap);
va_end(ap);
return ret;
}
int test_printf_stderr(const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = test_vprintf_stderr(fmt, ap);
va_end(ap);
return ret;
}

158
test/testutil/stanza.c Normal file
View File

@@ -0,0 +1,158 @@
/*
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "internal/nelem.h"
#include "../testutil.h"
#include "tu_local.h"
int test_start_file(STANZA *s, const char *testfile)
{
TEST_info("Reading %s", testfile);
set_test_title(testfile);
memset(s, 0, sizeof(*s));
if (!TEST_ptr(s->fp = BIO_new_file(testfile, "r")))
return 0;
s->test_file = testfile;
return 1;
}
int test_end_file(STANZA *s)
{
TEST_info("Completed %d tests with %d errors and %d skipped",
s->numtests, s->errors, s->numskip);
BIO_free(s->fp);
return 1;
}
/*
* Read a PEM block. Return 1 if okay, 0 on error.
*/
static int read_key(STANZA *s)
{
char tmpbuf[128];
if (s->key == NULL) {
if (!TEST_ptr(s->key = BIO_new(BIO_s_mem())))
return 0;
} else if (!TEST_int_gt(BIO_reset(s->key), 0)) {
return 0;
}
/* Read to PEM end line and place content in memory BIO */
while (BIO_gets(s->fp, tmpbuf, sizeof(tmpbuf))) {
s->curr++;
if (!TEST_int_gt(BIO_puts(s->key, tmpbuf), 0))
return 0;
if (strncmp(tmpbuf, "-----END", 8) == 0)
return 1;
}
TEST_error("Can't find key end");
return 0;
}
/*
* Delete leading and trailing spaces from a string
*/
static char *strip_spaces(char *p)
{
char *q;
/* Skip over leading spaces */
while (*p && isspace((unsigned char)*p))
p++;
if (!*p)
return NULL;
for (q = p + strlen(p) - 1; q != p && isspace((unsigned char)*q); )
*q-- = '\0';
return *p ? p : NULL;
}
/*
* Read next test stanza; return 1 if found, 0 on EOF or error.
*/
int test_readstanza(STANZA *s)
{
PAIR *pp = s->pairs;
char *p, *equals, *key, *value;
for (s->numpairs = 0; BIO_gets(s->fp, s->buff, sizeof(s->buff)); ) {
s->curr++;
if (!TEST_ptr(p = strchr(s->buff, '\n'))) {
TEST_info("Line %d too long", s->curr);
return 0;
}
*p = '\0';
/* Blank line marks end of tests. */
if (s->buff[0] == '\0')
break;
/* Lines starting with a pound sign are ignored. */
if (s->buff[0] == '#')
continue;
/* Parse into key=value */
if (!TEST_ptr(equals = strchr(s->buff, '='))) {
TEST_info("Missing = at line %d\n", s->curr);
return 0;
}
*equals++ = '\0';
if (!TEST_ptr(key = strip_spaces(s->buff))) {
TEST_info("Empty field at line %d\n", s->curr);
return 0;
}
if ((value = strip_spaces(equals)) == NULL)
value = "";
if (strcmp(key, "Title") == 0) {
TEST_info("Starting \"%s\" tests at line %d", value, s->curr);
continue;
}
if (s->numpairs == 0)
s->start = s->curr;
if (strcmp(key, "PrivateKey") == 0) {
if (!read_key(s))
return 0;
}
if (strcmp(key, "PublicKey") == 0) {
if (!read_key(s))
return 0;
}
if (!TEST_int_lt(s->numpairs++, TESTMAXPAIRS)
|| !TEST_ptr(pp->key = OPENSSL_strdup(key))
|| !TEST_ptr(pp->value = OPENSSL_strdup(value)))
return 0;
pp++;
}
/* If we read anything, return ok. */
return 1;
}
void test_clearstanza(STANZA *s)
{
PAIR *pp = s->pairs;
int i = s->numpairs;
for ( ; --i >= 0; pp++) {
OPENSSL_free(pp->key);
OPENSSL_free(pp->value);
}
s->numpairs = 0;
}

154
test/testutil/tap_bio.c Normal file
View File

@@ -0,0 +1,154 @@
/*
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the OpenSSL license (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 <string.h>
#include "tu_local.h"
static int tap_write_ex(BIO *b, const char *buf, size_t size, size_t *in_size);
static int tap_read_ex(BIO *b, char *buf, size_t size, size_t *out_size);
static int tap_puts(BIO *b, const char *str);
static int tap_gets(BIO *b, char *str, int size);
static long tap_ctrl(BIO *b, int cmd, long arg1, void *arg2);
static int tap_new(BIO *b);
static int tap_free(BIO *b);
static long tap_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
const BIO_METHOD *BIO_f_tap(void)
{
static BIO_METHOD *tap = NULL;
if (tap == NULL) {
tap = BIO_meth_new(BIO_TYPE_START | BIO_TYPE_FILTER, "tap");
if (tap != NULL) {
BIO_meth_set_write_ex(tap, tap_write_ex);
BIO_meth_set_read_ex(tap, tap_read_ex);
BIO_meth_set_puts(tap, tap_puts);
BIO_meth_set_gets(tap, tap_gets);
BIO_meth_set_ctrl(tap, tap_ctrl);
BIO_meth_set_create(tap, tap_new);
BIO_meth_set_destroy(tap, tap_free);
BIO_meth_set_callback_ctrl(tap, tap_callback_ctrl);
}
}
return tap;
}
static int tap_new(BIO *b)
{
BIO_set_data(b, NULL);
BIO_set_init(b, 1);
return 1;
}
static int tap_free(BIO *b)
{
if (b == NULL)
return 0;
BIO_set_data(b, NULL);
BIO_set_init(b, 0);
return 1;
}
static int tap_read_ex(BIO *b, char *buf, size_t size, size_t *out_size)
{
BIO *next = BIO_next(b);
int ret = 0;
ret = BIO_read_ex(next, buf, size, out_size);
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return ret;
}
/*
* Output a string to the specified bio and return 1 if successful.
*/
static int write_string(BIO *b, const char *buf, size_t n)
{
size_t m;
return BIO_write_ex(b, buf, n, &m) != 0 && m == n;
}
/*
* Write some data.
*
* This function implements a simple state machine that detects new lines.
* It indents the output and prefixes it with a '#' character.
*
* It returns the number of input characters that were output in in_size.
* More characters than this will likely have been output however any calling
* code will be unable to correctly assess the actual number of characters
* emitted and would be prone to failure if the actual number were returned.
*
* The BIO_data field is used as our state. If it is NULL, we've just
* seen a new line. If it is not NULL, we're processing characters in a line.
*/
static int tap_write_ex(BIO *b, const char *buf, size_t size, size_t *in_size)
{
BIO *next = BIO_next(b);
size_t i;
int j;
for (i = 0; i < size; i++) {
if (BIO_get_data(b) == NULL) {
BIO_set_data(b, "");
for (j = 0; j < subtest_level(); j++)
if (!write_string(next, " ", 1))
goto err;
if (!write_string(next, "# ", 2))
goto err;
}
if (!write_string(next, buf + i, 1))
goto err;
if (buf[i] == '\n')
BIO_set_data(b, NULL);
}
*in_size = i;
return 1;
err:
*in_size = i;
return 0;
}
static long tap_ctrl(BIO *b, int cmd, long num, void *ptr)
{
BIO *next = BIO_next(b);
switch (cmd) {
case BIO_CTRL_RESET:
BIO_set_data(b, NULL);
break;
default:
break;
}
return BIO_ctrl(next, cmd, num, ptr);
}
static long tap_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
return BIO_callback_ctrl(BIO_next(b), cmd, fp);
}
static int tap_gets(BIO *b, char *buf, int size)
{
return BIO_gets(BIO_next(b), buf, size);
}
static int tap_puts(BIO *b, const char *str)
{
size_t m;
if (!tap_write_ex(b, str, strlen(str), &m))
return 0;
return m;
}

View File

@@ -0,0 +1,14 @@
/*
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 "../testutil.h"
void cleanup_tests(void)
{
}

448
test/testutil/tests.c Normal file
View File

@@ -0,0 +1,448 @@
/*
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 "../testutil.h"
#include "output.h"
#include "tu_local.h"
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include "internal/nelem.h"
#include <openssl/asn1.h>
/*
* 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: ", prefix != NULL ? prefix : "ERROR");
if (type)
test_printf_stderr("(%s) ", type);
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_printf_stderr("\n");
}
/*
* A common routine to output test failure messages. Generally this should not
* be called directly, rather it should be called by the following functions.
*
* |desc| is a printf formatted description with arguments |args| that is
* supplied by the user and |desc| can be NULL. |type| is the data type
* that was tested (int, char, ptr, ...). |fmt| is a system provided
* printf format with following arguments that spell out the failure
* details i.e. the actual values compared and the operator used.
*
* The typical use for this is from an utility test function:
*
* int test6(const char *file, int line, int n) {
* if (n != 6) {
* test_fail_message(1, file, line, "int", "value %d is not %d", n, 6);
* return 0;
* }
* return 1;
* }
*
* calling test6(3, "oops") will return 0 and produce out along the lines of:
* FAIL oops: (int) value 3 is not 6\n
*/
static void test_fail_message(const char *prefix, const char *file, int line,
const char *type, const char *left,
const char *right, const char *op,
const char *fmt, ...)
PRINTF_FORMAT(8, 9);
static void test_fail_message_va(const char *prefix, const char *file,
int line, const char *type,
const char *left, const char *right,
const char *op, const char *fmt, va_list ap)
{
test_fail_message_prefix(prefix, file, line, type, left, right, op);
if (fmt != NULL) {
test_vprintf_stderr(fmt, ap);
test_printf_stderr("\n");
}
test_flush_stderr();
}
static void test_fail_message(const char *prefix, const char *file,
int line, const char *type,
const char *left, const char *right,
const char *op, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
test_fail_message_va(prefix, file, line, type, left, right, op, fmt, ap);
va_end(ap);
}
void test_info_c90(const char *desc, ...)
{
va_list ap;
va_start(ap, desc);
test_fail_message_va("INFO", NULL, -1, NULL, NULL, NULL, NULL, desc, ap);
va_end(ap);
}
void test_info(const char *file, int line, const char *desc, ...)
{
va_list ap;
va_start(ap, desc);
test_fail_message_va("INFO", file, line, NULL, NULL, NULL, NULL, desc, ap);
va_end(ap);
}
void test_error_c90(const char *desc, ...)
{
va_list ap;
va_start(ap, desc);
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_list ap;
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();
}
void test_openssl_errors(void)
{
ERR_print_errors_cb(openssl_error_cb, NULL);
ERR_clear_error();
}
/*
* Define some comparisons between pairs of various types.
* These functions return 1 if the test is true.
* Otherwise, they return 0 and pretty-print diagnostics.
*
* In each case the functions produced are:
* int test_name_eq(const type t1, const type t2, const char *desc, ...);
* int test_name_ne(const type t1, const type t2, const char *desc, ...);
* int test_name_lt(const type t1, const type t2, const char *desc, ...);
* int test_name_le(const type t1, const type t2, const char *desc, ...);
* int test_name_gt(const type t1, const type t2, const char *desc, ...);
* int test_name_ge(const type t1, const type t2, const char *desc, ...);
*
* The t1 and t2 arguments are to be compared for equality, inequality,
* less than, less than or equal to, greater than and greater than or
* equal to respectively. If the specified condition holds, the functions
* return 1. If the condition does not hold, the functions print a diagnostic
* message and return 0.
*
* The desc argument is a printf format string followed by its arguments and
* this is included in the output if the condition being tested for is false.
*/
#define DEFINE_COMPARISON(type, name, opname, op, fmt) \
int test_ ## name ## _ ## opname(const char *file, int line, \
const char *s1, const char *s2, \
const type t1, const type t2) \
{ \
if (t1 op t2) \
return 1; \
test_fail_message(NULL, file, line, #type, s1, s2, #op, \
"[" fmt "] compared to [" fmt "]", \
t1, t2); \
return 0; \
}
#define DEFINE_COMPARISONS(type, name, fmt) \
DEFINE_COMPARISON(type, name, eq, ==, fmt) \
DEFINE_COMPARISON(type, name, ne, !=, fmt) \
DEFINE_COMPARISON(type, name, lt, <, fmt) \
DEFINE_COMPARISON(type, name, le, <=, fmt) \
DEFINE_COMPARISON(type, name, gt, >, fmt) \
DEFINE_COMPARISON(type, name, ge, >=, fmt)
DEFINE_COMPARISONS(int, int, "%d")
DEFINE_COMPARISONS(unsigned int, uint, "%u")
DEFINE_COMPARISONS(char, char, "%c")
DEFINE_COMPARISONS(unsigned char, uchar, "%u")
DEFINE_COMPARISONS(long, long, "%ld")
DEFINE_COMPARISONS(unsigned long, ulong, "%lu")
DEFINE_COMPARISONS(size_t, size_t, "%zu")
DEFINE_COMPARISON(void *, ptr, eq, ==, "%p")
DEFINE_COMPARISON(void *, ptr, ne, !=, "%p")
int test_ptr_null(const char *file, int line, const char *s, const void *p)
{
if (p == NULL)
return 1;
test_fail_message(NULL, file, line, "ptr", s, "NULL", "==", "%p", p);
return 0;
}
int test_ptr(const char *file, int line, const char *s, const void *p)
{
if (p != NULL)
return 1;
test_fail_message(NULL, file, line, "ptr", s, "NULL", "!=", "%p", p);
return 0;
}
int test_true(const char *file, int line, const char *s, int b)
{
if (b)
return 1;
test_fail_message(NULL, file, line, "bool", s, "true", "==", "false");
return 0;
}
int test_false(const char *file, int line, const char *s, int b)
{
if (!b)
return 1;
test_fail_message(NULL, file, line, "bool", s, "false", "==", "true");
return 0;
}
int test_str_eq(const char *file, int line, const char *st1, const char *st2,
const char *s1, const char *s2)
{
if (s1 == NULL && s2 == NULL)
return 1;
if (s1 == NULL || s2 == NULL || strcmp(s1, s2) != 0) {
test_fail_string_message(NULL, file, line, "string", st1, st2, "==",
s1, s1 == NULL ? 0 : strlen(s1),
s2, s2 == NULL ? 0 : strlen(s2));
return 0;
}
return 1;
}
int test_str_ne(const char *file, int line, const char *st1, const char *st2,
const char *s1, const char *s2)
{
if ((s1 == NULL) ^ (s2 == NULL))
return 1;
if (s1 == NULL || strcmp(s1, s2) == 0) {
test_fail_string_message(NULL, file, line, "string", st1, st2, "!=",
s1, s1 == NULL ? 0 : strlen(s1),
s2, s2 == NULL ? 0 : strlen(s2));
return 0;
}
return 1;
}
int test_strn_eq(const char *file, int line, const char *st1, const char *st2,
const char *s1, const char *s2, size_t len)
{
if (s1 == NULL && s2 == NULL)
return 1;
if (s1 == NULL || s2 == NULL || strncmp(s1, s2, len) != 0) {
test_fail_string_message(NULL, file, line, "string", st1, st2, "==",
s1, s1 == NULL ? 0 : OPENSSL_strnlen(s1, len),
s2, s2 == NULL ? 0 : OPENSSL_strnlen(s2, len));
return 0;
}
return 1;
}
int test_strn_ne(const char *file, int line, const char *st1, const char *st2,
const char *s1, const char *s2, size_t len)
{
if ((s1 == NULL) ^ (s2 == NULL))
return 1;
if (s1 == NULL || strncmp(s1, s2, len) == 0) {
test_fail_string_message(NULL, file, line, "string", st1, st2, "!=",
s1, s1 == NULL ? 0 : OPENSSL_strnlen(s1, len),
s2, s2 == NULL ? 0 : OPENSSL_strnlen(s2, len));
return 0;
}
return 1;
}
int test_mem_eq(const char *file, int line, const char *st1, const char *st2,
const void *s1, size_t n1, const void *s2, size_t n2)
{
if (s1 == NULL && s2 == NULL)
return 1;
if (n1 != n2 || s1 == NULL || s2 == NULL || memcmp(s1, s2, n1) != 0) {
test_fail_memory_message(NULL, file, line, "memory", st1, st2, "==",
s1, n1, s2, n2);
return 0;
}
return 1;
}
int test_mem_ne(const char *file, int line, const char *st1, const char *st2,
const void *s1, size_t n1, const void *s2, size_t n2)
{
if ((s1 == NULL) ^ (s2 == NULL))
return 1;
if (n1 != n2)
return 1;
if (s1 == NULL || memcmp(s1, s2, n1) == 0) {
test_fail_memory_message(NULL, file, line, "memory", st1, st2, "!=",
s1, n1, s2, n2);
return 0;
}
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>" : (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, <=)

51
test/testutil/tu_local.h Normal file
View File

@@ -0,0 +1,51 @@
/*
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <stdlib.h> /* size_t */
#include <openssl/bn.h>
#include <openssl/bio.h>
#include "../testutil.h"
int subtest_level(void);
int openssl_error_cb(const char *str, size_t len, void *u);
const BIO_METHOD *BIO_f_tap(void);
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);
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);
void test_fail_bignum_message(const char *prefix, const char *file,
int line, const char *type,
const char *left, const char *right,
const char *op,
const BIGNUM *bn1, const BIGNUM *bn2);
void test_fail_bignum_mono_message(const char *prefix, const char *file,
int line, const char *type,
const char *left, const char *right,
const char *op, const BIGNUM *bn);
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 unsigned char *m1, size_t l1,
const unsigned char *m2, size_t l2);
void setup_test_framework(void);
__owur int pulldown_test_framework(int ret);
__owur int run_tests(const char *test_prog_name);
void set_test_title(const char *title);