fix warnings on 32 bit builds
[openssl.git] / test / dtlsv1listentest.c
1 /*
2  * Written by Matt Caswell for the OpenSSL project.
3  */
4 /* ====================================================================
5  * Copyright (c) 2016 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    openssl-core@openssl.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com).  This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com).
55  *
56  */
57
58 #include <string.h>
59 #include <openssl/ssl.h>
60 #include <openssl/bio.h>
61 #include <openssl/err.h>
62 #include <openssl/conf.h>
63 #include <openssl/engine.h>
64 #include "e_os.h"
65
66 /* Just a ClientHello without a cookie */
67 static const unsigned char clienthello_nocookie[] = {
68     0x16, /* Handshake */
69     0xFE, 0xFF, /* DTLSv1.0 */
70     0x00, 0x00, /* Epoch */
71     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
72     0x00, 0x3A, /* Record Length */
73     0x01, /* ClientHello */
74     0x00, 0x00, 0x2E, /* Message length */
75     0x00, 0x00, /* Message sequence */
76     0x00, 0x00, 0x00, /* Fragment offset */
77     0x00, 0x00, 0x2E, /* Fragment length */
78     0xFE, 0xFD, /* DTLSv1.2 */
79     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
80     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
81     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
82     0x00, /* Session id len */
83     0x00, /* Cookie len */
84     0x00, 0x04, /* Ciphersuites len */
85     0x00, 0x2f, /* AES128-SHA */
86     0x00, 0xff, /* Empty reneg info SCSV */
87     0x01, /* Compression methods len */
88     0x00, /* Null compression */
89     0x00, 0x00 /* Extensions len */
90 };
91
92 /* First fragment of a ClientHello without a cookie */
93 static const unsigned char clienthello_nocookie_frag[] = {
94     0x16, /* Handshake */
95     0xFE, 0xFF, /* DTLSv1.0 */
96     0x00, 0x00, /* Epoch */
97     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
98     0x00, 0x30, /* Record Length */
99     0x01, /* ClientHello */
100     0x00, 0x00, 0x2E, /* Message length */
101     0x00, 0x00, /* Message sequence */
102     0x00, 0x00, 0x00, /* Fragment offset */
103     0x00, 0x00, 0x24, /* Fragment length */
104     0xFE, 0xFD, /* DTLSv1.2 */
105     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
106     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
107     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
108     0x00, /* Session id len */
109     0x00 /* Cookie len */
110 };
111
112 /* First fragment of a ClientHello which is too short */
113 static const unsigned char clienthello_nocookie_short[] = {
114     0x16, /* Handshake */
115     0xFE, 0xFF, /* DTLSv1.0 */
116     0x00, 0x00, /* Epoch */
117     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
118     0x00, 0x2F, /* Record Length */
119     0x01, /* ClientHello */
120     0x00, 0x00, 0x2E, /* Message length */
121     0x00, 0x00, /* Message sequence */
122     0x00, 0x00, 0x00, /* Fragment offset */
123     0x00, 0x00, 0x23, /* Fragment length */
124     0xFE, 0xFD, /* DTLSv1.2 */
125     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
126     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
127     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
128     0x00 /* Session id len */
129 };
130
131 /* Second fragment of a ClientHello */
132 static const unsigned char clienthello_2ndfrag[] = {
133     0x16, /* Handshake */
134     0xFE, 0xFF, /* DTLSv1.0 */
135     0x00, 0x00, /* Epoch */
136     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
137     0x00, 0x38, /* Record Length */
138     0x01, /* ClientHello */
139     0x00, 0x00, 0x2E, /* Message length */
140     0x00, 0x00, /* Message sequence */
141     0x00, 0x00, 0x02, /* Fragment offset */
142     0x00, 0x00, 0x2C, /* Fragment length */
143     /* Version skipped - sent in first fragment */
144     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
145     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
146     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
147     0x00, /* Session id len */
148     0x00, /* Cookie len */
149     0x00, 0x04, /* Ciphersuites len */
150     0x00, 0x2f, /* AES128-SHA */
151     0x00, 0xff, /* Empty reneg info SCSV */
152     0x01, /* Compression methods len */
153     0x00, /* Null compression */
154     0x00, 0x00 /* Extensions len */
155 };
156
157 /* A ClientHello with a good cookie */
158 static const unsigned char clienthello_cookie[] = {
159     0x16, /* Handshake */
160     0xFE, 0xFF, /* DTLSv1.0 */
161     0x00, 0x00, /* Epoch */
162     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
163     0x00, 0x4E, /* Record Length */
164     0x01, /* ClientHello */
165     0x00, 0x00, 0x42, /* Message length */
166     0x00, 0x00, /* Message sequence */
167     0x00, 0x00, 0x00, /* Fragment offset */
168     0x00, 0x00, 0x42, /* Fragment length */
169     0xFE, 0xFD, /* DTLSv1.2 */
170     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
171     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
172     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
173     0x00, /* Session id len */
174     0x14, /* Cookie len */
175     0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
176     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
177     0x00, 0x04, /* Ciphersuites len */
178     0x00, 0x2f, /* AES128-SHA */
179     0x00, 0xff, /* Empty reneg info SCSV */
180     0x01, /* Compression methods len */
181     0x00, /* Null compression */
182     0x00, 0x00 /* Extensions len */
183 };
184
185 /* A fragmented ClientHello with a good cookie */
186 static const unsigned char clienthello_cookie_frag[] = {
187     0x16, /* Handshake */
188     0xFE, 0xFF, /* DTLSv1.0 */
189     0x00, 0x00, /* Epoch */
190     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
191     0x00, 0x44, /* Record Length */
192     0x01, /* ClientHello */
193     0x00, 0x00, 0x42, /* Message length */
194     0x00, 0x00, /* Message sequence */
195     0x00, 0x00, 0x00, /* Fragment offset */
196     0x00, 0x00, 0x38, /* Fragment length */
197     0xFE, 0xFD, /* DTLSv1.2 */
198     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
199     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
200     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
201     0x00, /* Session id len */
202     0x14, /* Cookie len */
203     0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
204     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
205 };
206
207
208 /* A ClientHello with a bad cookie */
209 static const unsigned char clienthello_badcookie[] = {
210     0x16, /* Handshake */
211     0xFE, 0xFF, /* DTLSv1.0 */
212     0x00, 0x00, /* Epoch */
213     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
214     0x00, 0x4E, /* Record Length */
215     0x01, /* ClientHello */
216     0x00, 0x00, 0x42, /* Message length */
217     0x00, 0x00, /* Message sequence */
218     0x00, 0x00, 0x00, /* Fragment offset */
219     0x00, 0x00, 0x42, /* Fragment length */
220     0xFE, 0xFD, /* DTLSv1.2 */
221     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
222     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
223     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
224     0x00, /* Session id len */
225     0x14, /* Cookie len */
226     0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
227     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
228     0x00, 0x04, /* Ciphersuites len */
229     0x00, 0x2f, /* AES128-SHA */
230     0x00, 0xff, /* Empty reneg info SCSV */
231     0x01, /* Compression methods len */
232     0x00, /* Null compression */
233     0x00, 0x00 /* Extensions len */
234 };
235
236 /* A fragmented ClientHello with the fragment boundary mid cookie */
237 static const unsigned char clienthello_cookie_short[] = {
238     0x16, /* Handshake */
239     0xFE, 0xFF, /* DTLSv1.0 */
240     0x00, 0x00, /* Epoch */
241     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
242     0x00, 0x43, /* Record Length */
243     0x01, /* ClientHello */
244     0x00, 0x00, 0x42, /* Message length */
245     0x00, 0x00, /* Message sequence */
246     0x00, 0x00, 0x00, /* Fragment offset */
247     0x00, 0x00, 0x37, /* Fragment length */
248     0xFE, 0xFD, /* DTLSv1.2 */
249     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
250     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
251     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
252     0x00, /* Session id len */
253     0x14, /* Cookie len */
254     0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
255     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
256 };
257
258 /* Bad record - too short */
259 static const unsigned char record_short[] = {
260     0x16, /* Handshake */
261     0xFE, 0xFF, /* DTLSv1.0 */
262     0x00, 0x00, /* Epoch */
263     0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
264 };
265
266 static const unsigned char verify[] = {
267     0x16, /* Handshake */
268     0xFE, 0xFF, /* DTLSv1.0 */
269     0x00, 0x00, /* Epoch */
270     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
271     0x00, 0x23, /* Record Length */
272     0x03, /* HelloVerifyRequest */
273     0x00, 0x00, 0x17, /* Message length */
274     0x00, 0x00, /* Message sequence */
275     0x00, 0x00, 0x00, /* Fragment offset */
276     0x00, 0x00, 0x17, /* Fragment length */
277     0xFE, 0xFF, /* DTLSv1.0 */
278     0x14, /* Cookie len */
279     0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
280     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
281 };
282
283 static struct {
284     const unsigned char *in;
285     unsigned int inlen;
286     /*
287      * GOOD == positive return value from DTLSv1_listen, no output yet
288      * VERIFY == 0 return value, HelloVerifyRequest sent
289      * DROP == 0 return value, no output
290      */
291     enum {GOOD, VERIFY, DROP} outtype;
292 } testpackets[9] = {
293     {
294         clienthello_nocookie,
295         sizeof(clienthello_nocookie),
296         VERIFY
297     },
298     {
299         clienthello_nocookie_frag,
300         sizeof(clienthello_nocookie_frag),
301         VERIFY
302     },
303     {
304         clienthello_nocookie_short,
305         sizeof(clienthello_nocookie_short),
306         DROP
307     },
308     {
309         clienthello_2ndfrag,
310         sizeof(clienthello_2ndfrag),
311         DROP
312     },
313     {
314         clienthello_cookie,
315         sizeof(clienthello_cookie),
316         GOOD
317     },
318     {
319         clienthello_cookie_frag,
320         sizeof(clienthello_cookie_frag),
321         GOOD
322     },
323     {
324         clienthello_badcookie,
325         sizeof(clienthello_badcookie),
326         VERIFY
327     },
328     {
329         clienthello_cookie_short,
330         sizeof(clienthello_cookie_short),
331         DROP
332     },
333     {
334         record_short,
335         sizeof(record_short),
336         DROP
337     }
338 };
339
340 #define COOKIE_LEN  20
341
342 static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
343 {
344     unsigned int i;
345
346     for (i = 0; i < COOKIE_LEN; i++, cookie++) {
347         *cookie = i;
348     }
349     *cookie_len = COOKIE_LEN;
350
351     return 1;
352 }
353
354 static int cookie_verify(SSL *ssl, const unsigned char *cookie,
355                          unsigned int cookie_len)
356 {
357     unsigned int i;
358
359     if (cookie_len != COOKIE_LEN)
360         return 0;
361
362     for (i = 0; i < COOKIE_LEN; i++, cookie++) {
363         if (*cookie != i)
364             return 0;
365     }
366
367     return 1;
368 }
369
370 int main(void)
371 {
372     SSL_CTX *ctx = NULL;
373     SSL *ssl = NULL;
374     BIO *outbio = NULL;
375     BIO *inbio = NULL;
376     BIO_ADDR *peer = BIO_ADDR_new();
377     char *data;
378     long datalen;
379     int ret, success = 0;
380     long i;
381
382     ctx = SSL_CTX_new(DTLS_server_method());
383     if (ctx == NULL || peer == NULL)
384         goto err;
385
386     SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
387     SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
388
389     /* Create an SSL object for the connection */
390     ssl = SSL_new(ctx);
391     if (ssl == NULL)
392         goto err;
393
394     outbio = BIO_new(BIO_s_mem());
395     if (outbio == NULL)
396         goto err;
397     SSL_set_wbio(ssl, outbio);
398
399     success = 1;
400     for (i = 0; i < (long)OSSL_NELEM(testpackets) && success; i++) {
401         inbio = BIO_new_mem_buf((char *)testpackets[i].in,
402                                 testpackets[i].inlen);
403         if (inbio == NULL) {
404             success = 0;
405             goto err;
406         }
407         /* Set Non-blocking IO behaviour */
408         BIO_set_mem_eof_return(inbio, -1);
409
410         SSL_set_rbio(ssl, inbio);
411
412         /* Process the incoming packet */
413         ret = DTLSv1_listen(ssl, peer);
414         if (ret < 0) {
415             success = 0;
416             goto err;
417         }
418
419         datalen = BIO_get_mem_data(outbio, &data);
420
421         if (testpackets[i].outtype == VERIFY) {
422             if (ret == 0) {
423                 if (datalen != sizeof(verify)
424                         || (memcmp(data, verify, sizeof(verify)) != 0)) {
425                     printf("Test %ld failure: incorrect HelloVerifyRequest\n", i);
426                     success = 0;
427                 } else {
428                     printf("Test %ld success\n", i);
429                 }
430             } else {
431                 printf ("Test %ld failure: should not have succeeded\n", i);
432                 success = 0;
433             }
434         } else if (datalen == 0) {
435             if ((ret == 0 && testpackets[i].outtype == DROP)
436                     || (ret == 1 && testpackets[i].outtype == GOOD)) {
437                 printf("Test %ld success\n", i);
438             } else {
439                 printf("Test %ld failure: wrong return value\n", i);
440                 success = 0;
441             }
442         } else {
443             printf("Test %ld failure: Unexpected data output\n", i);
444             success = 0;
445         }
446         (void)BIO_reset(outbio);
447         inbio = NULL;
448         /* Frees up inbio */
449         SSL_set_rbio(ssl, NULL);
450     }
451
452  err:
453     if (!success)
454         ERR_print_errors_fp(stderr);
455     /* Also frees up outbio */
456     SSL_free(ssl);
457     SSL_CTX_free(ctx);
458     BIO_free(inbio);
459     OPENSSL_free(peer);
460 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
461     CRYPTO_mem_leaks_fp(stderr);
462 #endif
463     return success ? 0 : 1;
464 }
465