summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2014-05-15 15:17:15 +1000
committerDamien Miller <djm@mindrot.org>2014-05-15 15:17:15 +1000
commitdef1de086707b0e6b046fe7e115c60aca0227a99 (patch)
tree16a736c080243e1e80fd1ea850ca0e88d657c2cc
parent167685756fde8bc213a8df2c8e1848e312db0f46 (diff)
- (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.
-rw-r--r--ChangeLog16
-rw-r--r--regress/unittests/Makefile5
-rw-r--r--regress/unittests/Makefile.inc59
-rw-r--r--regress/unittests/sshbuf/Makefile14
-rw-r--r--regress/unittests/sshbuf/test_sshbuf.c236
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_fixed.c122
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_fuzz.c123
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_basic.c480
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_crypto.c398
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c120
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_misc.c134
-rw-r--r--regress/unittests/sshbuf/tests.c28
-rw-r--r--regress/unittests/test_helper/Makefile13
-rw-r--r--regress/unittests/test_helper/fuzz.c374
-rw-r--r--regress/unittests/test_helper/test_helper.c452
-rw-r--r--regress/unittests/test_helper/test_helper.h288
16 files changed, 2862 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index da8db6b1d..acf986b23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -111,6 +111,22 @@
111 was removed from malloc.c 10 days ago. 111 was removed from malloc.c 10 days ago.
112 112
113 OK from miod@ 113 OK from miod@
114 - (djm) [regress/unittests/Makefile]
115 [regress/unittests/Makefile.inc]
116 [regress/unittests/sshbuf/Makefile]
117 [regress/unittests/sshbuf/test_sshbuf.c]
118 [regress/unittests/sshbuf/test_sshbuf_fixed.c]
119 [regress/unittests/sshbuf/test_sshbuf_fuzz.c]
120 [regress/unittests/sshbuf/test_sshbuf_getput_basic.c]
121 [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c]
122 [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c]
123 [regress/unittests/sshbuf/test_sshbuf_misc.c]
124 [regress/unittests/sshbuf/tests.c]
125 [regress/unittests/test_helper/Makefile]
126 [regress/unittests/test_helper/fuzz.c]
127 [regress/unittests/test_helper/test_helper.c]
128 [regress/unittests/test_helper/test_helper.h]
129 Import new unit tests from OpenBSD; not yet hooked up to build.
114 130
11520140430 13120140430
116 - (dtucker) [defines.h] Define __GNUC_PREREQ__ macro if we don't already 132 - (dtucker) [defines.h] Define __GNUC_PREREQ__ macro if we don't already
diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile
new file mode 100644
index 000000000..2581a5853
--- /dev/null
+++ b/regress/unittests/Makefile
@@ -0,0 +1,5 @@
1# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
2
3SUBDIR= test_helper sshbuf
4
5.include <bsd.subdir.mk>
diff --git a/regress/unittests/Makefile.inc b/regress/unittests/Makefile.inc
new file mode 100644
index 000000000..4c3363749
--- /dev/null
+++ b/regress/unittests/Makefile.inc
@@ -0,0 +1,59 @@
1# $OpenBSD: Makefile.inc,v 1.1 2014/04/30 05:32:00 djm Exp $
2
3.include <bsd.own.mk>
4.include <bsd.obj.mk>
5
6# enable warnings
7WARNINGS=Yes
8
9DEBUG=-g
10CFLAGS+= -fstack-protector-all
11CDIAGFLAGS= -Wall
12CDIAGFLAGS+= -Wextra
13CDIAGFLAGS+= -Werror
14CDIAGFLAGS+= -Wchar-subscripts
15CDIAGFLAGS+= -Wcomment
16CDIAGFLAGS+= -Wformat
17CDIAGFLAGS+= -Wformat-security
18CDIAGFLAGS+= -Wimplicit
19CDIAGFLAGS+= -Winline
20CDIAGFLAGS+= -Wmissing-declarations
21CDIAGFLAGS+= -Wmissing-prototypes
22CDIAGFLAGS+= -Wparentheses
23CDIAGFLAGS+= -Wpointer-arith
24CDIAGFLAGS+= -Wpointer-sign
25CDIAGFLAGS+= -Wreturn-type
26CDIAGFLAGS+= -Wshadow
27CDIAGFLAGS+= -Wsign-compare
28CDIAGFLAGS+= -Wstrict-aliasing
29CDIAGFLAGS+= -Wstrict-prototypes
30CDIAGFLAGS+= -Wswitch
31CDIAGFLAGS+= -Wtrigraphs
32CDIAGFLAGS+= -Wuninitialized
33CDIAGFLAGS+= -Wunused
34.if ${COMPILER_VERSION} == "gcc4"
35CDIAGFLAGS+= -Wold-style-definition
36.endif
37
38SSHREL=../../../../../usr.bin/ssh
39
40CFLAGS+=-I${.CURDIR}/../test_helper -I${.CURDIR}/${SSHREL}
41
42.if exists(${.CURDIR}/../test_helper/${__objdir})
43LDADD+=-L${.CURDIR}/../test_helper/${__objdir} -ltest_helper
44DPADD+=${.CURDIR}/../test_helper/${__objdir}/libtest_helper.a
45.else
46LDADD+=-L${.CURDIR}/../test_helper -ltest_helper
47DPADD+=${.CURDIR}/../test_helper/libtest_helper.a
48.endif
49
50.if exists(${.CURDIR}/${SSHREL}/lib/${__objdir})
51LDADD+=-L${.CURDIR}/${SSHREL}/lib/${__objdir} -lssh
52DPADD+=${.CURDIR}/${SSHREL}/lib/${__objdir}/libssh.a
53.else
54LDADD+=-L${.CURDIR}/${SSHREL}/lib -lssh
55DPADD+=${.CURDIR}/${SSHREL}/lib/libssh.a
56.endif
57
58LDADD+= -lcrypto
59DPADD+= ${LIBCRYPTO}
diff --git a/regress/unittests/sshbuf/Makefile b/regress/unittests/sshbuf/Makefile
new file mode 100644
index 000000000..85f99ac38
--- /dev/null
+++ b/regress/unittests/sshbuf/Makefile
@@ -0,0 +1,14 @@
1# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
2
3PROG=test_sshbuf
4SRCS=tests.c
5SRCS+=test_sshbuf.c
6SRCS+=test_sshbuf_getput_basic.c
7SRCS+=test_sshbuf_getput_crypto.c
8SRCS+=test_sshbuf_misc.c
9SRCS+=test_sshbuf_fuzz.c
10SRCS+=test_sshbuf_getput_fuzz.c
11SRCS+=test_sshbuf_fixed.c
12
13.include <bsd.regress.mk>
14
diff --git a/regress/unittests/sshbuf/test_sshbuf.c b/regress/unittests/sshbuf/test_sshbuf.c
new file mode 100644
index 000000000..834dcd050
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf.c
@@ -0,0 +1,236 @@
1/* $OpenBSD: test_sshbuf.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include <sys/types.h>
9#include <sys/param.h>
10#include <stdio.h>
11#include <stdint.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include "test_helper.h"
16
17#include "ssherr.h"
18#define SSHBUF_INTERNAL 1 /* access internals for testing */
19#include "sshbuf.h"
20
21void sshbuf_tests(void);
22
23void
24sshbuf_tests(void)
25{
26 struct sshbuf *p1;
27 const u_char *cdp;
28 u_char *dp;
29 size_t sz;
30 int r;
31
32 TEST_START("allocate sshbuf");
33 p1 = sshbuf_new();
34 ASSERT_PTR_NE(p1, NULL);
35 TEST_DONE();
36
37 TEST_START("max size on fresh buffer");
38 ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0);
39 TEST_DONE();
40
41 TEST_START("available on fresh buffer");
42 ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0);
43 TEST_DONE();
44
45 TEST_START("len = 0 on empty buffer");
46 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
47 TEST_DONE();
48
49 TEST_START("set valid max size");
50 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0);
51 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536);
52 TEST_DONE();
53
54 TEST_START("available on limited buffer");
55 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536);
56 TEST_DONE();
57
58 TEST_START("free");
59 sshbuf_free(p1);
60 TEST_DONE();
61
62 TEST_START("consume on empty buffer");
63 p1 = sshbuf_new();
64 ASSERT_PTR_NE(p1, NULL);
65 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
66 ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
67 sshbuf_free(p1);
68 TEST_DONE();
69
70 TEST_START("consume_end on empty buffer");
71 p1 = sshbuf_new();
72 ASSERT_PTR_NE(p1, NULL);
73 ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0);
74 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
75 sshbuf_free(p1);
76 TEST_DONE();
77
78 TEST_START("reserve space");
79 p1 = sshbuf_new();
80 ASSERT_PTR_NE(p1, NULL);
81 r = sshbuf_reserve(p1, 1, &dp);
82 ASSERT_INT_EQ(r, 0);
83 ASSERT_PTR_NE(dp, NULL);
84 *dp = 0x11;
85 r = sshbuf_reserve(p1, 3, &dp);
86 ASSERT_INT_EQ(r, 0);
87 ASSERT_PTR_NE(dp, NULL);
88 *dp++ = 0x22;
89 *dp++ = 0x33;
90 *dp++ = 0x44;
91 TEST_DONE();
92
93 TEST_START("sshbuf_len on filled buffer");
94 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
95 TEST_DONE();
96
97 TEST_START("sshbuf_ptr on filled buffer");
98 cdp = sshbuf_ptr(p1);
99 ASSERT_PTR_NE(cdp, NULL);
100 ASSERT_U8_EQ(cdp[0], 0x11);
101 ASSERT_U8_EQ(cdp[1], 0x22);
102 ASSERT_U8_EQ(cdp[2], 0x33);
103 ASSERT_U8_EQ(cdp[3], 0x44);
104 TEST_DONE();
105
106 TEST_START("consume on filled buffer");
107 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
108 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
109 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
110 r = sshbuf_consume(p1, 64);
111 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
112 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
113 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
114 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
115 cdp = sshbuf_ptr(p1);
116 ASSERT_PTR_NE(p1, NULL);
117 ASSERT_U8_EQ(cdp[0], 0x22);
118 ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0);
119 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
120 cdp = sshbuf_ptr(p1);
121 ASSERT_PTR_NE(p1, NULL);
122 ASSERT_U8_EQ(cdp[0], 0x44);
123 r = sshbuf_consume(p1, 2);
124 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
125 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
126 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
127 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
128 r = sshbuf_consume(p1, 1);
129 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
130 sshbuf_free(p1);
131 TEST_DONE();
132
133 TEST_START("consume_end on filled buffer");
134 p1 = sshbuf_new();
135 ASSERT_PTR_NE(p1, NULL);
136 r = sshbuf_reserve(p1, 4, &dp);
137 ASSERT_INT_EQ(r, 0);
138 ASSERT_PTR_NE(dp, NULL);
139 *dp++ = 0x11;
140 *dp++ = 0x22;
141 *dp++ = 0x33;
142 *dp++ = 0x44;
143 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
144 r = sshbuf_consume_end(p1, 5);
145 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
146 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
147 ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0);
148 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
149 cdp = sshbuf_ptr(p1);
150 ASSERT_PTR_NE(cdp, NULL);
151 ASSERT_U8_EQ(*cdp, 0x11);
152 r = sshbuf_consume_end(p1, 2);
153 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
154 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
155 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
156 sshbuf_free(p1);
157 TEST_DONE();
158
159 TEST_START("fill limited buffer");
160 p1 = sshbuf_new();
161 ASSERT_PTR_NE(p1, NULL);
162 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
163 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
164 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
165 r = sshbuf_reserve(p1, 1223, &dp);
166 ASSERT_INT_EQ(r, 0);
167 ASSERT_PTR_NE(dp, NULL);
168 memset(dp, 0xd7, 1223);
169 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
170 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
171 r = sshbuf_reserve(p1, 1, &dp);
172 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
173 ASSERT_PTR_EQ(dp, NULL);
174 TEST_DONE();
175
176 TEST_START("consume and force compaction");
177 ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0);
178 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
179 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
180 r = sshbuf_reserve(p1, 224, &dp);
181 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
182 ASSERT_PTR_EQ(dp, NULL);
183 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
184 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
185 r = sshbuf_reserve(p1, 223, &dp);
186 ASSERT_INT_EQ(r, 0);
187 ASSERT_PTR_NE(dp, NULL);
188 memset(dp, 0x7d, 223);
189 cdp = sshbuf_ptr(p1);
190 ASSERT_PTR_NE(cdp, NULL);
191 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
192 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
193 TEST_DONE();
194
195 TEST_START("resize full buffer");
196 r = sshbuf_set_max_size(p1, 1000);
197 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
198 sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC);
199 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0);
200 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
201 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223);
202 ASSERT_INT_EQ(sshbuf_len(p1), 1223);
203 TEST_DONE();
204
205 /* NB. uses sshbuf internals */
206 TEST_START("alloc chunking");
207 r = sshbuf_reserve(p1, 1, &dp);
208 ASSERT_INT_EQ(r, 0);
209 ASSERT_PTR_NE(dp, NULL);
210 *dp = 0xff;
211 cdp = sshbuf_ptr(p1);
212 ASSERT_PTR_NE(cdp, NULL);
213 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
214 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
215 ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1);
216 ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0);
217 sshbuf_free(p1);
218 TEST_DONE();
219
220 TEST_START("reset buffer");
221 p1 = sshbuf_new();
222 ASSERT_PTR_NE(p1, NULL);
223 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
224 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
225 r = sshbuf_reserve(p1, 1223, &dp);
226 ASSERT_INT_EQ(r, 0);
227 ASSERT_PTR_NE(dp, NULL);
228 memset(dp, 0xd7, 1223);
229 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
230 sshbuf_reset(p1);
231 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
232 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
233 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
234 sshbuf_free(p1);
235 TEST_DONE();
236}
diff --git a/regress/unittests/sshbuf/test_sshbuf_fixed.c b/regress/unittests/sshbuf/test_sshbuf_fixed.c
new file mode 100644
index 000000000..62c815a2e
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_fixed.c
@@ -0,0 +1,122 @@
1/* $OpenBSD: test_sshbuf_fixed.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include <sys/types.h>
9#include <sys/param.h>
10#include <stdio.h>
11#include <stdint.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include "test_helper.h"
16
17#define SSHBUF_INTERNAL 1 /* access internals for testing */
18#include "sshbuf.h"
19#include "ssherr.h"
20
21void sshbuf_fixed(void);
22
23const u_char test_buf[] = "\x01\x12\x34\x56\x78\x00\x00\x00\x05hello";
24
25void
26sshbuf_fixed(void)
27{
28 struct sshbuf *p1, *p2, *p3;
29 u_char c;
30 char *s;
31 u_int i;
32 size_t l;
33
34 TEST_START("sshbuf_from");
35 p1 = sshbuf_from(test_buf, sizeof(test_buf));
36 ASSERT_PTR_NE(p1, NULL);
37 ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL);
38 ASSERT_INT_EQ(sshbuf_check_reserve(p1, 1), SSH_ERR_BUFFER_READ_ONLY);
39 ASSERT_INT_EQ(sshbuf_reserve(p1, 1, NULL), SSH_ERR_BUFFER_READ_ONLY);
40 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 200), SSH_ERR_BUFFER_READ_ONLY);
41 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), SSH_ERR_BUFFER_READ_ONLY);
42 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
43 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf);
44 sshbuf_free(p1);
45 TEST_DONE();
46
47 TEST_START("sshbuf_from data");
48 p1 = sshbuf_from(test_buf, sizeof(test_buf) - 1);
49 ASSERT_PTR_NE(p1, NULL);
50 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf);
51 ASSERT_INT_EQ(sshbuf_get_u8(p1, &c), 0);
52 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 1);
53 ASSERT_U8_EQ(c, 1);
54 ASSERT_INT_EQ(sshbuf_get_u32(p1, &i), 0);
55 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 5);
56 ASSERT_U32_EQ(i, 0x12345678);
57 ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s, &l), 0);
58 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
59 ASSERT_STRING_EQ(s, "hello");
60 ASSERT_SIZE_T_EQ(l, 5);
61 sshbuf_free(p1);
62 free(s);
63 TEST_DONE();
64
65 TEST_START("sshbuf_fromb ");
66 p1 = sshbuf_new();
67 ASSERT_PTR_NE(p1, NULL);
68 ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1);
69 ASSERT_PTR_EQ(sshbuf_parent(p1), NULL);
70 ASSERT_INT_EQ(sshbuf_put(p1, test_buf, sizeof(test_buf) - 1), 0);
71 p2 = sshbuf_fromb(p1);
72 ASSERT_PTR_NE(p2, NULL);
73 ASSERT_U_INT_EQ(sshbuf_refcount(p1), 2);
74 ASSERT_PTR_EQ(sshbuf_parent(p1), NULL);
75 ASSERT_PTR_EQ(sshbuf_parent(p2), p1);
76 ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1));
77 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
78 ASSERT_PTR_NE(sshbuf_ptr(p2), NULL);
79 ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL);
80 ASSERT_PTR_EQ(sshbuf_mutable_ptr(p2), NULL);
81 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sshbuf_len(p2));
82 ASSERT_INT_EQ(sshbuf_get_u8(p2, &c), 0);
83 ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 1);
84 ASSERT_U8_EQ(c, 1);
85 ASSERT_INT_EQ(sshbuf_get_u32(p2, &i), 0);
86 ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 5);
87 ASSERT_U32_EQ(i, 0x12345678);
88 ASSERT_INT_EQ(sshbuf_get_cstring(p2, &s, &l), 0);
89 ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0);
90 ASSERT_STRING_EQ(s, "hello");
91 ASSERT_SIZE_T_EQ(l, 5);
92 sshbuf_free(p1);
93 ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1);
94 sshbuf_free(p2);
95 free(s);
96 TEST_DONE();
97
98 TEST_START("sshbuf_froms");
99 p1 = sshbuf_new();
100 ASSERT_PTR_NE(p1, NULL);
101 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x01), 0);
102 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
103 ASSERT_INT_EQ(sshbuf_put_cstring(p1, "hello"), 0);
104 p2 = sshbuf_new();
105 ASSERT_PTR_NE(p2, NULL);
106 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(test_buf) - 1);
107 ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0);
108 ASSERT_SIZE_T_EQ(sshbuf_len(p2), sizeof(test_buf) + 4 - 1);
109 ASSERT_INT_EQ(sshbuf_froms(p2, &p3), 0);
110 ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0);
111 ASSERT_PTR_NE(p3, NULL);
112 ASSERT_PTR_NE(sshbuf_ptr(p3), NULL);
113 ASSERT_SIZE_T_EQ(sshbuf_len(p3), sizeof(test_buf) - 1);
114 ASSERT_MEM_EQ(sshbuf_ptr(p3), test_buf, sizeof(test_buf) - 1);
115 sshbuf_free(p3);
116 ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0);
117 ASSERT_INT_EQ(sshbuf_consume_end(p2, 1), 0);
118 ASSERT_INT_EQ(sshbuf_froms(p2, &p3), SSH_ERR_MESSAGE_INCOMPLETE);
119 ASSERT_PTR_EQ(p3, NULL);
120 sshbuf_free(p2);
121 sshbuf_free(p1);
122}
diff --git a/regress/unittests/sshbuf/test_sshbuf_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_fuzz.c
new file mode 100644
index 000000000..a014b048c
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_fuzz.c
@@ -0,0 +1,123 @@
1/* $OpenBSD: test_sshbuf_fuzz.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include <sys/types.h>
9#include <sys/param.h>
10#include <stdio.h>
11#include <stdint.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include "test_helper.h"
16
17#include "ssherr.h"
18#include "sshbuf.h"
19
20#define NUM_FUZZ_TESTS (1 << 18)
21
22void sshbuf_fuzz_tests(void);
23
24void
25sshbuf_fuzz_tests(void)
26{
27 struct sshbuf *p1;
28 u_char *dp;
29 size_t sz, sz2, i;
30 u_int32_t r;
31 int ret;
32
33 /* NB. uses sshbuf internals */
34 TEST_START("fuzz alloc/dealloc");
35 p1 = sshbuf_new();
36 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0);
37 ASSERT_PTR_NE(p1, NULL);
38 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
39 ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
40 for (i = 0; i < NUM_FUZZ_TESTS; i++) {
41 r = arc4random_uniform(10);
42 if (r == 0) {
43 /* 10% chance: small reserve */
44 r = arc4random_uniform(10);
45 fuzz_reserve:
46 sz = sshbuf_avail(p1);
47 sz2 = sshbuf_len(p1);
48 ret = sshbuf_reserve(p1, r, &dp);
49 if (ret < 0) {
50 ASSERT_PTR_EQ(dp, NULL);
51 ASSERT_SIZE_T_LT(sz, r);
52 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
53 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
54 } else {
55 ASSERT_PTR_NE(dp, NULL);
56 ASSERT_SIZE_T_GE(sz, r);
57 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - r);
58 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 + r);
59 memset(dp, arc4random_uniform(255) + 1, r);
60 }
61 } else if (r < 3) {
62 /* 20% chance: big reserve */
63 r = arc4random_uniform(8 * 1024);
64 goto fuzz_reserve;
65 } else if (r == 3) {
66 /* 10% chance: small consume */
67 r = arc4random_uniform(10);
68 fuzz_consume:
69 sz = sshbuf_avail(p1);
70 sz2 = sshbuf_len(p1);
71 /* 50% change consume from end, otherwise start */
72 ret = ((arc4random() & 1) ?
73 sshbuf_consume : sshbuf_consume_end)(p1, r);
74 if (ret < 0) {
75 ASSERT_SIZE_T_LT(sz2, r);
76 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
77 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
78 } else {
79 ASSERT_SIZE_T_GE(sz2, r);
80 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz + r);
81 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 - r);
82 }
83 } else if (r < 8) {
84 /* 40% chance: big consume */
85 r = arc4random_uniform(2 * 1024);
86 goto fuzz_consume;
87 } else if (r == 8) {
88 /* 10% chance: reset max size */
89 r = arc4random_uniform(16 * 1024);
90 sz = sshbuf_max_size(p1);
91 if (sshbuf_set_max_size(p1, r) < 0)
92 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
93 else
94 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), r);
95 } else {
96 if (arc4random_uniform(8192) == 0) {
97 /* tiny chance: new buffer */
98 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
99 ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
100 sshbuf_free(p1);
101 p1 = sshbuf_new();
102 ASSERT_PTR_NE(p1, NULL);
103 ASSERT_INT_EQ(sshbuf_set_max_size(p1,
104 16 * 1024), 0);
105 } else {
106 /* Almost 10%: giant reserve */
107 /* use arc4random_buf for r > 2^32 on 64 bit */
108 arc4random_buf(&r, sizeof(r));
109 while (r < SSHBUF_SIZE_MAX / 2) {
110 r <<= 1;
111 r |= arc4random() & 1;
112 }
113 goto fuzz_reserve;
114 }
115 }
116 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
117 ASSERT_SIZE_T_LE(sshbuf_max_size(p1), 16 * 1024);
118 }
119 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
120 ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
121 sshbuf_free(p1);
122 TEST_DONE();
123}
diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_basic.c b/regress/unittests/sshbuf/test_sshbuf_getput_basic.c
new file mode 100644
index 000000000..2d469ec11
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_basic.c
@@ -0,0 +1,480 @@
1/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include <sys/types.h>
9#include <sys/param.h>
10#include <stdio.h>
11#include <stdint.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include "test_helper.h"
16#include "ssherr.h"
17#include "sshbuf.h"
18
19void sshbuf_getput_basic_tests(void);
20
21void
22sshbuf_getput_basic_tests(void)
23{
24 struct sshbuf *p1, *p2;
25 const u_char *cd;
26 u_char *d, d2[32], x[] = {
27 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x00, 0x99
28 };
29 u_int64_t v64;
30 u_int32_t v32;
31 u_int16_t v16;
32 u_char v8;
33 size_t s;
34 char *s2;
35 int r;
36 u_char bn1[] = { 0x00, 0x00, 0x00 };
37 u_char bn2[] = { 0x00, 0x00, 0x01, 0x02 };
38 u_char bn3[] = { 0x00, 0x80, 0x09 };
39 u_char bn_exp1[] = { 0x00, 0x00, 0x00, 0x00 };
40 u_char bn_exp2[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 0x02 };
41 u_char bn_exp3[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x80, 0x09 };
42
43 TEST_START("PEEK_U64");
44 ASSERT_U64_EQ(PEEK_U64(x), 0x1122334455667788ULL);
45 TEST_DONE();
46
47 TEST_START("PEEK_U32");
48 ASSERT_U32_EQ(PEEK_U32(x), 0x11223344);
49 TEST_DONE();
50
51 TEST_START("PEEK_U16");
52 ASSERT_U16_EQ(PEEK_U16(x), 0x1122);
53 TEST_DONE();
54
55 TEST_START("POKE_U64");
56 bzero(d2, sizeof(d2));
57 POKE_U64(d2, 0x1122334455667788ULL);
58 ASSERT_MEM_EQ(d2, x, 8);
59 TEST_DONE();
60
61 TEST_START("POKE_U32");
62 bzero(d2, sizeof(d2));
63 POKE_U32(d2, 0x11223344);
64 ASSERT_MEM_EQ(d2, x, 4);
65 TEST_DONE();
66
67 TEST_START("POKE_U16");
68 bzero(d2, sizeof(d2));
69 POKE_U16(d2, 0x1122);
70 ASSERT_MEM_EQ(d2, x, 2);
71 TEST_DONE();
72
73 TEST_START("sshbuf_put");
74 p1 = sshbuf_new();
75 ASSERT_PTR_NE(p1, NULL);
76 ASSERT_INT_EQ(sshbuf_put(p1, x, 5), 0);
77 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5);
78 cd = sshbuf_ptr(p1);
79 ASSERT_PTR_NE(cd, NULL);
80 ASSERT_U8_EQ(cd[0], 0x11);
81 ASSERT_U8_EQ(cd[1], 0x22);
82 ASSERT_U8_EQ(cd[2], 0x33);
83 ASSERT_U8_EQ(cd[3], 0x44);
84 ASSERT_U8_EQ(cd[4], 0x55);
85 TEST_DONE();
86
87 TEST_START("sshbuf_get");
88 ASSERT_INT_EQ(sshbuf_get(p1, d2, 4), 0);
89 ASSERT_MEM_EQ(d2, x, 4);
90 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
91 ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55);
92 TEST_DONE();
93
94 TEST_START("sshbuf_get truncated");
95 r = sshbuf_get(p1, d2, 4);
96 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
97 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
98 ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55);
99 TEST_DONE();
100
101 TEST_START("sshbuf_put truncated");
102 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0);
103 r = sshbuf_put(p1, x, 5);
104 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
105 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
106 sshbuf_free(p1);
107 TEST_DONE();
108
109 TEST_START("sshbuf_get_u64");
110 p1 = sshbuf_new();
111 ASSERT_PTR_NE(p1, NULL);
112 ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0);
113 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10);
114 ASSERT_INT_EQ(sshbuf_get_u64(p1, &v64), 0);
115 ASSERT_U64_EQ(v64, 0x1122334455667788ULL);
116 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
117 TEST_DONE();
118
119 TEST_START("sshbuf_get_u64 truncated");
120 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
121 r = sshbuf_get_u64(p1, &v64);
122 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
123 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
124 sshbuf_free(p1);
125 TEST_DONE();
126
127 TEST_START("sshbuf_get_u32");
128 p1 = sshbuf_new();
129 ASSERT_PTR_NE(p1, NULL);
130 ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0);
131 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10);
132 ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0);
133 ASSERT_U32_EQ(v32, 0x11223344);
134 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 6);
135 ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0);
136 ASSERT_U32_EQ(v32, 0x55667788);
137 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
138 TEST_DONE();
139
140 TEST_START("sshbuf_get_u32 truncated");
141 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
142 r = sshbuf_get_u32(p1, &v32);
143 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
144 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
145 sshbuf_free(p1);
146 TEST_DONE();
147
148 TEST_START("sshbuf_get_u16");
149 p1 = sshbuf_new();
150 ASSERT_PTR_NE(p1, NULL);
151 ASSERT_INT_EQ(sshbuf_put(p1, x, 9), 0);
152 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 9);
153 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
154 ASSERT_U16_EQ(v16, 0x1122);
155 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 7);
156 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
157 ASSERT_U16_EQ(v16, 0x3344);
158 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5);
159 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
160 ASSERT_U16_EQ(v16, 0x5566);
161 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
162 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
163 ASSERT_U16_EQ(v16, 0x7788);
164 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
165 TEST_DONE();
166
167 TEST_START("sshbuf_get_u16 truncated");
168 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
169 r = sshbuf_get_u16(p1, &v16);
170 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
171 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
172 sshbuf_free(p1);
173 TEST_DONE();
174
175 TEST_START("sshbuf_get_u8");
176 p1 = sshbuf_new();
177 ASSERT_PTR_NE(p1, NULL);
178 ASSERT_INT_EQ(sshbuf_put(p1, x, 2), 0);
179 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
180 ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0);
181 ASSERT_U8_EQ(v8, 0x11);
182 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
183 ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0);
184 ASSERT_U8_EQ(v8, 0x22);
185 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
186 TEST_DONE();
187
188 TEST_START("sshbuf_get_u8 truncated");
189 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
190 r = sshbuf_get_u8(p1, &v8);
191 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
192 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
193 sshbuf_free(p1);
194 TEST_DONE();
195
196 TEST_START("sshbuf_put_u64");
197 p1 = sshbuf_new();
198 ASSERT_PTR_NE(p1, NULL);
199 ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0);
200 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8);
201 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8);
202 sshbuf_free(p1);
203 TEST_DONE();
204
205 TEST_START("sshbuf_put_u64 exact");
206 p1 = sshbuf_new();
207 ASSERT_PTR_NE(p1, NULL);
208 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 8), 0);
209 ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0);
210 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8);
211 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8);
212 sshbuf_free(p1);
213 TEST_DONE();
214
215 TEST_START("sshbuf_put_u64 limited");
216 p1 = sshbuf_new();
217 ASSERT_PTR_NE(p1, NULL);
218 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 7), 0);
219 r = sshbuf_put_u64(p1, 0x1122334455667788ULL);
220 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
221 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
222 sshbuf_free(p1);
223 TEST_DONE();
224
225 TEST_START("sshbuf_put_u32");
226 p1 = sshbuf_new();
227 ASSERT_PTR_NE(p1, NULL);
228 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0);
229 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
230 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4);
231 sshbuf_free(p1);
232 TEST_DONE();
233
234 TEST_START("sshbuf_put_u32 exact");
235 p1 = sshbuf_new();
236 ASSERT_PTR_NE(p1, NULL);
237 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0);
238 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0);
239 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
240 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4);
241 sshbuf_free(p1);
242 TEST_DONE();
243
244 TEST_START("sshbuf_put_u32 limited");
245 p1 = sshbuf_new();
246 ASSERT_PTR_NE(p1, NULL);
247 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 3), 0);
248 r = sshbuf_put_u32(p1, 0x11223344);
249 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
250 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
251 sshbuf_free(p1);
252 TEST_DONE();
253
254 TEST_START("sshbuf_put_u16");
255 p1 = sshbuf_new();
256 ASSERT_PTR_NE(p1, NULL);
257 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0);
258 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
259 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2);
260 sshbuf_free(p1);
261 TEST_DONE();
262
263 TEST_START("sshbuf_put_u16");
264 p1 = sshbuf_new();
265 ASSERT_PTR_NE(p1, NULL);
266 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 2), 0);
267 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0);
268 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
269 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2);
270 sshbuf_free(p1);
271 TEST_DONE();
272
273 TEST_START("sshbuf_put_u16 limited");
274 p1 = sshbuf_new();
275 ASSERT_PTR_NE(p1, NULL);
276 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1), 0);
277 r = sshbuf_put_u16(p1, 0x1122);
278 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
279 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
280 sshbuf_free(p1);
281 TEST_DONE();
282
283 TEST_START("sshbuf_get_string");
284 p1 = sshbuf_new();
285 ASSERT_PTR_NE(p1, NULL);
286 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
287 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
288 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
289 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 + 4);
290 ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0);
291 ASSERT_SIZE_T_EQ(s, sizeof(x));
292 ASSERT_MEM_EQ(d, x, sizeof(x));
293 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
294 free(d);
295 sshbuf_free(p1);
296 TEST_DONE();
297
298 TEST_START("sshbuf_get_string exact");
299 p1 = sshbuf_new();
300 ASSERT_PTR_NE(p1, NULL);
301 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4), 0);
302 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
303 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
304 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
305 ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0);
306 ASSERT_SIZE_T_EQ(s, sizeof(x));
307 ASSERT_MEM_EQ(d, x, sizeof(x));
308 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
309 free(d);
310 sshbuf_free(p1);
311 TEST_DONE();
312
313 TEST_START("sshbuf_get_string truncated");
314 p1 = sshbuf_new();
315 ASSERT_PTR_NE(p1, NULL);
316 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
317 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
318 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
319 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
320 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3);
321 r = sshbuf_get_string(p1, &d, &s);
322 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
323 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3);
324 sshbuf_free(p1);
325 TEST_DONE();
326
327 TEST_START("sshbuf_get_string giant");
328 p1 = sshbuf_new();
329 ASSERT_PTR_NE(p1, NULL);
330 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0);
331 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
332 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
333 r = sshbuf_get_string(p1, &d, &s);
334 ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE);
335 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
336 sshbuf_free(p1);
337 TEST_DONE();
338
339 TEST_START("sshbuf_get_cstring giant");
340 p1 = sshbuf_new();
341 ASSERT_PTR_NE(p1, NULL);
342 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0);
343 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
344 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
345 r = sshbuf_get_cstring(p1, &s2, &s);
346 ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE);
347 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
348 sshbuf_free(p1);
349 TEST_DONE();
350
351 TEST_START("sshbuf_get_cstring embedded \\0");
352 p1 = sshbuf_new();
353 ASSERT_PTR_NE(p1, NULL);
354 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
355 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
356 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
357 r = sshbuf_get_cstring(p1, &s2, NULL);
358 ASSERT_INT_EQ(r, SSH_ERR_INVALID_FORMAT);
359 sshbuf_free(p1);
360 TEST_DONE();
361
362 TEST_START("sshbuf_get_cstring trailing \\0");
363 p1 = sshbuf_new();
364 ASSERT_PTR_NE(p1, NULL);
365 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x) - 1), 0);
366 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x) - 1), 0);
367 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 - 1);
368 ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s2, &s), 0);
369 ASSERT_SIZE_T_EQ(s, sizeof(x) - 1);
370 ASSERT_MEM_EQ(s2, x, s);
371 free(s2);
372 sshbuf_free(p1);
373 TEST_DONE();
374
375 TEST_START("sshbuf_put_string");
376 p1 = sshbuf_new();
377 ASSERT_PTR_NE(p1, NULL);
378 ASSERT_INT_EQ(sshbuf_put_string(p1, x, sizeof(x)), 0);
379 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
380 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), sizeof(x));
381 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, x, sizeof(x));
382 sshbuf_free(p1);
383 TEST_DONE();
384
385 TEST_START("sshbuf_put_string limited");
386 p1 = sshbuf_new();
387 ASSERT_PTR_NE(p1, NULL);
388 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4 - 1), 0);
389 r = sshbuf_put_string(p1, x, sizeof(x));
390 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
391 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
392 sshbuf_free(p1);
393 TEST_DONE();
394
395 TEST_START("sshbuf_put_string giant");
396 p1 = sshbuf_new();
397 ASSERT_PTR_NE(p1, NULL);
398 r = sshbuf_put_string(p1, (void *)0x01, 0xfffffffc);
399 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
400 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
401 sshbuf_free(p1);
402 TEST_DONE();
403
404 TEST_START("sshbuf_putf");
405 p1 = sshbuf_new();
406 ASSERT_PTR_NE(p1, NULL);
407 r = sshbuf_putf(p1, "%s %d %x", "hello", 23, 0x5f);
408 ASSERT_INT_EQ(r, 0);
409 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 11);
410 ASSERT_MEM_EQ(sshbuf_ptr(p1), "hello 23 5f", 11);
411 sshbuf_free(p1);
412 TEST_DONE();
413
414 TEST_START("sshbuf_putb");
415 p1 = sshbuf_new();
416 ASSERT_PTR_NE(p1, NULL);
417 p2 = sshbuf_new();
418 ASSERT_PTR_NE(p2, NULL);
419 ASSERT_INT_EQ(sshbuf_put(p1, "blahblahblah", 12), 0);
420 ASSERT_INT_EQ(sshbuf_putb(p2, p1), 0);
421 sshbuf_free(p1);
422 ASSERT_SIZE_T_EQ(sshbuf_len(p2), 12);
423 ASSERT_MEM_EQ(sshbuf_ptr(p2), "blahblahblah", 12);
424 sshbuf_free(p2);
425 TEST_DONE();
426
427 TEST_START("sshbuf_put_bignum2_bytes empty buf");
428 p1 = sshbuf_new();
429 ASSERT_PTR_NE(p1, NULL);
430 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, NULL, 0), 0);
431 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1));
432 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1));
433 sshbuf_free(p1);
434 TEST_DONE();
435
436 TEST_START("sshbuf_put_bignum2_bytes all zeroes");
437 p1 = sshbuf_new();
438 ASSERT_PTR_NE(p1, NULL);
439 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn1, sizeof(bn1)), 0);
440 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1));
441 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1));
442 sshbuf_free(p1);
443 TEST_DONE();
444
445 TEST_START("sshbuf_put_bignum2_bytes simple");
446 p1 = sshbuf_new();
447 ASSERT_PTR_NE(p1, NULL);
448 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2+2, sizeof(bn2)-2), 0);
449 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2));
450 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2));
451 sshbuf_free(p1);
452 TEST_DONE();
453
454 TEST_START("sshbuf_put_bignum2_bytes leading zero");
455 p1 = sshbuf_new();
456 ASSERT_PTR_NE(p1, NULL);
457 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2, sizeof(bn2)), 0);
458 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2));
459 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2));
460 sshbuf_free(p1);
461 TEST_DONE();
462
463 TEST_START("sshbuf_put_bignum2_bytes neg");
464 p1 = sshbuf_new();
465 ASSERT_PTR_NE(p1, NULL);
466 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3+1, sizeof(bn3)-1), 0);
467 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3));
468 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
469 sshbuf_free(p1);
470 TEST_DONE();
471
472 TEST_START("sshbuf_put_bignum2_bytes neg and leading zero");
473 p1 = sshbuf_new();
474 ASSERT_PTR_NE(p1, NULL);
475 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3, sizeof(bn3)), 0);
476 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3));
477 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
478 sshbuf_free(p1);
479 TEST_DONE();
480}
diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
new file mode 100644
index 000000000..d7d4dc378
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
@@ -0,0 +1,398 @@
1/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include <sys/types.h>
9#include <sys/param.h>
10#include <stdio.h>
11#include <stdint.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include <openssl/bn.h>
16#include <openssl/ec.h>
17#include <openssl/objects.h>
18
19#include "test_helper.h"
20#include "ssherr.h"
21#include "sshbuf.h"
22
23void sshbuf_getput_crypto_tests(void);
24
25void
26sshbuf_getput_crypto_tests(void)
27{
28 struct sshbuf *p1;
29 const u_char *d;
30 size_t s;
31 BIGNUM *bn, *bn2, *bn_x, *bn_y;
32 /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */
33 const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10";
34 /* This one has MSB set to test bignum2 encoding negative-avoidance */
35 const char *hexbn2 = "f0e0d0c0b0a0908070605040302010007fff11";
36 u_char expbn1[] = {
37 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
38 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
39 };
40 u_char expbn2[] = {
41 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
42 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
43 0x7f, 0xff, 0x11
44 };
45 int ec256_nid = NID_X9_62_prime256v1;
46 char *ec256_x = "0C828004839D0106AA59575216191357"
47 "34B451459DADB586677EF9DF55784999";
48 char *ec256_y = "4D196B50F0B4E94B3C73E3A9D4CD9DF2"
49 "C8F9A35E42BDD047550F69D80EC23CD4";
50 u_char expec256[] = {
51 0x04,
52 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
53 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
54 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
55 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
56 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
57 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
58 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
59 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4
60 };
61 EC_KEY *eck;
62 EC_POINT *ecp;
63 int r;
64
65#define MKBN(b, bnn) \
66 do { \
67 bnn = NULL; \
68 ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \
69 } while (0)
70
71 TEST_START("sshbuf_put_bignum1");
72 MKBN(hexbn1, bn);
73 p1 = sshbuf_new();
74 ASSERT_PTR_NE(p1, NULL);
75 ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
76 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 2);
77 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
78 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn1, sizeof(expbn1));
79 BN_free(bn);
80 sshbuf_free(p1);
81 TEST_DONE();
82
83 TEST_START("sshbuf_put_bignum1 limited");
84 MKBN(hexbn1, bn);
85 p1 = sshbuf_new();
86 ASSERT_PTR_NE(p1, NULL);
87 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
88 r = sshbuf_put_bignum1(p1, bn);
89 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
90 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
91 BN_free(bn);
92 sshbuf_free(p1);
93 TEST_DONE();
94
95 TEST_START("sshbuf_put_bignum1 bn2");
96 MKBN(hexbn2, bn);
97 p1 = sshbuf_new();
98 ASSERT_PTR_NE(p1, NULL);
99 ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
100 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 2);
101 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
102 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn2, sizeof(expbn2));
103 BN_free(bn);
104 sshbuf_free(p1);
105 TEST_DONE();
106
107 TEST_START("sshbuf_put_bignum1 bn2 limited");
108 MKBN(hexbn2, bn);
109 p1 = sshbuf_new();
110 ASSERT_PTR_NE(p1, NULL);
111 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
112 r = sshbuf_put_bignum1(p1, bn);
113 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
114 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
115 BN_free(bn);
116 sshbuf_free(p1);
117 TEST_DONE();
118
119 TEST_START("sshbuf_put_bignum2");
120 MKBN(hexbn1, bn);
121 p1 = sshbuf_new();
122 ASSERT_PTR_NE(p1, NULL);
123 ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
124 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4);
125 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn));
126 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1));
127 BN_free(bn);
128 sshbuf_free(p1);
129 TEST_DONE();
130
131 TEST_START("sshbuf_put_bignum2 limited");
132 MKBN(hexbn1, bn);
133 p1 = sshbuf_new();
134 ASSERT_PTR_NE(p1, NULL);
135 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 3), 0);
136 r = sshbuf_put_bignum2(p1, bn);
137 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
138 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
139 BN_free(bn);
140 sshbuf_free(p1);
141 TEST_DONE();
142
143 TEST_START("sshbuf_put_bignum2 bn2");
144 MKBN(hexbn2, bn);
145 p1 = sshbuf_new();
146 ASSERT_PTR_NE(p1, NULL);
147 ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
148 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */
149 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1);
150 ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00);
151 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2));
152 BN_free(bn);
153 sshbuf_free(p1);
154 TEST_DONE();
155
156 TEST_START("sshbuf_put_bignum2 bn2 limited");
157 MKBN(hexbn2, bn);
158 p1 = sshbuf_new();
159 ASSERT_PTR_NE(p1, NULL);
160 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn2) + 3), 0);
161 r = sshbuf_put_bignum2(p1, bn);
162 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
163 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
164 BN_free(bn);
165 sshbuf_free(p1);
166 TEST_DONE();
167
168 TEST_START("sshbuf_get_bignum1");
169 MKBN(hexbn1, bn);
170 p1 = sshbuf_new();
171 ASSERT_PTR_NE(p1, NULL);
172 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
173 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
174 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1));
175 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
176 bn2 = BN_new();
177 ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
178 ASSERT_BIGNUM_EQ(bn, bn2);
179 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
180 BN_free(bn);
181 BN_free(bn2);
182 sshbuf_free(p1);
183 TEST_DONE();
184
185 TEST_START("sshbuf_get_bignum1 truncated");
186 MKBN(hexbn1, bn);
187 p1 = sshbuf_new();
188 ASSERT_PTR_NE(p1, NULL);
189 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
190 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
191 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
192 bn2 = BN_new();
193 r = sshbuf_get_bignum1(p1, bn2);
194 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
195 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
196 BN_free(bn);
197 BN_free(bn2);
198 sshbuf_free(p1);
199 TEST_DONE();
200
201 TEST_START("sshbuf_get_bignum1 giant");
202 MKBN(hexbn1, bn);
203 p1 = sshbuf_new();
204 ASSERT_PTR_NE(p1, NULL);
205 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xffff), 0);
206 ASSERT_INT_EQ(sshbuf_reserve(p1, (0xffff + 7) / 8, NULL), 0);
207 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
208 bn2 = BN_new();
209 r = sshbuf_get_bignum1(p1, bn2);
210 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
211 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
212 BN_free(bn);
213 BN_free(bn2);
214 sshbuf_free(p1);
215 TEST_DONE();
216
217 TEST_START("sshbuf_get_bignum1 bn2");
218 MKBN(hexbn2, bn);
219 p1 = sshbuf_new();
220 ASSERT_PTR_NE(p1, NULL);
221 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
222 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
223 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2));
224 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
225 bn2 = BN_new();
226 ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
227 ASSERT_BIGNUM_EQ(bn, bn2);
228 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
229 BN_free(bn);
230 BN_free(bn2);
231 sshbuf_free(p1);
232 TEST_DONE();
233
234 TEST_START("sshbuf_get_bignum1 bn2 truncated");
235 MKBN(hexbn2, bn);
236 p1 = sshbuf_new();
237 ASSERT_PTR_NE(p1, NULL);
238 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
239 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
240 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
241 bn2 = BN_new();
242 r = sshbuf_get_bignum1(p1, bn2);
243 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
244 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
245 BN_free(bn);
246 BN_free(bn2);
247 sshbuf_free(p1);
248 TEST_DONE();
249
250 TEST_START("sshbuf_get_bignum2");
251 MKBN(hexbn1, bn);
252 p1 = sshbuf_new();
253 ASSERT_PTR_NE(p1, NULL);
254 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
255 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
256 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + sizeof(expbn1));
257 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
258 bn2 = BN_new();
259 ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
260 ASSERT_BIGNUM_EQ(bn, bn2);
261 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
262 BN_free(bn);
263 BN_free(bn2);
264 sshbuf_free(p1);
265 TEST_DONE();
266
267 TEST_START("sshbuf_get_bignum2 truncated");
268 MKBN(hexbn1, bn);
269 p1 = sshbuf_new();
270 ASSERT_PTR_NE(p1, NULL);
271 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
272 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
273 bn2 = BN_new();
274 r = sshbuf_get_bignum2(p1, bn2);
275 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
276 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 3);
277 BN_free(bn);
278 BN_free(bn2);
279 sshbuf_free(p1);
280 TEST_DONE();
281
282 TEST_START("sshbuf_get_bignum2 giant");
283 MKBN(hexbn1, bn);
284 p1 = sshbuf_new();
285 ASSERT_PTR_NE(p1, NULL);
286 ASSERT_INT_EQ(sshbuf_put_u32(p1, 65536), 0);
287 ASSERT_INT_EQ(sshbuf_reserve(p1, 65536, NULL), 0);
288 bn2 = BN_new();
289 r = sshbuf_get_bignum2(p1, bn2);
290 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
291 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 65536 + 4);
292 BN_free(bn);
293 BN_free(bn2);
294 sshbuf_free(p1);
295 TEST_DONE();
296
297 TEST_START("sshbuf_get_bignum2 bn2");
298 MKBN(hexbn2, bn);
299 p1 = sshbuf_new();
300 ASSERT_PTR_NE(p1, NULL);
301 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); /* MSB */
302 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
303 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
304 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + 1 + sizeof(expbn2));
305 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
306 bn2 = BN_new();
307 ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
308 ASSERT_BIGNUM_EQ(bn, bn2);
309 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
310 BN_free(bn);
311 BN_free(bn2);
312 sshbuf_free(p1);
313 TEST_DONE();
314
315 TEST_START("sshbuf_get_bignum2 bn2 truncated");
316 MKBN(hexbn2, bn);
317 p1 = sshbuf_new();
318 ASSERT_PTR_NE(p1, NULL);
319 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0);
320 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
321 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
322 bn2 = BN_new();
323 r = sshbuf_get_bignum2(p1, bn2);
324 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
325 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 1 + 4 - 1);
326 BN_free(bn);
327 BN_free(bn2);
328 sshbuf_free(p1);
329 TEST_DONE();
330
331 TEST_START("sshbuf_get_bignum2 bn2 negative");
332 MKBN(hexbn2, bn);
333 p1 = sshbuf_new();
334 ASSERT_PTR_NE(p1, NULL);
335 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
336 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
337 bn2 = BN_new();
338 r = sshbuf_get_bignum2(p1, bn2);
339 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_IS_NEGATIVE);
340 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4);
341 BN_free(bn);
342 BN_free(bn2);
343 sshbuf_free(p1);
344 TEST_DONE();
345
346 TEST_START("sshbuf_put_ec");
347 eck = EC_KEY_new_by_curve_name(ec256_nid);
348 ASSERT_PTR_NE(eck, NULL);
349 ecp = EC_POINT_new(EC_KEY_get0_group(eck));
350 ASSERT_PTR_NE(ecp, NULL);
351 MKBN(ec256_x, bn_x);
352 MKBN(ec256_y, bn_y);
353 ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp(
354 EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1);
355 ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1);
356 BN_free(bn_x);
357 BN_free(bn_y);
358 EC_POINT_free(ecp);
359 p1 = sshbuf_new();
360 ASSERT_PTR_NE(p1, NULL);
361 ASSERT_INT_EQ(sshbuf_put_eckey(p1, eck), 0);
362 ASSERT_INT_EQ(sshbuf_get_string_direct(p1, &d, &s), 0);
363 ASSERT_SIZE_T_EQ(s, sizeof(expec256));
364 ASSERT_MEM_EQ(d, expec256, sizeof(expec256));
365 sshbuf_free(p1);
366 EC_KEY_free(eck);
367 TEST_DONE();
368
369 TEST_START("sshbuf_get_ec");
370 eck = EC_KEY_new_by_curve_name(ec256_nid);
371 ASSERT_PTR_NE(eck, NULL);
372 p1 = sshbuf_new();
373 ASSERT_PTR_NE(p1, NULL);
374 ASSERT_INT_EQ(sshbuf_put_string(p1, expec256, sizeof(expec256)), 0);
375 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expec256) + 4);
376 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
377 ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0);
378 bn_x = BN_new();
379 bn_y = BN_new();
380 ASSERT_PTR_NE(bn_x, NULL);
381 ASSERT_PTR_NE(bn_y, NULL);
382 ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp(
383 EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck),
384 bn_x, bn_y, NULL), 1);
385 MKBN(ec256_x, bn);
386 MKBN(ec256_y, bn2);
387 ASSERT_INT_EQ(BN_cmp(bn_x, bn), 0);
388 ASSERT_INT_EQ(BN_cmp(bn_y, bn2), 0);
389 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
390 sshbuf_free(p1);
391 EC_KEY_free(eck);
392 BN_free(bn_x);
393 BN_free(bn_y);
394 BN_free(bn);
395 BN_free(bn2);
396 TEST_DONE();
397}
398
diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
new file mode 100644
index 000000000..a382ee154
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
@@ -0,0 +1,120 @@
1/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.2 2014/05/02 02:54:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include <sys/types.h>
9#include <sys/param.h>
10#include <stdio.h>
11#include <stdint.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include <openssl/bn.h>
16#include <openssl/ec.h>
17#include <openssl/objects.h>
18
19#include "test_helper.h"
20#include "ssherr.h"
21#include "sshbuf.h"
22
23void sshbuf_getput_fuzz_tests(void);
24
25static void
26attempt_parse_blob(u_char *blob, size_t len)
27{
28 struct sshbuf *p1;
29 BIGNUM *bn;
30 EC_KEY *eck;
31 u_char *s;
32 size_t l;
33 u_int8_t u8;
34 u_int16_t u16;
35 u_int32_t u32;
36 u_int64_t u64;
37
38 p1 = sshbuf_new();
39 ASSERT_PTR_NE(p1, NULL);
40 ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0);
41 sshbuf_get_u8(p1, &u8);
42 sshbuf_get_u16(p1, &u16);
43 sshbuf_get_u32(p1, &u32);
44 sshbuf_get_u64(p1, &u64);
45 if (sshbuf_get_string(p1, &s, &l) == 0) {
46 bzero(s, l);
47 free(s);
48 }
49 bn = BN_new();
50 sshbuf_get_bignum1(p1, bn);
51 BN_clear_free(bn);
52 bn = BN_new();
53 sshbuf_get_bignum2(p1, bn);
54 BN_clear_free(bn);
55 eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
56 ASSERT_PTR_NE(eck, NULL);
57 sshbuf_get_eckey(p1, eck);
58 EC_KEY_free(eck);
59 sshbuf_free(p1);
60}
61
62
63static void
64onerror(void *fuzz)
65{
66 fprintf(stderr, "Failed during fuzz:\n");
67 fuzz_dump((struct fuzz *)fuzz);
68}
69
70void
71sshbuf_getput_fuzz_tests(void)
72{
73 u_char blob[] = {
74 /* u8 */
75 0xd0,
76 /* u16 */
77 0xc0, 0xde,
78 /* u32 */
79 0xfa, 0xce, 0xde, 0xad,
80 /* u64 */
81 0xfe, 0xed, 0xac, 0x1d, 0x1f, 0x1c, 0xbe, 0xef,
82 /* string */
83 0x00, 0x00, 0x00, 0x09,
84 'O', ' ', 'G', 'o', 'r', 'g', 'o', 'n', '!',
85 /* bignum1 */
86 0x79,
87 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
88 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
89 /* bignum2 */
90 0x00, 0x00, 0x00, 0x14,
91 0x00,
92 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
93 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
94 0x7f, 0xff, 0x11,
95 /* EC point (NIST-256 curve) */
96 0x00, 0x00, 0x00, 0x41,
97 0x04,
98 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
99 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
100 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
101 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
102 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
103 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
104 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
105 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4,
106 };
107 struct fuzz *fuzz;
108
109 TEST_START("fuzz blob parsing");
110 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP |
111 FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
112 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, blob, sizeof(blob));
113 TEST_ONERROR(onerror, fuzz);
114 for(; !fuzz_done(fuzz); fuzz_next(fuzz))
115 attempt_parse_blob(blob, sizeof(blob));
116 fuzz_cleanup(fuzz);
117 TEST_DONE();
118 TEST_ONERROR(NULL, NULL);
119}
120
diff --git a/regress/unittests/sshbuf/test_sshbuf_misc.c b/regress/unittests/sshbuf/test_sshbuf_misc.c
new file mode 100644
index 000000000..a5b1ab2c9
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_misc.c
@@ -0,0 +1,134 @@
1/* $OpenBSD: test_sshbuf_misc.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include <sys/types.h>
9#include <sys/param.h>
10#include <stdio.h>
11#include <stdint.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include "test_helper.h"
16
17#include "sshbuf.h"
18
19void sshbuf_misc_tests(void);
20
21void
22sshbuf_misc_tests(void)
23{
24 struct sshbuf *p1;
25 char tmp[512], *p;
26 FILE *out;
27 size_t sz;
28
29 TEST_START("sshbuf_dump");
30 out = tmpfile();
31 ASSERT_PTR_NE(out, NULL);
32 p1 = sshbuf_new();
33 ASSERT_PTR_NE(p1, NULL);
34 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
35 sshbuf_dump(p1, out);
36 fflush(out);
37 rewind(out);
38 sz = fread(tmp, 1, sizeof(tmp), out);
39 ASSERT_INT_EQ(ferror(out), 0);
40 ASSERT_INT_NE(feof(out), 0);
41 ASSERT_SIZE_T_GT(sz, 0);
42 tmp[sz] = '\0';
43 ASSERT_PTR_NE(strstr(tmp, "12 34 56 78"), NULL);
44 fclose(out);
45 sshbuf_free(p1);
46 TEST_DONE();
47
48 TEST_START("sshbuf_dtob16");
49 p1 = sshbuf_new();
50 ASSERT_PTR_NE(p1, NULL);
51 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
52 p = sshbuf_dtob16(p1);
53 ASSERT_PTR_NE(p, NULL);
54 ASSERT_STRING_EQ(p, "12345678");
55 free(p);
56 sshbuf_free(p1);
57 TEST_DONE();
58
59 TEST_START("sshbuf_dtob64 len 1");
60 p1 = sshbuf_new();
61 ASSERT_PTR_NE(p1, NULL);
62 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
63 p = sshbuf_dtob64(p1);
64 ASSERT_PTR_NE(p, NULL);
65 ASSERT_STRING_EQ(p, "EQ==");
66 free(p);
67 sshbuf_free(p1);
68 TEST_DONE();
69
70 TEST_START("sshbuf_dtob64 len 2");
71 p1 = sshbuf_new();
72 ASSERT_PTR_NE(p1, NULL);
73 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
74 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
75 p = sshbuf_dtob64(p1);
76 ASSERT_PTR_NE(p, NULL);
77 ASSERT_STRING_EQ(p, "ESI=");
78 free(p);
79 sshbuf_free(p1);
80 TEST_DONE();
81
82 TEST_START("sshbuf_dtob64 len 3");
83 p1 = sshbuf_new();
84 ASSERT_PTR_NE(p1, NULL);
85 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
86 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
87 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x33), 0);
88 p = sshbuf_dtob64(p1);
89 ASSERT_PTR_NE(p, NULL);
90 ASSERT_STRING_EQ(p, "ESIz");
91 free(p);
92 sshbuf_free(p1);
93 TEST_DONE();
94
95 TEST_START("sshbuf_dtob64 len 8191");
96 p1 = sshbuf_new();
97 ASSERT_PTR_NE(p1, NULL);
98 ASSERT_INT_EQ(sshbuf_reserve(p1, 8192, NULL), 0);
99 bzero(sshbuf_mutable_ptr(p1), 8192);
100 p = sshbuf_dtob64(p1);
101 ASSERT_PTR_NE(p, NULL);
102 ASSERT_SIZE_T_EQ(strlen(p), ((8191 + 2) / 3) * 4);
103 free(p);
104 sshbuf_free(p1);
105 TEST_DONE();
106
107 TEST_START("sshbuf_b64tod len 1");
108 p1 = sshbuf_new();
109 ASSERT_PTR_NE(p1, NULL);
110 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A=="), 0);
111 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
112 ASSERT_U8_EQ(*sshbuf_ptr(p1), 0xd0);
113 sshbuf_free(p1);
114 TEST_DONE();
115
116 TEST_START("sshbuf_b64tod len 2");
117 p1 = sshbuf_new();
118 ASSERT_PTR_NE(p1, NULL);
119 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A8="), 0);
120 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
121 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), 0xd00f);
122 sshbuf_free(p1);
123 TEST_DONE();
124
125 TEST_START("sshbuf_b64tod len 4");
126 p1 = sshbuf_new();
127 ASSERT_PTR_NE(p1, NULL);
128 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A/QDw=="), 0);
129 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
130 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), 0xd00fd00f);
131 sshbuf_free(p1);
132 TEST_DONE();
133}
134
diff --git a/regress/unittests/sshbuf/tests.c b/regress/unittests/sshbuf/tests.c
new file mode 100644
index 000000000..8397e4011
--- /dev/null
+++ b/regress/unittests/sshbuf/tests.c
@@ -0,0 +1,28 @@
1/* $OpenBSD: tests.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include "test_helper.h"
9
10void sshbuf_tests(void);
11void sshbuf_getput_basic_tests(void);
12void sshbuf_getput_crypto_tests(void);
13void sshbuf_misc_tests(void);
14void sshbuf_fuzz_tests(void);
15void sshbuf_getput_fuzz_tests(void);
16void sshbuf_fixed(void);
17
18void
19tests(void)
20{
21 sshbuf_tests();
22 sshbuf_getput_basic_tests();
23 sshbuf_getput_crypto_tests();
24 sshbuf_misc_tests();
25 sshbuf_fuzz_tests();
26 sshbuf_getput_fuzz_tests();
27 sshbuf_fixed();
28}
diff --git a/regress/unittests/test_helper/Makefile b/regress/unittests/test_helper/Makefile
new file mode 100644
index 000000000..3e90903ef
--- /dev/null
+++ b/regress/unittests/test_helper/Makefile
@@ -0,0 +1,13 @@
1# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
2
3LIB= test_helper
4SRCS= test_helper.c fuzz.c
5
6DEBUGLIBS= no
7NOPROFILE= yes
8NOPIC= yes
9
10install:
11 @echo -n
12
13.include <bsd.lib.mk>
diff --git a/regress/unittests/test_helper/fuzz.c b/regress/unittests/test_helper/fuzz.c
new file mode 100644
index 000000000..b64af24ed
--- /dev/null
+++ b/regress/unittests/test_helper/fuzz.c
@@ -0,0 +1,374 @@
1/* $OpenBSD: fuzz.c,v 1.3 2014/05/02 09:41:32 andre Exp $ */
2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* Utility functions/framework for fuzz tests */
19
20#include <sys/types.h>
21
22#include <assert.h>
23#include <ctype.h>
24#include <stdio.h>
25#include <stdint.h>
26#include <stdlib.h>
27#include <string.h>
28#include <assert.h>
29
30#include "test_helper.h"
31
32/* #define FUZZ_DEBUG */
33
34#ifdef FUZZ_DEBUG
35# define FUZZ_DBG(x) do { \
36 printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \
37 printf x; \
38 printf("\n"); \
39 fflush(stdout); \
40 } while (0)
41#else
42# define FUZZ_DBG(x)
43#endif
44
45/* For brevity later */
46typedef unsigned long long fuzz_ullong;
47
48/* For base-64 fuzzing */
49static const char fuzz_b64chars[] =
50 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
51
52struct fuzz {
53 /* Fuzz method currently in use */
54 int strategy;
55
56 /* Fuzz methods remaining */
57 int strategies;
58
59 /* Original seed data blob */
60 void *seed;
61 size_t slen;
62
63 /* Current working copy of seed with fuzz mutations applied */
64 u_char *fuzzed;
65
66 /* Used by fuzz methods */
67 size_t o1, o2;
68};
69
70static const char *
71fuzz_ntop(u_int n)
72{
73 switch (n) {
74 case 0:
75 return "NONE";
76 case FUZZ_1_BIT_FLIP:
77 return "FUZZ_1_BIT_FLIP";
78 case FUZZ_2_BIT_FLIP:
79 return "FUZZ_2_BIT_FLIP";
80 case FUZZ_1_BYTE_FLIP:
81 return "FUZZ_1_BYTE_FLIP";
82 case FUZZ_2_BYTE_FLIP:
83 return "FUZZ_2_BYTE_FLIP";
84 case FUZZ_TRUNCATE_START:
85 return "FUZZ_TRUNCATE_START";
86 case FUZZ_TRUNCATE_END:
87 return "FUZZ_TRUNCATE_END";
88 case FUZZ_BASE64:
89 return "FUZZ_BASE64";
90 default:
91 abort();
92 }
93}
94
95void
96fuzz_dump(struct fuzz *fuzz)
97{
98 u_char *p = fuzz_ptr(fuzz);
99 size_t i, j, len = fuzz_len(fuzz);
100
101 switch (fuzz->strategy) {
102 case FUZZ_1_BIT_FLIP:
103 fprintf(stderr, "%s case %zu of %zu (bit: %zu)\n",
104 fuzz_ntop(fuzz->strategy),
105 fuzz->o1, fuzz->slen * 8, fuzz->o1);
106 break;
107 case FUZZ_2_BIT_FLIP:
108 fprintf(stderr, "%s case %llu of %llu (bits: %zu, %zu)\n",
109 fuzz_ntop(fuzz->strategy),
110 (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1,
111 ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8,
112 fuzz->o1, fuzz->o2);
113 break;
114 case FUZZ_1_BYTE_FLIP:
115 fprintf(stderr, "%s case %zu of %zu (byte: %zu)\n",
116 fuzz_ntop(fuzz->strategy),
117 fuzz->o1, fuzz->slen, fuzz->o1);
118 break;
119 case FUZZ_2_BYTE_FLIP:
120 fprintf(stderr, "%s case %llu of %llu (bytes: %zu, %zu)\n",
121 fuzz_ntop(fuzz->strategy),
122 (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1,
123 ((fuzz_ullong)fuzz->slen) * fuzz->slen,
124 fuzz->o1, fuzz->o2);
125 break;
126 case FUZZ_TRUNCATE_START:
127 fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n",
128 fuzz_ntop(fuzz->strategy),
129 fuzz->o1, fuzz->slen, fuzz->o1);
130 break;
131 case FUZZ_TRUNCATE_END:
132 fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n",
133 fuzz_ntop(fuzz->strategy),
134 fuzz->o1, fuzz->slen, fuzz->o1);
135 break;
136 case FUZZ_BASE64:
137 assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
138 fprintf(stderr, "%s case %llu of %llu (offset: %zu char: %c)\n",
139 fuzz_ntop(fuzz->strategy),
140 (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2,
141 fuzz->slen * (fuzz_ullong)64, fuzz->o1,
142 fuzz_b64chars[fuzz->o2]);
143 break;
144 default:
145 abort();
146 }
147
148 fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, len);
149 for (i = 0; i < len; i += 16) {
150 fprintf(stderr, "%.4zd: ", i);
151 for (j = i; j < i + 16; j++) {
152 if (j < len)
153 fprintf(stderr, "%02x ", p[j]);
154 else
155 fprintf(stderr, " ");
156 }
157 fprintf(stderr, " ");
158 for (j = i; j < i + 16; j++) {
159 if (j < len) {
160 if (isascii(p[j]) && isprint(p[j]))
161 fprintf(stderr, "%c", p[j]);
162 else
163 fprintf(stderr, ".");
164 }
165 }
166 fprintf(stderr, "\n");
167 }
168}
169
170struct fuzz *
171fuzz_begin(u_int strategies, const void *p, size_t l)
172{
173 struct fuzz *ret = calloc(sizeof(*ret), 1);
174
175 assert(p != NULL);
176 assert(ret != NULL);
177 ret->seed = malloc(l);
178 assert(ret->seed != NULL);
179 memcpy(ret->seed, p, l);
180 ret->slen = l;
181 ret->strategies = strategies;
182
183 assert(ret->slen < SIZE_MAX / 8);
184 assert(ret->strategies <= (FUZZ_MAX|(FUZZ_MAX-1)));
185
186 FUZZ_DBG(("begin, ret = %p", ret));
187
188 fuzz_next(ret);
189 return ret;
190}
191
192void
193fuzz_cleanup(struct fuzz *fuzz)
194{
195 FUZZ_DBG(("cleanup, fuzz = %p", fuzz));
196 assert(fuzz != NULL);
197 assert(fuzz->seed != NULL);
198 assert(fuzz->fuzzed != NULL);
199 free(fuzz->seed);
200 free(fuzz->fuzzed);
201 free(fuzz);
202}
203
204static int
205fuzz_strategy_done(struct fuzz *fuzz)
206{
207 FUZZ_DBG(("fuzz = %p, strategy = %s, o1 = %zu, o2 = %zu, slen = %zu",
208 fuzz, fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->o2, fuzz->slen));
209
210 switch (fuzz->strategy) {
211 case FUZZ_1_BIT_FLIP:
212 return fuzz->o1 >= fuzz->slen * 8;
213 case FUZZ_2_BIT_FLIP:
214 return fuzz->o2 >= fuzz->slen * 8;
215 case FUZZ_2_BYTE_FLIP:
216 return fuzz->o2 >= fuzz->slen;
217 case FUZZ_1_BYTE_FLIP:
218 case FUZZ_TRUNCATE_START:
219 case FUZZ_TRUNCATE_END:
220 case FUZZ_BASE64:
221 return fuzz->o1 >= fuzz->slen;
222 default:
223 abort();
224 }
225}
226
227void
228fuzz_next(struct fuzz *fuzz)
229{
230 u_int i;
231
232 FUZZ_DBG(("start, fuzz = %p, strategy = %s, strategies = 0x%lx, "
233 "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy),
234 (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen));
235
236 if (fuzz->strategy == 0 || fuzz_strategy_done(fuzz)) {
237 /* If we are just starting out, we need to allocate too */
238 if (fuzz->fuzzed == NULL) {
239 FUZZ_DBG(("alloc"));
240 fuzz->fuzzed = calloc(fuzz->slen, 1);
241 }
242 /* Pick next strategy */
243 FUZZ_DBG(("advance"));
244 for (i = 1; i <= FUZZ_MAX; i <<= 1) {
245 if ((fuzz->strategies & i) != 0) {
246 fuzz->strategy = i;
247 break;
248 }
249 }
250 FUZZ_DBG(("selected = %u", fuzz->strategy));
251 if (fuzz->strategy == 0) {
252 FUZZ_DBG(("done, no more strategies"));
253 return;
254 }
255 fuzz->strategies &= ~(fuzz->strategy);
256 fuzz->o1 = fuzz->o2 = 0;
257 }
258
259 assert(fuzz->fuzzed != NULL);
260
261 switch (fuzz->strategy) {
262 case FUZZ_1_BIT_FLIP:
263 assert(fuzz->o1 / 8 < fuzz->slen);
264 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
265 fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8);
266 fuzz->o1++;
267 break;
268 case FUZZ_2_BIT_FLIP:
269 assert(fuzz->o1 / 8 < fuzz->slen);
270 assert(fuzz->o2 / 8 < fuzz->slen);
271 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
272 fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8);
273 fuzz->fuzzed[fuzz->o2 / 8] ^= 1 << (fuzz->o2 % 8);
274 fuzz->o1++;
275 if (fuzz->o1 >= fuzz->slen * 8) {
276 fuzz->o1 = 0;
277 fuzz->o2++;
278 }
279 break;
280 case FUZZ_1_BYTE_FLIP:
281 assert(fuzz->o1 < fuzz->slen);
282 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
283 fuzz->fuzzed[fuzz->o1] ^= 0xff;
284 fuzz->o1++;
285 break;
286 case FUZZ_2_BYTE_FLIP:
287 assert(fuzz->o1 < fuzz->slen);
288 assert(fuzz->o2 < fuzz->slen);
289 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
290 fuzz->fuzzed[fuzz->o1] ^= 0xff;
291 fuzz->fuzzed[fuzz->o2] ^= 0xff;
292 fuzz->o1++;
293 if (fuzz->o1 >= fuzz->slen) {
294 fuzz->o1 = 0;
295 fuzz->o2++;
296 }
297 break;
298 case FUZZ_TRUNCATE_START:
299 case FUZZ_TRUNCATE_END:
300 assert(fuzz->o1 < fuzz->slen);
301 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
302 fuzz->o1++;
303 break;
304 case FUZZ_BASE64:
305 assert(fuzz->o1 < fuzz->slen);
306 assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
307 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
308 fuzz->fuzzed[fuzz->o1] = fuzz_b64chars[fuzz->o2];
309 fuzz->o2++;
310 if (fuzz->o2 >= sizeof(fuzz_b64chars) - 1) {
311 fuzz->o2 = 0;
312 fuzz->o1++;
313 }
314 break;
315 default:
316 abort();
317 }
318
319 FUZZ_DBG(("done, fuzz = %p, strategy = %s, strategies = 0x%lx, "
320 "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy),
321 (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen));
322}
323
324int
325fuzz_done(struct fuzz *fuzz)
326{
327 FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz,
328 (u_long)fuzz->strategies));
329
330 return fuzz_strategy_done(fuzz) && fuzz->strategies == 0;
331}
332
333size_t
334fuzz_len(struct fuzz *fuzz)
335{
336 assert(fuzz->fuzzed != NULL);
337 switch (fuzz->strategy) {
338 case FUZZ_1_BIT_FLIP:
339 case FUZZ_2_BIT_FLIP:
340 case FUZZ_1_BYTE_FLIP:
341 case FUZZ_2_BYTE_FLIP:
342 case FUZZ_BASE64:
343 return fuzz->slen;
344 case FUZZ_TRUNCATE_START:
345 case FUZZ_TRUNCATE_END:
346 assert(fuzz->o1 <= fuzz->slen);
347 return fuzz->slen - fuzz->o1;
348 default:
349 abort();
350 }
351}
352
353u_char *
354fuzz_ptr(struct fuzz *fuzz)
355{
356 assert(fuzz->fuzzed != NULL);
357 switch (fuzz->strategy) {
358 case FUZZ_1_BIT_FLIP:
359 case FUZZ_2_BIT_FLIP:
360 case FUZZ_1_BYTE_FLIP:
361 case FUZZ_2_BYTE_FLIP:
362 case FUZZ_BASE64:
363 return fuzz->fuzzed;
364 case FUZZ_TRUNCATE_START:
365 assert(fuzz->o1 <= fuzz->slen);
366 return fuzz->fuzzed + fuzz->o1;
367 case FUZZ_TRUNCATE_END:
368 assert(fuzz->o1 <= fuzz->slen);
369 return fuzz->fuzzed;
370 default:
371 abort();
372 }
373}
374
diff --git a/regress/unittests/test_helper/test_helper.c b/regress/unittests/test_helper/test_helper.c
new file mode 100644
index 000000000..8f0bbdec9
--- /dev/null
+++ b/regress/unittests/test_helper/test_helper.c
@@ -0,0 +1,452 @@
1/* $OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $ */
2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* Utility functions/framework for regress tests */
19
20#include <sys/types.h>
21#include <sys/param.h>
22
23#include <fcntl.h>
24#include <stdio.h>
25#include <stdint.h>
26#include <stdlib.h>
27#include <string.h>
28#include <assert.h>
29#include <unistd.h>
30
31#include <openssl/bn.h>
32
33#include <vis.h>
34
35#include "test_helper.h"
36
37#define TEST_CHECK_INT(r, pred) do { \
38 switch (pred) { \
39 case TEST_EQ: \
40 if (r == 0) \
41 return; \
42 break; \
43 case TEST_NE: \
44 if (r != 0) \
45 return; \
46 break; \
47 case TEST_LT: \
48 if (r < 0) \
49 return; \
50 break; \
51 case TEST_LE: \
52 if (r <= 0) \
53 return; \
54 break; \
55 case TEST_GT: \
56 if (r > 0) \
57 return; \
58 break; \
59 case TEST_GE: \
60 if (r >= 0) \
61 return; \
62 break; \
63 default: \
64 abort(); \
65 } \
66 } while (0)
67
68#define TEST_CHECK(x1, x2, pred) do { \
69 switch (pred) { \
70 case TEST_EQ: \
71 if (x1 == x2) \
72 return; \
73 break; \
74 case TEST_NE: \
75 if (x1 != x2) \
76 return; \
77 break; \
78 case TEST_LT: \
79 if (x1 < x2) \
80 return; \
81 break; \
82 case TEST_LE: \
83 if (x1 <= x2) \
84 return; \
85 break; \
86 case TEST_GT: \
87 if (x1 > x2) \
88 return; \
89 break; \
90 case TEST_GE: \
91 if (x1 >= x2) \
92 return; \
93 break; \
94 default: \
95 abort(); \
96 } \
97 } while (0)
98
99extern char *__progname;
100
101static int verbose_mode = 0;
102static int quiet_mode = 0;
103static char *active_test_name = NULL;
104static u_int test_number = 0;
105static test_onerror_func_t *test_onerror = NULL;
106static void *onerror_ctx = NULL;
107static const char *data_dir = NULL;
108
109int
110main(int argc, char **argv)
111{
112 int ch;
113
114 while ((ch = getopt(argc, argv, "vqd:")) != -1) {
115 switch (ch) {
116 case 'd':
117 data_dir = optarg;
118 break;
119 case 'q':
120 verbose_mode = 0;
121 quiet_mode = 1;
122 break;
123 case 'v':
124 verbose_mode = 1;
125 quiet_mode = 0;
126 break;
127 default:
128 fprintf(stderr, "Unrecognised command line option\n");
129 fprintf(stderr, "Usage: %s [-v]\n", __progname);
130 exit(1);
131 }
132 }
133 setvbuf(stdout, NULL, _IONBF, 0);
134 if (!quiet_mode)
135 printf("%s: ", __progname);
136 if (verbose_mode)
137 printf("\n");
138
139 tests();
140
141 if (!quiet_mode)
142 printf(" %u tests ok\n", test_number);
143 return 0;
144}
145
146const char *
147test_data_file(const char *name)
148{
149 static char ret[PATH_MAX];
150
151 if (data_dir != NULL)
152 snprintf(ret, sizeof(ret), "%s/%s", data_dir, name);
153 else
154 strlcpy(ret, name, sizeof(ret));
155 if (access(ret, F_OK) != 0) {
156 fprintf(stderr, "Cannot access data file %s: %s\n",
157 ret, strerror(errno));
158 exit(1);
159 }
160 return ret;
161}
162
163void
164test_start(const char *n)
165{
166 assert(active_test_name == NULL);
167 assert((active_test_name = strdup(n)) != NULL);
168 if (verbose_mode)
169 printf("test %u - \"%s\": ", test_number, active_test_name);
170 test_number++;
171}
172
173void
174set_onerror_func(test_onerror_func_t *f, void *ctx)
175{
176 test_onerror = f;
177 onerror_ctx = ctx;
178}
179
180void
181test_done(void)
182{
183 assert(active_test_name != NULL);
184 free(active_test_name);
185 active_test_name = NULL;
186 if (verbose_mode)
187 printf("OK\n");
188 else if (!quiet_mode) {
189 printf(".");
190 fflush(stdout);
191 }
192}
193
194void
195ssl_err_check(const char *file, int line)
196{
197 long openssl_error = ERR_get_error();
198
199 if (openssl_error == 0)
200 return;
201
202 fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s",
203 file, line, ERR_error_string(openssl_error, NULL));
204 abort();
205}
206
207static const char *
208pred_name(enum test_predicate p)
209{
210 switch (p) {
211 case TEST_EQ:
212 return "EQ";
213 case TEST_NE:
214 return "NE";
215 case TEST_LT:
216 return "LT";
217 case TEST_LE:
218 return "LE";
219 case TEST_GT:
220 return "GT";
221 case TEST_GE:
222 return "GE";
223 default:
224 return "UNKNOWN";
225 }
226}
227
228static void
229test_die(void)
230{
231 if (test_onerror != NULL)
232 test_onerror(onerror_ctx);
233 abort();
234}
235
236static void
237test_header(const char *file, int line, const char *a1, const char *a2,
238 const char *name, enum test_predicate pred)
239{
240 fprintf(stderr, "\n%s:%d test #%u \"%s\"\n",
241 file, line, test_number, active_test_name);
242 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n",
243 name, pred_name(pred), a1,
244 a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
245}
246
247void
248assert_bignum(const char *file, int line, const char *a1, const char *a2,
249 const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred)
250{
251 int r = BN_cmp(aa1, aa2);
252
253 TEST_CHECK_INT(r, pred);
254 test_header(file, line, a1, a2, "BIGNUM", pred);
255 fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1));
256 fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2));
257 test_die();
258}
259
260void
261assert_string(const char *file, int line, const char *a1, const char *a2,
262 const char *aa1, const char *aa2, enum test_predicate pred)
263{
264 int r = strcmp(aa1, aa2);
265
266 TEST_CHECK_INT(r, pred);
267 test_header(file, line, a1, a2, "STRING", pred);
268 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1));
269 fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2));
270 test_die();
271}
272
273static char *
274tohex(const void *_s, size_t l)
275{
276 u_int8_t *s = (u_int8_t *)_s;
277 size_t i, j;
278 const char *hex = "0123456789abcdef";
279 char *r = malloc((l * 2) + 1);
280
281 assert(r != NULL);
282 for (i = j = 0; i < l; i++) {
283 r[j++] = hex[(s[i] >> 4) & 0xf];
284 r[j++] = hex[s[i] & 0xf];
285 }
286 r[j] = '\0';
287 return r;
288}
289
290void
291assert_mem(const char *file, int line, const char *a1, const char *a2,
292 const void *aa1, const void *aa2, size_t l, enum test_predicate pred)
293{
294 int r = memcmp(aa1, aa2, l);
295
296 TEST_CHECK_INT(r, pred);
297 test_header(file, line, a1, a2, "STRING", pred);
298 fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l);
299 fprintf(stderr, "%12s = %s (len %zu)\n", a2, tohex(aa2, MIN(l, 256)), l);
300 test_die();
301}
302
303static int
304memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where)
305{
306 size_t i;
307
308 for (i = 0; i < l; i++) {
309 if (s[i] != v) {
310 *where = i;
311 return 1;
312 }
313 }
314 return 0;
315}
316
317void
318assert_mem_filled(const char *file, int line, const char *a1,
319 const void *aa1, u_char v, size_t l, enum test_predicate pred)
320{
321 size_t where = -1;
322 int r = memvalcmp(aa1, v, l, &where);
323 char tmp[64];
324
325 if (l == 0)
326 return;
327 TEST_CHECK_INT(r, pred);
328 test_header(file, line, a1, NULL, "MEM_ZERO", pred);
329 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
330 tohex(aa1, MIN(l, 20)), l > 20 ? "..." : "", l);
331 snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where);
332 fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp,
333 ((u_char *)aa1)[where], v);
334 test_die();
335}
336
337void
338assert_int(const char *file, int line, const char *a1, const char *a2,
339 int aa1, int aa2, enum test_predicate pred)
340{
341 TEST_CHECK(aa1, aa2, pred);
342 test_header(file, line, a1, a2, "INT", pred);
343 fprintf(stderr, "%12s = %d\n", a1, aa1);
344 fprintf(stderr, "%12s = %d\n", a2, aa2);
345 test_die();
346}
347
348void
349assert_size_t(const char *file, int line, const char *a1, const char *a2,
350 size_t aa1, size_t aa2, enum test_predicate pred)
351{
352 TEST_CHECK(aa1, aa2, pred);
353 test_header(file, line, a1, a2, "SIZE_T", pred);
354 fprintf(stderr, "%12s = %zu\n", a1, aa1);
355 fprintf(stderr, "%12s = %zu\n", a2, aa2);
356 test_die();
357}
358
359void
360assert_u_int(const char *file, int line, const char *a1, const char *a2,
361 u_int aa1, u_int aa2, enum test_predicate pred)
362{
363 TEST_CHECK(aa1, aa2, pred);
364 test_header(file, line, a1, a2, "U_INT", pred);
365 fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1);
366 fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2);
367 test_die();
368}
369
370void
371assert_long_long(const char *file, int line, const char *a1, const char *a2,
372 long long aa1, long long aa2, enum test_predicate pred)
373{
374 TEST_CHECK(aa1, aa2, pred);
375 test_header(file, line, a1, a2, "LONG LONG", pred);
376 fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1);
377 fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2);
378 test_die();
379}
380
381void
382assert_char(const char *file, int line, const char *a1, const char *a2,
383 char aa1, char aa2, enum test_predicate pred)
384{
385 char buf[8];
386
387 TEST_CHECK(aa1, aa2, pred);
388 test_header(file, line, a1, a2, "CHAR", pred);
389 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
390 vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1);
391 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
392 vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2);
393 test_die();
394}
395
396void
397assert_u8(const char *file, int line, const char *a1, const char *a2,
398 u_int8_t aa1, u_int8_t aa2, enum test_predicate pred)
399{
400 TEST_CHECK(aa1, aa2, pred);
401 test_header(file, line, a1, a2, "U8", pred);
402 fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1);
403 fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2);
404 test_die();
405}
406
407void
408assert_u16(const char *file, int line, const char *a1, const char *a2,
409 u_int16_t aa1, u_int16_t aa2, enum test_predicate pred)
410{
411 TEST_CHECK(aa1, aa2, pred);
412 test_header(file, line, a1, a2, "U16", pred);
413 fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1);
414 fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2);
415 test_die();
416}
417
418void
419assert_u32(const char *file, int line, const char *a1, const char *a2,
420 u_int32_t aa1, u_int32_t aa2, enum test_predicate pred)
421{
422 TEST_CHECK(aa1, aa2, pred);
423 test_header(file, line, a1, a2, "U32", pred);
424 fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1);
425 fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2);
426 test_die();
427}
428
429void
430assert_u64(const char *file, int line, const char *a1, const char *a2,
431 u_int64_t aa1, u_int64_t aa2, enum test_predicate pred)
432{
433 TEST_CHECK(aa1, aa2, pred);
434 test_header(file, line, a1, a2, "U64", pred);
435 fprintf(stderr, "%12s = 0x%016llx %llu\n", a1,
436 (unsigned long long)aa1, (unsigned long long)aa1);
437 fprintf(stderr, "%12s = 0x%016llx %llu\n", a2,
438 (unsigned long long)aa2, (unsigned long long)aa2);
439 test_die();
440}
441
442void
443assert_ptr(const char *file, int line, const char *a1, const char *a2,
444 const void *aa1, const void *aa2, enum test_predicate pred)
445{
446 TEST_CHECK(aa1, aa2, pred);
447 test_header(file, line, a1, a2, "PTR", pred);
448 fprintf(stderr, "%12s = %p\n", a1, aa1);
449 fprintf(stderr, "%12s = %p\n", a2, aa2);
450 test_die();
451}
452
diff --git a/regress/unittests/test_helper/test_helper.h b/regress/unittests/test_helper/test_helper.h
new file mode 100644
index 000000000..6ead92a1c
--- /dev/null
+++ b/regress/unittests/test_helper/test_helper.h
@@ -0,0 +1,288 @@
1/* $OpenBSD: test_helper.h,v 1.3 2014/05/02 09:41:32 andre Exp $ */
2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* Utility functions/framework for regress tests */
19
20#ifndef _TEST_HELPER_H
21#define _TEST_HELPER_H
22
23#include <sys/types.h>
24#include <stdint.h>
25
26#include <openssl/bn.h>
27#include <openssl/err.h>
28
29enum test_predicate {
30 TEST_EQ, TEST_NE, TEST_LT, TEST_LE, TEST_GT, TEST_GE
31};
32typedef void (test_onerror_func_t)(void *);
33
34/* Supplied by test suite */
35void tests(void);
36
37const char *test_data_file(const char *name);
38void test_start(const char *n);
39void set_onerror_func(test_onerror_func_t *f, void *ctx);
40void test_done(void);
41void ssl_err_check(const char *file, int line);
42void assert_bignum(const char *file, int line,
43 const char *a1, const char *a2,
44 const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred);
45void assert_string(const char *file, int line,
46 const char *a1, const char *a2,
47 const char *aa1, const char *aa2, enum test_predicate pred);
48void assert_mem(const char *file, int line,
49 const char *a1, const char *a2,
50 const void *aa1, const void *aa2, size_t l, enum test_predicate pred);
51void assert_mem_filled(const char *file, int line,
52 const char *a1,
53 const void *aa1, u_char v, size_t l, enum test_predicate pred);
54void assert_int(const char *file, int line,
55 const char *a1, const char *a2,
56 int aa1, int aa2, enum test_predicate pred);
57void assert_size_t(const char *file, int line,
58 const char *a1, const char *a2,
59 size_t aa1, size_t aa2, enum test_predicate pred);
60void assert_u_int(const char *file, int line,
61 const char *a1, const char *a2,
62 u_int aa1, u_int aa2, enum test_predicate pred);
63void assert_long_long(const char *file, int line,
64 const char *a1, const char *a2,
65 long long aa1, long long aa2, enum test_predicate pred);
66void assert_char(const char *file, int line,
67 const char *a1, const char *a2,
68 char aa1, char aa2, enum test_predicate pred);
69void assert_ptr(const char *file, int line,
70 const char *a1, const char *a2,
71 const void *aa1, const void *aa2, enum test_predicate pred);
72void assert_u8(const char *file, int line,
73 const char *a1, const char *a2,
74 u_int8_t aa1, u_int8_t aa2, enum test_predicate pred);
75void assert_u16(const char *file, int line,
76 const char *a1, const char *a2,
77 u_int16_t aa1, u_int16_t aa2, enum test_predicate pred);
78void assert_u32(const char *file, int line,
79 const char *a1, const char *a2,
80 u_int32_t aa1, u_int32_t aa2, enum test_predicate pred);
81void assert_u64(const char *file, int line,
82 const char *a1, const char *a2,
83 u_int64_t aa1, u_int64_t aa2, enum test_predicate pred);
84
85#define TEST_START(n) test_start(n)
86#define TEST_DONE() test_done()
87#define TEST_ONERROR(f, c) set_onerror_func(f, c)
88#define SSL_ERR_CHECK() ssl_err_check(__FILE__, __LINE__)
89
90#define ASSERT_BIGNUM_EQ(a1, a2) \
91 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
92#define ASSERT_STRING_EQ(a1, a2) \
93 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
94#define ASSERT_MEM_EQ(a1, a2, l) \
95 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_EQ)
96#define ASSERT_MEM_FILLED_EQ(a1, c, l) \
97 assert_mem_filled(__FILE__, __LINE__, #a1, a1, c, l, TEST_EQ)
98#define ASSERT_MEM_ZERO_EQ(a1, l) \
99 assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_EQ)
100#define ASSERT_INT_EQ(a1, a2) \
101 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
102#define ASSERT_SIZE_T_EQ(a1, a2) \
103 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
104#define ASSERT_U_INT_EQ(a1, a2) \
105 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
106#define ASSERT_LONG_LONG_EQ(a1, a2) \
107 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
108#define ASSERT_CHAR_EQ(a1, a2) \
109 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
110#define ASSERT_PTR_EQ(a1, a2) \
111 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
112#define ASSERT_U8_EQ(a1, a2) \
113 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
114#define ASSERT_U16_EQ(a1, a2) \
115 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
116#define ASSERT_U32_EQ(a1, a2) \
117 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
118#define ASSERT_U64_EQ(a1, a2) \
119 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
120
121#define ASSERT_BIGNUM_NE(a1, a2) \
122 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
123#define ASSERT_STRING_NE(a1, a2) \
124 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
125#define ASSERT_MEM_NE(a1, a2, l) \
126 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_NE)
127#define ASSERT_MEM_ZERO_NE(a1, l) \
128 assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_NE)
129#define ASSERT_INT_NE(a1, a2) \
130 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
131#define ASSERT_SIZE_T_NE(a1, a2) \
132 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
133#define ASSERT_U_INT_NE(a1, a2) \
134 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
135#define ASSERT_LONG_LONG_NE(a1, a2) \
136 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
137#define ASSERT_CHAR_NE(a1, a2) \
138 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
139#define ASSERT_PTR_NE(a1, a2) \
140 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
141#define ASSERT_U8_NE(a1, a2) \
142 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
143#define ASSERT_U16_NE(a1, a2) \
144 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
145#define ASSERT_U32_NE(a1, a2) \
146 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
147#define ASSERT_U64_NE(a1, a2) \
148 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
149
150#define ASSERT_BIGNUM_LT(a1, a2) \
151 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
152#define ASSERT_STRING_LT(a1, a2) \
153 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
154#define ASSERT_MEM_LT(a1, a2, l) \
155 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LT)
156#define ASSERT_INT_LT(a1, a2) \
157 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
158#define ASSERT_SIZE_T_LT(a1, a2) \
159 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
160#define ASSERT_U_INT_LT(a1, a2) \
161 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
162#define ASSERT_LONG_LONG_LT(a1, a2) \
163 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
164#define ASSERT_CHAR_LT(a1, a2) \
165 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
166#define ASSERT_PTR_LT(a1, a2) \
167 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
168#define ASSERT_U8_LT(a1, a2) \
169 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
170#define ASSERT_U16_LT(a1, a2) \
171 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
172#define ASSERT_U32_LT(a1, a2) \
173 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
174#define ASSERT_U64_LT(a1, a2) \
175 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
176
177#define ASSERT_BIGNUM_LE(a1, a2) \
178 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
179#define ASSERT_STRING_LE(a1, a2) \
180 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
181#define ASSERT_MEM_LE(a1, a2, l) \
182 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LE)
183#define ASSERT_INT_LE(a1, a2) \
184 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
185#define ASSERT_SIZE_T_LE(a1, a2) \
186 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
187#define ASSERT_U_INT_LE(a1, a2) \
188 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
189#define ASSERT_LONG_LONG_LE(a1, a2) \
190 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
191#define ASSERT_CHAR_LE(a1, a2) \
192 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
193#define ASSERT_PTR_LE(a1, a2) \
194 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
195#define ASSERT_U8_LE(a1, a2) \
196 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
197#define ASSERT_U16_LE(a1, a2) \
198 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
199#define ASSERT_U32_LE(a1, a2) \
200 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
201#define ASSERT_U64_LE(a1, a2) \
202 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
203
204#define ASSERT_BIGNUM_GT(a1, a2) \
205 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
206#define ASSERT_STRING_GT(a1, a2) \
207 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
208#define ASSERT_MEM_GT(a1, a2, l) \
209 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GT)
210#define ASSERT_INT_GT(a1, a2) \
211 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
212#define ASSERT_SIZE_T_GT(a1, a2) \
213 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
214#define ASSERT_U_INT_GT(a1, a2) \
215 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
216#define ASSERT_LONG_LONG_GT(a1, a2) \
217 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
218#define ASSERT_CHAR_GT(a1, a2) \
219 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
220#define ASSERT_PTR_GT(a1, a2) \
221 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
222#define ASSERT_U8_GT(a1, a2) \
223 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
224#define ASSERT_U16_GT(a1, a2) \
225 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
226#define ASSERT_U32_GT(a1, a2) \
227 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
228#define ASSERT_U64_GT(a1, a2) \
229 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
230
231#define ASSERT_BIGNUM_GE(a1, a2) \
232 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
233#define ASSERT_STRING_GE(a1, a2) \
234 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
235#define ASSERT_MEM_GE(a1, a2, l) \
236 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GE)
237#define ASSERT_INT_GE(a1, a2) \
238 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
239#define ASSERT_SIZE_T_GE(a1, a2) \
240 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
241#define ASSERT_U_INT_GE(a1, a2) \
242 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
243#define ASSERT_LONG_LONG_GE(a1, a2) \
244 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
245#define ASSERT_CHAR_GE(a1, a2) \
246 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
247#define ASSERT_PTR_GE(a1, a2) \
248 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
249#define ASSERT_U8_GE(a1, a2) \
250 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
251#define ASSERT_U16_GE(a1, a2) \
252 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
253#define ASSERT_U32_GE(a1, a2) \
254 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
255#define ASSERT_U64_GE(a1, a2) \
256 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
257
258/* Fuzzing support */
259
260struct fuzz;
261#define FUZZ_1_BIT_FLIP 0x00000001 /* Flip one bit at a time */
262#define FUZZ_2_BIT_FLIP 0x00000002 /* Flip two bits at a time */
263#define FUZZ_1_BYTE_FLIP 0x00000004 /* Flip one byte at a time */
264#define FUZZ_2_BYTE_FLIP 0x00000008 /* Flip two bytes at a time */
265#define FUZZ_TRUNCATE_START 0x00000010 /* Truncate from beginning */
266#define FUZZ_TRUNCATE_END 0x00000020 /* Truncate from end */
267#define FUZZ_BASE64 0x00000040 /* Try all base64 chars */
268#define FUZZ_MAX FUZZ_BASE64
269
270/* Start fuzzing a blob of data with selected strategies (bitmask) */
271struct fuzz *fuzz_begin(u_int strategies, const void *p, size_t l);
272
273/* Free a fuzz context */
274void fuzz_cleanup(struct fuzz *fuzz);
275
276/* Prepare the next fuzz case in the series */
277void fuzz_next(struct fuzz *fuzz);
278
279/* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */
280int fuzz_done(struct fuzz *fuzz);
281
282/* Return the length and a pointer to the current fuzzed case */
283size_t fuzz_len(struct fuzz *fuzz);
284u_char *fuzz_ptr(struct fuzz *fuzz);
285
286/* Dump the current fuzz case to stderr */
287void fuzz_dump(struct fuzz *fuzz);
288#endif /* _TEST_HELPER_H */