- (djm) [regress/unittests/Makefile]

[regress/unittests/Makefile.inc]
   [regress/unittests/sshbuf/Makefile]
   [regress/unittests/sshbuf/test_sshbuf.c]
   [regress/unittests/sshbuf/test_sshbuf_fixed.c]
   [regress/unittests/sshbuf/test_sshbuf_fuzz.c]
   [regress/unittests/sshbuf/test_sshbuf_getput_basic.c]
   [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c]
   [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c]
   [regress/unittests/sshbuf/test_sshbuf_misc.c]
   [regress/unittests/sshbuf/tests.c]
   [regress/unittests/test_helper/Makefile]
   [regress/unittests/test_helper/fuzz.c]
   [regress/unittests/test_helper/test_helper.c]
   [regress/unittests/test_helper/test_helper.h]
   Import new unit tests from OpenBSD; not yet hooked up to build.
This commit is contained in:
Damien Miller 2014-05-15 15:17:15 +10:00
parent 167685756f
commit def1de0867
16 changed files with 2862 additions and 0 deletions

View File

@ -111,6 +111,22 @@
was removed from malloc.c 10 days ago.
OK from miod@
- (djm) [regress/unittests/Makefile]
[regress/unittests/Makefile.inc]
[regress/unittests/sshbuf/Makefile]
[regress/unittests/sshbuf/test_sshbuf.c]
[regress/unittests/sshbuf/test_sshbuf_fixed.c]
[regress/unittests/sshbuf/test_sshbuf_fuzz.c]
[regress/unittests/sshbuf/test_sshbuf_getput_basic.c]
[regress/unittests/sshbuf/test_sshbuf_getput_crypto.c]
[regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c]
[regress/unittests/sshbuf/test_sshbuf_misc.c]
[regress/unittests/sshbuf/tests.c]
[regress/unittests/test_helper/Makefile]
[regress/unittests/test_helper/fuzz.c]
[regress/unittests/test_helper/test_helper.c]
[regress/unittests/test_helper/test_helper.h]
Import new unit tests from OpenBSD; not yet hooked up to build.
20140430
- (dtucker) [defines.h] Define __GNUC_PREREQ__ macro if we don't already

View File

@ -0,0 +1,5 @@
# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
SUBDIR= test_helper sshbuf
.include <bsd.subdir.mk>

View File

@ -0,0 +1,59 @@
# $OpenBSD: Makefile.inc,v 1.1 2014/04/30 05:32:00 djm Exp $
.include <bsd.own.mk>
.include <bsd.obj.mk>
# enable warnings
WARNINGS=Yes
DEBUG=-g
CFLAGS+= -fstack-protector-all
CDIAGFLAGS= -Wall
CDIAGFLAGS+= -Wextra
CDIAGFLAGS+= -Werror
CDIAGFLAGS+= -Wchar-subscripts
CDIAGFLAGS+= -Wcomment
CDIAGFLAGS+= -Wformat
CDIAGFLAGS+= -Wformat-security
CDIAGFLAGS+= -Wimplicit
CDIAGFLAGS+= -Winline
CDIAGFLAGS+= -Wmissing-declarations
CDIAGFLAGS+= -Wmissing-prototypes
CDIAGFLAGS+= -Wparentheses
CDIAGFLAGS+= -Wpointer-arith
CDIAGFLAGS+= -Wpointer-sign
CDIAGFLAGS+= -Wreturn-type
CDIAGFLAGS+= -Wshadow
CDIAGFLAGS+= -Wsign-compare
CDIAGFLAGS+= -Wstrict-aliasing
CDIAGFLAGS+= -Wstrict-prototypes
CDIAGFLAGS+= -Wswitch
CDIAGFLAGS+= -Wtrigraphs
CDIAGFLAGS+= -Wuninitialized
CDIAGFLAGS+= -Wunused
.if ${COMPILER_VERSION} == "gcc4"
CDIAGFLAGS+= -Wold-style-definition
.endif
SSHREL=../../../../../usr.bin/ssh
CFLAGS+=-I${.CURDIR}/../test_helper -I${.CURDIR}/${SSHREL}
.if exists(${.CURDIR}/../test_helper/${__objdir})
LDADD+=-L${.CURDIR}/../test_helper/${__objdir} -ltest_helper
DPADD+=${.CURDIR}/../test_helper/${__objdir}/libtest_helper.a
.else
LDADD+=-L${.CURDIR}/../test_helper -ltest_helper
DPADD+=${.CURDIR}/../test_helper/libtest_helper.a
.endif
.if exists(${.CURDIR}/${SSHREL}/lib/${__objdir})
LDADD+=-L${.CURDIR}/${SSHREL}/lib/${__objdir} -lssh
DPADD+=${.CURDIR}/${SSHREL}/lib/${__objdir}/libssh.a
.else
LDADD+=-L${.CURDIR}/${SSHREL}/lib -lssh
DPADD+=${.CURDIR}/${SSHREL}/lib/libssh.a
.endif
LDADD+= -lcrypto
DPADD+= ${LIBCRYPTO}

View File

@ -0,0 +1,14 @@
# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
PROG=test_sshbuf
SRCS=tests.c
SRCS+=test_sshbuf.c
SRCS+=test_sshbuf_getput_basic.c
SRCS+=test_sshbuf_getput_crypto.c
SRCS+=test_sshbuf_misc.c
SRCS+=test_sshbuf_fuzz.c
SRCS+=test_sshbuf_getput_fuzz.c
SRCS+=test_sshbuf_fixed.c
.include <bsd.regress.mk>

View File

@ -0,0 +1,236 @@
/* $OpenBSD: test_sshbuf.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
* Placed in the public domain
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "test_helper.h"
#include "ssherr.h"
#define SSHBUF_INTERNAL 1 /* access internals for testing */
#include "sshbuf.h"
void sshbuf_tests(void);
void
sshbuf_tests(void)
{
struct sshbuf *p1;
const u_char *cdp;
u_char *dp;
size_t sz;
int r;
TEST_START("allocate sshbuf");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
TEST_DONE();
TEST_START("max size on fresh buffer");
ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0);
TEST_DONE();
TEST_START("available on fresh buffer");
ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0);
TEST_DONE();
TEST_START("len = 0 on empty buffer");
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
TEST_DONE();
TEST_START("set valid max size");
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0);
ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536);
TEST_DONE();
TEST_START("available on limited buffer");
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536);
TEST_DONE();
TEST_START("free");
sshbuf_free(p1);
TEST_DONE();
TEST_START("consume on empty buffer");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
sshbuf_free(p1);
TEST_DONE();
TEST_START("consume_end on empty buffer");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0);
ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
sshbuf_free(p1);
TEST_DONE();
TEST_START("reserve space");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
r = sshbuf_reserve(p1, 1, &dp);
ASSERT_INT_EQ(r, 0);
ASSERT_PTR_NE(dp, NULL);
*dp = 0x11;
r = sshbuf_reserve(p1, 3, &dp);
ASSERT_INT_EQ(r, 0);
ASSERT_PTR_NE(dp, NULL);
*dp++ = 0x22;
*dp++ = 0x33;
*dp++ = 0x44;
TEST_DONE();
TEST_START("sshbuf_len on filled buffer");
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
TEST_DONE();
TEST_START("sshbuf_ptr on filled buffer");
cdp = sshbuf_ptr(p1);
ASSERT_PTR_NE(cdp, NULL);
ASSERT_U8_EQ(cdp[0], 0x11);
ASSERT_U8_EQ(cdp[1], 0x22);
ASSERT_U8_EQ(cdp[2], 0x33);
ASSERT_U8_EQ(cdp[3], 0x44);
TEST_DONE();
TEST_START("consume on filled buffer");
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
r = sshbuf_consume(p1, 64);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
cdp = sshbuf_ptr(p1);
ASSERT_PTR_NE(p1, NULL);
ASSERT_U8_EQ(cdp[0], 0x22);
ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
cdp = sshbuf_ptr(p1);
ASSERT_PTR_NE(p1, NULL);
ASSERT_U8_EQ(cdp[0], 0x44);
r = sshbuf_consume(p1, 2);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
r = sshbuf_consume(p1, 1);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
sshbuf_free(p1);
TEST_DONE();
TEST_START("consume_end on filled buffer");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
r = sshbuf_reserve(p1, 4, &dp);
ASSERT_INT_EQ(r, 0);
ASSERT_PTR_NE(dp, NULL);
*dp++ = 0x11;
*dp++ = 0x22;
*dp++ = 0x33;
*dp++ = 0x44;
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
r = sshbuf_consume_end(p1, 5);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
cdp = sshbuf_ptr(p1);
ASSERT_PTR_NE(cdp, NULL);
ASSERT_U8_EQ(*cdp, 0x11);
r = sshbuf_consume_end(p1, 2);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
sshbuf_free(p1);
TEST_DONE();
TEST_START("fill limited buffer");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
r = sshbuf_reserve(p1, 1223, &dp);
ASSERT_INT_EQ(r, 0);
ASSERT_PTR_NE(dp, NULL);
memset(dp, 0xd7, 1223);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
r = sshbuf_reserve(p1, 1, &dp);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_PTR_EQ(dp, NULL);
TEST_DONE();
TEST_START("consume and force compaction");
ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
r = sshbuf_reserve(p1, 224, &dp);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_PTR_EQ(dp, NULL);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
r = sshbuf_reserve(p1, 223, &dp);
ASSERT_INT_EQ(r, 0);
ASSERT_PTR_NE(dp, NULL);
memset(dp, 0x7d, 223);
cdp = sshbuf_ptr(p1);
ASSERT_PTR_NE(cdp, NULL);
ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
TEST_DONE();
TEST_START("resize full buffer");
r = sshbuf_set_max_size(p1, 1000);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0);
ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223);
ASSERT_INT_EQ(sshbuf_len(p1), 1223);
TEST_DONE();
/* NB. uses sshbuf internals */
TEST_START("alloc chunking");
r = sshbuf_reserve(p1, 1, &dp);
ASSERT_INT_EQ(r, 0);
ASSERT_PTR_NE(dp, NULL);
*dp = 0xff;
cdp = sshbuf_ptr(p1);
ASSERT_PTR_NE(cdp, NULL);
ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1);
ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0);
sshbuf_free(p1);
TEST_DONE();
TEST_START("reset buffer");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
r = sshbuf_reserve(p1, 1223, &dp);
ASSERT_INT_EQ(r, 0);
ASSERT_PTR_NE(dp, NULL);
memset(dp, 0xd7, 1223);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
sshbuf_reset(p1);
ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
sshbuf_free(p1);
TEST_DONE();
}

