1/*
2 * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/packet.h"
11#include "testutil.h"
12
13#define BUF_LEN 255
14
15static unsigned char smbuf[BUF_LEN + 1];
16
17static int test_PACKET_remaining(void)
18{
19    PACKET pkt;
20
21    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
22            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN)
23            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 1))
24            || !TEST_size_t_eq(PACKET_remaining(&pkt), 1)
25            || !TEST_true(PACKET_forward(&pkt, 1))
26            || !TEST_size_t_eq(PACKET_remaining(&pkt), 0))
27        return 0;
28
29    return 1;
30}
31
32static int test_PACKET_end(void)
33{
34    PACKET pkt;
35
36    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
37            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN)
38            || !TEST_ptr_eq(PACKET_end(&pkt), smbuf + BUF_LEN)
39            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 1))
40            || !TEST_ptr_eq(PACKET_end(&pkt), smbuf + BUF_LEN)
41            || !TEST_true(PACKET_forward(&pkt, 1))
42            || !TEST_ptr_eq(PACKET_end(&pkt), smbuf + BUF_LEN))
43        return 0;
44
45    return 1;
46}
47
48static int test_PACKET_get_1(void)
49{
50    unsigned int i = 0;
51    PACKET pkt;
52
53    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
54            || !TEST_true(PACKET_get_1(&pkt, &i))
55            || !TEST_uint_eq(i, 0x02)
56            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 2))
57            || !TEST_true(PACKET_get_1(&pkt, &i))
58            || !TEST_uint_eq(i, 0xfe)
59            || !TEST_false(PACKET_get_1(&pkt, &i)))
60        return 0;
61
62    return 1;
63}
64
65static int test_PACKET_get_4(void)
66{
67    unsigned long i = 0;
68    PACKET pkt;
69
70    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
71            || !TEST_true(PACKET_get_4(&pkt, &i))
72            || !TEST_ulong_eq(i, 0x08060402UL)
73            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 8))
74            || !TEST_true(PACKET_get_4(&pkt, &i))
75            || !TEST_ulong_eq(i, 0xfefcfaf8UL)
76            || !TEST_false(PACKET_get_4(&pkt, &i)))
77        return 0;
78
79    return 1;
80}
81
82static int test_PACKET_get_net_2(void)
83{
84    unsigned int i = 0;
85    PACKET pkt;
86
87    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
88            || !TEST_true(PACKET_get_net_2(&pkt, &i))
89            || !TEST_uint_eq(i, 0x0204)
90            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 4))
91            || !TEST_true(PACKET_get_net_2(&pkt, &i))
92            || !TEST_uint_eq(i, 0xfcfe)
93            || !TEST_false(PACKET_get_net_2(&pkt, &i)))
94        return 0;
95
96    return 1;
97}
98
99static int test_PACKET_get_net_3(void)
100{
101    unsigned long i = 0;
102    PACKET pkt;
103
104    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
105            || !TEST_true(PACKET_get_net_3(&pkt, &i))
106            || !TEST_ulong_eq(i, 0x020406UL)
107            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 6))
108            || !TEST_true(PACKET_get_net_3(&pkt, &i))
109            || !TEST_ulong_eq(i, 0xfafcfeUL)
110            || !TEST_false(PACKET_get_net_3(&pkt, &i)))
111        return 0;
112
113    return 1;
114}
115
116static int test_PACKET_get_net_4(void)
117{
118    unsigned long i = 0;
119    PACKET pkt;
120
121    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
122            || !TEST_true(PACKET_get_net_4(&pkt, &i))
123            || !TEST_ulong_eq(i, 0x02040608UL)
124            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 8))
125            || !TEST_true(PACKET_get_net_4(&pkt, &i))
126            || !TEST_ulong_eq(i, 0xf8fafcfeUL)
127            || !TEST_false(PACKET_get_net_4(&pkt, &i)))
128        return 0;
129
130    return 1;
131}
132
133static int test_PACKET_get_sub_packet(void)
134{
135    PACKET pkt, subpkt;
136    unsigned long i = 0;
137
138    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
139            || !TEST_true(PACKET_get_sub_packet(&pkt, &subpkt, 4))
140            || !TEST_true(PACKET_get_net_4(&subpkt, &i))
141            || !TEST_ulong_eq(i, 0x02040608UL)
142            || !TEST_size_t_eq(PACKET_remaining(&subpkt), 0)
143            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 8))
144            || !TEST_true(PACKET_get_sub_packet(&pkt, &subpkt, 4))
145            || !TEST_true(PACKET_get_net_4(&subpkt, &i))
146            || !TEST_ulong_eq(i, 0xf8fafcfeUL)
147            || !TEST_size_t_eq(PACKET_remaining(&subpkt), 0)
148            || !TEST_false(PACKET_get_sub_packet(&pkt, &subpkt, 4)))
149        return 0;
150
151    return 1;
152}
153
154static int test_PACKET_get_bytes(void)
155{
156    const unsigned char *bytes = NULL;
157    PACKET pkt;
158
159    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
160            || !TEST_true(PACKET_get_bytes(&pkt, &bytes, 4))
161            || !TEST_uchar_eq(bytes[0], 2)
162            || !TEST_uchar_eq(bytes[1], 4)
163            || !TEST_uchar_eq(bytes[2], 6)
164            || !TEST_uchar_eq(bytes[3], 8)
165            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN -4)
166            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 8))
167            || !TEST_true(PACKET_get_bytes(&pkt, &bytes, 4))
168            || !TEST_uchar_eq(bytes[0], 0xf8)
169            || !TEST_uchar_eq(bytes[1], 0xfa)
170            || !TEST_uchar_eq(bytes[2], 0xfc)
171            || !TEST_uchar_eq(bytes[3], 0xfe)
172            || !TEST_false(PACKET_remaining(&pkt)))
173        return 0;
174
175    return 1;
176}
177
178static int test_PACKET_copy_bytes(void)
179{
180    unsigned char bytes[4];
181    PACKET pkt;
182
183    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
184            || !TEST_true(PACKET_copy_bytes(&pkt, bytes, 4))
185            || !TEST_char_eq(bytes[0], 2)
186            || !TEST_char_eq(bytes[1], 4)
187            || !TEST_char_eq(bytes[2], 6)
188            || !TEST_char_eq(bytes[3], 8)
189            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN - 4)
190            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 8))
191            || !TEST_true(PACKET_copy_bytes(&pkt, bytes, 4))
192            || !TEST_uchar_eq(bytes[0], 0xf8)
193            || !TEST_uchar_eq(bytes[1], 0xfa)
194            || !TEST_uchar_eq(bytes[2], 0xfc)
195            || !TEST_uchar_eq(bytes[3], 0xfe)
196            || !TEST_false(PACKET_remaining(&pkt)))
197        return 0;
198
199    return 1;
200}
201
202static int test_PACKET_copy_all(void)
203{
204    unsigned char tmp[BUF_LEN];
205    PACKET pkt;
206    size_t len;
207
208    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
209            || !TEST_true(PACKET_copy_all(&pkt, tmp, BUF_LEN, &len))
210            || !TEST_size_t_eq(len, BUF_LEN)
211            || !TEST_mem_eq(smbuf, BUF_LEN, tmp, BUF_LEN)
212            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN)
213            || !TEST_false(PACKET_copy_all(&pkt, tmp, BUF_LEN - 1, &len)))
214        return 0;
215
216    return 1;
217}
218
219static int test_PACKET_memdup(void)
220{
221    unsigned char *data = NULL;
222    size_t len;
223    PACKET pkt;
224    int result = 0;
225
226    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
227            || !TEST_true(PACKET_memdup(&pkt, &data, &len))
228            || !TEST_size_t_eq(len, BUF_LEN)
229            || !TEST_mem_eq(data, len, PACKET_data(&pkt), len)
230            || !TEST_true(PACKET_forward(&pkt, 10))
231            || !TEST_true(PACKET_memdup(&pkt, &data, &len))
232            || !TEST_size_t_eq(len, BUF_LEN - 10)
233            || !TEST_mem_eq(data, len, PACKET_data(&pkt), len))
234        goto end;
235    result = 1;
236end:
237    OPENSSL_free(data);
238    return result;
239}
240
241static int test_PACKET_strndup(void)
242{
243    char buf1[10], buf2[10];
244    char *data = NULL;
245    PACKET pkt;
246    int result = 0;
247
248    memset(buf1, 'x', 10);
249    memset(buf2, 'y', 10);
250    buf2[5] = '\0';
251
252    if (!TEST_true(PACKET_buf_init(&pkt, (unsigned char*)buf1, 10))
253            || !TEST_true(PACKET_strndup(&pkt, &data))
254            || !TEST_size_t_eq(strlen(data), 10)
255            || !TEST_strn_eq(data, buf1, 10)
256            || !TEST_true(PACKET_buf_init(&pkt, (unsigned char*)buf2, 10))
257            || !TEST_true(PACKET_strndup(&pkt, &data))
258            || !TEST_size_t_eq(strlen(data), 5)
259            || !TEST_str_eq(data, buf2))
260        goto end;
261
262    result = 1;
263end:
264    OPENSSL_free(data);
265    return result;
266}
267
268static int test_PACKET_contains_zero_byte(void)
269{
270    char buf1[10], buf2[10];
271    PACKET pkt;
272
273    memset(buf1, 'x', 10);
274    memset(buf2, 'y', 10);
275    buf2[5] = '\0';
276
277    if (!TEST_true(PACKET_buf_init(&pkt, (unsigned char*)buf1, 10))
278            || !TEST_false(PACKET_contains_zero_byte(&pkt))
279            || !TEST_true(PACKET_buf_init(&pkt, (unsigned char*)buf2, 10))
280            || !TEST_true(PACKET_contains_zero_byte(&pkt)))
281        return 0;
282
283    return 1;
284}
285
286static int test_PACKET_forward(void)
287{
288    const unsigned char *byte = NULL;
289    PACKET pkt;
290
291    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
292            || !TEST_true(PACKET_forward(&pkt, 1))
293            || !TEST_true(PACKET_get_bytes(&pkt, &byte, 1))
294            || !TEST_uchar_eq(byte[0], 4)
295            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 3))
296            || !TEST_true(PACKET_get_bytes(&pkt, &byte, 1))
297            || !TEST_uchar_eq(byte[0], 0xfe))
298        return 0;
299
300    return 1;
301}
302
303static int test_PACKET_buf_init(void)
304{
305    unsigned char buf1[BUF_LEN] = { 0 };
306    PACKET pkt;
307
308    /* Also tests PACKET_remaining() */
309    if (!TEST_true(PACKET_buf_init(&pkt, buf1, 4))
310            || !TEST_size_t_eq(PACKET_remaining(&pkt), 4)
311            || !TEST_true(PACKET_buf_init(&pkt, buf1, BUF_LEN))
312            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN)
313            || !TEST_false(PACKET_buf_init(&pkt, buf1, -1)))
314        return 0;
315
316    return 1;
317}
318
319static int test_PACKET_null_init(void)
320{
321    PACKET pkt;
322
323    PACKET_null_init(&pkt);
324    if (!TEST_size_t_eq(PACKET_remaining(&pkt), 0)
325            || !TEST_false(PACKET_forward(&pkt, 1)))
326        return 0;
327
328    return 1;
329}
330
331static int test_PACKET_equal(void)
332{
333    PACKET pkt;
334
335    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, 4))
336            || !TEST_true(PACKET_equal(&pkt, smbuf, 4))
337            || !TEST_false(PACKET_equal(&pkt, smbuf + 1, 4))
338            || !TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
339            || !TEST_true(PACKET_equal(&pkt, smbuf, BUF_LEN))
340            || !TEST_false(PACKET_equal(&pkt, smbuf, BUF_LEN - 1))
341            || !TEST_false(PACKET_equal(&pkt, smbuf, BUF_LEN + 1))
342            || !TEST_false(PACKET_equal(&pkt, smbuf, 0)))
343        return 0;
344
345    return 1;
346}
347
348static int test_PACKET_get_length_prefixed_1(void)
349{
350    unsigned char buf1[BUF_LEN];
351    const size_t len = 16;
352    unsigned int i;
353    PACKET pkt, short_pkt, subpkt;
354
355    memset(&subpkt, 0, sizeof(subpkt));
356    buf1[0] = (unsigned char)len;
357    for (i = 1; i < BUF_LEN; i++)
358        buf1[i] = (i * 2) & 0xff;
359
360    if (!TEST_true(PACKET_buf_init(&pkt, buf1, BUF_LEN))
361            || !TEST_true(PACKET_buf_init(&short_pkt, buf1, len))
362            || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &subpkt))
363            || !TEST_size_t_eq(PACKET_remaining(&subpkt), len)
364            || !TEST_true(PACKET_get_net_2(&subpkt, &i))
365            || !TEST_uint_eq(i, 0x0204)
366            || !TEST_false(PACKET_get_length_prefixed_1(&short_pkt, &subpkt))
367            || !TEST_size_t_eq(PACKET_remaining(&short_pkt), len))
368        return 0;
369
370    return 1;
371}
372
373static int test_PACKET_get_length_prefixed_2(void)
374{
375    unsigned char buf1[1024];
376    const size_t len = 516;  /* 0x0204 */
377    unsigned int i;
378    PACKET pkt, short_pkt, subpkt;
379
380    memset(&subpkt, 0, sizeof(subpkt));
381    for (i = 1; i <= 1024; i++)
382        buf1[i - 1] = (i * 2) & 0xff;
383
384    if (!TEST_true(PACKET_buf_init(&pkt, buf1, 1024))
385            || !TEST_true(PACKET_buf_init(&short_pkt, buf1, len))
386            || !TEST_true(PACKET_get_length_prefixed_2(&pkt, &subpkt))
387            || !TEST_size_t_eq(PACKET_remaining(&subpkt), len)
388            || !TEST_true(PACKET_get_net_2(&subpkt, &i))
389            || !TEST_uint_eq(i, 0x0608)
390            || !TEST_false(PACKET_get_length_prefixed_2(&short_pkt, &subpkt))
391            || !TEST_size_t_eq(PACKET_remaining(&short_pkt), len))
392        return 0;
393
394    return 1;
395}
396
397static int test_PACKET_get_length_prefixed_3(void)
398{
399    unsigned char buf1[1024];
400    const size_t len = 516;  /* 0x000204 */
401    unsigned int i;
402    PACKET pkt, short_pkt, subpkt;
403
404    memset(&subpkt, 0, sizeof(subpkt));
405    for (i = 0; i < 1024; i++)
406        buf1[i] = (i * 2) & 0xff;
407
408    if (!TEST_true(PACKET_buf_init(&pkt, buf1, 1024))
409            || !TEST_true(PACKET_buf_init(&short_pkt, buf1, len))
410            || !TEST_true(PACKET_get_length_prefixed_3(&pkt, &subpkt))
411            || !TEST_size_t_eq(PACKET_remaining(&subpkt), len)
412            || !TEST_true(PACKET_get_net_2(&subpkt, &i))
413            || !TEST_uint_eq(i, 0x0608)
414            || !TEST_false(PACKET_get_length_prefixed_3(&short_pkt, &subpkt))
415            || !TEST_size_t_eq(PACKET_remaining(&short_pkt), len))
416        return 0;
417
418    return 1;
419}
420
421static int test_PACKET_as_length_prefixed_1(void)
422{
423    unsigned char buf1[BUF_LEN];
424    const size_t len = 16;
425    unsigned int i;
426    PACKET pkt, exact_pkt, subpkt;
427
428    memset(&subpkt, 0, sizeof(subpkt));
429    buf1[0] = (unsigned char)len;
430    for (i = 1; i < BUF_LEN; i++)
431        buf1[i] = (i * 2) & 0xff;
432
433    if (!TEST_true(PACKET_buf_init(&pkt, buf1, BUF_LEN))
434            || !TEST_true(PACKET_buf_init(&exact_pkt, buf1, len + 1))
435            || !TEST_false(PACKET_as_length_prefixed_1(&pkt, &subpkt))
436            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN)
437            || !TEST_true(PACKET_as_length_prefixed_1(&exact_pkt, &subpkt))
438            || !TEST_size_t_eq(PACKET_remaining(&exact_pkt), 0)
439            || !TEST_size_t_eq(PACKET_remaining(&subpkt), len))
440        return 0;
441
442    return 1;
443}
444
445static int test_PACKET_as_length_prefixed_2(void)
446{
447    unsigned char buf[1024];
448    const size_t len = 516;  /* 0x0204 */
449    unsigned int i;
450    PACKET pkt, exact_pkt, subpkt;
451
452    memset(&subpkt, 0, sizeof(subpkt));
453    for (i = 1; i <= 1024; i++)
454        buf[i-1] = (i * 2) & 0xff;
455
456    if (!TEST_true(PACKET_buf_init(&pkt, buf, 1024))
457            || !TEST_true(PACKET_buf_init(&exact_pkt, buf, len + 2))
458            || !TEST_false(PACKET_as_length_prefixed_2(&pkt, &subpkt))
459            || !TEST_size_t_eq(PACKET_remaining(&pkt), 1024)
460            || !TEST_true(PACKET_as_length_prefixed_2(&exact_pkt, &subpkt))
461            || !TEST_size_t_eq(PACKET_remaining(&exact_pkt), 0)
462            || !TEST_size_t_eq(PACKET_remaining(&subpkt), len))
463        return 0;
464
465    return 1;
466}
467
468int setup_tests(void)
469{
470    unsigned int i;
471
472    for (i = 1; i <= BUF_LEN; i++)
473        smbuf[i - 1] = (i * 2) & 0xff;
474
475    ADD_TEST(test_PACKET_buf_init);
476    ADD_TEST(test_PACKET_null_init);
477    ADD_TEST(test_PACKET_remaining);
478    ADD_TEST(test_PACKET_end);
479    ADD_TEST(test_PACKET_equal);
480    ADD_TEST(test_PACKET_get_1);
481    ADD_TEST(test_PACKET_get_4);
482    ADD_TEST(test_PACKET_get_net_2);
483    ADD_TEST(test_PACKET_get_net_3);
484    ADD_TEST(test_PACKET_get_net_4);
485    ADD_TEST(test_PACKET_get_sub_packet);
486    ADD_TEST(test_PACKET_get_bytes);
487    ADD_TEST(test_PACKET_copy_bytes);
488    ADD_TEST(test_PACKET_copy_all);
489    ADD_TEST(test_PACKET_memdup);
490    ADD_TEST(test_PACKET_strndup);
491    ADD_TEST(test_PACKET_contains_zero_byte);
492    ADD_TEST(test_PACKET_forward);
493    ADD_TEST(test_PACKET_get_length_prefixed_1);
494    ADD_TEST(test_PACKET_get_length_prefixed_2);
495    ADD_TEST(test_PACKET_get_length_prefixed_3);
496    ADD_TEST(test_PACKET_as_length_prefixed_1);
497    ADD_TEST(test_PACKET_as_length_prefixed_2);
498    return 1;
499}
500