1 /* $OpenBSD: test_sshbuf_misc.c,v 1.4 2019/07/16 22:16:49 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 #include "ssherr.h"
23
24 void sshbuf_misc_tests(void);
25
26 void
sshbuf_misc_tests(void)27 sshbuf_misc_tests(void)
28 {
29 struct sshbuf *p1;
30 char tmp[512], msg[] = "imploring ping silence ping over", *p;
31 FILE *out;
32 size_t sz;
33
34 TEST_START("sshbuf_dump");
35 out = tmpfile();
36 ASSERT_PTR_NE(out, NULL);
37 p1 = sshbuf_new();
38 ASSERT_PTR_NE(p1, NULL);
39 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
40 sshbuf_dump(p1, out);
41 fflush(out);
42 rewind(out);
43 sz = fread(tmp, 1, sizeof(tmp), out);
44 ASSERT_INT_EQ(ferror(out), 0);
45 ASSERT_INT_NE(feof(out), 0);
46 ASSERT_SIZE_T_GT(sz, 0);
47 tmp[sz] = '\0';
48 ASSERT_PTR_NE(strstr(tmp, "12 34 56 78"), NULL);
49 fclose(out);
50 sshbuf_free(p1);
51 TEST_DONE();
52
53 TEST_START("sshbuf_dtob16");
54 p1 = sshbuf_new();
55 ASSERT_PTR_NE(p1, NULL);
56 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
57 p = sshbuf_dtob16(p1);
58 ASSERT_PTR_NE(p, NULL);
59 ASSERT_STRING_EQ(p, "12345678");
60 free(p);
61 sshbuf_free(p1);
62 TEST_DONE();
63
64 TEST_START("sshbuf_dtob64_string len 1");
65 p1 = sshbuf_new();
66 ASSERT_PTR_NE(p1, NULL);
67 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
68 p = sshbuf_dtob64_string(p1, 0);
69 ASSERT_PTR_NE(p, NULL);
70 ASSERT_STRING_EQ(p, "EQ==");
71 free(p);
72 sshbuf_free(p1);
73 TEST_DONE();
74
75 TEST_START("sshbuf_dtob64_string len 2");
76 p1 = sshbuf_new();
77 ASSERT_PTR_NE(p1, NULL);
78 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
79 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
80 p = sshbuf_dtob64_string(p1, 0);
81 ASSERT_PTR_NE(p, NULL);
82 ASSERT_STRING_EQ(p, "ESI=");
83 free(p);
84 sshbuf_free(p1);
85 TEST_DONE();
86
87 TEST_START("sshbuf_dtob64_string len 3");
88 p1 = sshbuf_new();
89 ASSERT_PTR_NE(p1, NULL);
90 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
91 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
92 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x33), 0);
93 p = sshbuf_dtob64_string(p1, 0);
94 ASSERT_PTR_NE(p, NULL);
95 ASSERT_STRING_EQ(p, "ESIz");
96 free(p);
97 sshbuf_free(p1);
98 TEST_DONE();
99
100 TEST_START("sshbuf_dtob64_string len 8191");
101 p1 = sshbuf_new();
102 ASSERT_PTR_NE(p1, NULL);
103 ASSERT_INT_EQ(sshbuf_reserve(p1, 8192, NULL), 0);
104 bzero(sshbuf_mutable_ptr(p1), 8192);
105 p = sshbuf_dtob64_string(p1, 0);
106 ASSERT_PTR_NE(p, NULL);
107 ASSERT_SIZE_T_EQ(strlen(p), ((8191 + 2) / 3) * 4);
108 free(p);
109 sshbuf_free(p1);
110 TEST_DONE();
111
112 TEST_START("sshbuf_b64tod len 1");
113 p1 = sshbuf_new();
114 ASSERT_PTR_NE(p1, NULL);
115 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A=="), 0);
116 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
117 ASSERT_U8_EQ(*sshbuf_ptr(p1), 0xd0);
118 sshbuf_free(p1);
119 TEST_DONE();
120
121 TEST_START("sshbuf_b64tod len 2");
122 p1 = sshbuf_new();
123 ASSERT_PTR_NE(p1, NULL);
124 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A8="), 0);
125 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
126 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), 0xd00f);
127 sshbuf_free(p1);
128 TEST_DONE();
129
130 TEST_START("sshbuf_b64tod len 4");
131 p1 = sshbuf_new();
132 ASSERT_PTR_NE(p1, NULL);
133 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A/QDw=="), 0);
134 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
135 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), 0xd00fd00f);
136 sshbuf_free(p1);
137 TEST_DONE();
138
139 TEST_START("sshbuf_dup_string");
140 p1 = sshbuf_new();
141 ASSERT_PTR_NE(p1, NULL);
142 /* Check empty buffer */
143 p = sshbuf_dup_string(p1);
144 ASSERT_PTR_NE(p, NULL);
145 ASSERT_SIZE_T_EQ(strlen(p), 0);
146 free(p);
147 /* Check buffer with string */
148 ASSERT_INT_EQ(sshbuf_put(p1, "quad1", strlen("quad1")), 0);
149 p = sshbuf_dup_string(p1);
150 ASSERT_PTR_NE(p, NULL);
151 ASSERT_SIZE_T_EQ(strlen(p), strlen("quad1"));
152 ASSERT_STRING_EQ(p, "quad1");
153 free(p);
154 /* Check buffer with terminating nul */
155 ASSERT_INT_EQ(sshbuf_put(p1, "\0", 1), 0);
156 p = sshbuf_dup_string(p1);
157 ASSERT_PTR_NE(p, NULL);
158 ASSERT_SIZE_T_EQ(strlen(p), strlen("quad1"));
159 ASSERT_STRING_EQ(p, "quad1");
160 free(p);
161 /* Check buffer with data after nul (expect failure) */
162 ASSERT_INT_EQ(sshbuf_put(p1, "quad2", strlen("quad2")), 0);
163 p = sshbuf_dup_string(p1);
164 ASSERT_PTR_EQ(p, NULL);
165 sshbuf_free(p1);
166 TEST_DONE();
167
168 TEST_START("sshbuf_cmp");
169 p1 = sshbuf_from(msg, sizeof(msg) - 1);
170 ASSERT_PTR_NE(p1, NULL);
171 ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "i", 1), 0);
172 ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "j", 1), SSH_ERR_INVALID_FORMAT);
173 ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "imploring", 9), 0);
174 ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "implored", 9), SSH_ERR_INVALID_FORMAT);
175 ASSERT_INT_EQ(sshbuf_cmp(p1, 10, "ping", 4), 0);
176 ASSERT_INT_EQ(sshbuf_cmp(p1, 10, "ring", 4), SSH_ERR_INVALID_FORMAT);
177 ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "over", 4), 0);
178 ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "rove", 4), SSH_ERR_INVALID_FORMAT);
179 ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "overt", 5),
180 SSH_ERR_MESSAGE_INCOMPLETE);
181 ASSERT_INT_EQ(sshbuf_cmp(p1, 32, "ping", 4),
182 SSH_ERR_MESSAGE_INCOMPLETE);
183 ASSERT_INT_EQ(sshbuf_cmp(p1, 1000, "silence", 7),
184 SSH_ERR_MESSAGE_INCOMPLETE);
185 ASSERT_INT_EQ(sshbuf_cmp(p1, 0, msg, sizeof(msg) - 1), 0);
186 TEST_DONE();
187
188 TEST_START("sshbuf_find");
189 p1 = sshbuf_from(msg, sizeof(msg) - 1);
190 ASSERT_PTR_NE(p1, NULL);
191 ASSERT_INT_EQ(sshbuf_find(p1, 0, "i", 1, &sz), 0);
192 ASSERT_SIZE_T_EQ(sz, 0);
193 ASSERT_INT_EQ(sshbuf_find(p1, 0, "j", 1, &sz), SSH_ERR_INVALID_FORMAT);
194 ASSERT_INT_EQ(sshbuf_find(p1, 0, "imploring", 9, &sz), 0);
195 ASSERT_SIZE_T_EQ(sz, 0);
196 ASSERT_INT_EQ(sshbuf_find(p1, 0, "implored", 9, &sz),
197 SSH_ERR_INVALID_FORMAT);
198 ASSERT_INT_EQ(sshbuf_find(p1, 3, "ping", 4, &sz), 0);
199 ASSERT_SIZE_T_EQ(sz, 10);
200 ASSERT_INT_EQ(sshbuf_find(p1, 11, "ping", 4, &sz), 0);
201 ASSERT_SIZE_T_EQ(sz, 23);
202 ASSERT_INT_EQ(sshbuf_find(p1, 20, "over", 4, &sz), 0);
203 ASSERT_SIZE_T_EQ(sz, 28);
204 ASSERT_INT_EQ(sshbuf_find(p1, 28, "over", 4, &sz), 0);
205 ASSERT_SIZE_T_EQ(sz, 28);
206 ASSERT_INT_EQ(sshbuf_find(p1, 28, "rove", 4, &sz),
207 SSH_ERR_INVALID_FORMAT);
208 ASSERT_INT_EQ(sshbuf_find(p1, 28, "overt", 5, &sz),
209 SSH_ERR_MESSAGE_INCOMPLETE);
210 ASSERT_INT_EQ(sshbuf_find(p1, 32, "ping", 4, &sz),
211 SSH_ERR_MESSAGE_INCOMPLETE);
212 ASSERT_INT_EQ(sshbuf_find(p1, 1000, "silence", 7, &sz),
213 SSH_ERR_MESSAGE_INCOMPLETE);
214 ASSERT_INT_EQ(sshbuf_find(p1, 0, msg + 1, sizeof(msg) - 2, &sz), 0);
215 ASSERT_SIZE_T_EQ(sz, 1);
216 TEST_DONE();
217 }
218
219