View File

@ -0,0 +1,122 @@
/* $OpenBSD: test_sshbuf_fixed.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
* Placed in the public domain
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "test_helper.h"
#define SSHBUF_INTERNAL 1 /* access internals for testing */
#include "sshbuf.h"
#include "ssherr.h"
void sshbuf_fixed(void);
const u_char test_buf[] = "\x01\x12\x34\x56\x78\x00\x00\x00\x05hello";
void
sshbuf_fixed(void)
{
struct sshbuf *p1, *p2, *p3;
u_char c;
char *s;
u_int i;
size_t l;
TEST_START("sshbuf_from");
p1 = sshbuf_from(test_buf, sizeof(test_buf));
ASSERT_PTR_NE(p1, NULL);
ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL);
ASSERT_INT_EQ(sshbuf_check_reserve(p1, 1), SSH_ERR_BUFFER_READ_ONLY);
ASSERT_INT_EQ(sshbuf_reserve(p1, 1, NULL), SSH_ERR_BUFFER_READ_ONLY);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 200), SSH_ERR_BUFFER_READ_ONLY);
ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), SSH_ERR_BUFFER_READ_ONLY);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_from data");
p1 = sshbuf_from(test_buf, sizeof(test_buf) - 1);
ASSERT_PTR_NE(p1, NULL);
ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf);
ASSERT_INT_EQ(sshbuf_get_u8(p1, &c), 0);
ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 1);
ASSERT_U8_EQ(c, 1);
ASSERT_INT_EQ(sshbuf_get_u32(p1, &i), 0);
ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 5);
ASSERT_U32_EQ(i, 0x12345678);
ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s, &l), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
ASSERT_STRING_EQ(s, "hello");
ASSERT_SIZE_T_EQ(l, 5);
sshbuf_free(p1);
free(s);
TEST_DONE();
TEST_START("sshbuf_fromb ");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1);
ASSERT_PTR_EQ(sshbuf_parent(p1), NULL);
ASSERT_INT_EQ(sshbuf_put(p1, test_buf, sizeof(test_buf) - 1), 0);
p2 = sshbuf_fromb(p1);
ASSERT_PTR_NE(p2, NULL);
ASSERT_U_INT_EQ(sshbuf_refcount(p1), 2);
ASSERT_PTR_EQ(sshbuf_parent(p1), NULL);
ASSERT_PTR_EQ(sshbuf_parent(p2), p1);
ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1));
ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
ASSERT_PTR_NE(sshbuf_ptr(p2), NULL);
ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL);
ASSERT_PTR_EQ(sshbuf_mutable_ptr(p2), NULL);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sshbuf_len(p2));
ASSERT_INT_EQ(sshbuf_get_u8(p2, &c), 0);
ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 1);
ASSERT_U8_EQ(c, 1);
ASSERT_INT_EQ(sshbuf_get_u32(p2, &i), 0);
ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 5);
ASSERT_U32_EQ(i, 0x12345678);
ASSERT_INT_EQ(sshbuf_get_cstring(p2, &s, &l), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0);
ASSERT_STRING_EQ(s, "hello");
ASSERT_SIZE_T_EQ(l, 5);
sshbuf_free(p1);
ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1);
sshbuf_free(p2);
free(s);
TEST_DONE();
TEST_START("sshbuf_froms");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x01), 0);
ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
ASSERT_INT_EQ(sshbuf_put_cstring(p1, "hello"), 0);
p2 = sshbuf_new();
ASSERT_PTR_NE(p2, NULL);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(test_buf) - 1);
ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p2), sizeof(test_buf) + 4 - 1);
ASSERT_INT_EQ(sshbuf_froms(p2, &p3), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0);
ASSERT_PTR_NE(p3, NULL);
ASSERT_PTR_NE(sshbuf_ptr(p3), NULL);
ASSERT_SIZE_T_EQ(sshbuf_len(p3), sizeof(test_buf) - 1);
ASSERT_MEM_EQ(sshbuf_ptr(p3), test_buf, sizeof(test_buf) - 1);
sshbuf_free(p3);
ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0);
ASSERT_INT_EQ(sshbuf_consume_end(p2, 1), 0);
ASSERT_INT_EQ(sshbuf_froms(p2, &p3), SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_PTR_EQ(p3, NULL);
sshbuf_free(p2);
sshbuf_free(p1);
}

View File

@ -0,0 +1,123 @@
/* $OpenBSD: test_sshbuf_fuzz.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
* Placed in the public domain
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "test_helper.h"
#include "ssherr.h"
#include "sshbuf.h"
#define NUM_FUZZ_TESTS (1 << 18)
void sshbuf_fuzz_tests(void);
void
sshbuf_fuzz_tests(void)
{
struct sshbuf *p1;
u_char *dp;
size_t sz, sz2, i;
u_int32_t r;
int ret;
/* NB. uses sshbuf internals */
TEST_START("fuzz alloc/dealloc");
p1 = sshbuf_new();
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0);
ASSERT_PTR_NE(p1, NULL);
ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
for (i = 0; i < NUM_FUZZ_TESTS; i++) {
r = arc4random_uniform(10);
if (r == 0) {
/* 10% chance: small reserve */
r = arc4random_uniform(10);
fuzz_reserve:
sz = sshbuf_avail(p1);
sz2 = sshbuf_len(p1);
ret = sshbuf_reserve(p1, r, &dp);
if (ret < 0) {
ASSERT_PTR_EQ(dp, NULL);
ASSERT_SIZE_T_LT(sz, r);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
} else {
ASSERT_PTR_NE(dp, NULL);
ASSERT_SIZE_T_GE(sz, r);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - r);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 + r);
memset(dp, arc4random_uniform(255) + 1, r);
}
} else if (r < 3) {
/* 20% chance: big reserve */
r = arc4random_uniform(8 * 1024);
goto fuzz_reserve;
} else if (r == 3) {
/* 10% chance: small consume */
r = arc4random_uniform(10);
fuzz_consume:
sz = sshbuf_avail(p1);
sz2 = sshbuf_len(p1);
/* 50% change consume from end, otherwise start */
ret = ((arc4random() & 1) ?
sshbuf_consume : sshbuf_consume_end)(p1, r);
if (ret < 0) {
ASSERT_SIZE_T_LT(sz2, r);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
} else {
ASSERT_SIZE_T_GE(sz2, r);
ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz + r);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 - r);
}
} else if (r < 8) {
/* 40% chance: big consume */
r = arc4random_uniform(2 * 1024);
goto fuzz_consume;
} else if (r == 8) {
/* 10% chance: reset max size */
r = arc4random_uniform(16 * 1024);
sz = sshbuf_max_size(p1);
if (sshbuf_set_max_size(p1, r) < 0)
ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
else
ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), r);
} else {
if (arc4random_uniform(8192) == 0) {
/* tiny chance: new buffer */
ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
sshbuf_free(p1);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1,
16 * 1024), 0);
} else {
/* Almost 10%: giant reserve */
/* use arc4random_buf for r > 2^32 on 64 bit */
arc4random_buf(&r, sizeof(r));
while (r < SSHBUF_SIZE_MAX / 2) {
r <<= 1;
r |= arc4random() & 1;
}
goto fuzz_reserve;
}
}
ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
ASSERT_SIZE_T_LE(sshbuf_max_size(p1), 16 * 1024);
}
ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
sshbuf_free(p1);
TEST_DONE();
}

