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