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