xref: /src/crypto/openssl/test/dtlstest.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
1 /*
2  * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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/bio.h>
12 #include <openssl/crypto.h>
13 #include <openssl/ssl.h>
14 #include <openssl/err.h>
15 
16 #include "helpers/ssltestlib.h"
17 #include "testutil.h"
18 
19 static char *cert = NULL;
20 static char *privkey = NULL;
21 static unsigned int timer_cb_count;
22 
23 #define NUM_TESTS 2
24 
25 #define DUMMY_CERT_STATUS_LEN 12
26 
27 static unsigned char certstatus[] = {
28     SSL3_RT_HANDSHAKE, /* Content type */
29     0xfe, 0xfd, /* Record version */
30     0, 1, /* Epoch */
31     0, 0, 0, 0, 0, 0x0f, /* Record sequence number */
32     0, DTLS1_HM_HEADER_LENGTH + DUMMY_CERT_STATUS_LEN - 2,
33     SSL3_MT_CERTIFICATE_STATUS, /* Cert Status handshake message type */
34     0, 0, DUMMY_CERT_STATUS_LEN, /* Message len */
35     0, 5, /* Message sequence */
36     0, 0, 0, /* Fragment offset */
37     0, 0, DUMMY_CERT_STATUS_LEN - 2, /* Fragment len */
38     0x80, 0x80, 0x80, 0x80, 0x80,
39     0x80, 0x80, 0x80, 0x80, 0x80 /* Dummy data */
40 };
41 
42 #define RECORD_SEQUENCE 10
43 
44 static const char dummy_cookie[] = "0123456";
45 
generate_cookie_cb(SSL * ssl,unsigned char * cookie,unsigned int * cookie_len)46 static int generate_cookie_cb(SSL *ssl, unsigned char *cookie,
47     unsigned int *cookie_len)
48 {
49     memcpy(cookie, dummy_cookie, sizeof(dummy_cookie));
50     *cookie_len = sizeof(dummy_cookie);
51     return 1;
52 }
53 
verify_cookie_cb(SSL * ssl,const unsigned char * cookie,unsigned int cookie_len)54 static int verify_cookie_cb(SSL *ssl, const unsigned char *cookie,
55     unsigned int cookie_len)
56 {
57     return TEST_mem_eq(cookie, cookie_len, dummy_cookie, sizeof(dummy_cookie));
58 }
59 
timer_cb(SSL * s,unsigned int timer_us)60 static unsigned int timer_cb(SSL *s, unsigned int timer_us)
61 {
62     ++timer_cb_count;
63 
64     if (timer_us == 0)
65         return 50000;
66     else
67         return 2 * timer_us;
68 }
69 
test_dtls_unprocessed(int testidx)70 static int test_dtls_unprocessed(int testidx)
71 {
72     SSL_CTX *sctx = NULL, *cctx = NULL;
73     SSL *serverssl1 = NULL, *clientssl1 = NULL;
74     BIO *c_to_s_fbio, *c_to_s_mempacket;
75     int testresult = 0;
76 
77     timer_cb_count = 0;
78 
79     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
80             DTLS_client_method(),
81             DTLS1_VERSION, 0,
82             &sctx, &cctx, cert, privkey)))
83         return 0;
84 
85 #ifndef OPENSSL_NO_DTLS1_2
86     if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "AES128-SHA")))
87         goto end;
88 #else
89     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
90     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "AES128-SHA:@SECLEVEL=0"))
91         || !TEST_true(SSL_CTX_set_cipher_list(cctx,
92             "AES128-SHA:@SECLEVEL=0")))
93         goto end;
94 #endif
95 
96     c_to_s_fbio = BIO_new(bio_f_tls_dump_filter());
97     if (!TEST_ptr(c_to_s_fbio))
98         goto end;
99 
100     /* BIO is freed by create_ssl_connection on error */
101     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1,
102             NULL, c_to_s_fbio)))
103         goto end;
104 
105     DTLS_set_timer_cb(clientssl1, timer_cb);
106 
107     if (testidx == 1)
108         certstatus[RECORD_SEQUENCE] = 0xff;
109 
110     /*
111      * Inject a dummy record from the next epoch. In test 0, this should never
112      * get used because the message sequence number is too big. In test 1 we set
113      * the record sequence number to be way off in the future.
114      */
115     c_to_s_mempacket = SSL_get_wbio(clientssl1);
116     c_to_s_mempacket = BIO_next(c_to_s_mempacket);
117     mempacket_test_inject(c_to_s_mempacket, (char *)certstatus,
118         sizeof(certstatus), 1, INJECT_PACKET_IGNORE_REC_SEQ);
119 
120     /*
121      * Create the connection. We use "create_bare_ssl_connection" here so that
122      * we can force the connection to not do "SSL_read" once partly connected.
123      * We don't want to accidentally read the dummy records we injected because
124      * they will fail to decrypt.
125      */
126     if (!TEST_true(create_bare_ssl_connection(serverssl1, clientssl1,
127             SSL_ERROR_NONE, 0, 0)))
128         goto end;
129 
130     if (timer_cb_count == 0) {
131         printf("timer_callback was not called.\n");
132         goto end;
133     }
134 
135     testresult = 1;
136 end:
137     SSL_free(serverssl1);
138     SSL_free(clientssl1);
139     SSL_CTX_free(sctx);
140     SSL_CTX_free(cctx);
141 
142     return testresult;
143 }
144 
145 /* One record for the cookieless initial ClientHello */
146 #define CLI_TO_SRV_COOKIE_EXCH 1
147 
148 /*
149  * In a resumption handshake we use 2 records for the initial ClientHello in
150  * this test because we are using a very small MTU and the ClientHello is
151  * bigger than in the non resumption case.
152  */
153 #define CLI_TO_SRV_RESUME_COOKIE_EXCH 2
154 #define SRV_TO_CLI_COOKIE_EXCH 1
155 
156 #define CLI_TO_SRV_EPOCH_0_RECS 3
157 #define CLI_TO_SRV_EPOCH_1_RECS 1
158 #if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
159 #define SRV_TO_CLI_EPOCH_0_RECS 10
160 #else
161 /*
162  * In this case we have no ServerKeyExchange message, because we don't have
163  * ECDHE or DHE. When it is present it gets fragmented into 3 records in this
164  * test.
165  */
166 #define SRV_TO_CLI_EPOCH_0_RECS 9
167 #endif
168 #define SRV_TO_CLI_EPOCH_1_RECS 1
169 #define TOTAL_FULL_HAND_RECORDS \
170     (CLI_TO_SRV_COOKIE_EXCH + SRV_TO_CLI_COOKIE_EXCH + CLI_TO_SRV_EPOCH_0_RECS + CLI_TO_SRV_EPOCH_1_RECS + SRV_TO_CLI_EPOCH_0_RECS + SRV_TO_CLI_EPOCH_1_RECS)
171 
172 #define CLI_TO_SRV_RESUME_EPOCH_0_RECS 3
173 #define CLI_TO_SRV_RESUME_EPOCH_1_RECS 1
174 #define SRV_TO_CLI_RESUME_EPOCH_0_RECS 2
175 #define SRV_TO_CLI_RESUME_EPOCH_1_RECS 1
176 #define TOTAL_RESUME_HAND_RECORDS \
177     (CLI_TO_SRV_RESUME_COOKIE_EXCH + SRV_TO_CLI_COOKIE_EXCH + CLI_TO_SRV_RESUME_EPOCH_0_RECS + CLI_TO_SRV_RESUME_EPOCH_1_RECS + SRV_TO_CLI_RESUME_EPOCH_0_RECS + SRV_TO_CLI_RESUME_EPOCH_1_RECS)
178 
179 #define TOTAL_RECORDS (TOTAL_FULL_HAND_RECORDS + TOTAL_RESUME_HAND_RECORDS)
180 
181 /*
182  * We are assuming a ServerKeyExchange message is sent in this test. If we don't
183  * have either DH or EC, then it won't be
184  */
185 #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
test_dtls_drop_records(int idx)186 static int test_dtls_drop_records(int idx)
187 {
188     SSL_CTX *sctx = NULL, *cctx = NULL;
189     SSL *serverssl = NULL, *clientssl = NULL;
190     BIO *c_to_s_fbio, *mempackbio;
191     int testresult = 0;
192     int epoch = 0;
193     SSL_SESSION *sess = NULL;
194     int cli_to_srv_cookie, cli_to_srv_epoch0, cli_to_srv_epoch1;
195     int srv_to_cli_epoch0;
196 
197     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
198             DTLS_client_method(),
199             DTLS1_VERSION, 0,
200             &sctx, &cctx, cert, privkey)))
201         return 0;
202 
203 #ifdef OPENSSL_NO_DTLS1_2
204     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
205     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0"))
206         || !TEST_true(SSL_CTX_set_cipher_list(cctx,
207             "DEFAULT:@SECLEVEL=0")))
208         goto end;
209 #endif
210 
211     if (!TEST_true(SSL_CTX_set_dh_auto(sctx, 1)))
212         goto end;
213 
214     SSL_CTX_set_options(sctx, SSL_OP_COOKIE_EXCHANGE);
215     SSL_CTX_set_cookie_generate_cb(sctx, generate_cookie_cb);
216     SSL_CTX_set_cookie_verify_cb(sctx, verify_cookie_cb);
217 
218     if (idx >= TOTAL_FULL_HAND_RECORDS) {
219         /* We're going to do a resumption handshake. Get a session first. */
220         if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
221                 NULL, NULL))
222             || !TEST_true(create_ssl_connection(serverssl, clientssl,
223                 SSL_ERROR_NONE))
224             || !TEST_ptr(sess = SSL_get1_session(clientssl)))
225             goto end;
226 
227         SSL_shutdown(clientssl);
228         SSL_shutdown(serverssl);
229         SSL_free(serverssl);
230         SSL_free(clientssl);
231         serverssl = clientssl = NULL;
232 
233         cli_to_srv_epoch0 = CLI_TO_SRV_RESUME_EPOCH_0_RECS;
234         cli_to_srv_epoch1 = CLI_TO_SRV_RESUME_EPOCH_1_RECS;
235         srv_to_cli_epoch0 = SRV_TO_CLI_RESUME_EPOCH_0_RECS;
236         cli_to_srv_cookie = CLI_TO_SRV_RESUME_COOKIE_EXCH;
237         idx -= TOTAL_FULL_HAND_RECORDS;
238     } else {
239         cli_to_srv_epoch0 = CLI_TO_SRV_EPOCH_0_RECS;
240         cli_to_srv_epoch1 = CLI_TO_SRV_EPOCH_1_RECS;
241         srv_to_cli_epoch0 = SRV_TO_CLI_EPOCH_0_RECS;
242         cli_to_srv_cookie = CLI_TO_SRV_COOKIE_EXCH;
243     }
244 
245     c_to_s_fbio = BIO_new(bio_f_tls_dump_filter());
246     if (!TEST_ptr(c_to_s_fbio))
247         goto end;
248 
249     /* BIO is freed by create_ssl_connection on error */
250     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
251             NULL, c_to_s_fbio)))
252         goto end;
253 
254     if (sess != NULL) {
255         if (!TEST_true(SSL_set_session(clientssl, sess)))
256             goto end;
257     }
258 
259     DTLS_set_timer_cb(clientssl, timer_cb);
260     DTLS_set_timer_cb(serverssl, timer_cb);
261 
262     /* Work out which record to drop based on the test number */
263     if (idx >= cli_to_srv_cookie + cli_to_srv_epoch0 + cli_to_srv_epoch1) {
264         mempackbio = SSL_get_wbio(serverssl);
265         idx -= cli_to_srv_cookie + cli_to_srv_epoch0 + cli_to_srv_epoch1;
266         if (idx >= SRV_TO_CLI_COOKIE_EXCH + srv_to_cli_epoch0) {
267             epoch = 1;
268             idx -= SRV_TO_CLI_COOKIE_EXCH + srv_to_cli_epoch0;
269         }
270     } else {
271         mempackbio = SSL_get_wbio(clientssl);
272         if (idx >= cli_to_srv_cookie + cli_to_srv_epoch0) {
273             epoch = 1;
274             idx -= cli_to_srv_cookie + cli_to_srv_epoch0;
275         }
276         mempackbio = BIO_next(mempackbio);
277     }
278     BIO_ctrl(mempackbio, MEMPACKET_CTRL_SET_DROP_EPOCH, epoch, NULL);
279     BIO_ctrl(mempackbio, MEMPACKET_CTRL_SET_DROP_REC, idx, NULL);
280 
281     if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
282         goto end;
283 
284     if (sess != NULL && !TEST_true(SSL_session_reused(clientssl)))
285         goto end;
286 
287     /* If the test did what we planned then it should have dropped a record */
288     if (!TEST_int_eq((int)BIO_ctrl(mempackbio, MEMPACKET_CTRL_GET_DROP_REC, 0,
289                          NULL),
290             -1))
291         goto end;
292 
293     testresult = 1;
294 end:
295     SSL_SESSION_free(sess);
296     SSL_free(serverssl);
297     SSL_free(clientssl);
298     SSL_CTX_free(sctx);
299     SSL_CTX_free(cctx);
300 
301     return testresult;
302 }
303 #endif /* !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) */
304 
test_cookie(void)305 static int test_cookie(void)
306 {
307     SSL_CTX *sctx = NULL, *cctx = NULL;
308     SSL *serverssl = NULL, *clientssl = NULL;
309     int testresult = 0;
310 
311     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
312             DTLS_client_method(),
313             DTLS1_VERSION, 0,
314             &sctx, &cctx, cert, privkey)))
315         return 0;
316 
317     SSL_CTX_set_options(sctx, SSL_OP_COOKIE_EXCHANGE);
318     SSL_CTX_set_cookie_generate_cb(sctx, generate_cookie_cb);
319     SSL_CTX_set_cookie_verify_cb(sctx, verify_cookie_cb);
320 
321 #ifdef OPENSSL_NO_DTLS1_2
322     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
323     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0"))
324         || !TEST_true(SSL_CTX_set_cipher_list(cctx,
325             "DEFAULT:@SECLEVEL=0")))
326         goto end;
327 #endif
328 
329     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
330             NULL, NULL))
331         || !TEST_true(create_ssl_connection(serverssl, clientssl,
332             SSL_ERROR_NONE)))
333         goto end;
334 
335     testresult = 1;
336 end:
337     SSL_free(serverssl);
338     SSL_free(clientssl);
339     SSL_CTX_free(sctx);
340     SSL_CTX_free(cctx);
341 
342     return testresult;
343 }
344 
test_dtls_duplicate_records(void)345 static int test_dtls_duplicate_records(void)
346 {
347     SSL_CTX *sctx = NULL, *cctx = NULL;
348     SSL *serverssl = NULL, *clientssl = NULL;
349     int testresult = 0;
350 
351     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
352             DTLS_client_method(),
353             DTLS1_VERSION, 0,
354             &sctx, &cctx, cert, privkey)))
355         return 0;
356 
357 #ifdef OPENSSL_NO_DTLS1_2
358     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
359     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0"))
360         || !TEST_true(SSL_CTX_set_cipher_list(cctx,
361             "DEFAULT:@SECLEVEL=0")))
362         goto end;
363 #endif
364 
365     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
366             NULL, NULL)))
367         goto end;
368 
369     DTLS_set_timer_cb(clientssl, timer_cb);
370     DTLS_set_timer_cb(serverssl, timer_cb);
371 
372     BIO_ctrl(SSL_get_wbio(clientssl), MEMPACKET_CTRL_SET_DUPLICATE_REC, 1, NULL);
373     BIO_ctrl(SSL_get_wbio(serverssl), MEMPACKET_CTRL_SET_DUPLICATE_REC, 1, NULL);
374 
375     if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
376         goto end;
377 
378     testresult = 1;
379 end:
380     SSL_free(serverssl);
381     SSL_free(clientssl);
382     SSL_CTX_free(sctx);
383     SSL_CTX_free(cctx);
384 
385     return testresult;
386 }
387 
388 /*
389  * Test just sending a Finished message as the first message. Should fail due
390  * to an unexpected message.
391  */
test_just_finished(void)392 static int test_just_finished(void)
393 {
394     int testresult = 0, ret;
395     SSL_CTX *sctx = NULL;
396     SSL *serverssl = NULL;
397     BIO *rbio = NULL, *wbio = NULL, *sbio = NULL;
398     unsigned char buf[] = {
399         /* Record header */
400         SSL3_RT_HANDSHAKE, /* content type */
401         (DTLS1_2_VERSION >> 8) & 0xff, /* protocol version hi byte */
402         DTLS1_2_VERSION & 0xff, /* protocol version lo byte */
403         0, 0, /* epoch */
404         0, 0, 0, 0, 0, 0, /* record sequence */
405         0, DTLS1_HM_HEADER_LENGTH + SHA_DIGEST_LENGTH, /* record length */
406 
407         /* Message header */
408         SSL3_MT_FINISHED, /* message type */
409         0, 0, SHA_DIGEST_LENGTH, /* message length */
410         0, 0, /* message sequence */
411         0, 0, 0, /* fragment offset */
412         0, 0, SHA_DIGEST_LENGTH, /* fragment length */
413 
414         /* Message body */
415         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
416     };
417 
418     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
419             NULL, 0, 0,
420             &sctx, NULL, cert, privkey)))
421         return 0;
422 
423 #ifdef OPENSSL_NO_DTLS1_2
424     /* DTLSv1 is not allowed at the default security level */
425     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0")))
426         goto end;
427 #endif
428 
429     serverssl = SSL_new(sctx);
430     rbio = BIO_new(BIO_s_mem());
431     wbio = BIO_new(BIO_s_mem());
432 
433     if (!TEST_ptr(serverssl) || !TEST_ptr(rbio) || !TEST_ptr(wbio))
434         goto end;
435 
436     sbio = rbio;
437     SSL_set0_rbio(serverssl, rbio);
438     SSL_set0_wbio(serverssl, wbio);
439     rbio = wbio = NULL;
440     DTLS_set_timer_cb(serverssl, timer_cb);
441 
442     if (!TEST_int_eq(BIO_write(sbio, buf, sizeof(buf)), sizeof(buf)))
443         goto end;
444 
445     /* We expect the attempt to process the message to fail */
446     if (!TEST_int_le(ret = SSL_accept(serverssl), 0))
447         goto end;
448 
449     /* Check that we got the error we were expecting */
450     if (!TEST_int_eq(SSL_get_error(serverssl, ret), SSL_ERROR_SSL))
451         goto end;
452 
453     if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()), SSL_R_UNEXPECTED_MESSAGE))
454         goto end;
455 
456     testresult = 1;
457 end:
458     BIO_free(rbio);
459     BIO_free(wbio);
460     SSL_free(serverssl);
461     SSL_CTX_free(sctx);
462 
463     return testresult;
464 }
465 
466 /*
467  * Test that swapping later records before Finished or CCS still works
468  * Test 0: Test receiving a handshake record early from next epoch on server side
469  * Test 1: Test receiving a handshake record early from next epoch on client side
470  * Test 2: Test receiving an app data record early from next epoch on client side
471  * Test 3: Test receiving an app data before Finished on client side
472  */
test_swap_records(int idx)473 static int test_swap_records(int idx)
474 {
475     SSL_CTX *sctx = NULL, *cctx = NULL;
476     SSL *sssl = NULL, *cssl = NULL;
477     int testresult = 0;
478     BIO *bio;
479     char msg[] = { 0x00, 0x01, 0x02, 0x03 };
480     char buf[10];
481 
482     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
483             DTLS_client_method(),
484             DTLS1_VERSION, 0,
485             &sctx, &cctx, cert, privkey)))
486         return 0;
487 
488 #ifndef OPENSSL_NO_DTLS1_2
489     if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "AES128-SHA")))
490         goto end;
491 #else
492     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
493     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "AES128-SHA:@SECLEVEL=0"))
494         || !TEST_true(SSL_CTX_set_cipher_list(cctx,
495             "AES128-SHA:@SECLEVEL=0")))
496         goto end;
497 #endif
498 
499     if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl,
500             NULL, NULL)))
501         goto end;
502 
503     /* Send flight 1: ClientHello */
504     if (!TEST_int_le(SSL_connect(cssl), 0))
505         goto end;
506 
507     /* Recv flight 1, send flight 2: ServerHello, Certificate, ServerHelloDone */
508     if (!TEST_int_le(SSL_accept(sssl), 0))
509         goto end;
510 
511     /* Recv flight 2, send flight 3: ClientKeyExchange, CCS, Finished */
512     if (!TEST_int_le(SSL_connect(cssl), 0))
513         goto end;
514 
515     if (idx == 0) {
516         /* Swap Finished and CCS within the datagram */
517         bio = SSL_get_wbio(cssl);
518         if (!TEST_ptr(bio)
519             || !TEST_true(mempacket_swap_epoch(bio)))
520             goto end;
521     }
522 
523     /* Recv flight 3, send flight 4: datagram 0(NST, CCS) datagram 1(Finished) */
524     if (!TEST_int_gt(SSL_accept(sssl), 0))
525         goto end;
526 
527     /* Send flight 4 (cont'd): datagram 2(app data) */
528     if (!TEST_int_eq(SSL_write(sssl, msg, sizeof(msg)), (int)sizeof(msg)))
529         goto end;
530 
531     bio = SSL_get_wbio(sssl);
532     if (!TEST_ptr(bio))
533         goto end;
534     if (idx == 1) {
535         /* Finished comes before NST/CCS */
536         if (!TEST_true(mempacket_move_packet(bio, 0, 1)))
537             goto end;
538     } else if (idx == 2) {
539         /* App data comes before NST/CCS */
540         if (!TEST_true(mempacket_move_packet(bio, 0, 2)))
541             goto end;
542     } else if (idx == 3) {
543         /* App data comes before Finished */
544         bio = SSL_get_wbio(sssl);
545         if (!TEST_true(mempacket_move_packet(bio, 1, 2)))
546             goto end;
547     }
548 
549     /*
550      * Recv flight 4 (datagram 1): NST, CCS, + flight 5: app data
551      *      + flight 4 (datagram 2): Finished
552      */
553     if (!TEST_int_gt(SSL_connect(cssl), 0))
554         goto end;
555 
556     if (idx == 0 || idx == 1) {
557         /* App data was not received early, so it should not be pending */
558         if (!TEST_int_eq(SSL_pending(cssl), 0)
559             || !TEST_false(SSL_has_pending(cssl)))
560             goto end;
561 
562     } else {
563         /* We received the app data early so it should be buffered already */
564         if (!TEST_int_eq(SSL_pending(cssl), (int)sizeof(msg))
565             || !TEST_true(SSL_has_pending(cssl)))
566             goto end;
567     }
568 
569     /*
570      * Recv flight 5 (app data)
571      */
572     if (!TEST_int_eq(SSL_read(cssl, buf, sizeof(buf)), (int)sizeof(msg)))
573         goto end;
574 
575     testresult = 1;
576 end:
577     SSL_free(cssl);
578     SSL_free(sssl);
579     SSL_CTX_free(cctx);
580     SSL_CTX_free(sctx);
581 
582     return testresult;
583 }
584 
test_duplicate_app_data(void)585 static int test_duplicate_app_data(void)
586 {
587     SSL_CTX *sctx = NULL, *cctx = NULL;
588     SSL *sssl = NULL, *cssl = NULL;
589     int testresult = 0;
590     BIO *bio;
591     char msg[] = { 0x00, 0x01, 0x02, 0x03 };
592     char buf[10];
593     int ret;
594 
595     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
596             DTLS_client_method(),
597             DTLS1_VERSION, 0,
598             &sctx, &cctx, cert, privkey)))
599         return 0;
600 
601 #ifndef OPENSSL_NO_DTLS1_2
602     if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "AES128-SHA")))
603         goto end;
604 #else
605     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
606     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "AES128-SHA:@SECLEVEL=0"))
607         || !TEST_true(SSL_CTX_set_cipher_list(cctx,
608             "AES128-SHA:@SECLEVEL=0")))
609         goto end;
610 #endif
611 
612     if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl,
613             NULL, NULL)))
614         goto end;
615 
616     /* Send flight 1: ClientHello */
617     if (!TEST_int_le(SSL_connect(cssl), 0))
618         goto end;
619 
620     /* Recv flight 1, send flight 2: ServerHello, Certificate, ServerHelloDone */
621     if (!TEST_int_le(SSL_accept(sssl), 0))
622         goto end;
623 
624     /* Recv flight 2, send flight 3: ClientKeyExchange, CCS, Finished */
625     if (!TEST_int_le(SSL_connect(cssl), 0))
626         goto end;
627 
628     /* Recv flight 3, send flight 4: datagram 0(NST, CCS) datagram 1(Finished) */
629     if (!TEST_int_gt(SSL_accept(sssl), 0))
630         goto end;
631 
632     bio = SSL_get_wbio(sssl);
633     if (!TEST_ptr(bio))
634         goto end;
635 
636     /*
637      * Send flight 4 (cont'd): datagram 2(app data)
638      * + datagram 3 (app data duplicate)
639      */
640     if (!TEST_int_eq(SSL_write(sssl, msg, sizeof(msg)), (int)sizeof(msg)))
641         goto end;
642 
643     if (!TEST_true(mempacket_dup_last_packet(bio)))
644         goto end;
645 
646     /* App data comes before NST/CCS */
647     if (!TEST_true(mempacket_move_packet(bio, 0, 2)))
648         goto end;
649 
650     /*
651      * Recv flight 4 (datagram 2): app data + flight 4 (datagram 0): NST, CCS, +
652      *      + flight 4 (datagram 1): Finished
653      */
654     if (!TEST_int_gt(SSL_connect(cssl), 0))
655         goto end;
656 
657     /*
658      * Read flight 4 (app data)
659      */
660     if (!TEST_int_eq(SSL_read(cssl, buf, sizeof(buf)), (int)sizeof(msg)))
661         goto end;
662 
663     if (!TEST_mem_eq(buf, sizeof(msg), msg, sizeof(msg)))
664         goto end;
665 
666     /*
667      * Read flight 4, datagram 3. We expect the duplicated app data to have been
668      * dropped, with no more data available
669      */
670     if (!TEST_int_le(ret = SSL_read(cssl, buf, sizeof(buf)), 0)
671         || !TEST_int_eq(SSL_get_error(cssl, ret), SSL_ERROR_WANT_READ))
672         goto end;
673 
674     testresult = 1;
675 end:
676     SSL_free(cssl);
677     SSL_free(sssl);
678     SSL_CTX_free(cctx);
679     SSL_CTX_free(sctx);
680 
681     return testresult;
682 }
683 
684 /* Confirm that we can create a connections using DTLSv1_listen() */
test_listen(void)685 static int test_listen(void)
686 {
687     SSL_CTX *sctx = NULL, *cctx = NULL;
688     SSL *serverssl = NULL, *clientssl = NULL;
689     int testresult = 0;
690 
691     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
692             DTLS_client_method(),
693             DTLS1_VERSION, 0,
694             &sctx, &cctx, cert, privkey)))
695         return 0;
696 
697 #ifdef OPENSSL_NO_DTLS1_2
698     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
699     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0"))
700         || !TEST_true(SSL_CTX_set_cipher_list(cctx,
701             "DEFAULT:@SECLEVEL=0")))
702         goto end;
703 #endif
704 
705     SSL_CTX_set_cookie_generate_cb(sctx, generate_cookie_cb);
706     SSL_CTX_set_cookie_verify_cb(sctx, verify_cookie_cb);
707 
708     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
709             NULL, NULL)))
710         goto end;
711 
712     DTLS_set_timer_cb(clientssl, timer_cb);
713     DTLS_set_timer_cb(serverssl, timer_cb);
714 
715     /*
716      * The last parameter to create_bare_ssl_connection() requests that
717      * DTLSv1_listen() is used.
718      */
719     if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl,
720             SSL_ERROR_NONE, 1, 1)))
721         goto end;
722 
723     testresult = 1;
724 end:
725     SSL_free(serverssl);
726     SSL_free(clientssl);
727     SSL_CTX_free(sctx);
728     SSL_CTX_free(cctx);
729 
730     return testresult;
731 }
732 
733 OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n")
734 
setup_tests(void)735 int setup_tests(void)
736 {
737     if (!test_skip_common_options()) {
738         TEST_error("Error parsing test options\n");
739         return 0;
740     }
741 
742     if (!TEST_ptr(cert = test_get_argument(0))
743         || !TEST_ptr(privkey = test_get_argument(1)))
744         return 0;
745 
746     ADD_ALL_TESTS(test_dtls_unprocessed, NUM_TESTS);
747 #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
748     ADD_ALL_TESTS(test_dtls_drop_records, TOTAL_RECORDS);
749 #endif
750     ADD_TEST(test_cookie);
751     ADD_TEST(test_dtls_duplicate_records);
752     ADD_TEST(test_just_finished);
753     ADD_ALL_TESTS(test_swap_records, 4);
754     ADD_TEST(test_listen);
755     ADD_TEST(test_duplicate_app_data);
756 
757     return 1;
758 }
759 
cleanup_tests(void)760 void cleanup_tests(void)
761 {
762     bio_f_tls_dump_filter_free();
763     bio_s_mempacket_test_free();
764 }
765