summaryrefslogtreecommitdiff
path: root/regress/unittests/sshbuf
diff options
context:
space:
mode:
Diffstat (limited to 'regress/unittests/sshbuf')
-rw-r--r--regress/unittests/sshbuf/Makefile14
-rw-r--r--regress/unittests/sshbuf/test_sshbuf.c240
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_fixed.c126
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_fuzz.c127
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_basic.c484
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_crypto.c409
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c130
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_misc.c138
-rw-r--r--regress/unittests/sshbuf/tests.c28
9 files changed, 1696 insertions, 0 deletions
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..ee77d6934
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf.c
@@ -0,0 +1,240 @@
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#define SSHBUF_INTERNAL 1 /* access internals for testing */
9#include "includes.h"
10
11#include <sys/types.h>
12#include <sys/param.h>
13#include <stdio.h>
14#ifdef HAVE_STDINT_H
15# include <stdint.h>
16#endif
17#include <stdlib.h>
18#include <string.h>
19
20#include "../test_helper/test_helper.h"
21
22#include "ssherr.h"
23#include "sshbuf.h"
24
25void sshbuf_tests(void);
26
27void
28sshbuf_tests(void)
29{
30 struct sshbuf *p1;
31 const u_char *cdp;
32 u_char *dp;
33 size_t sz;
34 int r;
35
36 TEST_START("allocate sshbuf");
37 p1 = sshbuf_new();
38 ASSERT_PTR_NE(p1, NULL);
39 TEST_DONE();
40
41 TEST_START("max size on fresh buffer");
42 ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0);
43 TEST_DONE();
44
45 TEST_START("available on fresh buffer");
46 ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0);
47 TEST_DONE();
48
49 TEST_START("len = 0 on empty buffer");
50 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
51 TEST_DONE();
52
53 TEST_START("set valid max size");
54 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0);
55 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536);
56 TEST_DONE();
57
58 TEST_START("available on limited buffer");
59 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536);
60 TEST_DONE();
61
62 TEST_START("free");
63 sshbuf_free(p1);
64 TEST_DONE();
65
66 TEST_START("consume on empty buffer");
67 p1 = sshbuf_new();
68 ASSERT_PTR_NE(p1, NULL);
69 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
70 ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
71 sshbuf_free(p1);
72 TEST_DONE();
73
74 TEST_START("consume_end on empty buffer");
75 p1 = sshbuf_new();
76 ASSERT_PTR_NE(p1, NULL);
77 ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0);
78 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
79 sshbuf_free(p1);
80 TEST_DONE();
81
82 TEST_START("reserve space");
83 p1 = sshbuf_new();
84 ASSERT_PTR_NE(p1, NULL);
85 r = sshbuf_reserve(p1, 1, &dp);
86 ASSERT_INT_EQ(r, 0);
87 ASSERT_PTR_NE(dp, NULL);
88 *dp = 0x11;
89 r = sshbuf_reserve(p1, 3, &dp);
90 ASSERT_INT_EQ(r, 0);
91 ASSERT_PTR_NE(dp, NULL);
92 *dp++ = 0x22;
93 *dp++ = 0x33;
94 *dp++ = 0x44;
95 TEST_DONE();
96
97 TEST_START("sshbuf_len on filled buffer");
98 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
99 TEST_DONE();
100
101 TEST_START("sshbuf_ptr on filled buffer");
102 cdp = sshbuf_ptr(p1);
103 ASSERT_PTR_NE(cdp, NULL);
104 ASSERT_U8_EQ(cdp[0], 0x11);
105 ASSERT_U8_EQ(cdp[1], 0x22);
106 ASSERT_U8_EQ(cdp[2], 0x33);
107 ASSERT_U8_EQ(cdp[3], 0x44);
108 TEST_DONE();
109
110 TEST_START("consume on filled buffer");
111 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
112 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
113 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
114 r = sshbuf_consume(p1, 64);
115 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
116 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
117 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
118 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
119 cdp = sshbuf_ptr(p1);
120 ASSERT_PTR_NE(p1, NULL);
121 ASSERT_U8_EQ(cdp[0], 0x22);
122 ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0);
123 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
124 cdp = sshbuf_ptr(p1);
125 ASSERT_PTR_NE(p1, NULL);
126 ASSERT_U8_EQ(cdp[0], 0x44);
127 r = sshbuf_consume(p1, 2);
128 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
129 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
130 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
131 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
132 r = sshbuf_consume(p1, 1);
133 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
134 sshbuf_free(p1);
135 TEST_DONE();
136
137 TEST_START("consume_end on filled buffer");
138 p1 = sshbuf_new();
139 ASSERT_PTR_NE(p1, NULL);
140 r = sshbuf_reserve(p1, 4, &dp);
141 ASSERT_INT_EQ(r, 0);
142 ASSERT_PTR_NE(dp, NULL);
143 *dp++ = 0x11;
144 *dp++ = 0x22;
145 *dp++ = 0x33;
146 *dp++ = 0x44;
147 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
148 r = sshbuf_consume_end(p1, 5);
149 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
150 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
151 ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0);
152 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
153 cdp = sshbuf_ptr(p1);
154 ASSERT_PTR_NE(cdp, NULL);
155 ASSERT_U8_EQ(*cdp, 0x11);
156 r = sshbuf_consume_end(p1, 2);
157 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
158 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
159 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
160 sshbuf_free(p1);
161 TEST_DONE();
162
163 TEST_START("fill limited buffer");
164 p1 = sshbuf_new();
165 ASSERT_PTR_NE(p1, NULL);
166 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
167 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
168 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
169 r = sshbuf_reserve(p1, 1223, &dp);
170 ASSERT_INT_EQ(r, 0);
171 ASSERT_PTR_NE(dp, NULL);
172 memset(dp, 0xd7, 1223);
173 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
174 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
175 r = sshbuf_reserve(p1, 1, &dp);
176 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
177 ASSERT_PTR_EQ(dp, NULL);
178 TEST_DONE();
179
180 TEST_START("consume and force compaction");
181 ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0);
182 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
183 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
184 r = sshbuf_reserve(p1, 224, &dp);
185 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
186 ASSERT_PTR_EQ(dp, NULL);
187 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
188 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
189 r = sshbuf_reserve(p1, 223, &dp);
190 ASSERT_INT_EQ(r, 0);
191 ASSERT_PTR_NE(dp, NULL);
192 memset(dp, 0x7d, 223);
193 cdp = sshbuf_ptr(p1);
194 ASSERT_PTR_NE(cdp, NULL);
195 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
196 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
197 TEST_DONE();
198
199 TEST_START("resize full buffer");
200 r = sshbuf_set_max_size(p1, 1000);
201 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
202 sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC);
203 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0);
204 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
205 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223);
206 ASSERT_INT_EQ(sshbuf_len(p1), 1223);
207 TEST_DONE();
208
209 /* NB. uses sshbuf internals */
210 TEST_START("alloc chunking");
211 r = sshbuf_reserve(p1, 1, &dp);
212 ASSERT_INT_EQ(r, 0);
213 ASSERT_PTR_NE(dp, NULL);
214 *dp = 0xff;
215 cdp = sshbuf_ptr(p1);
216 ASSERT_PTR_NE(cdp, NULL);
217 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
218 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
219 ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1);
220 ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0);
221 sshbuf_free(p1);
222 TEST_DONE();
223
224 TEST_START("reset buffer");
225 p1 = sshbuf_new();
226 ASSERT_PTR_NE(p1, NULL);
227 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
228 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
229 r = sshbuf_reserve(p1, 1223, &dp);
230 ASSERT_INT_EQ(r, 0);
231 ASSERT_PTR_NE(dp, NULL);
232 memset(dp, 0xd7, 1223);
233 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
234 sshbuf_reset(p1);
235 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
236 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
237 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
238 sshbuf_free(p1);
239 TEST_DONE();
240}
diff --git a/regress/unittests/sshbuf/test_sshbuf_fixed.c b/regress/unittests/sshbuf/test_sshbuf_fixed.c
new file mode 100644
index 000000000..df4925f7c
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_fixed.c
@@ -0,0 +1,126 @@
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#define SSHBUF_INTERNAL 1 /* access internals for testing */
9#include "includes.h"
10
11#include <sys/types.h>
12#include <sys/param.h>
13#include <stdio.h>
14#ifdef HAVE_STDINT_H
15# include <stdint.h>
16#endif
17#include <stdlib.h>
18#include <string.h>
19
20#include "../test_helper/test_helper.h"
21
22#include "sshbuf.h"
23#include "ssherr.h"
24
25void sshbuf_fixed(void);
26
27const u_char test_buf[] = "\x01\x12\x34\x56\x78\x00\x00\x00\x05hello";
28
29void
30sshbuf_fixed(void)
31{
32 struct sshbuf *p1, *p2, *p3;
33 u_char c;
34 char *s;
35 u_int i;
36 size_t l;
37
38 TEST_START("sshbuf_from");
39 p1 = sshbuf_from(test_buf, sizeof(test_buf));
40 ASSERT_PTR_NE(p1, NULL);
41 ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL);
42 ASSERT_INT_EQ(sshbuf_check_reserve(p1, 1), SSH_ERR_BUFFER_READ_ONLY);
43 ASSERT_INT_EQ(sshbuf_reserve(p1, 1, NULL), SSH_ERR_BUFFER_READ_ONLY);
44 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 200), SSH_ERR_BUFFER_READ_ONLY);
45 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), SSH_ERR_BUFFER_READ_ONLY);
46 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
47 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf);
48 sshbuf_free(p1);
49 TEST_DONE();
50
51 TEST_START("sshbuf_from data");
52 p1 = sshbuf_from(test_buf, sizeof(test_buf) - 1);
53 ASSERT_PTR_NE(p1, NULL);
54 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf);
55 ASSERT_INT_EQ(sshbuf_get_u8(p1, &c), 0);
56 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 1);
57 ASSERT_U8_EQ(c, 1);
58 ASSERT_INT_EQ(sshbuf_get_u32(p1, &i), 0);
59 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 5);
60 ASSERT_U32_EQ(i, 0x12345678);
61 ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s, &l), 0);
62 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
63 ASSERT_STRING_EQ(s, "hello");
64 ASSERT_SIZE_T_EQ(l, 5);
65 sshbuf_free(p1);
66 free(s);
67 TEST_DONE();
68
69 TEST_START("sshbuf_fromb ");
70 p1 = sshbuf_new();
71 ASSERT_PTR_NE(p1, NULL);
72 ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1);
73 ASSERT_PTR_EQ(sshbuf_parent(p1), NULL);
74 ASSERT_INT_EQ(sshbuf_put(p1, test_buf, sizeof(test_buf) - 1), 0);
75 p2 = sshbuf_fromb(p1);
76 ASSERT_PTR_NE(p2, NULL);
77 ASSERT_U_INT_EQ(sshbuf_refcount(p1), 2);
78 ASSERT_PTR_EQ(sshbuf_parent(p1), NULL);
79 ASSERT_PTR_EQ(sshbuf_parent(p2), p1);
80 ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1));
81 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
82 ASSERT_PTR_NE(sshbuf_ptr(p2), NULL);
83 ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL);
84 ASSERT_PTR_EQ(sshbuf_mutable_ptr(p2), NULL);
85 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sshbuf_len(p2));
86 ASSERT_INT_EQ(sshbuf_get_u8(p2, &c), 0);
87 ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 1);
88 ASSERT_U8_EQ(c, 1);
89 ASSERT_INT_EQ(sshbuf_get_u32(p2, &i), 0);
90 ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 5);
91 ASSERT_U32_EQ(i, 0x12345678);
92 ASSERT_INT_EQ(sshbuf_get_cstring(p2, &s, &l), 0);
93 ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0);
94 ASSERT_STRING_EQ(s, "hello");
95 ASSERT_SIZE_T_EQ(l, 5);
96 sshbuf_free(p1);
97 ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1);
98 sshbuf_free(p2);
99 free(s);
100 TEST_DONE();
101
102 TEST_START("sshbuf_froms");
103 p1 = sshbuf_new();
104 ASSERT_PTR_NE(p1, NULL);
105 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x01), 0);
106 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
107 ASSERT_INT_EQ(sshbuf_put_cstring(p1, "hello"), 0);
108 p2 = sshbuf_new();
109 ASSERT_PTR_NE(p2, NULL);
110 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(test_buf) - 1);
111 ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0);
112 ASSERT_SIZE_T_EQ(sshbuf_len(p2), sizeof(test_buf) + 4 - 1);
113 ASSERT_INT_EQ(sshbuf_froms(p2, &p3), 0);
114 ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0);
115 ASSERT_PTR_NE(p3, NULL);
116 ASSERT_PTR_NE(sshbuf_ptr(p3), NULL);
117 ASSERT_SIZE_T_EQ(sshbuf_len(p3), sizeof(test_buf) - 1);
118 ASSERT_MEM_EQ(sshbuf_ptr(p3), test_buf, sizeof(test_buf) - 1);
119 sshbuf_free(p3);
120 ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0);
121 ASSERT_INT_EQ(sshbuf_consume_end(p2, 1), 0);
122 ASSERT_INT_EQ(sshbuf_froms(p2, &p3), SSH_ERR_MESSAGE_INCOMPLETE);
123 ASSERT_PTR_EQ(p3, NULL);
124 sshbuf_free(p2);
125 sshbuf_free(p1);
126}
diff --git a/regress/unittests/sshbuf/test_sshbuf_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_fuzz.c
new file mode 100644
index 000000000..c52376b53
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_fuzz.c
@@ -0,0 +1,127 @@
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 "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14# include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include "../test_helper/test_helper.h"
20
21#include "ssherr.h"
22#include "sshbuf.h"
23
24#define NUM_FUZZ_TESTS (1 << 18)
25
26void sshbuf_fuzz_tests(void);
27
28void
29sshbuf_fuzz_tests(void)
30{
31 struct sshbuf *p1;
32 u_char *dp;
33 size_t sz, sz2, i;
34 u_int32_t r;
35 int ret;
36
37 /* NB. uses sshbuf internals */
38 TEST_START("fuzz alloc/dealloc");
39 p1 = sshbuf_new();
40 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0);
41 ASSERT_PTR_NE(p1, NULL);
42 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
43 ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
44 for (i = 0; i < NUM_FUZZ_TESTS; i++) {
45 r = arc4random_uniform(10);
46 if (r == 0) {
47 /* 10% chance: small reserve */
48 r = arc4random_uniform(10);
49 fuzz_reserve:
50 sz = sshbuf_avail(p1);
51 sz2 = sshbuf_len(p1);
52 ret = sshbuf_reserve(p1, r, &dp);
53 if (ret < 0) {
54 ASSERT_PTR_EQ(dp, NULL);
55 ASSERT_SIZE_T_LT(sz, r);
56 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
57 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
58 } else {
59 ASSERT_PTR_NE(dp, NULL);
60 ASSERT_SIZE_T_GE(sz, r);
61 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - r);
62 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 + r);
63 memset(dp, arc4random_uniform(255) + 1, r);
64 }
65 } else if (r < 3) {
66 /* 20% chance: big reserve */
67 r = arc4random_uniform(8 * 1024);
68 goto fuzz_reserve;
69 } else if (r == 3) {
70 /* 10% chance: small consume */
71 r = arc4random_uniform(10);
72 fuzz_consume:
73 sz = sshbuf_avail(p1);
74 sz2 = sshbuf_len(p1);
75 /* 50% change consume from end, otherwise start */
76 ret = ((arc4random() & 1) ?
77 sshbuf_consume : sshbuf_consume_end)(p1, r);
78 if (ret < 0) {
79 ASSERT_SIZE_T_LT(sz2, r);
80 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
81 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
82 } else {
83 ASSERT_SIZE_T_GE(sz2, r);
84 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz + r);
85 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 - r);
86 }
87 } else if (r < 8) {
88 /* 40% chance: big consume */
89 r = arc4random_uniform(2 * 1024);
90 goto fuzz_consume;
91 } else if (r == 8) {
92 /* 10% chance: reset max size */
93 r = arc4random_uniform(16 * 1024);
94 sz = sshbuf_max_size(p1);
95 if (sshbuf_set_max_size(p1, r) < 0)
96 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
97 else
98 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), r);
99 } else {
100 if (arc4random_uniform(8192) == 0) {
101 /* tiny chance: new buffer */
102 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
103 ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
104 sshbuf_free(p1);
105 p1 = sshbuf_new();
106 ASSERT_PTR_NE(p1, NULL);
107 ASSERT_INT_EQ(sshbuf_set_max_size(p1,
108 16 * 1024), 0);
109 } else {
110 /* Almost 10%: giant reserve */
111 /* use arc4random_buf for r > 2^32 on 64 bit */
112 arc4random_buf(&r, sizeof(r));
113 while (r < SSHBUF_SIZE_MAX / 2) {
114 r <<= 1;
115 r |= arc4random() & 1;
116 }
117 goto fuzz_reserve;
118 }
119 }
120 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
121 ASSERT_SIZE_T_LE(sshbuf_max_size(p1), 16 * 1024);
122 }
123 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
124 ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
125 sshbuf_free(p1);
126 TEST_DONE();
127}
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..966e8432b
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_basic.c
@@ -0,0 +1,484 @@
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 "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14# include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include "../test_helper/test_helper.h"
20#include "ssherr.h"
21#include "sshbuf.h"
22
23void sshbuf_getput_basic_tests(void);
24
25void
26sshbuf_getput_basic_tests(void)
27{
28 struct sshbuf *p1, *p2;
29 const u_char *cd;
30 u_char *d, d2[32], x[] = {
31 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x00, 0x99
32 };
33 u_int64_t v64;
34 u_int32_t v32;
35 u_int16_t v16;
36 u_char v8;
37 size_t s;
38 char *s2;
39 int r;
40 u_char bn1[] = { 0x00, 0x00, 0x00 };
41 u_char bn2[] = { 0x00, 0x00, 0x01, 0x02 };
42 u_char bn3[] = { 0x00, 0x80, 0x09 };
43 u_char bn_exp1[] = { 0x00, 0x00, 0x00, 0x00 };
44 u_char bn_exp2[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 0x02 };
45 u_char bn_exp3[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x80, 0x09 };
46
47 TEST_START("PEEK_U64");
48 ASSERT_U64_EQ(PEEK_U64(x), 0x1122334455667788ULL);
49 TEST_DONE();
50
51 TEST_START("PEEK_U32");
52 ASSERT_U32_EQ(PEEK_U32(x), 0x11223344);
53 TEST_DONE();
54
55 TEST_START("PEEK_U16");
56 ASSERT_U16_EQ(PEEK_U16(x), 0x1122);
57 TEST_DONE();
58
59 TEST_START("POKE_U64");
60 bzero(d2, sizeof(d2));
61 POKE_U64(d2, 0x1122334455667788ULL);
62 ASSERT_MEM_EQ(d2, x, 8);
63 TEST_DONE();
64
65 TEST_START("POKE_U32");
66 bzero(d2, sizeof(d2));
67 POKE_U32(d2, 0x11223344);
68 ASSERT_MEM_EQ(d2, x, 4);
69 TEST_DONE();
70
71 TEST_START("POKE_U16");
72 bzero(d2, sizeof(d2));
73 POKE_U16(d2, 0x1122);
74 ASSERT_MEM_EQ(d2, x, 2);
75 TEST_DONE();
76
77 TEST_START("sshbuf_put");
78 p1 = sshbuf_new();
79 ASSERT_PTR_NE(p1, NULL);
80 ASSERT_INT_EQ(sshbuf_put(p1, x, 5), 0);
81 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5);
82 cd = sshbuf_ptr(p1);
83 ASSERT_PTR_NE(cd, NULL);
84 ASSERT_U8_EQ(cd[0], 0x11);
85 ASSERT_U8_EQ(cd[1], 0x22);
86 ASSERT_U8_EQ(cd[2], 0x33);
87 ASSERT_U8_EQ(cd[3], 0x44);
88 ASSERT_U8_EQ(cd[4], 0x55);
89 TEST_DONE();
90
91 TEST_START("sshbuf_get");
92 ASSERT_INT_EQ(sshbuf_get(p1, d2, 4), 0);
93 ASSERT_MEM_EQ(d2, x, 4);
94 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
95 ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55);
96 TEST_DONE();
97
98 TEST_START("sshbuf_get truncated");
99 r = sshbuf_get(p1, d2, 4);
100 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
101 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
102 ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55);
103 TEST_DONE();
104
105 TEST_START("sshbuf_put truncated");
106 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0);
107 r = sshbuf_put(p1, x, 5);
108 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
109 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
110 sshbuf_free(p1);
111 TEST_DONE();
112
113 TEST_START("sshbuf_get_u64");
114 p1 = sshbuf_new();
115 ASSERT_PTR_NE(p1, NULL);
116 ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0);
117 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10);
118 ASSERT_INT_EQ(sshbuf_get_u64(p1, &v64), 0);
119 ASSERT_U64_EQ(v64, 0x1122334455667788ULL);
120 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
121 TEST_DONE();
122
123 TEST_START("sshbuf_get_u64 truncated");
124 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
125 r = sshbuf_get_u64(p1, &v64);
126 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
127 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
128 sshbuf_free(p1);
129 TEST_DONE();
130
131 TEST_START("sshbuf_get_u32");
132 p1 = sshbuf_new();
133 ASSERT_PTR_NE(p1, NULL);
134 ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0);
135 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10);
136 ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0);
137 ASSERT_U32_EQ(v32, 0x11223344);
138 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 6);
139 ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0);
140 ASSERT_U32_EQ(v32, 0x55667788);
141 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
142 TEST_DONE();
143
144 TEST_START("sshbuf_get_u32 truncated");
145 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
146 r = sshbuf_get_u32(p1, &v32);
147 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
148 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
149 sshbuf_free(p1);
150 TEST_DONE();
151
152 TEST_START("sshbuf_get_u16");
153 p1 = sshbuf_new();
154 ASSERT_PTR_NE(p1, NULL);
155 ASSERT_INT_EQ(sshbuf_put(p1, x, 9), 0);
156 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 9);
157 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
158 ASSERT_U16_EQ(v16, 0x1122);
159 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 7);
160 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
161 ASSERT_U16_EQ(v16, 0x3344);
162 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5);
163 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
164 ASSERT_U16_EQ(v16, 0x5566);
165 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
166 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
167 ASSERT_U16_EQ(v16, 0x7788);
168 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
169 TEST_DONE();
170
171 TEST_START("sshbuf_get_u16 truncated");
172 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
173 r = sshbuf_get_u16(p1, &v16);
174 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
175 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
176 sshbuf_free(p1);
177 TEST_DONE();
178
179 TEST_START("sshbuf_get_u8");
180 p1 = sshbuf_new();
181 ASSERT_PTR_NE(p1, NULL);
182 ASSERT_INT_EQ(sshbuf_put(p1, x, 2), 0);
183 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
184 ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0);
185 ASSERT_U8_EQ(v8, 0x11);
186 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
187 ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0);
188 ASSERT_U8_EQ(v8, 0x22);
189 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
190 TEST_DONE();
191
192 TEST_START("sshbuf_get_u8 truncated");
193 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
194 r = sshbuf_get_u8(p1, &v8);
195 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
196 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
197 sshbuf_free(p1);
198 TEST_DONE();
199
200 TEST_START("sshbuf_put_u64");
201 p1 = sshbuf_new();
202 ASSERT_PTR_NE(p1, NULL);
203 ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0);
204 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8);
205 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8);
206 sshbuf_free(p1);
207 TEST_DONE();
208
209 TEST_START("sshbuf_put_u64 exact");
210 p1 = sshbuf_new();
211 ASSERT_PTR_NE(p1, NULL);
212 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 8), 0);
213 ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0);
214 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8);
215 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8);
216 sshbuf_free(p1);
217 TEST_DONE();
218
219 TEST_START("sshbuf_put_u64 limited");
220 p1 = sshbuf_new();
221 ASSERT_PTR_NE(p1, NULL);
222 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 7), 0);
223 r = sshbuf_put_u64(p1, 0x1122334455667788ULL);
224 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
225 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
226 sshbuf_free(p1);
227 TEST_DONE();
228
229 TEST_START("sshbuf_put_u32");
230 p1 = sshbuf_new();
231 ASSERT_PTR_NE(p1, NULL);
232 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0);
233 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
234 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4);
235 sshbuf_free(p1);
236 TEST_DONE();
237
238 TEST_START("sshbuf_put_u32 exact");
239 p1 = sshbuf_new();
240 ASSERT_PTR_NE(p1, NULL);
241 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0);
242 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0);
243 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
244 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4);
245 sshbuf_free(p1);
246 TEST_DONE();
247
248 TEST_START("sshbuf_put_u32 limited");
249 p1 = sshbuf_new();
250 ASSERT_PTR_NE(p1, NULL);
251 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 3), 0);
252 r = sshbuf_put_u32(p1, 0x11223344);
253 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
254 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
255 sshbuf_free(p1);
256 TEST_DONE();
257
258 TEST_START("sshbuf_put_u16");
259 p1 = sshbuf_new();
260 ASSERT_PTR_NE(p1, NULL);
261 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0);
262 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
263 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2);
264 sshbuf_free(p1);
265 TEST_DONE();
266
267 TEST_START("sshbuf_put_u16");
268 p1 = sshbuf_new();
269 ASSERT_PTR_NE(p1, NULL);
270 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 2), 0);
271 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0);
272 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
273 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2);
274 sshbuf_free(p1);
275 TEST_DONE();
276
277 TEST_START("sshbuf_put_u16 limited");
278 p1 = sshbuf_new();
279 ASSERT_PTR_NE(p1, NULL);
280 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1), 0);
281 r = sshbuf_put_u16(p1, 0x1122);
282 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
283 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
284 sshbuf_free(p1);
285 TEST_DONE();
286
287 TEST_START("sshbuf_get_string");
288 p1 = sshbuf_new();
289 ASSERT_PTR_NE(p1, NULL);
290 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
291 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
292 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
293 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 + 4);
294 ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0);
295 ASSERT_SIZE_T_EQ(s, sizeof(x));
296 ASSERT_MEM_EQ(d, x, sizeof(x));
297 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
298 free(d);
299 sshbuf_free(p1);
300 TEST_DONE();
301
302 TEST_START("sshbuf_get_string exact");
303 p1 = sshbuf_new();
304 ASSERT_PTR_NE(p1, NULL);
305 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4), 0);
306 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
307 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
308 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
309 ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0);
310 ASSERT_SIZE_T_EQ(s, sizeof(x));
311 ASSERT_MEM_EQ(d, x, sizeof(x));
312 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
313 free(d);
314 sshbuf_free(p1);
315 TEST_DONE();
316
317 TEST_START("sshbuf_get_string truncated");
318 p1 = sshbuf_new();
319 ASSERT_PTR_NE(p1, NULL);
320 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
321 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
322 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
323 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
324 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3);
325 r = sshbuf_get_string(p1, &d, &s);
326 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
327 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3);
328 sshbuf_free(p1);
329 TEST_DONE();
330
331 TEST_START("sshbuf_get_string giant");
332 p1 = sshbuf_new();
333 ASSERT_PTR_NE(p1, NULL);
334 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0);
335 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
336 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
337 r = sshbuf_get_string(p1, &d, &s);
338 ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE);
339 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
340 sshbuf_free(p1);
341 TEST_DONE();
342
343 TEST_START("sshbuf_get_cstring giant");
344 p1 = sshbuf_new();
345 ASSERT_PTR_NE(p1, NULL);
346 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0);
347 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
348 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
349 r = sshbuf_get_cstring(p1, &s2, &s);
350 ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE);
351 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
352 sshbuf_free(p1);
353 TEST_DONE();
354
355 TEST_START("sshbuf_get_cstring embedded \\0");
356 p1 = sshbuf_new();
357 ASSERT_PTR_NE(p1, NULL);
358 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
359 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
360 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
361 r = sshbuf_get_cstring(p1, &s2, NULL);
362 ASSERT_INT_EQ(r, SSH_ERR_INVALID_FORMAT);
363 sshbuf_free(p1);
364 TEST_DONE();
365
366 TEST_START("sshbuf_get_cstring trailing \\0");
367 p1 = sshbuf_new();
368 ASSERT_PTR_NE(p1, NULL);
369 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x) - 1), 0);
370 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x) - 1), 0);
371 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 - 1);
372 ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s2, &s), 0);
373 ASSERT_SIZE_T_EQ(s, sizeof(x) - 1);
374 ASSERT_MEM_EQ(s2, x, s);
375 free(s2);
376 sshbuf_free(p1);
377 TEST_DONE();
378
379 TEST_START("sshbuf_put_string");
380 p1 = sshbuf_new();
381 ASSERT_PTR_NE(p1, NULL);
382 ASSERT_INT_EQ(sshbuf_put_string(p1, x, sizeof(x)), 0);
383 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
384 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), sizeof(x));
385 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, x, sizeof(x));
386 sshbuf_free(p1);
387 TEST_DONE();
388
389 TEST_START("sshbuf_put_string limited");
390 p1 = sshbuf_new();
391 ASSERT_PTR_NE(p1, NULL);
392 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4 - 1), 0);
393 r = sshbuf_put_string(p1, x, sizeof(x));
394 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
395 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
396 sshbuf_free(p1);
397 TEST_DONE();
398
399 TEST_START("sshbuf_put_string giant");
400 p1 = sshbuf_new();
401 ASSERT_PTR_NE(p1, NULL);
402 r = sshbuf_put_string(p1, (void *)0x01, 0xfffffffc);
403 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
404 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
405 sshbuf_free(p1);
406 TEST_DONE();
407
408 TEST_START("sshbuf_putf");
409 p1 = sshbuf_new();
410 ASSERT_PTR_NE(p1, NULL);
411 r = sshbuf_putf(p1, "%s %d %x", "hello", 23, 0x5f);
412 ASSERT_INT_EQ(r, 0);
413 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 11);
414 ASSERT_MEM_EQ(sshbuf_ptr(p1), "hello 23 5f", 11);
415 sshbuf_free(p1);
416 TEST_DONE();
417
418 TEST_START("sshbuf_putb");
419 p1 = sshbuf_new();
420 ASSERT_PTR_NE(p1, NULL);
421 p2 = sshbuf_new();
422 ASSERT_PTR_NE(p2, NULL);
423 ASSERT_INT_EQ(sshbuf_put(p1, "blahblahblah", 12), 0);
424 ASSERT_INT_EQ(sshbuf_putb(p2, p1), 0);
425 sshbuf_free(p1);
426 ASSERT_SIZE_T_EQ(sshbuf_len(p2), 12);
427 ASSERT_MEM_EQ(sshbuf_ptr(p2), "blahblahblah", 12);
428 sshbuf_free(p2);
429 TEST_DONE();
430
431 TEST_START("sshbuf_put_bignum2_bytes empty buf");
432 p1 = sshbuf_new();
433 ASSERT_PTR_NE(p1, NULL);
434 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, NULL, 0), 0);
435 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1));
436 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1));
437 sshbuf_free(p1);
438 TEST_DONE();
439
440 TEST_START("sshbuf_put_bignum2_bytes all zeroes");
441 p1 = sshbuf_new();
442 ASSERT_PTR_NE(p1, NULL);
443 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn1, sizeof(bn1)), 0);
444 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1));
445 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1));
446 sshbuf_free(p1);
447 TEST_DONE();
448
449 TEST_START("sshbuf_put_bignum2_bytes simple");
450 p1 = sshbuf_new();
451 ASSERT_PTR_NE(p1, NULL);
452 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2+2, sizeof(bn2)-2), 0);
453 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2));
454 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2));
455 sshbuf_free(p1);
456 TEST_DONE();
457
458 TEST_START("sshbuf_put_bignum2_bytes leading zero");
459 p1 = sshbuf_new();
460 ASSERT_PTR_NE(p1, NULL);
461 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2, sizeof(bn2)), 0);
462 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2));
463 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2));
464 sshbuf_free(p1);
465 TEST_DONE();
466
467 TEST_START("sshbuf_put_bignum2_bytes neg");
468 p1 = sshbuf_new();
469 ASSERT_PTR_NE(p1, NULL);
470 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3+1, sizeof(bn3)-1), 0);
471 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3));
472 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
473 sshbuf_free(p1);
474 TEST_DONE();
475
476 TEST_START("sshbuf_put_bignum2_bytes neg and leading zero");
477 p1 = sshbuf_new();
478 ASSERT_PTR_NE(p1, NULL);
479 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3, sizeof(bn3)), 0);
480 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3));
481 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
482 sshbuf_free(p1);
483 TEST_DONE();
484}
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..0c4c71ecd
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
@@ -0,0 +1,409 @@
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 "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14# include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include <openssl/bn.h>
20#include <openssl/objects.h>
21#ifdef OPENSSL_HAS_NISTP256
22# include <openssl/ec.h>
23#endif
24
25#include "../test_helper/test_helper.h"
26#include "ssherr.h"
27#include "sshbuf.h"
28
29void sshbuf_getput_crypto_tests(void);
30
31void
32sshbuf_getput_crypto_tests(void)
33{
34 struct sshbuf *p1;
35 const u_char *d;
36 size_t s;
37 BIGNUM *bn, *bn2;
38 /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */
39 const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10";
40 /* This one has MSB set to test bignum2 encoding negative-avoidance */
41 const char *hexbn2 = "f0e0d0c0b0a0908070605040302010007fff11";
42 u_char expbn1[] = {
43 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
44 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
45 };
46 u_char expbn2[] = {
47 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
48 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
49 0x7f, 0xff, 0x11
50 };
51#ifdef OPENSSL_HAS_NISTP256
52 BIGNUM *bn_x, *bn_y;
53 int ec256_nid = NID_X9_62_prime256v1;
54 char *ec256_x = "0C828004839D0106AA59575216191357"
55 "34B451459DADB586677EF9DF55784999";
56 char *ec256_y = "4D196B50F0B4E94B3C73E3A9D4CD9DF2"
57 "C8F9A35E42BDD047550F69D80EC23CD4";
58 u_char expec256[] = {
59 0x04,
60 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
61 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
62 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
63 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
64 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
65 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
66 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
67 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4
68 };
69 EC_KEY *eck;
70 EC_POINT *ecp;
71#endif
72 int r;
73
74#define MKBN(b, bnn) \
75 do { \
76 bnn = NULL; \
77 ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \
78 } while (0)
79
80 TEST_START("sshbuf_put_bignum1");
81 MKBN(hexbn1, bn);
82 p1 = sshbuf_new();
83 ASSERT_PTR_NE(p1, NULL);
84 ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
85 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 2);
86 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
87 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn1, sizeof(expbn1));
88 BN_free(bn);
89 sshbuf_free(p1);
90 TEST_DONE();
91
92 TEST_START("sshbuf_put_bignum1 limited");
93 MKBN(hexbn1, bn);
94 p1 = sshbuf_new();
95 ASSERT_PTR_NE(p1, NULL);
96 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
97 r = sshbuf_put_bignum1(p1, bn);
98 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
99 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
100 BN_free(bn);
101 sshbuf_free(p1);
102 TEST_DONE();
103
104 TEST_START("sshbuf_put_bignum1 bn2");
105 MKBN(hexbn2, bn);
106 p1 = sshbuf_new();
107 ASSERT_PTR_NE(p1, NULL);
108 ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
109 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 2);
110 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
111 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn2, sizeof(expbn2));
112 BN_free(bn);
113 sshbuf_free(p1);
114 TEST_DONE();
115
116 TEST_START("sshbuf_put_bignum1 bn2 limited");
117 MKBN(hexbn2, bn);
118 p1 = sshbuf_new();
119 ASSERT_PTR_NE(p1, NULL);
120 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
121 r = sshbuf_put_bignum1(p1, bn);
122 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
123 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
124 BN_free(bn);
125 sshbuf_free(p1);
126 TEST_DONE();
127
128 TEST_START("sshbuf_put_bignum2");
129 MKBN(hexbn1, bn);
130 p1 = sshbuf_new();
131 ASSERT_PTR_NE(p1, NULL);
132 ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
133 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4);
134 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn));
135 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1));
136 BN_free(bn);
137 sshbuf_free(p1);
138 TEST_DONE();
139
140 TEST_START("sshbuf_put_bignum2 limited");
141 MKBN(hexbn1, bn);
142 p1 = sshbuf_new();
143 ASSERT_PTR_NE(p1, NULL);
144 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 3), 0);
145 r = sshbuf_put_bignum2(p1, bn);
146 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
147 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
148 BN_free(bn);
149 sshbuf_free(p1);
150 TEST_DONE();
151
152 TEST_START("sshbuf_put_bignum2 bn2");
153 MKBN(hexbn2, bn);
154 p1 = sshbuf_new();
155 ASSERT_PTR_NE(p1, NULL);
156 ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
157 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */
158 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1);
159 ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00);
160 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2));
161 BN_free(bn);
162 sshbuf_free(p1);
163 TEST_DONE();
164
165 TEST_START("sshbuf_put_bignum2 bn2 limited");
166 MKBN(hexbn2, bn);
167 p1 = sshbuf_new();
168 ASSERT_PTR_NE(p1, NULL);
169 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn2) + 3), 0);
170 r = sshbuf_put_bignum2(p1, bn);
171 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
172 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
173 BN_free(bn);
174 sshbuf_free(p1);
175 TEST_DONE();
176
177 TEST_START("sshbuf_get_bignum1");
178 MKBN(hexbn1, bn);
179 p1 = sshbuf_new();
180 ASSERT_PTR_NE(p1, NULL);
181 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
182 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
183 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1));
184 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
185 bn2 = BN_new();
186 ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
187 ASSERT_BIGNUM_EQ(bn, bn2);
188 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
189 BN_free(bn);
190 BN_free(bn2);
191 sshbuf_free(p1);
192 TEST_DONE();
193
194 TEST_START("sshbuf_get_bignum1 truncated");
195 MKBN(hexbn1, bn);
196 p1 = sshbuf_new();
197 ASSERT_PTR_NE(p1, NULL);
198 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
199 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
200 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
201 bn2 = BN_new();
202 r = sshbuf_get_bignum1(p1, bn2);
203 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
204 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
205 BN_free(bn);
206 BN_free(bn2);
207 sshbuf_free(p1);
208 TEST_DONE();
209
210 TEST_START("sshbuf_get_bignum1 giant");
211 MKBN(hexbn1, bn);
212 p1 = sshbuf_new();
213 ASSERT_PTR_NE(p1, NULL);
214 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xffff), 0);
215 ASSERT_INT_EQ(sshbuf_reserve(p1, (0xffff + 7) / 8, NULL), 0);
216 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
217 bn2 = BN_new();
218 r = sshbuf_get_bignum1(p1, bn2);
219 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
220 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
221 BN_free(bn);
222 BN_free(bn2);
223 sshbuf_free(p1);
224 TEST_DONE();
225
226 TEST_START("sshbuf_get_bignum1 bn2");
227 MKBN(hexbn2, bn);
228 p1 = sshbuf_new();
229 ASSERT_PTR_NE(p1, NULL);
230 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
231 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
232 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2));
233 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
234 bn2 = BN_new();
235 ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
236 ASSERT_BIGNUM_EQ(bn, bn2);
237 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
238 BN_free(bn);
239 BN_free(bn2);
240 sshbuf_free(p1);
241 TEST_DONE();
242
243 TEST_START("sshbuf_get_bignum1 bn2 truncated");
244 MKBN(hexbn2, bn);
245 p1 = sshbuf_new();
246 ASSERT_PTR_NE(p1, NULL);
247 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
248 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
249 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
250 bn2 = BN_new();
251 r = sshbuf_get_bignum1(p1, bn2);
252 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
253 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
254 BN_free(bn);
255 BN_free(bn2);
256 sshbuf_free(p1);
257 TEST_DONE();
258
259 TEST_START("sshbuf_get_bignum2");
260 MKBN(hexbn1, bn);
261 p1 = sshbuf_new();
262 ASSERT_PTR_NE(p1, NULL);
263 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
264 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
265 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + sizeof(expbn1));
266 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
267 bn2 = BN_new();
268 ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
269 ASSERT_BIGNUM_EQ(bn, bn2);
270 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
271 BN_free(bn);
272 BN_free(bn2);
273 sshbuf_free(p1);
274 TEST_DONE();
275
276 TEST_START("sshbuf_get_bignum2 truncated");
277 MKBN(hexbn1, bn);
278 p1 = sshbuf_new();
279 ASSERT_PTR_NE(p1, NULL);
280 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
281 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
282 bn2 = BN_new();
283 r = sshbuf_get_bignum2(p1, bn2);
284 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
285 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 3);
286 BN_free(bn);
287 BN_free(bn2);
288 sshbuf_free(p1);
289 TEST_DONE();
290
291 TEST_START("sshbuf_get_bignum2 giant");
292 MKBN(hexbn1, bn);
293 p1 = sshbuf_new();
294 ASSERT_PTR_NE(p1, NULL);
295 ASSERT_INT_EQ(sshbuf_put_u32(p1, 65536), 0);
296 ASSERT_INT_EQ(sshbuf_reserve(p1, 65536, NULL), 0);
297 bn2 = BN_new();
298 r = sshbuf_get_bignum2(p1, bn2);
299 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
300 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 65536 + 4);
301 BN_free(bn);
302 BN_free(bn2);
303 sshbuf_free(p1);
304 TEST_DONE();
305
306 TEST_START("sshbuf_get_bignum2 bn2");
307 MKBN(hexbn2, bn);
308 p1 = sshbuf_new();
309 ASSERT_PTR_NE(p1, NULL);
310 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); /* MSB */
311 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
312 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
313 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + 1 + sizeof(expbn2));
314 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
315 bn2 = BN_new();
316 ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
317 ASSERT_BIGNUM_EQ(bn, bn2);
318 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
319 BN_free(bn);
320 BN_free(bn2);
321 sshbuf_free(p1);
322 TEST_DONE();
323
324 TEST_START("sshbuf_get_bignum2 bn2 truncated");
325 MKBN(hexbn2, bn);
326 p1 = sshbuf_new();
327 ASSERT_PTR_NE(p1, NULL);
328 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0);
329 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
330 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
331 bn2 = BN_new();
332 r = sshbuf_get_bignum2(p1, bn2);
333 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
334 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 1 + 4 - 1);
335 BN_free(bn);
336 BN_free(bn2);
337 sshbuf_free(p1);
338 TEST_DONE();
339
340 TEST_START("sshbuf_get_bignum2 bn2 negative");
341 MKBN(hexbn2, bn);
342 p1 = sshbuf_new();
343 ASSERT_PTR_NE(p1, NULL);
344 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
345 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
346 bn2 = BN_new();
347 r = sshbuf_get_bignum2(p1, bn2);
348 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_IS_NEGATIVE);
349 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4);
350 BN_free(bn);
351 BN_free(bn2);
352 sshbuf_free(p1);
353 TEST_DONE();
354
355#ifdef OPENSSL_HAS_NISTP256
356 TEST_START("sshbuf_put_ec");
357 eck = EC_KEY_new_by_curve_name(ec256_nid);
358 ASSERT_PTR_NE(eck, NULL);
359 ecp = EC_POINT_new(EC_KEY_get0_group(eck));
360 ASSERT_PTR_NE(ecp, NULL);
361 MKBN(ec256_x, bn_x);
362 MKBN(ec256_y, bn_y);
363 ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp(
364 EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1);
365 ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1);
366 BN_free(bn_x);
367 BN_free(bn_y);
368 EC_POINT_free(ecp);
369 p1 = sshbuf_new();
370 ASSERT_PTR_NE(p1, NULL);
371 ASSERT_INT_EQ(sshbuf_put_eckey(p1, eck), 0);
372 ASSERT_INT_EQ(sshbuf_get_string_direct(p1, &d, &s), 0);
373 ASSERT_SIZE_T_EQ(s, sizeof(expec256));
374 ASSERT_MEM_EQ(d, expec256, sizeof(expec256));
375 sshbuf_free(p1);
376 EC_KEY_free(eck);
377 TEST_DONE();
378
379 TEST_START("sshbuf_get_ec");
380 eck = EC_KEY_new_by_curve_name(ec256_nid);
381 ASSERT_PTR_NE(eck, NULL);
382 p1 = sshbuf_new();
383 ASSERT_PTR_NE(p1, NULL);
384 ASSERT_INT_EQ(sshbuf_put_string(p1, expec256, sizeof(expec256)), 0);
385 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expec256) + 4);
386 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
387 ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0);
388 bn_x = BN_new();
389 bn_y = BN_new();
390 ASSERT_PTR_NE(bn_x, NULL);
391 ASSERT_PTR_NE(bn_y, NULL);
392 ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp(
393 EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck),
394 bn_x, bn_y, NULL), 1);
395 MKBN(ec256_x, bn);
396 MKBN(ec256_y, bn2);
397 ASSERT_INT_EQ(BN_cmp(bn_x, bn), 0);
398 ASSERT_INT_EQ(BN_cmp(bn_y, bn2), 0);
399 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
400 sshbuf_free(p1);
401 EC_KEY_free(eck);
402 BN_free(bn_x);
403 BN_free(bn_y);
404 BN_free(bn);
405 BN_free(bn2);
406 TEST_DONE();
407#endif
408}
409
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..8c3269b13
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
@@ -0,0 +1,130 @@
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 "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14# include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include <openssl/bn.h>
20#include <openssl/objects.h>
21#ifdef OPENSSL_HAS_NISTP256
22# include <openssl/ec.h>
23#endif
24
25#include "../test_helper/test_helper.h"
26#include "ssherr.h"
27#include "sshbuf.h"
28
29void sshbuf_getput_fuzz_tests(void);
30
31static void
32attempt_parse_blob(u_char *blob, size_t len)
33{
34 struct sshbuf *p1;
35 BIGNUM *bn;
36#ifdef OPENSSL_HAS_NISTP256
37 EC_KEY *eck;
38#endif
39 u_char *s;
40 size_t l;
41 u_int8_t u8;
42 u_int16_t u16;
43 u_int32_t u32;
44 u_int64_t u64;
45
46 p1 = sshbuf_new();
47 ASSERT_PTR_NE(p1, NULL);
48 ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0);
49 sshbuf_get_u8(p1, &u8);
50 sshbuf_get_u16(p1, &u16);
51 sshbuf_get_u32(p1, &u32);
52 sshbuf_get_u64(p1, &u64);
53 if (sshbuf_get_string(p1, &s, &l) == 0) {
54 bzero(s, l);
55 free(s);
56 }
57 bn = BN_new();
58 sshbuf_get_bignum1(p1, bn);
59 BN_clear_free(bn);
60 bn = BN_new();
61 sshbuf_get_bignum2(p1, bn);
62 BN_clear_free(bn);
63#ifdef OPENSSL_HAS_NISTP256
64 eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
65 ASSERT_PTR_NE(eck, NULL);
66 sshbuf_get_eckey(p1, eck);
67 EC_KEY_free(eck);
68#endif
69 sshbuf_free(p1);
70}
71
72
73static void
74onerror(void *fuzz)
75{
76 fprintf(stderr, "Failed during fuzz:\n");
77 fuzz_dump((struct fuzz *)fuzz);
78}
79
80void
81sshbuf_getput_fuzz_tests(void)
82{
83 u_char blob[] = {
84 /* u8 */
85 0xd0,
86 /* u16 */
87 0xc0, 0xde,
88 /* u32 */
89 0xfa, 0xce, 0xde, 0xad,
90 /* u64 */
91 0xfe, 0xed, 0xac, 0x1d, 0x1f, 0x1c, 0xbe, 0xef,
92 /* string */
93 0x00, 0x00, 0x00, 0x09,
94 'O', ' ', 'G', 'o', 'r', 'g', 'o', 'n', '!',
95 /* bignum1 */
96 0x79,
97 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
98 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
99 /* bignum2 */
100 0x00, 0x00, 0x00, 0x14,
101 0x00,
102 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
103 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
104 0x7f, 0xff, 0x11,
105 /* EC point (NIST-256 curve) */
106 0x00, 0x00, 0x00, 0x41,
107 0x04,
108 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
109 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
110 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
111 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
112 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
113 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
114 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
115 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4,
116 };
117 struct fuzz *fuzz;
118
119 TEST_START("fuzz blob parsing");
120 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP |
121 FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
122 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, blob, sizeof(blob));
123 TEST_ONERROR(onerror, fuzz);
124 for(; !fuzz_done(fuzz); fuzz_next(fuzz))
125 attempt_parse_blob(blob, sizeof(blob));
126 fuzz_cleanup(fuzz);
127 TEST_DONE();
128 TEST_ONERROR(NULL, NULL);
129}
130
diff --git a/regress/unittests/sshbuf/test_sshbuf_misc.c b/regress/unittests/sshbuf/test_sshbuf_misc.c
new file mode 100644
index 000000000..f155491a0
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_misc.c
@@ -0,0 +1,138 @@
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 "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14# include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include "../test_helper/test_helper.h"
20
21#include "sshbuf.h"
22
23void sshbuf_misc_tests(void);
24
25void
26sshbuf_misc_tests(void)
27{
28 struct sshbuf *p1;
29 char tmp[512], *p;
30 FILE *out;
31 size_t sz;
32
33 TEST_START("sshbuf_dump");
34 out = tmpfile();
35 ASSERT_PTR_NE(out, NULL);
36 p1 = sshbuf_new();
37 ASSERT_PTR_NE(p1, NULL);
38 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
39 sshbuf_dump(p1, out);
40 fflush(out);
41 rewind(out);
42 sz = fread(tmp, 1, sizeof(tmp), out);
43 ASSERT_INT_EQ(ferror(out), 0);
44 ASSERT_INT_NE(feof(out), 0);
45 ASSERT_SIZE_T_GT(sz, 0);
46 tmp[sz] = '\0';
47 ASSERT_PTR_NE(strstr(tmp, "12 34 56 78"), NULL);
48 fclose(out);
49 sshbuf_free(p1);
50 TEST_DONE();
51
52 TEST_START("sshbuf_dtob16");
53 p1 = sshbuf_new();
54 ASSERT_PTR_NE(p1, NULL);
55 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
56 p = sshbuf_dtob16(p1);
57 ASSERT_PTR_NE(p, NULL);
58 ASSERT_STRING_EQ(p, "12345678");
59 free(p);
60 sshbuf_free(p1);
61 TEST_DONE();
62
63 TEST_START("sshbuf_dtob64 len 1");
64 p1 = sshbuf_new();
65 ASSERT_PTR_NE(p1, NULL);
66 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
67 p = sshbuf_dtob64(p1);
68 ASSERT_PTR_NE(p, NULL);
69 ASSERT_STRING_EQ(p, "EQ==");
70 free(p);
71 sshbuf_free(p1);
72 TEST_DONE();
73
74 TEST_START("sshbuf_dtob64 len 2");
75 p1 = sshbuf_new();
76 ASSERT_PTR_NE(p1, NULL);
77 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
78 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
79 p = sshbuf_dtob64(p1);
80 ASSERT_PTR_NE(p, NULL);
81 ASSERT_STRING_EQ(p, "ESI=");
82 free(p);
83 sshbuf_free(p1);
84 TEST_DONE();
85
86 TEST_START("sshbuf_dtob64 len 3");
87 p1 = sshbuf_new();
88 ASSERT_PTR_NE(p1, NULL);
89 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
90 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
91 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x33), 0);
92 p = sshbuf_dtob64(p1);
93 ASSERT_PTR_NE(p, NULL);
94 ASSERT_STRING_EQ(p, "ESIz");
95 free(p);
96 sshbuf_free(p1);
97 TEST_DONE();
98
99 TEST_START("sshbuf_dtob64 len 8191");
100 p1 = sshbuf_new();
101 ASSERT_PTR_NE(p1, NULL);
102 ASSERT_INT_EQ(sshbuf_reserve(p1, 8192, NULL), 0);
103 bzero(sshbuf_mutable_ptr(p1), 8192);
104 p = sshbuf_dtob64(p1);
105 ASSERT_PTR_NE(p, NULL);
106 ASSERT_SIZE_T_EQ(strlen(p), ((8191 + 2) / 3) * 4);
107 free(p);
108 sshbuf_free(p1);
109 TEST_DONE();
110
111 TEST_START("sshbuf_b64tod len 1");
112 p1 = sshbuf_new();
113 ASSERT_PTR_NE(p1, NULL);
114 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A=="), 0);
115 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
116 ASSERT_U8_EQ(*sshbuf_ptr(p1), 0xd0);
117 sshbuf_free(p1);
118 TEST_DONE();
119
120 TEST_START("sshbuf_b64tod len 2");
121 p1 = sshbuf_new();
122 ASSERT_PTR_NE(p1, NULL);
123 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A8="), 0);
124 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
125 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), 0xd00f);
126 sshbuf_free(p1);
127 TEST_DONE();
128
129 TEST_START("sshbuf_b64tod len 4");
130 p1 = sshbuf_new();
131 ASSERT_PTR_NE(p1, NULL);
132 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A/QDw=="), 0);
133 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
134 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), 0xd00fd00f);
135 sshbuf_free(p1);
136 TEST_DONE();
137}
138
diff --git a/regress/unittests/sshbuf/tests.c b/regress/unittests/sshbuf/tests.c
new file mode 100644
index 000000000..1557e4342
--- /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/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}