View File

@ -0,0 +1,480 @@
/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
* Placed in the public domain
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "test_helper.h"
#include "ssherr.h"
#include "sshbuf.h"
void sshbuf_getput_basic_tests(void);
void
sshbuf_getput_basic_tests(void)
{
struct sshbuf *p1, *p2;
const u_char *cd;
u_char *d, d2[32], x[] = {
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x00, 0x99
};
u_int64_t v64;
u_int32_t v32;
u_int16_t v16;
u_char v8;
size_t s;
char *s2;
int r;
u_char bn1[] = { 0x00, 0x00, 0x00 };
u_char bn2[] = { 0x00, 0x00, 0x01, 0x02 };
u_char bn3[] = { 0x00, 0x80, 0x09 };
u_char bn_exp1[] = { 0x00, 0x00, 0x00, 0x00 };
u_char bn_exp2[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 0x02 };
u_char bn_exp3[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x80, 0x09 };
TEST_START("PEEK_U64");
ASSERT_U64_EQ(PEEK_U64(x), 0x1122334455667788ULL);
TEST_DONE();
TEST_START("PEEK_U32");
ASSERT_U32_EQ(PEEK_U32(x), 0x11223344);
TEST_DONE();
TEST_START("PEEK_U16");
ASSERT_U16_EQ(PEEK_U16(x), 0x1122);
TEST_DONE();
TEST_START("POKE_U64");
bzero(d2, sizeof(d2));
POKE_U64(d2, 0x1122334455667788ULL);
ASSERT_MEM_EQ(d2, x, 8);
TEST_DONE();
TEST_START("POKE_U32");
bzero(d2, sizeof(d2));
POKE_U32(d2, 0x11223344);
ASSERT_MEM_EQ(d2, x, 4);
TEST_DONE();
TEST_START("POKE_U16");
bzero(d2, sizeof(d2));
POKE_U16(d2, 0x1122);
ASSERT_MEM_EQ(d2, x, 2);
TEST_DONE();
TEST_START("sshbuf_put");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put(p1, x, 5), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5);
cd = sshbuf_ptr(p1);
ASSERT_PTR_NE(cd, NULL);
ASSERT_U8_EQ(cd[0], 0x11);
ASSERT_U8_EQ(cd[1], 0x22);
ASSERT_U8_EQ(cd[2], 0x33);
ASSERT_U8_EQ(cd[3], 0x44);
ASSERT_U8_EQ(cd[4], 0x55);
TEST_DONE();
TEST_START("sshbuf_get");
ASSERT_INT_EQ(sshbuf_get(p1, d2, 4), 0);
ASSERT_MEM_EQ(d2, x, 4);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55);
TEST_DONE();
TEST_START("sshbuf_get truncated");
r = sshbuf_get(p1, d2, 4);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55);
TEST_DONE();
TEST_START("sshbuf_put truncated");
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0);
r = sshbuf_put(p1, x, 5);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_u64");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10);
ASSERT_INT_EQ(sshbuf_get_u64(p1, &v64), 0);
ASSERT_U64_EQ(v64, 0x1122334455667788ULL);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
TEST_DONE();
TEST_START("sshbuf_get_u64 truncated");
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
r = sshbuf_get_u64(p1, &v64);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_u32");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10);
ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0);
ASSERT_U32_EQ(v32, 0x11223344);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 6);
ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0);
ASSERT_U32_EQ(v32, 0x55667788);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
TEST_DONE();
TEST_START("sshbuf_get_u32 truncated");
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
r = sshbuf_get_u32(p1, &v32);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_u16");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put(p1, x, 9), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 9);
ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
ASSERT_U16_EQ(v16, 0x1122);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 7);
ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
ASSERT_U16_EQ(v16, 0x3344);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5);
ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
ASSERT_U16_EQ(v16, 0x5566);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
ASSERT_U16_EQ(v16, 0x7788);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
TEST_DONE();
TEST_START("sshbuf_get_u16 truncated");
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
r = sshbuf_get_u16(p1, &v16);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_u8");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put(p1, x, 2), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0);
ASSERT_U8_EQ(v8, 0x11);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0);
ASSERT_U8_EQ(v8, 0x22);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
TEST_DONE();
TEST_START("sshbuf_get_u8 truncated");
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
r = sshbuf_get_u8(p1, &v8);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_u64");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8);
ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_u64 exact");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 8), 0);
ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8);
ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_u64 limited");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 7), 0);
r = sshbuf_put_u64(p1, 0x1122334455667788ULL);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_u32");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_u32 exact");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0);
ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_u32 limited");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 3), 0);
r = sshbuf_put_u32(p1, 0x11223344);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_u16");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_u16");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 2), 0);
ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_u16 limited");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1), 0);
r = sshbuf_put_u16(p1, 0x1122);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_string");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 + 4);
ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0);
ASSERT_SIZE_T_EQ(s, sizeof(x));
ASSERT_MEM_EQ(d, x, sizeof(x));
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
free(d);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_string exact");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4), 0);
ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0);
ASSERT_SIZE_T_EQ(s, sizeof(x));
ASSERT_MEM_EQ(d, x, sizeof(x));
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
free(d);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_string truncated");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3);
r = sshbuf_get_string(p1, &d, &s);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_string giant");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0);
ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
r = sshbuf_get_string(p1, &d, &s);
ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_cstring giant");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0);
ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
r = sshbuf_get_cstring(p1, &s2, &s);
ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_cstring embedded \\0");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
r = sshbuf_get_cstring(p1, &s2, NULL);
ASSERT_INT_EQ(r, SSH_ERR_INVALID_FORMAT);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_cstring trailing \\0");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x) - 1), 0);
ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x) - 1), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 - 1);
ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s2, &s), 0);
ASSERT_SIZE_T_EQ(s, sizeof(x) - 1);
ASSERT_MEM_EQ(s2, x, s);
free(s2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_string");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_string(p1, x, sizeof(x)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), sizeof(x));
ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, x, sizeof(x));
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_string limited");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4 - 1), 0);
r = sshbuf_put_string(p1, x, sizeof(x));
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_string giant");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
r = sshbuf_put_string(p1, (void *)0x01, 0xfffffffc);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_putf");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
r = sshbuf_putf(p1, "%s %d %x", "hello", 23, 0x5f);
ASSERT_INT_EQ(r, 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 11);
ASSERT_MEM_EQ(sshbuf_ptr(p1), "hello 23 5f", 11);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_putb");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
p2 = sshbuf_new();
ASSERT_PTR_NE(p2, NULL);
ASSERT_INT_EQ(sshbuf_put(p1, "blahblahblah", 12), 0);
ASSERT_INT_EQ(sshbuf_putb(p2, p1), 0);
sshbuf_free(p1);
ASSERT_SIZE_T_EQ(sshbuf_len(p2), 12);
ASSERT_MEM_EQ(sshbuf_ptr(p2), "blahblahblah", 12);
sshbuf_free(p2);
TEST_DONE();
TEST_START("sshbuf_put_bignum2_bytes empty buf");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, NULL, 0), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1));
ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1));
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum2_bytes all zeroes");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn1, sizeof(bn1)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1));
ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1));
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum2_bytes simple");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2+2, sizeof(bn2)-2), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2));
ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2));
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum2_bytes leading zero");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2, sizeof(bn2)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2));
ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2));
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum2_bytes neg");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3+1, sizeof(bn3)-1), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3));
ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum2_bytes neg and leading zero");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3, sizeof(bn3)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3));
ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
sshbuf_free(p1);
TEST_DONE();
}

