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 
25 void sshbuf_tests(void);
26 
27 void
28 sshbuf_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 }
241