1 /* $OpenBSD: test_sshbuf.c,v 1.2 2021/12/14 21:25:27 deraadt 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 <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 void sshbuf_tests(void);
25
26 #ifndef roundup
27 #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
28 #endif
29
30 void
sshbuf_tests(void)31 sshbuf_tests(void)
32 {
33 struct sshbuf *p1;
34 const u_char *cdp;
35 u_char *dp;
36 size_t sz;
37 int r;
38
39 TEST_START("allocate sshbuf");
40 p1 = sshbuf_new();
41 ASSERT_PTR_NE(p1, NULL);
42 TEST_DONE();
43
44 TEST_START("max size on fresh buffer");
45 ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0);
46 TEST_DONE();
47
48 TEST_START("available on fresh buffer");
49 ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0);
50 TEST_DONE();
51
52 TEST_START("len = 0 on empty buffer");
53 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
54 TEST_DONE();
55
56 TEST_START("set valid max size");
57 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0);
58 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536);
59 TEST_DONE();
60
61 TEST_START("available on limited buffer");
62 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536);
63 TEST_DONE();
64
65 TEST_START("free");
66 sshbuf_free(p1);
67 TEST_DONE();
68
69 TEST_START("consume on empty buffer");
70 p1 = sshbuf_new();
71 ASSERT_PTR_NE(p1, NULL);
72 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
73 ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
74 sshbuf_free(p1);
75 TEST_DONE();
76
77 TEST_START("consume_end on empty buffer");
78 p1 = sshbuf_new();
79 ASSERT_PTR_NE(p1, NULL);
80 ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0);
81 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
82 sshbuf_free(p1);
83 TEST_DONE();
84
85 TEST_START("reserve space");
86 p1 = sshbuf_new();
87 ASSERT_PTR_NE(p1, NULL);
88 r = sshbuf_reserve(p1, 1, &dp);
89 ASSERT_INT_EQ(r, 0);
90 ASSERT_PTR_NE(dp, NULL);
91 *dp = 0x11;
92 r = sshbuf_reserve(p1, 3, &dp);
93 ASSERT_INT_EQ(r, 0);
94 ASSERT_PTR_NE(dp, NULL);
95 *dp++ = 0x22;
96 *dp++ = 0x33;
97 *dp++ = 0x44;
98 TEST_DONE();
99
100 TEST_START("sshbuf_len on filled buffer");
101 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
102 TEST_DONE();
103
104 TEST_START("sshbuf_ptr on filled buffer");
105 cdp = sshbuf_ptr(p1);
106 ASSERT_PTR_NE(cdp, NULL);
107 ASSERT_U8_EQ(cdp[0], 0x11);
108 ASSERT_U8_EQ(cdp[1], 0x22);
109 ASSERT_U8_EQ(cdp[2], 0x33);
110 ASSERT_U8_EQ(cdp[3], 0x44);
111 TEST_DONE();
112
113 TEST_START("consume on filled buffer");
114 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
115 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
116 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
117 r = sshbuf_consume(p1, 64);
118 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
119 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
120 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
121 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
122 cdp = sshbuf_ptr(p1);
123 ASSERT_PTR_NE(p1, NULL);
124 ASSERT_U8_EQ(cdp[0], 0x22);
125 ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0);
126 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
127 cdp = sshbuf_ptr(p1);
128 ASSERT_PTR_NE(p1, NULL);
129 ASSERT_U8_EQ(cdp[0], 0x44);
130 r = sshbuf_consume(p1, 2);
131 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
132 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
133 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
134 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
135 r = sshbuf_consume(p1, 1);
136 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
137 sshbuf_free(p1);
138 TEST_DONE();
139
140 TEST_START("consume_end on filled buffer");
141 p1 = sshbuf_new();
142 ASSERT_PTR_NE(p1, NULL);
143 r = sshbuf_reserve(p1, 4, &dp);
144 ASSERT_INT_EQ(r, 0);
145 ASSERT_PTR_NE(dp, NULL);
146 *dp++ = 0x11;
147 *dp++ = 0x22;
148 *dp++ = 0x33;
149 *dp++ = 0x44;
150 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
151 r = sshbuf_consume_end(p1, 5);
152 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
153 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
154 ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0);
155 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
156 cdp = sshbuf_ptr(p1);
157 ASSERT_PTR_NE(cdp, NULL);
158 ASSERT_U8_EQ(*cdp, 0x11);
159 r = sshbuf_consume_end(p1, 2);
160 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
161 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
162 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
163 sshbuf_free(p1);
164 TEST_DONE();
165
166 TEST_START("fill limited buffer");
167 p1 = sshbuf_new();
168 ASSERT_PTR_NE(p1, NULL);
169 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
170 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
171 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
172 r = sshbuf_reserve(p1, 1223, &dp);
173 ASSERT_INT_EQ(r, 0);
174 ASSERT_PTR_NE(dp, NULL);
175 memset(dp, 0xd7, 1223);
176 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
177 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
178 r = sshbuf_reserve(p1, 1, &dp);
179 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
180 ASSERT_PTR_EQ(dp, NULL);
181 TEST_DONE();
182
183 TEST_START("consume and force compaction");
184 ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0);
185 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
186 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
187 r = sshbuf_reserve(p1, 224, &dp);
188 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
189 ASSERT_PTR_EQ(dp, NULL);
190 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
191 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
192 r = sshbuf_reserve(p1, 223, &dp);
193 ASSERT_INT_EQ(r, 0);
194 ASSERT_PTR_NE(dp, NULL);
195 memset(dp, 0x7d, 223);
196 cdp = sshbuf_ptr(p1);
197 ASSERT_PTR_NE(cdp, NULL);
198 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
199 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
200 TEST_DONE();
201
202 TEST_START("resize full buffer");
203 r = sshbuf_set_max_size(p1, 1000);
204 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
205 sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC);
206 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0);
207 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
208 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223);
209 ASSERT_INT_EQ(sshbuf_len(p1), 1223);
210 TEST_DONE();
211
212 /* NB. uses sshbuf internals */
213 TEST_START("alloc chunking");
214 r = sshbuf_reserve(p1, 1, &dp);
215 ASSERT_INT_EQ(r, 0);
216 ASSERT_PTR_NE(dp, NULL);
217 *dp = 0xff;
218 cdp = sshbuf_ptr(p1);
219 ASSERT_PTR_NE(cdp, NULL);
220 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
221 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
222 ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1);
223 ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0);
224 sshbuf_free(p1);
225 TEST_DONE();
226
227 TEST_START("reset buffer");
228 p1 = sshbuf_new();
229 ASSERT_PTR_NE(p1, NULL);
230 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
231 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
232 r = sshbuf_reserve(p1, 1223, &dp);
233 ASSERT_INT_EQ(r, 0);
234 ASSERT_PTR_NE(dp, NULL);
235 memset(dp, 0xd7, 1223);
236 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
237 sshbuf_reset(p1);
238 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
239 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
240 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
241 sshbuf_free(p1);
242 TEST_DONE();
243 }
244