View File

@ -0,0 +1,398 @@
/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
* Placed in the public domain
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/objects.h>
#include "test_helper.h"
#include "ssherr.h"
#include "sshbuf.h"
void sshbuf_getput_crypto_tests(void);
void
sshbuf_getput_crypto_tests(void)
{
struct sshbuf *p1;
const u_char *d;
size_t s;
BIGNUM *bn, *bn2, *bn_x, *bn_y;
/* This one has num_bits != num_bytes * 8 to test bignum1 encoding */
const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10";
/* This one has MSB set to test bignum2 encoding negative-avoidance */
const char *hexbn2 = "f0e0d0c0b0a0908070605040302010007fff11";
u_char expbn1[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
};
u_char expbn2[] = {
0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
0x7f, 0xff, 0x11
};
int ec256_nid = NID_X9_62_prime256v1;
char *ec256_x = "0C828004839D0106AA59575216191357"
"34B451459DADB586677EF9DF55784999";
char *ec256_y = "4D196B50F0B4E94B3C73E3A9D4CD9DF2"
"C8F9A35E42BDD047550F69D80EC23CD4";
u_char expec256[] = {
0x04,
0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4
};
EC_KEY *eck;
EC_POINT *ecp;
int r;
#define MKBN(b, bnn) \
do { \
bnn = NULL; \
ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \
} while (0)
TEST_START("sshbuf_put_bignum1");
MKBN(hexbn1, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 2);
ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn1, sizeof(expbn1));
BN_free(bn);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum1 limited");
MKBN(hexbn1, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
r = sshbuf_put_bignum1(p1, bn);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
BN_free(bn);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum1 bn2");
MKBN(hexbn2, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 2);
ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn2, sizeof(expbn2));
BN_free(bn);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum1 bn2 limited");
MKBN(hexbn2, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
r = sshbuf_put_bignum1(p1, bn);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
BN_free(bn);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum2");
MKBN(hexbn1, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4);
ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn));
ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1));
BN_free(bn);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum2 limited");
MKBN(hexbn1, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 3), 0);
r = sshbuf_put_bignum2(p1, bn);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
BN_free(bn);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum2 bn2");
MKBN(hexbn2, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */
ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1);
ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00);
ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2));
BN_free(bn);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_bignum2 bn2 limited");
MKBN(hexbn2, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn2) + 3), 0);
r = sshbuf_put_bignum2(p1, bn);
ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
BN_free(bn);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum1");
MKBN(hexbn1, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1));
ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
bn2 = BN_new();
ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
ASSERT_BIGNUM_EQ(bn, bn2);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum1 truncated");
MKBN(hexbn1, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
bn2 = BN_new();
r = sshbuf_get_bignum1(p1, bn2);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum1 giant");
MKBN(hexbn1, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xffff), 0);
ASSERT_INT_EQ(sshbuf_reserve(p1, (0xffff + 7) / 8, NULL), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
bn2 = BN_new();
r = sshbuf_get_bignum1(p1, bn2);
ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum1 bn2");
MKBN(hexbn2, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2));
ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
bn2 = BN_new();
ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
ASSERT_BIGNUM_EQ(bn, bn2);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum1 bn2 truncated");
MKBN(hexbn2, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
bn2 = BN_new();
r = sshbuf_get_bignum1(p1, bn2);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum2");
MKBN(hexbn1, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + sizeof(expbn1));
ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
bn2 = BN_new();
ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
ASSERT_BIGNUM_EQ(bn, bn2);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum2 truncated");
MKBN(hexbn1, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
bn2 = BN_new();
r = sshbuf_get_bignum2(p1, bn2);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 3);
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum2 giant");
MKBN(hexbn1, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, 65536), 0);
ASSERT_INT_EQ(sshbuf_reserve(p1, 65536, NULL), 0);
bn2 = BN_new();
r = sshbuf_get_bignum2(p1, bn2);
ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 65536 + 4);
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum2 bn2");
MKBN(hexbn2, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); /* MSB */
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + 1 + sizeof(expbn2));
ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
bn2 = BN_new();
ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
ASSERT_BIGNUM_EQ(bn, bn2);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum2 bn2 truncated");
MKBN(hexbn2, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0);
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
bn2 = BN_new();
r = sshbuf_get_bignum2(p1, bn2);
ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 1 + 4 - 1);
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_get_bignum2 bn2 negative");
MKBN(hexbn2, bn);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
bn2 = BN_new();
r = sshbuf_get_bignum2(p1, bn2);
ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_IS_NEGATIVE);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4);
BN_free(bn);
BN_free(bn2);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_put_ec");
eck = EC_KEY_new_by_curve_name(ec256_nid);
ASSERT_PTR_NE(eck, NULL);
ecp = EC_POINT_new(EC_KEY_get0_group(eck));
ASSERT_PTR_NE(ecp, NULL);
MKBN(ec256_x, bn_x);
MKBN(ec256_y, bn_y);
ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp(
EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1);
ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1);
BN_free(bn_x);
BN_free(bn_y);
EC_POINT_free(ecp);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_eckey(p1, eck), 0);
ASSERT_INT_EQ(sshbuf_get_string_direct(p1, &d, &s), 0);
ASSERT_SIZE_T_EQ(s, sizeof(expec256));
ASSERT_MEM_EQ(d, expec256, sizeof(expec256));
sshbuf_free(p1);
EC_KEY_free(eck);
TEST_DONE();
TEST_START("sshbuf_get_ec");
eck = EC_KEY_new_by_curve_name(ec256_nid);
ASSERT_PTR_NE(eck, NULL);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_string(p1, expec256, sizeof(expec256)), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expec256) + 4);
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0);
bn_x = BN_new();
bn_y = BN_new();
ASSERT_PTR_NE(bn_x, NULL);
ASSERT_PTR_NE(bn_y, NULL);
ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp(
EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck),
bn_x, bn_y, NULL), 1);
MKBN(ec256_x, bn);
MKBN(ec256_y, bn2);
ASSERT_INT_EQ(BN_cmp(bn_x, bn), 0);
ASSERT_INT_EQ(BN_cmp(bn_y, bn2), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
sshbuf_free(p1);
EC_KEY_free(eck);
BN_free(bn_x);
BN_free(bn_y);
BN_free(bn);
BN_free(bn2);
TEST_DONE();
}

View File

@ -0,0 +1,120 @@
/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.2 2014/05/02 02:54:00 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
* Placed in the public domain
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/objects.h>
#include "test_helper.h"
#include "ssherr.h"
#include "sshbuf.h"
void sshbuf_getput_fuzz_tests(void);
static void
attempt_parse_blob(u_char *blob, size_t len)
{
struct sshbuf *p1;
BIGNUM *bn;
EC_KEY *eck;
u_char *s;
size_t l;
u_int8_t u8;
u_int16_t u16;
u_int32_t u32;
u_int64_t u64;
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0);
sshbuf_get_u8(p1, &u8);
sshbuf_get_u16(p1, &u16);
sshbuf_get_u32(p1, &u32);
sshbuf_get_u64(p1, &u64);
if (sshbuf_get_string(p1, &s, &l) == 0) {
bzero(s, l);
free(s);
}
bn = BN_new();
sshbuf_get_bignum1(p1, bn);
BN_clear_free(bn);
bn = BN_new();
sshbuf_get_bignum2(p1, bn);
BN_clear_free(bn);
eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
ASSERT_PTR_NE(eck, NULL);
sshbuf_get_eckey(p1, eck);
EC_KEY_free(eck);
sshbuf_free(p1);
}
static void
onerror(void *fuzz)
{
fprintf(stderr, "Failed during fuzz:\n");
fuzz_dump((struct fuzz *)fuzz);
}
void
sshbuf_getput_fuzz_tests(void)
{
u_char blob[] = {
/* u8 */
0xd0,
/* u16 */
0xc0, 0xde,
/* u32 */
0xfa, 0xce, 0xde, 0xad,
/* u64 */
0xfe, 0xed, 0xac, 0x1d, 0x1f, 0x1c, 0xbe, 0xef,
/* string */
0x00, 0x00, 0x00, 0x09,
'O', ' ', 'G', 'o', 'r', 'g', 'o', 'n', '!',
/* bignum1 */
0x79,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
/* bignum2 */
0x00, 0x00, 0x00, 0x14,
0x00,
0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
0x7f, 0xff, 0x11,
/* EC point (NIST-256 curve) */
0x00, 0x00, 0x00, 0x41,
0x04,
0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4,
};
struct fuzz *fuzz;
TEST_START("fuzz blob parsing");
fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP |
FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, blob, sizeof(blob));
TEST_ONERROR(onerror, fuzz);
for(; !fuzz_done(fuzz); fuzz_next(fuzz))
attempt_parse_blob(blob, sizeof(blob));
fuzz_cleanup(fuzz);
TEST_DONE();
TEST_ONERROR(NULL, NULL);
}

