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