Add tests for the WPACKET implementation
[openssl.git] / test / wpackettest.c
1 /*
2  * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 <string.h>
11 #include <openssl/buffer.h>
12 #include "../ssl/packet_locl.h"
13 #include "testutil.h"
14
15 const static unsigned char simple1 = 0xff;
16 const static unsigned char simple2[] = { 0x01, 0xff };
17 const static unsigned char simple3[] = { 0x00, 0x00, 0x00, 0x01, 0xff };
18 const static unsigned char nestedsub[] = { 0x03, 0xff, 0x01, 0xff };
19 const static unsigned char seqsub[] = { 0x01, 0xff, 0x01, 0xff };
20 const static unsigned char empty = 0x00;
21 const static unsigned char alloc[] = { 0x02, 0xfe, 0xff };
22 const static unsigned char submem[] = { 0x03, 0x02, 0xfe, 0xff };
23
24 static BUF_MEM *buf;
25
26 static void testfail(const char *msg, WPACKET *pkt)
27 {
28     fprintf(stderr, "%s", msg);
29     WPACKET_cleanup(pkt);
30 }
31
32 static int test_WPACKET_init(void)
33 {
34     WPACKET pkt;
35     int i;
36     size_t written;
37
38     if (       !WPACKET_init(&pkt, buf)
39             || !WPACKET_put_bytes(&pkt, 0xff, 1)
40                 /* Closing a top level WPACKET should fail */
41             ||  WPACKET_close(&pkt)
42                 /* Finishing a top level WPACKET should succeed */
43             || !WPACKET_finish(&pkt)
44                 /*
45                  * Can't call close or finish on a WPACKET that's already
46                  * finished.
47                  */
48             ||  WPACKET_close(&pkt)
49             ||  WPACKET_finish(&pkt)
50             || !WPACKET_get_total_written(&pkt, &written)
51             ||  written != sizeof(simple1)
52             ||  memcmp(buf->data, &simple1, written) != 0) {
53         testfail("test_WPACKET_init():1 failed\n", &pkt);
54         return 0;
55     }
56
57     /* Now try with a one byte length prefix */
58     if (       !WPACKET_init_len(&pkt, buf, 1)
59             || !WPACKET_put_bytes(&pkt, 0xff, 1)
60             || !WPACKET_finish(&pkt)
61             || !WPACKET_get_total_written(&pkt, &written)
62             ||  written != sizeof(simple2)
63             ||  memcmp(buf->data, &simple2, written) != 0) {
64         testfail("test_WPACKET_init():2 failed\n", &pkt);
65         return 0;
66     }
67
68     /* And a longer length prefix */
69     if (       !WPACKET_init_len(&pkt, buf, 4)
70             || !WPACKET_put_bytes(&pkt, 0xff, 1)
71             || !WPACKET_finish(&pkt)
72             || !WPACKET_get_total_written(&pkt, &written)
73             ||  written != sizeof(simple3)
74             ||  memcmp(buf->data, &simple3, written) != 0) {
75         testfail("test_WPACKET_init():3 failed\n", &pkt);
76         return 0;
77     }
78
79     if (!WPACKET_init_len(&pkt, buf, 1)) {
80         testfail("test_WPACKET_init():4 failed\n", &pkt);
81         return 0;
82     }
83     for (i = 1; i < 257; i++) {
84         /*
85          * Putting more bytes in than fit for the size of the length prefix
86          * should fail
87          */
88         if ((!WPACKET_put_bytes(&pkt, 0xff, 1)) == (i != 256)) {
89             testfail("test_WPACKET_init():4 failed\n", &pkt);
90             return 0;
91         }
92     }
93     if (!WPACKET_finish(&pkt)) {
94         testfail("test_WPACKET_init():4 failed\n", &pkt);
95         return 0;
96     }
97
98     return 1;
99 }
100
101 static int test_WPACKET_set_packet_len(void)
102 {
103     WPACKET pkt;
104     size_t written;
105     unsigned char len;
106
107     /*
108      * Calling set_packet_len when the packet len is already set
109      * should fail
110      */
111     if (       !WPACKET_init_len(&pkt, buf, 1)
112             ||  WPACKET_set_packet_len(&pkt, &len, sizeof(len))
113             || !WPACKET_finish(&pkt)) {
114         testfail("test_WPACKET_set_packet_len():1 failed\n", &pkt);
115         return 0;
116     }
117
118     if (       !WPACKET_init(&pkt, buf)
119             || !WPACKET_set_packet_len(&pkt, &len, sizeof(len))
120                 /* Can't set it again */
121             ||  WPACKET_set_packet_len(&pkt, &len, sizeof(len))
122             || !WPACKET_put_bytes(&pkt, 0xff, 1)
123             || !WPACKET_finish(&pkt)
124             || !WPACKET_get_total_written(&pkt, &written)
125             ||  written != sizeof(simple1)
126             ||  memcmp(buf->data, &simple1, written) != 0
127             ||  len != 1) {
128         testfail("test_WPACKET_set_packet_len():2 failed\n", &pkt);
129         return 0;
130     }
131
132     return 1;
133 }
134
135 static int test_WPACKET_set_max_size(void)
136 {
137     WPACKET pkt;
138     size_t written;
139     unsigned char len;
140
141     if (       !WPACKET_init(&pkt, buf)
142                 /*
143                  * No previous lenbytes set so we should be ok to set the max
144                  * possible max size
145                  */
146             || !WPACKET_set_max_size(&pkt, SIZE_MAX)
147                 /* We should be able to set it smaller too */
148             || !WPACKET_set_max_size(&pkt, SIZE_MAX -1)
149                 /* And setting it bigger again should be ok */
150             || !WPACKET_set_max_size(&pkt, SIZE_MAX)
151             || !WPACKET_set_packet_len(&pkt, &len, 1)
152                 /*
153                  * Max size can't be bigger than biggest that will fit in
154                  * lenbytes
155                  */
156             ||  WPACKET_set_max_size(&pkt, 0x0101)
157                 /* It can be the same as the maximum possible size */
158             || !WPACKET_set_max_size(&pkt, 0xff)
159                 /* Or it can be less */
160             || !WPACKET_set_max_size(&pkt, 0x00)
161                 /*
162                  * Should fail because packet is already filled
163                  */
164             ||  WPACKET_put_bytes(&pkt, 0xff, 1)
165                 /*
166                  * You can't put in more bytes than max size
167                  */
168             || !WPACKET_set_max_size(&pkt, 0x01)
169             || !WPACKET_put_bytes(&pkt, 0xff, 1)
170             ||  WPACKET_put_bytes(&pkt, 0xff, 1)
171             || !WPACKET_finish(&pkt)
172             || !WPACKET_get_total_written(&pkt, &written)
173             ||  written != sizeof(simple1)
174             ||  memcmp(buf->data, &simple1, written) != 0
175             ||  len != 1) {
176         testfail("test_WPACKET_set_max_size():1 failed\n", &pkt);
177         return 0;
178     }
179
180     if (       !WPACKET_init_len(&pkt, buf, 1)
181                 /*
182                  * Should fail because we already consumed 1 byte with the
183                  * length
184                  */
185             ||  WPACKET_set_max_size(&pkt, 0)
186             || !WPACKET_set_max_size(&pkt, 1)
187             ||  WPACKET_put_bytes(&pkt, 0xff, 1)
188             || !WPACKET_set_max_size(&pkt, 2)
189             || !WPACKET_put_bytes(&pkt, 0xff, 1)
190             ||  WPACKET_put_bytes(&pkt, 0xff, 1)
191             || !WPACKET_finish(&pkt)
192             || !WPACKET_get_total_written(&pkt, &written)
193             ||  written != sizeof(simple2)
194             ||  memcmp(buf->data, &simple2, written) != 0
195             ||  len != 1) {
196         testfail("test_WPACKET_set_max_size():2 failed\n", &pkt);
197         return 0;
198     }
199
200     return 1;
201 }
202
203 static int test_WPACKET_start_sub_packet(void)
204 {
205     WPACKET pkt;
206     size_t written;
207     size_t len;
208
209     if (       !WPACKET_init(&pkt, buf)
210             || !WPACKET_start_sub_packet(&pkt)
211             || !WPACKET_put_bytes(&pkt, 0xff, 1)
212                 /* Can't finish because we have a sub packet */
213             ||  WPACKET_finish(&pkt)
214             || !WPACKET_close(&pkt)
215                 /* Sub packet is closed so can't close again */
216             ||  WPACKET_close(&pkt)
217                 /* Now a top level so finish should succeed */
218             || !WPACKET_finish(&pkt)
219             || !WPACKET_get_total_written(&pkt, &written)
220             ||  written != sizeof(simple1)
221             ||  memcmp(buf->data, &simple1, written) != 0) {
222         testfail("test_WPACKET_start_sub_packet():1 failed\n", &pkt);
223         return 0;
224     }
225
226    /* Single sub-packet with length prefix */
227     if (       !WPACKET_init(&pkt, buf)
228             || !WPACKET_start_sub_packet_len(&pkt, 1)
229             || !WPACKET_put_bytes(&pkt, 0xff, 1)
230             || !WPACKET_close(&pkt)
231             || !WPACKET_finish(&pkt)
232             || !WPACKET_get_total_written(&pkt, &written)
233             ||  written != sizeof(simple2)
234             ||  memcmp(buf->data, &simple2, written) != 0) {
235         testfail("test_WPACKET_start_sub_packet():2 failed\n", &pkt);
236         return 0;
237     }
238
239     /* Nested sub-packets with length prefixes */
240     if (       !WPACKET_init(&pkt, buf)
241             || !WPACKET_start_sub_packet_len(&pkt, 1)
242             || !WPACKET_put_bytes(&pkt, 0xff, 1)
243             || !WPACKET_start_sub_packet_len(&pkt, 1)
244             || !WPACKET_put_bytes(&pkt, 0xff, 1)
245             || !WPACKET_get_length(&pkt, &len)
246             || len != 1
247             || !WPACKET_close(&pkt)
248             || !WPACKET_get_length(&pkt, &len)
249             || len != 3
250             || !WPACKET_close(&pkt)
251             || !WPACKET_finish(&pkt)
252             || !WPACKET_get_total_written(&pkt, &written)
253             ||  written != sizeof(nestedsub)
254             ||  memcmp(buf->data, &nestedsub, written) != 0) {
255         testfail("test_WPACKET_start_sub_packet():3 failed\n", &pkt);
256         return 0;
257     }
258
259     /* Sequential sub-packets with length prefixes */
260     if (       !WPACKET_init(&pkt, buf)
261             || !WPACKET_start_sub_packet_len(&pkt, 1)
262             || !WPACKET_put_bytes(&pkt, 0xff, 1)
263             || !WPACKET_close(&pkt)
264             || !WPACKET_start_sub_packet_len(&pkt, 1)
265             || !WPACKET_put_bytes(&pkt, 0xff, 1)
266             || !WPACKET_close(&pkt)
267             || !WPACKET_finish(&pkt)
268             || !WPACKET_get_total_written(&pkt, &written)
269             ||  written != sizeof(seqsub)
270             ||  memcmp(buf->data, &seqsub, written) != 0) {
271         testfail("test_WPACKET_start_sub_packet():4 failed\n", &pkt);
272         return 0;
273     }
274
275     return 1;
276 }
277
278
279 static int test_WPACKET_set_flags(void)
280 {
281     WPACKET pkt;
282     size_t written;
283
284     /* Set packet to be non-zero length */
285     if (       !WPACKET_init(&pkt, buf)
286             || !WPACKET_set_flags(&pkt, OPENSSL_WPACKET_FLAGS_NON_ZERO_LENGTH)
287                 /* Should fail because of zero length */
288             ||  WPACKET_finish(&pkt)
289             || !WPACKET_put_bytes(&pkt, 0xff, 1)
290             || !WPACKET_finish(&pkt)
291             || !WPACKET_get_total_written(&pkt, &written)
292             ||  written != sizeof(simple1)
293             ||  memcmp(buf->data, &simple1, written) != 0) {
294         testfail("test_WPACKET_set_flags():1 failed\n", &pkt);
295         return 0;
296     }
297
298     /* Repeat above test in a sub-packet */
299     if (       !WPACKET_init(&pkt, buf)
300             || !WPACKET_start_sub_packet(&pkt)
301             || !WPACKET_set_flags(&pkt, OPENSSL_WPACKET_FLAGS_NON_ZERO_LENGTH)
302                 /* Should fail because of zero length */
303             ||  WPACKET_close(&pkt)
304             || !WPACKET_put_bytes(&pkt, 0xff, 1)
305             || !WPACKET_close(&pkt)
306             || !WPACKET_finish(&pkt)
307             || !WPACKET_get_total_written(&pkt, &written)
308             ||  written != sizeof(simple1)
309             ||  memcmp(buf->data, &simple1, written) != 0) {
310         testfail("test_WPACKET_set_flags():2 failed\n", &pkt);
311         return 0;
312     }
313
314     /* Set packet to abandon non-zero length */
315     if (       !WPACKET_init_len(&pkt, buf, 1)
316             || !WPACKET_set_flags(&pkt,
317                                   OPENSSL_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)
318             || !WPACKET_finish(&pkt)
319             || !WPACKET_get_total_written(&pkt, &written)
320             ||  written != 0) {
321         testfail("test_WPACKET_set_flags():3 failed\n", &pkt);
322         return 0;
323     }
324
325     /* Repeat above test but only abandon a sub-packet */
326     if (       !WPACKET_init_len(&pkt, buf, 1)
327             || !WPACKET_start_sub_packet_len(&pkt, 1)
328             || !WPACKET_set_flags(&pkt,
329                                   OPENSSL_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)
330             || !WPACKET_close(&pkt)
331             || !WPACKET_finish(&pkt)
332             || !WPACKET_get_total_written(&pkt, &written)
333             ||  written != sizeof(empty)
334             ||  memcmp(buf->data, &empty, written) != 0) {
335         testfail("test_WPACKET_set_flags():4 failed\n", &pkt);
336         return 0;
337     }
338
339     /* And repeat with a non empty sub-packet */
340     if (       !WPACKET_init(&pkt, buf)
341             || !WPACKET_start_sub_packet_len(&pkt, 1)
342             || !WPACKET_set_flags(&pkt,
343                                   OPENSSL_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)
344             || !WPACKET_put_bytes(&pkt, 0xff, 1)
345             || !WPACKET_close(&pkt)
346             || !WPACKET_finish(&pkt)
347             || !WPACKET_get_total_written(&pkt, &written)
348             ||  written != sizeof(simple2)
349             ||  memcmp(buf->data, &simple2, written) != 0) {
350         testfail("test_WPACKET_set_flags():5 failed\n", &pkt);
351         return 0;
352     }
353     return 1;
354 }
355
356 static int test_WPACKET_allocate_bytes(void)
357 {
358     WPACKET pkt;
359     size_t written;
360     unsigned char *bytes;
361
362     if (       !WPACKET_init_len(&pkt, buf, 1)
363             || !WPACKET_allocate_bytes(&pkt, 2, &bytes)) {
364         testfail("test_WPACKET_allocate_bytes():1 failed\n", &pkt);
365         return 0;
366     }
367     bytes[0] = 0xfe;
368     bytes[1] = 0xff;
369     if (       !WPACKET_finish(&pkt)
370             || !WPACKET_get_total_written(&pkt, &written)
371             ||  written != sizeof(alloc)
372             ||  memcmp(buf->data, &alloc, written) != 0) {
373         testfail("test_WPACKET_allocate_bytes():2 failed\n", &pkt);
374         return 0;
375     }
376
377     return 1;
378 }
379
380 static int test_WPACKET_memcpy(void)
381 {
382     WPACKET pkt;
383     size_t written;
384     const unsigned char bytes[] = { 0xfe, 0xff };
385
386     if (       !WPACKET_init_len(&pkt, buf, 1)
387             || !WPACKET_memcpy(&pkt, bytes, sizeof(bytes))
388             || !WPACKET_finish(&pkt)
389             || !WPACKET_get_total_written(&pkt, &written)
390             ||  written != sizeof(alloc)
391             ||  memcmp(buf->data, &alloc, written) != 0) {
392         testfail("test_WPACKET_memcpy():1 failed\n", &pkt);
393         return 0;
394     }
395
396     /* Repeat with WPACKET_sub_memcpy() */
397     if (       !WPACKET_init_len(&pkt, buf, 1)
398             || !WPACKET_sub_memcpy(&pkt, bytes, sizeof(bytes), 1)
399             || !WPACKET_finish(&pkt)
400             || !WPACKET_get_total_written(&pkt, &written)
401             ||  written != sizeof(submem)
402             ||  memcmp(buf->data, &submem, written) != 0) {
403         testfail("test_WPACKET_memcpy():2 failed\n", &pkt);
404         return 0;
405     }
406
407     return 1;
408 }
409
410 int main(int argc, char *argv[])
411 {
412     BIO *err = NULL;
413     int testresult = 0;
414
415     err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
416
417     CRYPTO_set_mem_debug(1);
418     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
419
420     buf = BUF_MEM_new();
421     if (buf != NULL) {
422         ADD_TEST(test_WPACKET_init);
423         ADD_TEST(test_WPACKET_set_packet_len);
424         ADD_TEST(test_WPACKET_set_max_size);
425         ADD_TEST(test_WPACKET_start_sub_packet);
426         ADD_TEST(test_WPACKET_set_flags);
427         ADD_TEST(test_WPACKET_allocate_bytes);
428         ADD_TEST(test_WPACKET_memcpy);
429
430         testresult = run_tests(argv[0]);
431
432         BUF_MEM_free(buf);
433     }
434
435 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
436     if (CRYPTO_mem_leaks(err) <= 0)
437         testresult = 1;
438 #endif
439     BIO_free(err);
440
441     if (!testresult)
442         printf("PASS\n");
443
444     return testresult;
445 }
446