1 /* $OpenBSD: test_sshbuf_misc.c,v 1.5 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 #include "includes.h"
9
10 #include <sys/types.h>
11 #include <stdio.h>
12 #ifdef HAVE_STDINT_H
13 # include <stdint.h>
14 #endif
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include "../test_helper/test_helper.h"
19
20 #include "sshbuf.h"
21 #include "ssherr.h"
22
23 void sshbuf_misc_tests(void);
24
25 void
sshbuf_misc_tests(void)26 sshbuf_misc_tests(void)
27 {
28 struct sshbuf *p1;
29 char tmp[512], msg[] = "imploring ping silence ping over", *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_string 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_string(p1, 0);
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_string 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_string(p1, 0);
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_string 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_string(p1, 0);
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_string 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_string(p1, 0);
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 TEST_START("sshbuf_dup_string");
139 p1 = sshbuf_new();
140 ASSERT_PTR_NE(p1, NULL);
141 /* Check empty buffer */
142 p = sshbuf_dup_string(p1);
143 ASSERT_PTR_NE(p, NULL);
144 ASSERT_SIZE_T_EQ(strlen(p), 0);
145 free(p);
146 /* Check buffer with string */
147 ASSERT_INT_EQ(sshbuf_put(p1, "quad1", strlen("quad1")), 0);
148 p = sshbuf_dup_string(p1);
149 ASSERT_PTR_NE(p, NULL);
150 ASSERT_SIZE_T_EQ(strlen(p), strlen("quad1"));
151 ASSERT_STRING_EQ(p, "quad1");
152 free(p);
153 /* Check buffer with terminating nul */
154 ASSERT_INT_EQ(sshbuf_put(p1, "\0", 1), 0);
155 p = sshbuf_dup_string(p1);
156 ASSERT_PTR_NE(p, NULL);
157 ASSERT_SIZE_T_EQ(strlen(p), strlen("quad1"));
158 ASSERT_STRING_EQ(p, "quad1");
159 free(p);
160 /* Check buffer with data after nul (expect failure) */
161 ASSERT_INT_EQ(sshbuf_put(p1, "quad2", strlen("quad2")), 0);
162 p = sshbuf_dup_string(p1);
163 ASSERT_PTR_EQ(p, NULL);
164 sshbuf_free(p1);
165 TEST_DONE();
166
167 TEST_START("sshbuf_cmp");
168 p1 = sshbuf_from(msg, sizeof(msg) - 1);
169 ASSERT_PTR_NE(p1, NULL);
170 ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "i", 1), 0);
171 ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "j", 1), SSH_ERR_INVALID_FORMAT);
172 ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "imploring", 9), 0);
173 ASSERT_INT_EQ(sshbuf_cmp(p1, 0, "implored", 9), SSH_ERR_INVALID_FORMAT);
174 ASSERT_INT_EQ(sshbuf_cmp(p1, 10, "ping", 4), 0);
175 ASSERT_INT_EQ(sshbuf_cmp(p1, 10, "ring", 4), SSH_ERR_INVALID_FORMAT);
176 ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "over", 4), 0);
177 ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "rove", 4), SSH_ERR_INVALID_FORMAT);
178 ASSERT_INT_EQ(sshbuf_cmp(p1, 28, "overt", 5),
179 SSH_ERR_MESSAGE_INCOMPLETE);
180 ASSERT_INT_EQ(sshbuf_cmp(p1, 32, "ping", 4),
181 SSH_ERR_MESSAGE_INCOMPLETE);
182 ASSERT_INT_EQ(sshbuf_cmp(p1, 1000, "silence", 7),
183 SSH_ERR_MESSAGE_INCOMPLETE);
184 ASSERT_INT_EQ(sshbuf_cmp(p1, 0, msg, sizeof(msg) - 1), 0);
185 TEST_DONE();
186
187 TEST_START("sshbuf_find");
188 p1 = sshbuf_from(msg, sizeof(msg) - 1);
189 ASSERT_PTR_NE(p1, NULL);
190 ASSERT_INT_EQ(sshbuf_find(p1, 0, "i", 1, &sz), 0);
191 ASSERT_SIZE_T_EQ(sz, 0);
192 ASSERT_INT_EQ(sshbuf_find(p1, 0, "j", 1, &sz), SSH_ERR_INVALID_FORMAT);
193 ASSERT_INT_EQ(sshbuf_find(p1, 0, "imploring", 9, &sz), 0);
194 ASSERT_SIZE_T_EQ(sz, 0);
195 ASSERT_INT_EQ(sshbuf_find(p1, 0, "implored", 9, &sz),
196 SSH_ERR_INVALID_FORMAT);
197 ASSERT_INT_EQ(sshbuf_find(p1, 3, "ping", 4, &sz), 0);
198 ASSERT_SIZE_T_EQ(sz, 10);
199 ASSERT_INT_EQ(sshbuf_find(p1, 11, "ping", 4, &sz), 0);
200 ASSERT_SIZE_T_EQ(sz, 23);
201 ASSERT_INT_EQ(sshbuf_find(p1, 20, "over", 4, &sz), 0);
202 ASSERT_SIZE_T_EQ(sz, 28);
203 ASSERT_INT_EQ(sshbuf_find(p1, 28, "over", 4, &sz), 0);
204 ASSERT_SIZE_T_EQ(sz, 28);
205 ASSERT_INT_EQ(sshbuf_find(p1, 28, "rove", 4, &sz),
206 SSH_ERR_INVALID_FORMAT);
207 ASSERT_INT_EQ(sshbuf_find(p1, 28, "overt", 5, &sz),
208 SSH_ERR_MESSAGE_INCOMPLETE);
209 ASSERT_INT_EQ(sshbuf_find(p1, 32, "ping", 4, &sz),
210 SSH_ERR_MESSAGE_INCOMPLETE);
211 ASSERT_INT_EQ(sshbuf_find(p1, 1000, "silence", 7, &sz),
212 SSH_ERR_MESSAGE_INCOMPLETE);
213 ASSERT_INT_EQ(sshbuf_find(p1, 0, msg + 1, sizeof(msg) - 2, &sz), 0);
214 ASSERT_SIZE_T_EQ(sz, 1);
215 TEST_DONE();
216 }
217
218