Imported OpenSSL 1.1.1a
This commit is contained in:
58
test/testutil/basic_output.c
Normal file
58
test/testutil/basic_output.c
Normal 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
16
test/testutil/cb.c
Normal 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
299
test/testutil/driver.c
Normal 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;
|
||||
}
|
||||
|
||||
529
test/testutil/format_output.c
Normal file
529
test/testutil/format_output.c
Normal 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
15
test/testutil/init.c
Normal 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
106
test/testutil/main.c
Normal 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
32
test/testutil/output.h
Normal 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 */
|
||||
34
test/testutil/output_helpers.c
Normal file
34
test/testutil/output_helpers.c
Normal 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
158
test/testutil/stanza.c
Normal 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
154
test/testutil/tap_bio.c
Normal 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;
|
||||
}
|
||||
14
test/testutil/test_cleanup.c
Normal file
14
test/testutil/test_cleanup.c
Normal 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
448
test/testutil/tests.c
Normal 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
51
test/testutil/tu_local.h
Normal 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);
|
||||
Reference in New Issue
Block a user