View File

@ -0,0 +1,134 @@
/* $OpenBSD: test_sshbuf_misc.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
* Placed in the public domain
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "test_helper.h"
#include "sshbuf.h"
void sshbuf_misc_tests(void);
void
sshbuf_misc_tests(void)
{
struct sshbuf *p1;
char tmp[512], *p;
FILE *out;
size_t sz;
TEST_START("sshbuf_dump");
out = tmpfile();
ASSERT_PTR_NE(out, NULL);
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
sshbuf_dump(p1, out);
fflush(out);
rewind(out);
sz = fread(tmp, 1, sizeof(tmp), out);
ASSERT_INT_EQ(ferror(out), 0);
ASSERT_INT_NE(feof(out), 0);
ASSERT_SIZE_T_GT(sz, 0);
tmp[sz] = '\0';
ASSERT_PTR_NE(strstr(tmp, "12 34 56 78"), NULL);
fclose(out);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_dtob16");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
p = sshbuf_dtob16(p1);
ASSERT_PTR_NE(p, NULL);
ASSERT_STRING_EQ(p, "12345678");
free(p);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_dtob64 len 1");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
p = sshbuf_dtob64(p1);
ASSERT_PTR_NE(p, NULL);
ASSERT_STRING_EQ(p, "EQ==");
free(p);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_dtob64 len 2");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
p = sshbuf_dtob64(p1);
ASSERT_PTR_NE(p, NULL);
ASSERT_STRING_EQ(p, "ESI=");
free(p);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_dtob64 len 3");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x33), 0);
p = sshbuf_dtob64(p1);
ASSERT_PTR_NE(p, NULL);
ASSERT_STRING_EQ(p, "ESIz");
free(p);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_dtob64 len 8191");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_reserve(p1, 8192, NULL), 0);
bzero(sshbuf_mutable_ptr(p1), 8192);
p = sshbuf_dtob64(p1);
ASSERT_PTR_NE(p, NULL);
ASSERT_SIZE_T_EQ(strlen(p), ((8191 + 2) / 3) * 4);
free(p);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_b64tod len 1");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A=="), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
ASSERT_U8_EQ(*sshbuf_ptr(p1), 0xd0);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_b64tod len 2");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A8="), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), 0xd00f);
sshbuf_free(p1);
TEST_DONE();
TEST_START("sshbuf_b64tod len 4");
p1 = sshbuf_new();
ASSERT_PTR_NE(p1, NULL);
ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A/QDw=="), 0);
ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), 0xd00fd00f);
sshbuf_free(p1);
TEST_DONE();
}

View File

@ -0,0 +1,28 @@
/* $OpenBSD: tests.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
/*
* Regress test for sshbuf.h buffer API
*
* Placed in the public domain
*/
#include "test_helper.h"
void sshbuf_tests(void);
void sshbuf_getput_basic_tests(void);
void sshbuf_getput_crypto_tests(void);
void sshbuf_misc_tests(void);
void sshbuf_fuzz_tests(void);
void sshbuf_getput_fuzz_tests(void);
void sshbuf_fixed(void);
void
tests(void)
{
sshbuf_tests();
sshbuf_getput_basic_tests();
sshbuf_getput_crypto_tests();
sshbuf_misc_tests();
sshbuf_fuzz_tests();
sshbuf_getput_fuzz_tests();
sshbuf_fixed();
}

View File

@ -0,0 +1,13 @@
# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
LIB= test_helper
SRCS= test_helper.c fuzz.c
DEBUGLIBS= no
NOPROFILE= yes
NOPIC= yes
install:
@echo -n
.include <bsd.lib.mk>

View File

