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
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