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