@ -0,0 +1,374 @@
/* $OpenBSD: fuzz.c,v 1.3 2014/05/02 09:41:32 andre Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Utility functions/framework for fuzz tests */
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "test_helper.h"
/* #define FUZZ_DEBUG */
#ifdef FUZZ_DEBUG
# define FUZZ_DBG(x) do { \
printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \
printf x; \
printf("\n"); \
fflush(stdout); \
} while (0)
#else
# define FUZZ_DBG(x)
#endif
/* For brevity later */
typedef unsigned long long fuzz_ullong;
/* For base-64 fuzzing */
static const char fuzz_b64chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
struct fuzz {
/* Fuzz method currently in use */
int strategy;
/* Fuzz methods remaining */
int strategies;
/* Original seed data blob */
void *seed;
size_t slen;
/* Current working copy of seed with fuzz mutations applied */
u_char *fuzzed;
/* Used by fuzz methods */
size_t o1, o2;
};
static const char *
fuzz_ntop(u_int n)
{
switch (n) {
case 0:
return "NONE";
case FUZZ_1_BIT_FLIP:
return "FUZZ_1_BIT_FLIP";
case FUZZ_2_BIT_FLIP:
return "FUZZ_2_BIT_FLIP";
case FUZZ_1_BYTE_FLIP:
return "FUZZ_1_BYTE_FLIP";
case FUZZ_2_BYTE_FLIP:
return "FUZZ_2_BYTE_FLIP";
case FUZZ_TRUNCATE_START:
return "FUZZ_TRUNCATE_START";
case FUZZ_TRUNCATE_END:
return "FUZZ_TRUNCATE_END";
case FUZZ_BASE64:
return "FUZZ_BASE64";
default:
abort();
}
}
void
fuzz_dump(struct fuzz *fuzz)
{
u_char *p = fuzz_ptr(fuzz);
size_t i, j, len = fuzz_len(fuzz);
switch (fuzz->strategy) {
case FUZZ_1_BIT_FLIP:
fprintf(stderr, "%s case %zu of %zu (bit: %zu)\n",
fuzz_ntop(fuzz->strategy),
fuzz->o1, fuzz->slen * 8, fuzz->o1);
break;
case FUZZ_2_BIT_FLIP:
fprintf(stderr, "%s case %llu of %llu (bits: %zu, %zu)\n",
fuzz_ntop(fuzz->strategy),
(((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1,
((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8,
fuzz->o1, fuzz->o2);
break;
case FUZZ_1_BYTE_FLIP:
fprintf(stderr, "%s case %zu of %zu (byte: %zu)\n",
fuzz_ntop(fuzz->strategy),
fuzz->o1, fuzz->slen, fuzz->o1);
break;
case FUZZ_2_BYTE_FLIP:
fprintf(stderr, "%s case %llu of %llu (bytes: %zu, %zu)\n",
fuzz_ntop(fuzz->strategy),
(((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1,
((fuzz_ullong)fuzz->slen) * fuzz->slen,
fuzz->o1, fuzz->o2);
break;
case FUZZ_TRUNCATE_START:
fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n",
fuzz_ntop(fuzz->strategy),
fuzz->o1, fuzz->slen, fuzz->o1);
break;
case FUZZ_TRUNCATE_END:
fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n",
fuzz_ntop(fuzz->strategy),
fuzz->o1, fuzz->slen, fuzz->o1);
break;
case FUZZ_BASE64:
assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
fprintf(stderr, "%s case %llu of %llu (offset: %zu char: %c)\n",
fuzz_ntop(fuzz->strategy),
(fuzz->o1 * (fuzz_ullong)64) + fuzz->o2,
fuzz->slen * (fuzz_ullong)64, fuzz->o1,
fuzz_b64chars[fuzz->o2]);
break;
default:
abort();
}
fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, len);
for (i = 0; i < len; i += 16) {
fprintf(stderr, "%.4zd: ", i);
for (j = i; j < i + 16; j++) {
if (j < len)
fprintf(stderr, "%02x ", p[j]);
else
fprintf(stderr, " ");
}
fprintf(stderr, " ");
for (j = i; j < i + 16; j++) {
if (j < len) {
if (isascii(p[j]) && isprint(p[j]))
fprintf(stderr, "%c", p[j]);
else
fprintf(stderr, ".");
}
}
fprintf(stderr, "\n");
}
}
struct fuzz *
fuzz_begin(u_int strategies, const void *p, size_t l)
{
struct fuzz *ret = calloc(sizeof(*ret), 1);
assert(p != NULL);
assert(ret != NULL);
ret->seed = malloc(l);
assert(ret->seed != NULL);
memcpy(ret->seed, p, l);
ret->slen = l;
ret->strategies = strategies;
assert(ret->slen < SIZE_MAX / 8);
assert(ret->strategies <= (FUZZ_MAX|(FUZZ_MAX-1)));
FUZZ_DBG(("begin, ret = %p", ret));
fuzz_next(ret);
return ret;
}
void
fuzz_cleanup(struct fuzz *fuzz)
{
FUZZ_DBG(("cleanup, fuzz = %p", fuzz));
assert(fuzz != NULL);
assert(fuzz->seed != NULL);
assert(fuzz->fuzzed != NULL);
free(fuzz->seed);
free(fuzz->fuzzed);
free(fuzz);
}
static int
fuzz_strategy_done(struct fuzz *fuzz)
{
FUZZ_DBG(("fuzz = %p, strategy = %s, o1 = %zu, o2 = %zu, slen = %zu",
fuzz, fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->o2, fuzz->slen));
switch (fuzz->strategy) {
case FUZZ_1_BIT_FLIP:
return fuzz->o1 >= fuzz->slen * 8;
case FUZZ_2_BIT_FLIP:
return fuzz->o2 >= fuzz->slen * 8;
case FUZZ_2_BYTE_FLIP:
return fuzz->o2 >= fuzz->slen;
case FUZZ_1_BYTE_FLIP:
case FUZZ_TRUNCATE_START:
case FUZZ_TRUNCATE_END:
case FUZZ_BASE64:
return fuzz->o1 >= fuzz->slen;
default:
abort();
}
}
void
fuzz_next(struct fuzz *fuzz)
{
u_int i;
FUZZ_DBG(("start, fuzz = %p, strategy = %s, strategies = 0x%lx, "
"o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy),
(u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen));
if (fuzz->strategy == 0 || fuzz_strategy_done(fuzz)) {
/* If we are just starting out, we need to allocate too */
if (fuzz->fuzzed == NULL) {
FUZZ_DBG(("alloc"));
fuzz->fuzzed = calloc(fuzz->slen, 1);
}
/* Pick next strategy */
FUZZ_DBG(("advance"));
for (i = 1; i <= FUZZ_MAX; i <<= 1) {
if ((fuzz->strategies & i) != 0) {
fuzz->strategy = i;
break;
}
}
FUZZ_DBG(("selected = %u", fuzz->strategy));
if (fuzz->strategy == 0) {
FUZZ_DBG(("done, no more strategies"));
return;
}
fuzz->strategies &= ~(fuzz->strategy);
fuzz->o1 = fuzz->o2 = 0;
}
assert(fuzz->fuzzed != NULL);
switch (fuzz->strategy) {
case FUZZ_1_BIT_FLIP:
assert(fuzz->o1 / 8 < fuzz->slen);
memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8);
fuzz->o1++;
break;
case FUZZ_2_BIT_FLIP:
assert(fuzz->o1 / 8 < fuzz->slen);
assert(fuzz->o2 / 8 < fuzz->slen);
memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8);
fuzz->fuzzed[fuzz->o2 / 8] ^= 1 << (fuzz->o2 % 8);
fuzz->o1++;
if (fuzz->o1 >= fuzz->slen * 8) {
fuzz->o1 = 0;
fuzz->o2++;
}
break;
case FUZZ_1_BYTE_FLIP:
assert(fuzz->o1 < fuzz->slen);
memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
fuzz->fuzzed[fuzz->o1] ^= 0xff;
fuzz->o1++;
break;
case FUZZ_2_BYTE_FLIP:
assert(fuzz->o1 < fuzz->slen);
assert(fuzz->o2 < fuzz->slen);
memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
fuzz->fuzzed[fuzz->o1] ^= 0xff;
fuzz->fuzzed[fuzz->o2] ^= 0xff;
fuzz->o1++;
if (fuzz->o1 >= fuzz->slen) {
fuzz->o1 = 0;
fuzz->o2++;
}
break;
case FUZZ_TRUNCATE_START:
case FUZZ_TRUNCATE_END:
assert(fuzz->o1 < fuzz->slen);
memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
fuzz->o1++;
break;
case FUZZ_BASE64:
assert(fuzz->o1 < fuzz->slen);
assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
fuzz->fuzzed[fuzz->o1] = fuzz_b64chars[fuzz->o2];
fuzz->o2++;
if (fuzz->o2 >= sizeof(fuzz_b64chars) - 1) {
fuzz->o2 = 0;
fuzz->o1++;
}
break;
default:
abort();
}
FUZZ_DBG(("done, fuzz = %p, strategy = %s, strategies = 0x%lx, "
"o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy),
(u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen));
}
int
fuzz_done(struct fuzz *fuzz)
{
FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz,
(u_long)fuzz->strategies));
return fuzz_strategy_done(fuzz) && fuzz->strategies == 0;
}
size_t
fuzz_len(struct fuzz *fuzz)
{
assert(fuzz->fuzzed != NULL);
switch (fuzz->strategy) {
case FUZZ_1_BIT_FLIP:
case FUZZ_2_BIT_FLIP:
case FUZZ_1_BYTE_FLIP:
case FUZZ_2_BYTE_FLIP:
case FUZZ_BASE64:
return fuzz->slen;
case FUZZ_TRUNCATE_START:
case FUZZ_TRUNCATE_END:
assert(fuzz->o1 <= fuzz->slen);
return fuzz->slen - fuzz->o1;
default:
abort();
}
}
u_char *
fuzz_ptr(struct fuzz *fuzz)
{
assert(fuzz->fuzzed != NULL);
switch (fuzz->strategy) {
case FUZZ_1_BIT_FLIP:
case FUZZ_2_BIT_FLIP:
case FUZZ_1_BYTE_FLIP:
case FUZZ_2_BYTE_FLIP:
case FUZZ_BASE64:
return fuzz->fuzzed;
case FUZZ_TRUNCATE_START:
assert(fuzz->o1 <= fuzz->slen);
return fuzz->fuzzed + fuzz->o1;
case FUZZ_TRUNCATE_END:
assert(fuzz->o1 <= fuzz->slen);
return fuzz->fuzzed;
default:
abort();
}
}

View File

@ -0,0 +1,452 @@
/* $OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Utility functions/framework for regress tests */
#include <sys/types.h>
#include <sys/param.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <openssl/bn.h>
#include <vis.h>
#include "test_helper.h"
#define TEST_CHECK_INT(r, pred) do { \
switch (pred) { \
case TEST_EQ: \
if (r == 0) \
return; \
break; \
case TEST_NE: \
if (r != 0) \
return; \
break; \
case TEST_LT: \
if (r < 0) \
return; \
break; \
case TEST_LE: \
if (r <= 0) \
return; \
break; \
case TEST_GT: \
if (r > 0) \
return; \
break; \
case TEST_GE: \
if (r >= 0) \
return; \
break; \
default: \
abort(); \
} \
} while (0)
#define TEST_CHECK(x1, x2, pred) do { \
switch (pred) { \
case TEST_EQ: \
if (x1 == x2) \
return; \
break; \
case TEST_NE: \
if (x1 != x2) \
return; \
break; \
case TEST_LT: \
if (x1 < x2) \
return; \
break; \
case TEST_LE: \
if (x1 <= x2) \
return; \
break; \
case TEST_GT: \
if (x1 > x2) \
return; \
break; \
case TEST_GE: \
if (x1 >= x2) \
return; \
break; \
default: \
abort(); \
} \
} while (0)
extern char *__progname;
static int verbose_mode = 0;
static int quiet_mode = 0;
static char *active_test_name = NULL;
static u_int test_number = 0;
static test_onerror_func_t *test_onerror = NULL;
static void *onerror_ctx = NULL;
static const char *data_dir = NULL;
int
main(int argc, char **argv)
{
int ch;
while ((ch = getopt(argc, argv, "vqd:")) != -1) {
switch (ch) {
case 'd':
data_dir = optarg;
break;
case 'q':
verbose_mode = 0;
quiet_mode = 1;
break;
case 'v':
verbose_mode = 1;
quiet_mode = 0;
break;
default:
fprintf(stderr, "Unrecognised command line option\n");
fprintf(stderr, "Usage: %s [-v]\n", __progname);
exit(1);
}
}
setvbuf(stdout, NULL, _IONBF, 0);
if (!quiet_mode)
printf("%s: ", __progname);
if (verbose_mode)
printf("\n");
tests();
if (!quiet_mode)
printf(" %u tests ok\n", test_number);
return 0;
}
const char *
test_data_file(const char *name)
{
static char ret[PATH_MAX];
if (data_dir != NULL)
snprintf(ret, sizeof(ret), "%s/%s", data_dir, name);
else
strlcpy(ret, name, sizeof(ret));
if (access(ret, F_OK) != 0) {
fprintf(stderr, "Cannot access data file %s: %s\n",
ret, strerror(errno));
exit(1);
}
return ret;
}
void
test_start(const char *n)
{
assert(active_test_name == NULL);
assert((active_test_name = strdup(n)) != NULL);
if (verbose_mode)
printf("test %u - \"%s\": ", test_number, active_test_name);
test_number++;
}
void
set_onerror_func(test_onerror_func_t *f, void *ctx)
{
test_onerror = f;
onerror_ctx = ctx;
}
void
test_done(void)
{
assert(active_test_name != NULL);
free(active_test_name);
active_test_name = NULL;
if (verbose_mode)
printf("OK\n");
else if (!quiet_mode) {
printf(".");
fflush(stdout);
}
}
void
ssl_err_check(const char *file, int line)
{
long openssl_error = ERR_get_error();
if (openssl_error == 0)
return;
fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s",
file, line, ERR_error_string(openssl_error, NULL));
abort();
}
static const char *
pred_name(enum test_predicate p)
{
switch (p) {
case TEST_EQ:
return "EQ";
case TEST_NE:
return "NE";
case TEST_LT:
return "LT";
case TEST_LE:
return "LE";
case TEST_GT:
return "GT";
case TEST_GE:
return "GE";
default:
return "UNKNOWN";
}
}
static void
test_die(void)
{
if (test_onerror != NULL)
test_onerror(onerror_ctx);
abort();
}
static void
test_header(const char *file, int line, const char *a1, const char *a2,
const char *name, enum test_predicate pred)
{
fprintf(stderr, "\n%s:%d test #%u \"%s\"\n",
file, line, test_number, active_test_name);
fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n",
name, pred_name(pred), a1,
a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
}
void
assert_bignum(const char *file, int line, const char *a1, const char *a2,
const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred)
{
int r = BN_cmp(aa1, aa2);
TEST_CHECK_INT(r, pred);
test_header(file, line, a1, a2, "BIGNUM", pred);
fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1));
fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2));
test_die();
}
void
assert_string(const char *file, int line, const char *a1, const char *a2,
const char *aa1, const char *aa2, enum test_predicate pred)
{
int r = strcmp(aa1, aa2);
TEST_CHECK_INT(r, pred);
test_header(file, line, a1, a2, "STRING", pred);
fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1));
fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2));
test_die();
}
static char *
tohex(const void *_s, size_t l)
{
u_int8_t *s = (u_int8_t *)_s;
size_t i, j;
const char *hex = "0123456789abcdef";
char *r = malloc((l * 2) + 1);
assert(r != NULL);
for (i = j = 0; i < l; i++) {
r[j++] = hex[(s[i] >> 4) & 0xf];
r[j++] = hex[s[i] & 0xf];
}
r[j] = '\0';
return r;
}
void
assert_mem(const char *file, int line, const char *a1, const char *a2,
const void *aa1, const void *aa2, size_t l, enum test_predicate pred)
{
int r = memcmp(aa1, aa2, l);
TEST_CHECK_INT(r, pred);
test_header(file, line, a1, a2, "STRING", pred);
fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l);
fprintf(stderr, "%12s = %s (len %zu)\n", a2, tohex(aa2, MIN(l, 256)), l);
test_die();
}
static int
memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where)
{
size_t i;
for (i = 0; i < l; i++) {
if (s[i] != v) {
*where = i;
return 1;
}
}
return 0;
}
void
assert_mem_filled(const char *file, int line, const char *a1,
const void *aa1, u_char v, size_t l, enum test_predicate pred)
{
size_t where = -1;
int r = memvalcmp(aa1, v, l, &where);
char tmp[64];
if (l == 0)
return;
TEST_CHECK_INT(r, pred);
test_header(file, line, a1, NULL, "MEM_ZERO", pred);
fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
tohex(aa1, MIN(l, 20)), l > 20 ? "..." : "", l);
snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where);
fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp,
((u_char *)aa1)[where], v);
test_die();
}
void
assert_int(const char *file, int line, const char *a1, const char *a2,
int aa1, int aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "INT", pred);
fprintf(stderr, "%12s = %d\n", a1, aa1);
fprintf(stderr, "%12s = %d\n", a2, aa2);
test_die();
}
void
assert_size_t(const char *file, int line, const char *a1, const char *a2,
size_t aa1, size_t aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "SIZE_T", pred);
fprintf(stderr, "%12s = %zu\n", a1, aa1);
fprintf(stderr, "%12s = %zu\n", a2, aa2);
test_die();
}
void
assert_u_int(const char *file, int line, const char *a1, const char *a2,
u_int aa1, u_int aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "U_INT", pred);
fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1);
fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2);
test_die();
}
void
assert_long_long(const char *file, int line, const char *a1, const char *a2,
long long aa1, long long aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "LONG LONG", pred);
fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1);
fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2);
test_die();
}
void
assert_char(const char *file, int line, const char *a1, const char *a2,
char aa1, char aa2, enum test_predicate pred)
{
char buf[8];
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "CHAR", pred);
fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1);
fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2);
test_die();
}
void
assert_u8(const char *file, int line, const char *a1, const char *a2,
u_int8_t aa1, u_int8_t aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "U8", pred);
fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1);
fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2);
test_die();
}
void
assert_u16(const char *file, int line, const char *a1, const char *a2,
u_int16_t aa1, u_int16_t aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "U16", pred);
fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1);
fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2);
test_die();
}
void
assert_u32(const char *file, int line, const char *a1, const char *a2,
u_int32_t aa1, u_int32_t aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "U32", pred);
fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1);
fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2);
test_die();
}
void
assert_u64(const char *file, int line, const char *a1, const char *a2,
u_int64_t aa1, u_int64_t aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "U64", pred);
fprintf(stderr, "%12s = 0x%016llx %llu\n", a1,
(unsigned long long)aa1, (unsigned long long)aa1);
fprintf(stderr, "%12s = 0x%016llx %llu\n", a2,
(unsigned long long)aa2, (unsigned long long)aa2);
test_die();
}
void
assert_ptr(const char *file, int line, const char *a1, const char *a2,
const void *aa1, const void *aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "PTR", pred);
fprintf(stderr, "%12s = %p\n", a1, aa1);
fprintf(stderr, "%12s = %p\n", a2, aa2);
test_die();
}

