Documentation for new SSL functions
[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 #ifndef OPENSSL_NO_ENGINE
64  #include <openssl/engine.h>
65 #endif
66 #include "e_os.h"
67
68 /* Just a ClientHello without a cookie */
69 static const unsigned char clienthello_nocookie[] = {
70     0x16, /* Handshake */
71     0xFE, 0xFF, /* DTLSv1.0 */
72     0x00, 0x00, /* Epoch */
73     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
74     0x00, 0x3A, /* Record Length */
75     0x01, /* ClientHello */
76     0x00, 0x00, 0x2E, /* Message length */
77     0x00, 0x00, /* Message sequence */
78     0x00, 0x00, 0x00, /* Fragment offset */
79     0x00, 0x00, 0x2E, /* Fragment length */
80     0xFE, 0xFD, /* DTLSv1.2 */
81     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
82     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
83     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
84     0x00, /* Session id len */
85     0x00, /* Cookie len */
86     0x00, 0x04, /* Ciphersuites len */
87     0x00, 0x2f, /* AES128-SHA */
88     0x00, 0xff, /* Empty reneg info SCSV */
89     0x01, /* Compression methods len */
90     0x00, /* Null compression */
91     0x00, 0x00 /* Extensions len */
92 };
93
94 /* First fragment of a ClientHello without a cookie */
95 static const unsigned char clienthello_nocookie_frag[] = {
96     0x16, /* Handshake */
97     0xFE, 0xFF, /* DTLSv1.0 */
98     0x00, 0x00, /* Epoch */
99     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
100     0x00, 0x30, /* Record Length */
101     0x01, /* ClientHello */
102     0x00, 0x00, 0x2E, /* Message length */
103     0x00, 0x00, /* Message sequence */
104     0x00, 0x00, 0x00, /* Fragment offset */
105     0x00, 0x00, 0x24, /* Fragment length */
106     0xFE, 0xFD, /* DTLSv1.2 */
107     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
108     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
109     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
110     0x00, /* Session id len */
111     0x00 /* Cookie len */
112 };
113
114 /* First fragment of a ClientHello which is too short */
115 static const unsigned char clienthello_nocookie_short[] = {
116     0x16, /* Handshake */
117     0xFE, 0xFF, /* DTLSv1.0 */
118     0x00, 0x00, /* Epoch */
119     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
120     0x00, 0x2F, /* Record Length */
121     0x01, /* ClientHello */
122     0x00, 0x00, 0x2E, /* Message length */
123     0x00, 0x00, /* Message sequence */
124     0x00, 0x00, 0x00, /* Fragment offset */
125     0x00, 0x00, 0x23, /* Fragment length */
126     0xFE, 0xFD, /* DTLSv1.2 */
127     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
128     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
129     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
130     0x00 /* Session id len */
131 };
132
133 /* Second fragment of a ClientHello */
134 static const unsigned char clienthello_2ndfrag[] = {
135     0x16, /* Handshake */
136     0xFE, 0xFF, /* DTLSv1.0 */
137     0x00, 0x00, /* Epoch */
138     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
139     0x00, 0x38, /* Record Length */
140     0x01, /* ClientHello */
141     0x00, 0x00, 0x2E, /* Message length */
142     0x00, 0x00, /* Message sequence */
143     0x00, 0x00, 0x02, /* Fragment offset */
144     0x00, 0x00, 0x2C, /* Fragment length */
145     /* Version skipped - sent in first fragment */
146     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
147     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
148     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
149     0x00, /* Session id len */
150     0x00, /* Cookie len */
151     0x00, 0x04, /* Ciphersuites len */
152     0x00, 0x2f, /* AES128-SHA */
153     0x00, 0xff, /* Empty reneg info SCSV */
154     0x01, /* Compression methods len */
155     0x00, /* Null compression */
156     0x00, 0x00 /* Extensions len */
157 };
158
159 /* A ClientHello with a good cookie */
160 static const unsigned char clienthello_cookie[] = {
161     0x16, /* Handshake */
162     0xFE, 0xFF, /* DTLSv1.0 */
163     0x00, 0x00, /* Epoch */
164     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
165     0x00, 0x4E, /* Record Length */
166     0x01, /* ClientHello */
167     0x00, 0x00, 0x42, /* Message length */
168     0x00, 0x00, /* Message sequence */
169     0x00, 0x00, 0x00, /* Fragment offset */
170     0x00, 0x00, 0x42, /* Fragment length */
171     0xFE, 0xFD, /* DTLSv1.2 */
172     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
173     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
174     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
175     0x00, /* Session id len */
176     0x14, /* Cookie len */
177     0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
178     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
179     0x00, 0x04, /* Ciphersuites len */
180     0x00, 0x2f, /* AES128-SHA */
181     0x00, 0xff, /* Empty reneg info SCSV */
182     0x01, /* Compression methods len */
183     0x00, /* Null compression */
184     0x00, 0x00 /* Extensions len */
185 };
186
187 /* A fragmented ClientHello with a good cookie */
188 static const unsigned char clienthello_cookie_frag[] = {
189     0x16, /* Handshake */
190     0xFE, 0xFF, /* DTLSv1.0 */
191     0x00, 0x00, /* Epoch */
192     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
193     0x00, 0x44, /* Record Length */
194     0x01, /* ClientHello */
195     0x00, 0x00, 0x42, /* Message length */
196     0x00, 0x00, /* Message sequence */
197     0x00, 0x00, 0x00, /* Fragment offset */
198     0x00, 0x00, 0x38, /* Fragment length */
199     0xFE, 0xFD, /* DTLSv1.2 */
200     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
201     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
202     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
203     0x00, /* Session id len */
204     0x14, /* Cookie len */
205     0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
206     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
207 };
208
209
210 /* A ClientHello with a bad cookie */
211 static const unsigned char clienthello_badcookie[] = {
212     0x16, /* Handshake */
213     0xFE, 0xFF, /* DTLSv1.0 */
214     0x00, 0x00, /* Epoch */
215     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
216     0x00, 0x4E, /* Record Length */
217     0x01, /* ClientHello */
218     0x00, 0x00, 0x42, /* Message length */
219     0x00, 0x00, /* Message sequence */
220     0x00, 0x00, 0x00, /* Fragment offset */
221     0x00, 0x00, 0x42, /* Fragment length */
222     0xFE, 0xFD, /* DTLSv1.2 */
223     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
224     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
225     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
226     0x00, /* Session id len */
227     0x14, /* Cookie len */
228     0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
229     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
230     0x00, 0x04, /* Ciphersuites len */
231     0x00, 0x2f, /* AES128-SHA */
232     0x00, 0xff, /* Empty reneg info SCSV */
233     0x01, /* Compression methods len */
234     0x00, /* Null compression */
235     0x00, 0x00 /* Extensions len */
236 };
237
238 /* A fragmented ClientHello with the fragment boundary mid cookie */
239 static const unsigned char clienthello_cookie_short[] = {
240     0x16, /* Handshake */
241     0xFE, 0xFF, /* DTLSv1.0 */
242     0x00, 0x00, /* Epoch */
243     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
244     0x00, 0x43, /* Record Length */
245     0x01, /* ClientHello */
246     0x00, 0x00, 0x42, /* Message length */
247     0x00, 0x00, /* Message sequence */
248     0x00, 0x00, 0x00, /* Fragment offset */
249     0x00, 0x00, 0x37, /* Fragment length */
250     0xFE, 0xFD, /* DTLSv1.2 */
251     0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
252     0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
253     0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
254     0x00, /* Session id len */
255     0x14, /* Cookie len */
256     0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
257     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
258 };
259
260 /* Bad record - too short */
261 static const unsigned char record_short[] = {
262     0x16, /* Handshake */
263     0xFE, 0xFF, /* DTLSv1.0 */
264     0x00, 0x00, /* Epoch */
265     0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
266 };
267
268 static const unsigned char verify[] = {
269     0x16, /* Handshake */
270     0xFE, 0xFF, /* DTLSv1.0 */
271     0x00, 0x00, /* Epoch */
272     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
273     0x00, 0x23, /* Record Length */
274     0x03, /* HelloVerifyRequest */
275     0x00, 0x00, 0x17, /* Message length */
276     0x00, 0x00, /* Message sequence */
277     0x00, 0x00, 0x00, /* Fragment offset */
278     0x00, 0x00, 0x17, /* Fragment length */
279     0xFE, 0xFF, /* DTLSv1.0 */
280     0x14, /* Cookie len */
281     0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
282     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
283 };
284
285 static struct {
286     const unsigned char *in;
287     unsigned int inlen;
288     /*
289      * GOOD == positive return value from DTLSv1_listen, no output yet
290      * VERIFY == 0 return value, HelloVerifyRequest sent
291      * DROP == 0 return value, no output
292      */
293     enum {GOOD, VERIFY, DROP} outtype;
294 } testpackets[9] = {
295     {
296         clienthello_nocookie,
297         sizeof(clienthello_nocookie),
298         VERIFY
299     },
300     {
301         clienthello_nocookie_frag,
302         sizeof(clienthello_nocookie_frag),
303         VERIFY
304     },
305     {
306         clienthello_nocookie_short,
307         sizeof(clienthello_nocookie_short),
308         DROP
309     },
310     {
311         clienthello_2ndfrag,
312         sizeof(clienthello_2ndfrag),
313         DROP
314     },
315     {
316         clienthello_cookie,
317         sizeof(clienthello_cookie),
318         GOOD
319     },
320     {
321         clienthello_cookie_frag,
322         sizeof(clienthello_cookie_frag),
323         GOOD
324     },
325     {
326         clienthello_badcookie,
327         sizeof(clienthello_badcookie),
328         VERIFY
329     },
330     {
331         clienthello_cookie_short,
332         sizeof(clienthello_cookie_short),
333         DROP
334     },
335     {
336         record_short,
337         sizeof(record_short),
338         DROP
339     }
340 };
341
342 #define COOKIE_LEN  20
343
344 static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
345 {
346     unsigned int i;
347
348     for (i = 0; i < COOKIE_LEN; i++, cookie++) {
349         *cookie = i;
350     }
351     *cookie_len = COOKIE_LEN;
352
353     return 1;
354 }
355
356 static int cookie_verify(SSL *ssl, const unsigned char *cookie,
357                          unsigned int cookie_len)
358 {
359     unsigned int i;
360
361     if (cookie_len != COOKIE_LEN)
362         return 0;
363
364     for (i = 0; i < COOKIE_LEN; i++, cookie++) {
365         if (*cookie != i)
366             return 0;
367     }
368
369     return 1;
370 }
371
372 int main(void)
373 {
374     SSL_CTX *ctx = NULL;
375     SSL *ssl = NULL;
376     BIO *outbio = NULL;
377     BIO *inbio = NULL;
378     BIO_ADDR *peer = BIO_ADDR_new();
379     char *data;
380     long datalen;
381     int ret, success = 0;
382     long i;
383
384     ctx = SSL_CTX_new(DTLS_server_method());
385     if (ctx == NULL || peer == NULL)
386         goto err;
387
388     SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
389     SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
390
391     /* Create an SSL object for the connection */
392     ssl = SSL_new(ctx);
393     if (ssl == NULL)
394         goto err;
395
396     outbio = BIO_new(BIO_s_mem());
397     if (outbio == NULL)
398         goto err;
399     SSL_set_wbio(ssl, outbio);
400
401     success = 1;
402     for (i = 0; i < (long)OSSL_NELEM(testpackets) && success; i++) {
403         inbio = BIO_new_mem_buf((char *)testpackets[i].in,
404                                 testpackets[i].inlen);
405         if (inbio == NULL) {
406             success = 0;
407             goto err;
408         }
409         /* Set Non-blocking IO behaviour */
410         BIO_set_mem_eof_return(inbio, -1);
411
412         SSL_set_rbio(ssl, inbio);
413
414         /* Process the incoming packet */
415         ret = DTLSv1_listen(ssl, peer);
416         if (ret < 0) {
417             success = 0;
418             goto err;
419         }
420
421         datalen = BIO_get_mem_data(outbio, &data);
422
423         if (testpackets[i].outtype == VERIFY) {
424             if (ret == 0) {
425                 if (datalen != sizeof(verify)
426                         || (memcmp(data, verify, sizeof(verify)) != 0)) {
427                     printf("Test %ld failure: incorrect HelloVerifyRequest\n", i);
428                     success = 0;
429                 } else {
430                     printf("Test %ld success\n", i);
431                 }
432             } else {
433                 printf ("Test %ld failure: should not have succeeded\n", i);
434                 success = 0;
435             }
436         } else if (datalen == 0) {
437             if ((ret == 0 && testpackets[i].outtype == DROP)
438                     || (ret == 1 && testpackets[i].outtype == GOOD)) {
439                 printf("Test %ld success\n", i);
440             } else {
441                 printf("Test %ld failure: wrong return value\n", i);
442                 success = 0;
443             }
444         } else {
445             printf("Test %ld failure: Unexpected data output\n", i);
446             success = 0;
447         }
448         (void)BIO_reset(outbio);
449         inbio = NULL;
450         /* Frees up inbio */
451         SSL_set_rbio(ssl, NULL);
452     }
453
454  err:
455     if (!success)
456         ERR_print_errors_fp(stderr);
457     /* Also frees up outbio */
458     SSL_free(ssl);
459     SSL_CTX_free(ctx);
460     BIO_free(inbio);
461     OPENSSL_free(peer);
462 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
463     CRYPTO_mem_leaks_fp(stderr);
464 #endif
465     return success ? 0 : 1;
466 }
467