diff options
Diffstat (limited to 'crypto/openssh/regress/unittests/sshbuf')
9 files changed, 1892 insertions, 0 deletions
| diff --git a/crypto/openssh/regress/unittests/sshbuf/Makefile b/crypto/openssh/regress/unittests/sshbuf/Makefile new file mode 100644 index 000000000000..a8ddfaf7ed24 --- /dev/null +++ b/crypto/openssh/regress/unittests/sshbuf/Makefile @@ -0,0 +1,22 @@ +#	$OpenBSD: Makefile,v 1.10 2021/01/09 12:24:31 dtucker Exp $ + +#	$OpenBSD: Makefile,v 1.8 2020/01/26 00:09:50 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 + +# From usr.bin/ssh +SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c +SRCS+=sshbuf-io.c atomicio.c misc.c xmalloc.c log.c fatal.c ssherr.c cleanup.c +SRCS+=match.c addr.c addrmatch.c + +run-regress-${PROG}: ${PROG} +	env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} + diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf.c new file mode 100644 index 000000000000..e22b390fe33d --- /dev/null +++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf.c @@ -0,0 +1,243 @@ +/* 	$OpenBSD: test_sshbuf.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#define SSHBUF_INTERNAL 1	/* access internals for testing */ +#include "includes.h" + +#include <sys/types.h> +#include <stdio.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <stdlib.h> +#include <string.h> + +#include "../test_helper/test_helper.h" + +#include "ssherr.h" +#include "sshbuf.h" + +void sshbuf_tests(void); + +#ifndef roundup +#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y)) +#endif + +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(); +} diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fixed.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fixed.c new file mode 100644 index 000000000000..dff77f042152 --- /dev/null +++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fixed.c @@ -0,0 +1,125 @@ +/* 	$OpenBSD: test_sshbuf_fixed.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#define SSHBUF_INTERNAL 1  /* access internals for testing */ +#include "includes.h" + +#include <sys/types.h> +#include <stdio.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <stdlib.h> +#include <string.h> + +#include "../test_helper/test_helper.h" + +#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); +} diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c new file mode 100644 index 000000000000..c0b809dcde1b --- /dev/null +++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c @@ -0,0 +1,131 @@ +/* 	$OpenBSD: test_sshbuf_fuzz.c,v 1.4 2021/12/18 06:53:59 anton Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include <sys/types.h> +#include <stdio.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <stdlib.h> +#include <string.h> + +#include "../test_helper/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, ntests = NUM_FUZZ_TESTS; +	u_int32_t r; +	int ret; + +	if (test_is_fast()) +		ntests >>= 2; +	if (test_is_slow()) +		ntests <<= 2; + +	/* 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 < ntests; 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(); +} diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c new file mode 100644 index 000000000000..3da413edd35c --- /dev/null +++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c @@ -0,0 +1,712 @@ +/* 	$OpenBSD: test_sshbuf_getput_basic.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include <sys/types.h> +#include <stdio.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <stdlib.h> +#include <string.h> + +#include "../test_helper/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(); + +	TEST_START("sshbuf_peek_u64"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); +	ASSERT_INT_EQ(sshbuf_peek_u64(p1, 0, &v64), 0); +	ASSERT_U64_EQ(v64, 0x1122334455667788ULL); +	ASSERT_INT_EQ(sshbuf_peek_u64(p1, 2, &v64), 0); +	ASSERT_U64_EQ(v64, 0x3344556677880099ULL); +	ASSERT_INT_EQ(sshbuf_peek_u64(p1, 3, &v64), SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_peek_u64(p1, sizeof(x), &v64), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_peek_u64(p1, 1000, &v64), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_peek_u32"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); +	ASSERT_INT_EQ(sshbuf_peek_u32(p1, 0, &v32), 0); +	ASSERT_U32_EQ(v32, 0x11223344); +	ASSERT_INT_EQ(sshbuf_peek_u32(p1, 6, &v32), 0); +	ASSERT_U32_EQ(v32, 0x77880099); +	ASSERT_INT_EQ(sshbuf_peek_u32(p1, 7, &v32), SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_peek_u32(p1, sizeof(x), &v32), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_peek_u32(p1, 1000, &v32), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_peek_u16"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); +	ASSERT_INT_EQ(sshbuf_peek_u16(p1, 0, &v16), 0); +	ASSERT_U16_EQ(v16, 0x1122); +	ASSERT_INT_EQ(sshbuf_peek_u16(p1, 8, &v16), 0); +	ASSERT_U16_EQ(v16, 0x99); +	ASSERT_INT_EQ(sshbuf_peek_u16(p1, 9, &v16), SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_peek_u16(p1, sizeof(x), &v16), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_peek_u16(p1, 1000, &v16), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_peek_u8"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); +	ASSERT_INT_EQ(sshbuf_peek_u8(p1, 0, &v8), 0); +	ASSERT_U8_EQ(v8, 0x11); +	ASSERT_INT_EQ(sshbuf_peek_u8(p1, 9, &v8), 0); +	ASSERT_U8_EQ(v8, 0x99); +	ASSERT_INT_EQ(sshbuf_peek_u8(p1, sizeof(x), &v8), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_peek_u8(p1, 1000, &v8), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_poke_u64"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke at start of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u64(p1, 0, 0xa1b2c3d4e5f60718ULL), 0); +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "a1b2c3d4e5f607180000"); +	free(s2); +	sshbuf_reset(p1); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke aligned with end of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u64(p1, 2, 0xa1b2c3d4e5f60718ULL), 0); +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "0000a1b2c3d4e5f60718"); +	free(s2); +	sshbuf_reset(p1); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke past end of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u64(p1, 3, 0xa1b2c3d4e5f60718ULL), +	    SSH_ERR_NO_BUFFER_SPACE); +	ASSERT_INT_EQ(sshbuf_poke_u64(p1, 10, 0xa1b2c3d4e5f60718ULL), +	    SSH_ERR_NO_BUFFER_SPACE); +	ASSERT_INT_EQ(sshbuf_poke_u64(p1, 1000, 0xa1b2c3d4e5f60718ULL), +	    SSH_ERR_NO_BUFFER_SPACE); +	/* ensure failed pokes do not modify buffer */ +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "00000000000000000000"); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_poke_u32"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke at start of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u32(p1, 0, 0xa1b2c3d4), 0); +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "a1b2c3d4000000000000"); +	free(s2); +	sshbuf_reset(p1); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke aligned with end of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u32(p1, 6, 0xa1b2c3d4), 0); +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "000000000000a1b2c3d4"); +	free(s2); +	sshbuf_reset(p1); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke past end of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u32(p1, 7, 0xa1b2c3d4), +	    SSH_ERR_NO_BUFFER_SPACE); +	ASSERT_INT_EQ(sshbuf_poke_u32(p1, 10, 0xa1b2c3d4), +	    SSH_ERR_NO_BUFFER_SPACE); +	ASSERT_INT_EQ(sshbuf_poke_u32(p1, 1000, 0xa1b2c3d4), +	    SSH_ERR_NO_BUFFER_SPACE); +	/* ensure failed pokes do not modify buffer */ +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "00000000000000000000"); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_poke_u16"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke at start of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u16(p1, 0, 0xa1b2), 0); +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "a1b20000000000000000"); +	free(s2); +	sshbuf_reset(p1); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke aligned with end of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u16(p1, 8, 0xa1b2), 0); +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "0000000000000000a1b2"); +	free(s2); +	sshbuf_reset(p1); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke past end of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u16(p1, 9, 0xa1b2), +	    SSH_ERR_NO_BUFFER_SPACE); +	ASSERT_INT_EQ(sshbuf_poke_u16(p1, 10, 0xa1b2), +	    SSH_ERR_NO_BUFFER_SPACE); +	ASSERT_INT_EQ(sshbuf_poke_u16(p1, 1000, 0xa1b2), +	    SSH_ERR_NO_BUFFER_SPACE); +	/* ensure failed pokes do not modify buffer */ +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "00000000000000000000"); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_poke_u8"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke at start of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u8(p1, 0, 0xa1), 0); +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "a1000000000000000000"); +	free(s2); +	sshbuf_reset(p1); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke aligned with end of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u8(p1, 9, 0xa1), 0); +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "000000000000000000a1"); +	free(s2); +	sshbuf_reset(p1); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke past end of buffer */ +	ASSERT_INT_EQ(sshbuf_poke_u8(p1, 10, 0xa1), SSH_ERR_NO_BUFFER_SPACE); +	ASSERT_INT_EQ(sshbuf_poke_u8(p1, 1000, 0xa1), SSH_ERR_NO_BUFFER_SPACE); +	/* ensure failed pokes do not modify buffer */ +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "00000000000000000000"); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_poke"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke at start of buffer */ +	ASSERT_INT_EQ(sshbuf_poke(p1, 0, "hello!", 6), 0); +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "68656c6c6f2100000000"); +	free(s2); +	sshbuf_reset(p1); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke aligned with end of buffer */ +	ASSERT_INT_EQ(sshbuf_poke(p1, 4, "hello!", 6), 0); +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "0000000068656c6c6f21"); +	free(s2); +	sshbuf_reset(p1); +	ASSERT_INT_EQ(sshbuf_reserve(p1, 10, NULL), 0); +	/* poke past end of buffer */ +	ASSERT_INT_EQ(sshbuf_poke(p1, 7, "hello!", 6), +	    SSH_ERR_NO_BUFFER_SPACE); +	ASSERT_INT_EQ(sshbuf_poke(p1, 10, "hello!", 6), +	    SSH_ERR_NO_BUFFER_SPACE); +	ASSERT_INT_EQ(sshbuf_poke(p1, 1000, "hello!", 6), +	    SSH_ERR_NO_BUFFER_SPACE); +	/* ensure failed pokes do not modify buffer */ +	s2 = sshbuf_dtob16(p1); +	ASSERT_PTR_NE(s2, NULL); +	ASSERT_STRING_EQ(s2, "00000000000000000000"); +	sshbuf_free(p1); +	TEST_DONE(); +} diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c new file mode 100644 index 000000000000..e3620e97fe99 --- /dev/null +++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c @@ -0,0 +1,280 @@ +/* 	$OpenBSD: test_sshbuf_getput_crypto.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#ifdef WITH_OPENSSL + +#include <sys/types.h> +#include <stdio.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <stdlib.h> +#include <string.h> + +#include <openssl/bn.h> +#include <openssl/objects.h> +#ifdef OPENSSL_HAS_NISTP256 +# include <openssl/ec.h> +#endif + +#include "../test_helper/test_helper.h" +#include "ssherr.h" +#include "sshbuf.h" + +void sshbuf_getput_crypto_tests(void); + +void +sshbuf_getput_crypto_tests(void) +{ +	struct sshbuf *p1; +	BIGNUM *bn, *bn2; +	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 +	}; +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) +	const u_char *d; +	size_t s; +	BIGNUM *bn_x, *bn_y; +	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; +#endif +	int r; + +#define MKBN(b, bnn) \ +	do { \ +		bnn = NULL; \ +		ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \ +	} while (0) + +	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_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 = NULL; +	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 = NULL; +	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 = NULL; +	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 = NULL; +	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 = NULL; +	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 = NULL; +	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(); + +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) +	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(); +#endif +} + +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c new file mode 100644 index 000000000000..3b4895895ef1 --- /dev/null +++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c @@ -0,0 +1,132 @@ +/* 	$OpenBSD: test_sshbuf_getput_fuzz.c,v 1.5 2021/12/14 21:25:27 deraadt Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include <sys/types.h> +#include <stdio.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <stdlib.h> +#include <string.h> + +#ifdef WITH_OPENSSL +#include <openssl/bn.h> +#include <openssl/objects.h> +#ifdef OPENSSL_HAS_NISTP256 +# include <openssl/ec.h> +#endif +#endif + +#include "../test_helper/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; +#ifdef WITH_OPENSSL +	BIGNUM *bn; +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) +	EC_KEY *eck; +#endif /* defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) */ +#endif /* WITH_OPENSSL */ +	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); +	} +#ifdef WITH_OPENSSL +	bn = NULL; +	sshbuf_get_bignum2(p1, &bn); +	BN_clear_free(bn); +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) +	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); +#endif /* defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) */ +#endif /* WITH_OPENSSL */ +	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', '!', +		/* 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; +	u_int fuzzers = FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP | +	    FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP | +	    FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END; + +	if (test_is_fast()) +		fuzzers &= ~(FUZZ_2_BYTE_FLIP|FUZZ_2_BIT_FLIP); + +	TEST_START("fuzz blob parsing"); +	fuzz = fuzz_begin(fuzzers, 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); +} + diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c new file mode 100644 index 000000000000..249ecf235764 --- /dev/null +++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c @@ -0,0 +1,217 @@ +/* 	$OpenBSD: test_sshbuf_misc.c,v 1.5 2021/12/14 21:25:27 deraadt Exp $ */ +/* + * Regress test for sshbuf.h buffer API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include <sys/types.h> +#include <stdio.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <stdlib.h> +#include <string.h> + +#include "../test_helper/test_helper.h" + +#include "sshbuf.h" +#include "ssherr.h" + +void sshbuf_misc_tests(void); + +void +sshbuf_misc_tests(void) +{ +	struct sshbuf *p1; +	char tmp[512], msg[] = "imploring ping silence ping over", *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_string len 1"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0); +	p = sshbuf_dtob64_string(p1, 0); +	ASSERT_PTR_NE(p, NULL); +	ASSERT_STRING_EQ(p, "EQ=="); +	free(p); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_dtob64_string 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_string(p1, 0); +	ASSERT_PTR_NE(p, NULL); +	ASSERT_STRING_EQ(p, "ESI="); +	free(p); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_dtob64_string 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_string(p1, 0); +	ASSERT_PTR_NE(p, NULL); +	ASSERT_STRING_EQ(p, "ESIz"); +	free(p); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_dtob64_string 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_string(p1, 0); +	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(); + +	TEST_START("sshbuf_dup_string"); +	p1 = sshbuf_new(); +	ASSERT_PTR_NE(p1, NULL); +	/* Check empty buffer */ +	p = sshbuf_dup_string(p1); +	ASSERT_PTR_NE(p, NULL); +	ASSERT_SIZE_T_EQ(strlen(p), 0); +	free(p); +	/* Check buffer with string */ +	ASSERT_INT_EQ(sshbuf_put(p1, "quad1", strlen("quad1")), 0); +	p = sshbuf_dup_string(p1); +	ASSERT_PTR_NE(p, NULL); +	ASSERT_SIZE_T_EQ(strlen(p), strlen("quad1")); +	ASSERT_STRING_EQ(p, "quad1"); +	free(p); +	/* Check buffer with terminating nul */ +	ASSERT_INT_EQ(sshbuf_put(p1, "\0", 1), 0); +	p = sshbuf_dup_string(p1); +	ASSERT_PTR_NE(p, NULL); +	ASSERT_SIZE_T_EQ(strlen(p), strlen("quad1")); +	ASSERT_STRING_EQ(p, "quad1"); +	free(p); +	/* Check buffer with data after nul (expect failure) */ +	ASSERT_INT_EQ(sshbuf_put(p1, "quad2", strlen("quad2")), 0); +	p = sshbuf_dup_string(p1); +	ASSERT_PTR_EQ(p, NULL); +	sshbuf_free(p1); +	TEST_DONE(); + +	TEST_START("sshbuf_cmp"); +	p1 = sshbuf_from(msg, sizeof(msg) - 1); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "i", 1), 0); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "j", 1), SSH_ERR_INVALID_FORMAT); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "imploring", 9), 0); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "implored", 9), SSH_ERR_INVALID_FORMAT); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 10, "ping", 4), 0); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 10, "ring", 4), SSH_ERR_INVALID_FORMAT); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "over", 4), 0); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "rove", 4), SSH_ERR_INVALID_FORMAT); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "overt", 5), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 32, "ping", 4), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 1000, "silence", 7), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_cmp(p1, 0, msg, sizeof(msg) - 1), 0); +	TEST_DONE(); + +	TEST_START("sshbuf_find"); +	p1 = sshbuf_from(msg, sizeof(msg) - 1); +	ASSERT_PTR_NE(p1, NULL); +	ASSERT_INT_EQ(sshbuf_find(p1, 0, "i", 1, &sz), 0); +	ASSERT_SIZE_T_EQ(sz, 0); +	ASSERT_INT_EQ(sshbuf_find(p1, 0, "j", 1, &sz), SSH_ERR_INVALID_FORMAT); +	ASSERT_INT_EQ(sshbuf_find(p1, 0, "imploring", 9, &sz), 0); +	ASSERT_SIZE_T_EQ(sz, 0); +	ASSERT_INT_EQ(sshbuf_find(p1, 0, "implored", 9, &sz), +	    SSH_ERR_INVALID_FORMAT); +	ASSERT_INT_EQ(sshbuf_find(p1, 3, "ping", 4, &sz), 0); +	ASSERT_SIZE_T_EQ(sz, 10); +	ASSERT_INT_EQ(sshbuf_find(p1, 11, "ping", 4, &sz), 0); +	ASSERT_SIZE_T_EQ(sz, 23); +	ASSERT_INT_EQ(sshbuf_find(p1, 20, "over", 4, &sz), 0); +	ASSERT_SIZE_T_EQ(sz, 28); +	ASSERT_INT_EQ(sshbuf_find(p1, 28, "over", 4, &sz), 0); +	ASSERT_SIZE_T_EQ(sz, 28); +	ASSERT_INT_EQ(sshbuf_find(p1, 28, "rove", 4, &sz), +	    SSH_ERR_INVALID_FORMAT); +	ASSERT_INT_EQ(sshbuf_find(p1, 28, "overt", 5, &sz), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_find(p1, 32, "ping", 4, &sz), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_find(p1, 1000, "silence", 7, &sz), +	    SSH_ERR_MESSAGE_INCOMPLETE); +	ASSERT_INT_EQ(sshbuf_find(p1, 0, msg + 1, sizeof(msg) - 2, &sz), 0); +	ASSERT_SIZE_T_EQ(sz, 1); +	TEST_DONE(); +} + diff --git a/crypto/openssh/regress/unittests/sshbuf/tests.c b/crypto/openssh/regress/unittests/sshbuf/tests.c new file mode 100644 index 000000000000..29916a10bc5b --- /dev/null +++ b/crypto/openssh/regress/unittests/sshbuf/tests.c @@ -0,0 +1,30 @@ +/* 	$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/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(); +#ifdef WITH_OPENSSL +	sshbuf_getput_crypto_tests(); +#endif +	sshbuf_misc_tests(); +	sshbuf_fuzz_tests(); +	sshbuf_getput_fuzz_tests(); +	sshbuf_fixed(); +} | 