View File

@ -0,0 +1,288 @@
/* $OpenBSD: test_helper.h,v 1.3 2014/05/02 09:41:32 andre Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Utility functions/framework for regress tests */
#ifndef _TEST_HELPER_H
#define _TEST_HELPER_H
#include <sys/types.h>
#include <stdint.h>
#include <openssl/bn.h>
#include <openssl/err.h>
enum test_predicate {
TEST_EQ, TEST_NE, TEST_LT, TEST_LE, TEST_GT, TEST_GE
};
typedef void (test_onerror_func_t)(void *);
/* Supplied by test suite */
void tests(void);
const char *test_data_file(const char *name);
void test_start(const char *n);
void set_onerror_func(test_onerror_func_t *f, void *ctx);
void test_done(void);
void ssl_err_check(const char *file, int line);
void assert_bignum(const char *file, int line,
const char *a1, const char *a2,
const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred);
void assert_string(const char *file, int line,
const char *a1, const char *a2,
const char *aa1, const char *aa2, enum test_predicate pred);
void assert_mem(const char *file, int line,
const char *a1, const char *a2,
const void *aa1, const void *aa2, size_t l, enum test_predicate pred);
void assert_mem_filled(const char *file, int line,
const char *a1,
const void *aa1, u_char v, size_t l, enum test_predicate pred);
void assert_int(const char *file, int line,
const char *a1, const char *a2,
int aa1, int aa2, enum test_predicate pred);
void assert_size_t(const char *file, int line,
const char *a1, const char *a2,
size_t aa1, size_t aa2, enum test_predicate pred);
void assert_u_int(const char *file, int line,
const char *a1, const char *a2,
u_int aa1, u_int aa2, enum test_predicate pred);
void assert_long_long(const char *file, int line,
const char *a1, const char *a2,
long long aa1, long long aa2, enum test_predicate pred);
void assert_char(const char *file, int line,
const char *a1, const char *a2,
char aa1, char aa2, enum test_predicate pred);
void assert_ptr(const char *file, int line,
const char *a1, const char *a2,
const void *aa1, const void *aa2, enum test_predicate pred);
void assert_u8(const char *file, int line,
const char *a1, const char *a2,
u_int8_t aa1, u_int8_t aa2, enum test_predicate pred);
void assert_u16(const char *file, int line,
const char *a1, const char *a2,
u_int16_t aa1, u_int16_t aa2, enum test_predicate pred);
void assert_u32(const char *file, int line,
const char *a1, const char *a2,
u_int32_t aa1, u_int32_t aa2, enum test_predicate pred);
void assert_u64(const char *file, int line,
const char *a1, const char *a2,
u_int64_t aa1, u_int64_t aa2, enum test_predicate pred);
#define TEST_START(n) test_start(n)
#define TEST_DONE() test_done()
#define TEST_ONERROR(f, c) set_onerror_func(f, c)
#define SSL_ERR_CHECK() ssl_err_check(__FILE__, __LINE__)
#define ASSERT_BIGNUM_EQ(a1, a2) \
assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_STRING_EQ(a1, a2) \
assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_MEM_EQ(a1, a2, l) \
assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_EQ)
#define ASSERT_MEM_FILLED_EQ(a1, c, l) \
assert_mem_filled(__FILE__, __LINE__, #a1, a1, c, l, TEST_EQ)
#define ASSERT_MEM_ZERO_EQ(a1, l) \
assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_EQ)
#define ASSERT_INT_EQ(a1, a2) \
assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_SIZE_T_EQ(a1, a2) \
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_U_INT_EQ(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_LONG_LONG_EQ(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_CHAR_EQ(a1, a2) \
assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_PTR_EQ(a1, a2) \
assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_U8_EQ(a1, a2) \
assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_U16_EQ(a1, a2) \
assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_U32_EQ(a1, a2) \
assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_U64_EQ(a1, a2) \
assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_BIGNUM_NE(a1, a2) \
assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_STRING_NE(a1, a2) \
assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_MEM_NE(a1, a2, l) \
assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_NE)
#define ASSERT_MEM_ZERO_NE(a1, l) \
assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_NE)
#define ASSERT_INT_NE(a1, a2) \
assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_SIZE_T_NE(a1, a2) \
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_U_INT_NE(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_LONG_LONG_NE(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_CHAR_NE(a1, a2) \
assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_PTR_NE(a1, a2) \
assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_U8_NE(a1, a2) \
assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_U16_NE(a1, a2) \
assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_U32_NE(a1, a2) \
assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_U64_NE(a1, a2) \
assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_BIGNUM_LT(a1, a2) \
assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_STRING_LT(a1, a2) \
assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_MEM_LT(a1, a2, l) \
assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LT)
#define ASSERT_INT_LT(a1, a2) \
assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_SIZE_T_LT(a1, a2) \
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_U_INT_LT(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_LONG_LONG_LT(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_CHAR_LT(a1, a2) \
assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_PTR_LT(a1, a2) \
assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_U8_LT(a1, a2) \
assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_U16_LT(a1, a2) \
assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_U32_LT(a1, a2) \
assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_U64_LT(a1, a2) \
assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_BIGNUM_LE(a1, a2) \
assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_STRING_LE(a1, a2) \
assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_MEM_LE(a1, a2, l) \
assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LE)
#define ASSERT_INT_LE(a1, a2) \
assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_SIZE_T_LE(a1, a2) \
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_U_INT_LE(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_LONG_LONG_LE(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_CHAR_LE(a1, a2) \
assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_PTR_LE(a1, a2) \
assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_U8_LE(a1, a2) \
assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_U16_LE(a1, a2) \
assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_U32_LE(a1, a2) \
assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_U64_LE(a1, a2) \
assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_BIGNUM_GT(a1, a2) \
assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_STRING_GT(a1, a2) \
assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_MEM_GT(a1, a2, l) \
assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GT)
#define ASSERT_INT_GT(a1, a2) \
assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_SIZE_T_GT(a1, a2) \
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_U_INT_GT(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_LONG_LONG_GT(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_CHAR_GT(a1, a2) \
assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_PTR_GT(a1, a2) \
assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_U8_GT(a1, a2) \
assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_U16_GT(a1, a2) \
assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_U32_GT(a1, a2) \
assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_U64_GT(a1, a2) \
assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_BIGNUM_GE(a1, a2) \
assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_STRING_GE(a1, a2) \
assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_MEM_GE(a1, a2, l) \
assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GE)
#define ASSERT_INT_GE(a1, a2) \
assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_SIZE_T_GE(a1, a2) \
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_U_INT_GE(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_LONG_LONG_GE(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_CHAR_GE(a1, a2) \
assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_PTR_GE(a1, a2) \
assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_U8_GE(a1, a2) \
assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_U16_GE(a1, a2) \
assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_U32_GE(a1, a2) \
assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_U64_GE(a1, a2) \
assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
/* Fuzzing support */
struct fuzz;
#define FUZZ_1_BIT_FLIP 0x00000001 /* Flip one bit at a time */
#define FUZZ_2_BIT_FLIP 0x00000002 /* Flip two bits at a time */
#define FUZZ_1_BYTE_FLIP 0x00000004 /* Flip one byte at a time */
#define FUZZ_2_BYTE_FLIP 0x00000008 /* Flip two bytes at a time */
#define FUZZ_TRUNCATE_START 0x00000010 /* Truncate from beginning */
#define FUZZ_TRUNCATE_END 0x00000020 /* Truncate from end */
#define FUZZ_BASE64 0x00000040 /* Try all base64 chars */
#define FUZZ_MAX FUZZ_BASE64
/* Start fuzzing a blob of data with selected strategies (bitmask) */
struct fuzz *fuzz_begin(u_int strategies, const void *p, size_t l);
/* Free a fuzz context */
void fuzz_cleanup(struct fuzz *fuzz);
/* Prepare the next fuzz case in the series */
void fuzz_next(struct fuzz *fuzz);
/* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */
int fuzz_done(struct fuzz *fuzz);
/* Return the length and a pointer to the current fuzzed case */
size_t fuzz_len(struct fuzz *fuzz);
u_char *fuzz_ptr(struct fuzz *fuzz);
/* Dump the current fuzz case to stderr */
void fuzz_dump(struct fuzz *fuzz);
#endif /* _TEST_HELPER_H */