summaryrefslogtreecommitdiff
path: root/src/regress/lib/libssl/dtls
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libssl/dtls')
-rw-r--r--src/regress/lib/libssl/dtls/Makefile19
-rw-r--r--src/regress/lib/libssl/dtls/dtlstest.c1072
2 files changed, 0 insertions, 1091 deletions
diff --git a/src/regress/lib/libssl/dtls/Makefile b/src/regress/lib/libssl/dtls/Makefile
deleted file mode 100644
index 79ca4077d3..0000000000
--- a/src/regress/lib/libssl/dtls/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
1# $OpenBSD: Makefile,v 1.2 2021/06/19 17:11:34 jsing Exp $
2
3PROG= dtlstest
4LDADD= ${SSL_INT} -lcrypto
5DPADD= ${LIBSSL} ${LIBCRYPTO}
6WARNINGS= Yes
7CFLAGS+= -DLIBRESSL_INTERNAL -Werror
8CFLAGS+= -I${.CURDIR}/../../../../lib/libssl
9
10REGRESS_TARGETS= \
11 regress-dtlstest
12
13regress-dtlstest: ${PROG}
14 ./dtlstest \
15 ${.CURDIR}/../../libssl/certs/server.pem \
16 ${.CURDIR}/../../libssl/certs/server.pem \
17 ${.CURDIR}/../../libssl/certs/ca.pem
18
19.include <bsd.regress.mk>
diff --git a/src/regress/lib/libssl/dtls/dtlstest.c b/src/regress/lib/libssl/dtls/dtlstest.c
deleted file mode 100644
index 08424c1a4b..0000000000
--- a/src/regress/lib/libssl/dtls/dtlstest.c
+++ /dev/null
@@ -1,1072 +0,0 @@
1/* $OpenBSD: dtlstest.c,v 1.14 2021/06/19 18:28:51 tb Exp $ */
2/*
3 * Copyright (c) 2020, 2021 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <netinet/in.h>
19#include <sys/socket.h>
20
21#include <err.h>
22#include <limits.h>
23#include <poll.h>
24#include <unistd.h>
25
26#include <openssl/bio.h>
27#include <openssl/err.h>
28#include <openssl/ssl.h>
29
30#include "ssl_locl.h"
31
32const char *server_ca_file;
33const char *server_cert_file;
34const char *server_key_file;
35
36char dtls_cookie[32];
37
38int debug = 0;
39
40void tls12_record_layer_set_initial_epoch(struct tls12_record_layer *rl,
41 uint16_t epoch);
42
43static void
44hexdump(const unsigned char *buf, size_t len)
45{
46 size_t i;
47
48 for (i = 1; i <= len; i++)
49 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
50
51 if (len % 8)
52 fprintf(stderr, "\n");
53}
54
55#define BIO_C_DELAY_COUNT 1000
56#define BIO_C_DELAY_FLUSH 1001
57#define BIO_C_DELAY_PACKET 1002
58#define BIO_C_DROP_PACKET 1003
59#define BIO_C_DROP_RANDOM 1004
60
61struct bio_packet_monkey_ctx {
62 unsigned int delay_count;
63 unsigned int delay_mask;
64 unsigned int drop_rand;
65 unsigned int drop_mask;
66 uint8_t *delayed_msg;
67 size_t delayed_msg_len;
68};
69
70static int
71bio_packet_monkey_new(BIO *bio)
72{
73 struct bio_packet_monkey_ctx *ctx;
74
75 if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
76 return 0;
77
78 bio->flags = 0;
79 bio->init = 1;
80 bio->num = 0;
81 bio->ptr = ctx;
82
83 return 1;
84}
85
86static int
87bio_packet_monkey_free(BIO *bio)
88{
89 struct bio_packet_monkey_ctx *ctx;
90
91 if (bio == NULL)
92 return 1;
93
94 ctx = bio->ptr;
95 free(ctx->delayed_msg);
96 free(ctx);
97
98 return 1;
99}
100
101static int
102bio_packet_monkey_delay_flush(BIO *bio)
103{
104 struct bio_packet_monkey_ctx *ctx = bio->ptr;
105
106 if (ctx->delayed_msg == NULL)
107 return 1;
108
109 if (debug)
110 fprintf(stderr, "DEBUG: flushing delayed packet...\n");
111 if (debug > 1)
112 hexdump(ctx->delayed_msg, ctx->delayed_msg_len);
113
114 BIO_write(bio->next_bio, ctx->delayed_msg, ctx->delayed_msg_len);
115
116 free(ctx->delayed_msg);
117 ctx->delayed_msg = NULL;
118
119 return BIO_ctrl(bio->next_bio, BIO_CTRL_FLUSH, 0, NULL);
120}
121
122static long
123bio_packet_monkey_ctrl(BIO *bio, int cmd, long num, void *ptr)
124{
125 struct bio_packet_monkey_ctx *ctx;
126
127 ctx = bio->ptr;
128
129 switch (cmd) {
130 case BIO_C_DELAY_COUNT:
131 if (num < 1 || num > 31)
132 return 0;
133 ctx->delay_count = num;
134 return 1;
135
136 case BIO_C_DELAY_FLUSH:
137 return bio_packet_monkey_delay_flush(bio);
138
139 case BIO_C_DELAY_PACKET:
140 if (num < 1 || num > 31)
141 return 0;
142 ctx->delay_mask |= 1 << ((unsigned int)num - 1);
143 return 1;
144
145 case BIO_C_DROP_PACKET:
146 if (num < 1 || num > 31)
147 return 0;
148 ctx->drop_mask |= 1 << ((unsigned int)num - 1);
149 return 1;
150
151 case BIO_C_DROP_RANDOM:
152 if (num < 0 || (size_t)num > UINT_MAX)
153 return 0;
154 ctx->drop_rand = (unsigned int)num;
155 return 1;
156 }
157
158 if (bio->next_bio == NULL)
159 return 0;
160
161 return BIO_ctrl(bio->next_bio, cmd, num, ptr);
162}
163
164static int
165bio_packet_monkey_read(BIO *bio, char *out, int out_len)
166{
167 struct bio_packet_monkey_ctx *ctx = bio->ptr;
168 int ret;
169
170 if (ctx == NULL || bio->next_bio == NULL)
171 return 0;
172
173 ret = BIO_read(bio->next_bio, out, out_len);
174
175 if (ret > 0) {
176 if (debug)
177 fprintf(stderr, "DEBUG: read packet...\n");
178 if (debug > 1)
179 hexdump(out, ret);
180 }
181
182 BIO_clear_retry_flags(bio);
183 if (ret <= 0 && BIO_should_retry(bio->next_bio))
184 BIO_set_retry_read(bio);
185
186 return ret;
187}
188
189static int
190bio_packet_monkey_write(BIO *bio, const char *in, int in_len)
191{
192 struct bio_packet_monkey_ctx *ctx = bio->ptr;
193 const char *label = "writing";
194 int delay = 0, drop = 0;
195 int ret;
196
197 if (ctx == NULL || bio->next_bio == NULL)
198 return 0;
199
200 if (ctx->delayed_msg != NULL && ctx->delay_count > 0)
201 ctx->delay_count--;
202
203 if (ctx->delayed_msg != NULL && ctx->delay_count == 0) {
204 if (debug)
205 fprintf(stderr, "DEBUG: writing delayed packet...\n");
206 if (debug > 1)
207 hexdump(ctx->delayed_msg, ctx->delayed_msg_len);
208
209 ret = BIO_write(bio->next_bio, ctx->delayed_msg,
210 ctx->delayed_msg_len);
211
212 BIO_clear_retry_flags(bio);
213 if (ret <= 0 && BIO_should_retry(bio->next_bio)) {
214 BIO_set_retry_write(bio);
215 return (ret);
216 }
217
218 free(ctx->delayed_msg);
219 ctx->delayed_msg = NULL;
220 }
221
222 if (ctx->delay_mask > 0) {
223 delay = ctx->delay_mask & 1;
224 ctx->delay_mask >>= 1;
225 }
226 if (ctx->drop_rand > 0) {
227 drop = arc4random_uniform(ctx->drop_rand) == 0;
228 } else if (ctx->drop_mask > 0) {
229 drop = ctx->drop_mask & 1;
230 ctx->drop_mask >>= 1;
231 }
232
233 if (delay)
234 label = "delaying";
235 if (drop)
236 label = "dropping";
237 if (debug)
238 fprintf(stderr, "DEBUG: %s packet...\n", label);
239 if (debug > 1)
240 hexdump(in, in_len);
241
242 if (drop)
243 return in_len;
244
245 if (delay) {
246 if (ctx->delayed_msg != NULL)
247 return 0;
248 if ((ctx->delayed_msg = calloc(1, in_len)) == NULL)
249 return 0;
250 memcpy(ctx->delayed_msg, in, in_len);
251 ctx->delayed_msg_len = in_len;
252 return in_len;
253 }
254
255 ret = BIO_write(bio->next_bio, in, in_len);
256
257 BIO_clear_retry_flags(bio);
258 if (ret <= 0 && BIO_should_retry(bio->next_bio))
259 BIO_set_retry_write(bio);
260
261 return ret;
262}
263
264static int
265bio_packet_monkey_puts(BIO *bio, const char *str)
266{
267 return bio_packet_monkey_write(bio, str, strlen(str));
268}
269
270static const BIO_METHOD bio_packet_monkey = {
271 .type = BIO_TYPE_BUFFER,
272 .name = "packet monkey",
273 .bread = bio_packet_monkey_read,
274 .bwrite = bio_packet_monkey_write,
275 .bputs = bio_packet_monkey_puts,
276 .ctrl = bio_packet_monkey_ctrl,
277 .create = bio_packet_monkey_new,
278 .destroy = bio_packet_monkey_free
279};
280
281static const BIO_METHOD *
282BIO_f_packet_monkey(void)
283{
284 return &bio_packet_monkey;
285}
286
287static BIO *
288BIO_new_packet_monkey(void)
289{
290 return BIO_new(BIO_f_packet_monkey());
291}
292
293static int
294BIO_packet_monkey_delay(BIO *bio, int num, int count)
295{
296 if (!BIO_ctrl(bio, BIO_C_DELAY_COUNT, count, NULL))
297 return 0;
298
299 return BIO_ctrl(bio, BIO_C_DELAY_PACKET, num, NULL);
300}
301
302static int
303BIO_packet_monkey_delay_flush(BIO *bio)
304{
305 return BIO_ctrl(bio, BIO_C_DELAY_FLUSH, 0, NULL);
306}
307
308static int
309BIO_packet_monkey_drop(BIO *bio, int num)
310{
311 return BIO_ctrl(bio, BIO_C_DROP_PACKET, num, NULL);
312}
313
314#if 0
315static int
316BIO_packet_monkey_drop_random(BIO *bio, int num)
317{
318 return BIO_ctrl(bio, BIO_C_DROP_RANDOM, num, NULL);
319}
320#endif
321
322static int
323datagram_pair(int *client_sock, int *server_sock,
324 struct sockaddr_in *server_sin)
325{
326 struct sockaddr_in sin;
327 socklen_t sock_len;
328 int cs = -1, ss = -1;
329
330 memset(&sin, 0, sizeof(sin));
331 sin.sin_family = AF_INET;
332 sin.sin_port = 0;
333 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
334
335 if ((ss = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
336 err(1, "server socket");
337 if (bind(ss, (struct sockaddr *)&sin, sizeof(sin)) == -1)
338 err(1, "server bind");
339 sock_len = sizeof(sin);
340 if (getsockname(ss, (struct sockaddr *)&sin, &sock_len) == -1)
341 err(1, "server getsockname");
342
343 if ((cs = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
344 err(1, "client socket");
345 if (connect(cs, (struct sockaddr *)&sin, sizeof(sin)) == -1)
346 err(1, "client connect");
347
348 *client_sock = cs;
349 *server_sock = ss;
350 memcpy(server_sin, &sin, sizeof(sin));
351
352 return 1;
353}
354
355static int
356poll_timeout(SSL *client, SSL *server)
357{
358 int client_timeout = 0, server_timeout = 0;
359 struct timeval timeout;
360
361 if (DTLSv1_get_timeout(client, &timeout))
362 client_timeout = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
363
364 if (DTLSv1_get_timeout(server, &timeout))
365 server_timeout = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
366
367 if (client_timeout <= 0)
368 return server_timeout;
369 if (client_timeout > 0 && server_timeout <= 0)
370 return client_timeout;
371 if (client_timeout < server_timeout)
372 return client_timeout;
373
374 return server_timeout;
375}
376
377static int
378dtls_cookie_generate(SSL *ssl, unsigned char *cookie,
379 unsigned int *cookie_len)
380{
381 arc4random_buf(dtls_cookie, sizeof(dtls_cookie));
382 memcpy(cookie, dtls_cookie, sizeof(dtls_cookie));
383 *cookie_len = sizeof(dtls_cookie);
384
385 return 1;
386}
387
388static int
389dtls_cookie_verify(SSL *ssl, const unsigned char *cookie,
390 unsigned int cookie_len)
391{
392 return cookie_len == sizeof(dtls_cookie) &&
393 memcmp(cookie, dtls_cookie, sizeof(dtls_cookie)) == 0;
394}
395
396static void
397dtls_info_callback(const SSL *ssl, int type, int val)
398{
399 /*
400 * Squeals ahead... remove the bbio from the info callback, so we can
401 * drop specific messages. Ideally this would be an option for the SSL.
402 */
403 if (ssl->wbio == ssl->bbio)
404 ((SSL *)ssl)->wbio = BIO_pop(ssl->wbio);
405}
406
407static SSL *
408dtls_client(int sock, struct sockaddr_in *server_sin, long mtu)
409{
410 SSL_CTX *ssl_ctx = NULL;
411 SSL *ssl = NULL;
412 BIO *bio = NULL;
413
414 if ((bio = BIO_new_dgram(sock, BIO_NOCLOSE)) == NULL)
415 errx(1, "client bio");
416 if (!BIO_socket_nbio(sock, 1))
417 errx(1, "client nbio");
418 if (!BIO_ctrl_set_connected(bio, 1, server_sin))
419 errx(1, "client set connected");
420
421 if ((ssl_ctx = SSL_CTX_new(DTLS_method())) == NULL)
422 errx(1, "client context");
423
424 if ((ssl = SSL_new(ssl_ctx)) == NULL)
425 errx(1, "client ssl");
426
427 SSL_set_bio(ssl, bio, bio);
428 bio = NULL;
429
430 if (mtu > 0) {
431 SSL_set_options(ssl, SSL_OP_NO_QUERY_MTU);
432 SSL_set_mtu(ssl, mtu);
433 }
434
435 SSL_CTX_free(ssl_ctx);
436 BIO_free(bio);
437
438 return ssl;
439}
440
441static SSL *
442dtls_server(int sock, long options, long mtu)
443{
444 SSL_CTX *ssl_ctx = NULL;
445 SSL *ssl = NULL;
446 BIO *bio = NULL;
447
448 if ((bio = BIO_new_dgram(sock, BIO_NOCLOSE)) == NULL)
449 errx(1, "server bio");
450 if (!BIO_socket_nbio(sock, 1))
451 errx(1, "server nbio");
452
453 if ((ssl_ctx = SSL_CTX_new(DTLS_method())) == NULL)
454 errx(1, "server context");
455
456 SSL_CTX_set_cookie_generate_cb(ssl_ctx, dtls_cookie_generate);
457 SSL_CTX_set_cookie_verify_cb(ssl_ctx, dtls_cookie_verify);
458 SSL_CTX_set_dh_auto(ssl_ctx, 2);
459 SSL_CTX_set_options(ssl_ctx, options);
460
461 if (SSL_CTX_use_certificate_chain_file(ssl_ctx, server_cert_file) != 1) {
462 fprintf(stderr, "FAIL: Failed to load server certificate");
463 goto failure;
464 }
465 if (SSL_CTX_use_PrivateKey_file(ssl_ctx, server_key_file,
466 SSL_FILETYPE_PEM) != 1) {
467 fprintf(stderr, "FAIL: Failed to load server private key");
468 goto failure;
469 }
470
471 if ((ssl = SSL_new(ssl_ctx)) == NULL)
472 errx(1, "server ssl");
473
474 if (SSL_use_certificate_chain_file(ssl, server_cert_file) != 1) {
475 fprintf(stderr, "FAIL: Failed to load server certificate");
476 goto failure;
477 }
478 SSL_set_bio(ssl, bio, bio);
479 bio = NULL;
480
481 if (mtu > 0) {
482 SSL_set_options(ssl, SSL_OP_NO_QUERY_MTU);
483 SSL_set_mtu(ssl, mtu);
484 }
485
486 failure:
487 SSL_CTX_free(ssl_ctx);
488 BIO_free(bio);
489
490 return ssl;
491}
492
493static int
494ssl_error(SSL *ssl, const char *name, const char *desc, int ssl_ret,
495 short *events)
496{
497 int ssl_err;
498
499 ssl_err = SSL_get_error(ssl, ssl_ret);
500
501 if (ssl_err == SSL_ERROR_WANT_READ) {
502 *events = POLLIN;
503 } else if (ssl_err == SSL_ERROR_WANT_WRITE) {
504 *events = POLLOUT;
505 } else if (ssl_err == SSL_ERROR_SYSCALL && errno == 0) {
506 /* Yup, this is apparently a thing... */
507 } else {
508 fprintf(stderr, "FAIL: %s %s failed - ssl err = %d, errno = %d\n",
509 name, desc, ssl_err, errno);
510 ERR_print_errors_fp(stderr);
511 return 0;
512 }
513
514 return 1;
515}
516
517static int
518do_connect(SSL *ssl, const char *name, int *done, short *events)
519{
520 int ssl_ret;
521
522 if ((ssl_ret = SSL_connect(ssl)) != 1)
523 return ssl_error(ssl, name, "connect", ssl_ret, events);
524
525 fprintf(stderr, "INFO: %s connect done\n", name);
526 *done = 1;
527
528 return 1;
529}
530
531static int
532do_connect_read(SSL *ssl, const char *name, int *done, short *events)
533{
534 uint8_t buf[2048];
535 int ssl_ret;
536 int i;
537
538 if ((ssl_ret = SSL_connect(ssl)) != 1)
539 return ssl_error(ssl, name, "connect", ssl_ret, events);
540
541 fprintf(stderr, "INFO: %s connect done\n", name);
542 *done = 1;
543
544 for (i = 0; i < 3; i++) {
545 fprintf(stderr, "INFO: %s reading after connect\n", name);
546 if ((ssl_ret = SSL_read(ssl, buf, sizeof(buf))) != 3) {
547 fprintf(stderr, "ERROR: %s read failed\n", name);
548 return 0;
549 }
550 }
551
552 return 1;
553}
554
555static int
556do_connect_shutdown(SSL *ssl, const char *name, int *done, short *events)
557{
558 uint8_t buf[2048];
559 int ssl_ret;
560
561 if ((ssl_ret = SSL_connect(ssl)) != 1)
562 return ssl_error(ssl, name, "connect", ssl_ret, events);
563
564 fprintf(stderr, "INFO: %s connect done\n", name);
565 *done = 1;
566
567 ssl_ret = SSL_read(ssl, buf, sizeof(buf));
568 if (SSL_get_error(ssl, ssl_ret) != SSL_ERROR_ZERO_RETURN) {
569 fprintf(stderr, "FAIL: %s did not receive close-notify\n", name);
570 return 0;
571 }
572
573 fprintf(stderr, "INFO: %s received close-notify\n", name);
574
575 return 1;
576}
577
578static int
579do_accept(SSL *ssl, const char *name, int *done, short *events)
580{
581 int ssl_ret;
582
583 if ((ssl_ret = SSL_accept(ssl)) != 1)
584 return ssl_error(ssl, name, "accept", ssl_ret, events);
585
586 fprintf(stderr, "INFO: %s accept done\n", name);
587 *done = 1;
588
589 return 1;
590}
591
592static int
593do_accept_write(SSL *ssl, const char *name, int *done, short *events)
594{
595 int ssl_ret;
596 BIO *bio;
597 int i;
598
599 if ((ssl_ret = SSL_accept(ssl)) != 1)
600 return ssl_error(ssl, name, "accept", ssl_ret, events);
601
602 fprintf(stderr, "INFO: %s accept done\n", name);
603
604 for (i = 0; i < 3; i++) {
605 fprintf(stderr, "INFO: %s writing after accept\n", name);
606 if ((ssl_ret = SSL_write(ssl, "abc", 3)) != 3) {
607 fprintf(stderr, "ERROR: %s write failed\n", name);
608 return 0;
609 }
610 }
611
612 if ((bio = SSL_get_wbio(ssl)) == NULL)
613 errx(1, "SSL has NULL bio");
614
615 /* Flush any delayed packets. */
616 BIO_packet_monkey_delay_flush(bio);
617
618 *done = 1;
619 return 1;
620}
621
622static int
623do_accept_shutdown(SSL *ssl, const char *name, int *done, short *events)
624{
625 int ssl_ret;
626 BIO *bio;
627
628 if ((ssl_ret = SSL_accept(ssl)) != 1)
629 return ssl_error(ssl, name, "accept", ssl_ret, events);
630
631 fprintf(stderr, "INFO: %s accept done\n", name);
632
633 SSL_shutdown(ssl);
634
635 if ((bio = SSL_get_wbio(ssl)) == NULL)
636 errx(1, "SSL has NULL bio");
637
638 /* Flush any delayed packets. */
639 BIO_packet_monkey_delay_flush(bio);
640
641 *done = 1;
642 return 1;
643}
644
645static int
646do_read(SSL *ssl, const char *name, int *done, short *events)
647{
648 uint8_t buf[512];
649 int ssl_ret;
650
651 if ((ssl_ret = SSL_read(ssl, buf, sizeof(buf))) > 0) {
652 fprintf(stderr, "INFO: %s read done\n", name);
653 if (debug > 1)
654 hexdump(buf, ssl_ret);
655 *done = 1;
656 return 1;
657 }
658
659 return ssl_error(ssl, name, "read", ssl_ret, events);
660}
661
662static int
663do_write(SSL *ssl, const char *name, int *done, short *events)
664{
665 const uint8_t buf[] = "Hello, World!\n";
666 int ssl_ret;
667
668 if ((ssl_ret = SSL_write(ssl, buf, sizeof(buf))) > 0) {
669 fprintf(stderr, "INFO: %s write done\n", name);
670 *done = 1;
671 return 1;
672 }
673
674 return ssl_error(ssl, name, "write", ssl_ret, events);
675}
676
677static int
678do_shutdown(SSL *ssl, const char *name, int *done, short *events)
679{
680 int ssl_ret;
681
682 ssl_ret = SSL_shutdown(ssl);
683 if (ssl_ret == 1) {
684 fprintf(stderr, "INFO: %s shutdown done\n", name);
685 *done = 1;
686 return 1;
687 }
688 return ssl_error(ssl, name, "shutdown", ssl_ret, events);
689}
690
691typedef int (ssl_func)(SSL *ssl, const char *name, int *done, short *events);
692
693static int
694do_client_server_loop(SSL *client, ssl_func *client_func, SSL *server,
695 ssl_func *server_func, struct pollfd pfd[2])
696{
697 int client_done = 0, server_done = 0;
698 int i = 0;
699
700 pfd[0].revents = POLLIN;
701 pfd[1].revents = POLLIN;
702
703 do {
704 if (!client_done) {
705 if (debug)
706 fprintf(stderr, "DEBUG: client loop\n");
707 if (DTLSv1_handle_timeout(client) > 0)
708 fprintf(stderr, "INFO: client timeout\n");
709 if (!client_func(client, "client", &client_done,
710 &pfd[0].events))
711 return 0;
712 if (client_done)
713 pfd[0].events = 0;
714 }
715 if (!server_done) {
716 if (debug)
717 fprintf(stderr, "DEBUG: server loop\n");
718 if (DTLSv1_handle_timeout(server) > 0)
719 fprintf(stderr, "INFO: server timeout\n");
720 if (!server_func(server, "server", &server_done,
721 &pfd[1].events))
722 return 0;
723 if (server_done)
724 pfd[1].events = 0;
725 }
726 if (poll(pfd, 2, poll_timeout(client, server)) == -1)
727 err(1, "poll");
728
729 } while (i++ < 100 && (!client_done || !server_done));
730
731 if (!client_done || !server_done)
732 fprintf(stderr, "FAIL: gave up\n");
733
734 return client_done && server_done;
735}
736
737#define MAX_PACKET_DELAYS 32
738#define MAX_PACKET_DROPS 32
739
740struct dtls_delay {
741 uint8_t packet;
742 uint8_t count;
743};
744
745struct dtls_test {
746 const unsigned char *desc;
747 long mtu;
748 long ssl_options;
749 int client_bbio_off;
750 int server_bbio_off;
751 uint16_t initial_epoch;
752 int write_after_accept;
753 int shutdown_after_accept;
754 struct dtls_delay client_delays[MAX_PACKET_DELAYS];
755 struct dtls_delay server_delays[MAX_PACKET_DELAYS];
756 uint8_t client_drops[MAX_PACKET_DROPS];
757 uint8_t server_drops[MAX_PACKET_DROPS];
758};
759
760static const struct dtls_test dtls_tests[] = {
761 {
762 .desc = "DTLS without cookies",
763 .ssl_options = 0,
764 },
765 {
766 .desc = "DTLS without cookies (initial epoch 0xfffe)",
767 .ssl_options = 0,
768 .initial_epoch = 0xfffe,
769 },
770 {
771 .desc = "DTLS without cookies (initial epoch 0xffff)",
772 .ssl_options = 0,
773 .initial_epoch = 0xffff,
774 },
775 {
776 .desc = "DTLS with cookies",
777 .ssl_options = SSL_OP_COOKIE_EXCHANGE,
778 },
779 {
780 .desc = "DTLS with low MTU",
781 .mtu = 256,
782 .ssl_options = 0,
783 },
784 {
785 .desc = "DTLS with low MTU and cookies",
786 .mtu = 256,
787 .ssl_options = SSL_OP_COOKIE_EXCHANGE,
788 },
789 {
790 .desc = "DTLS with dropped server response",
791 .ssl_options = 0,
792 .server_drops = { 1 },
793 },
794 {
795 .desc = "DTLS with two dropped server responses",
796 .ssl_options = 0,
797 .server_drops = { 1, 2 },
798 },
799 {
800 .desc = "DTLS with dropped ServerHello",
801 .ssl_options = SSL_OP_NO_TICKET,
802 .server_bbio_off = 1,
803 .server_drops = { 1 },
804 },
805 {
806 .desc = "DTLS with dropped server Certificate",
807 .ssl_options = SSL_OP_NO_TICKET,
808 .server_bbio_off = 1,
809 .server_drops = { 2 },
810 },
811 {
812 .desc = "DTLS with dropped ServerKeyExchange",
813 .ssl_options = SSL_OP_NO_TICKET,
814 .server_bbio_off = 1,
815 .server_drops = { 3 },
816 },
817 {
818 .desc = "DTLS with dropped ServerHelloDone",
819 .ssl_options = SSL_OP_NO_TICKET,
820 .server_bbio_off = 1,
821 .server_drops = { 4 },
822 },
823#if 0
824 /*
825 * These two result in the server accept completing and the
826 * client looping on a timeout. Presumably the server should not
827 * complete until the client Finished is received... this due to
828 * a flaw in the DTLSv1.0 specification, which is addressed in
829 * DTLSv1.2 (see references to "last flight" in RFC 6347 section
830 * 4.2.4). Our DTLS server code still needs to support this.
831 */
832 {
833 .desc = "DTLS with dropped server CCS",
834 .ssl_options = 0,
835 .server_bbio_off = 1,
836 .server_drops = { 5 },
837 },
838 {
839 .desc = "DTLS with dropped server Finished",
840 .ssl_options = 0,
841 .server_bbio_off = 1,
842 .server_drops = { 6 },
843 },
844#endif
845 {
846 .desc = "DTLS with dropped ClientKeyExchange",
847 .ssl_options = 0,
848 .client_bbio_off = 1,
849 .client_drops = { 2 },
850 },
851 {
852 .desc = "DTLS with dropped client CCS",
853 .ssl_options = 0,
854 .client_bbio_off = 1,
855 .client_drops = { 3 },
856 },
857 {
858 .desc = "DTLS with dropped client Finished",
859 .ssl_options = 0,
860 .client_bbio_off = 1,
861 .client_drops = { 4 },
862 },
863 {
864 /* Send CCS after client Finished. */
865 .desc = "DTLS with delayed client CCS",
866 .ssl_options = 0,
867 .client_bbio_off = 1,
868 .client_delays = { { 3, 2 } },
869 },
870 {
871 /*
872 * Send CCS after server Finished - note app data will be
873 * dropped if we send the CCS after app data.
874 */
875 .desc = "DTLS with delayed server CCS",
876 .ssl_options = SSL_OP_NO_TICKET,
877 .server_bbio_off = 1,
878 .server_delays = { { 5, 2 } },
879 .write_after_accept = 1,
880 },
881 {
882 .desc = "DTLS with delayed server CCS (initial epoch 0xfffe)",
883 .ssl_options = SSL_OP_NO_TICKET,
884 .server_bbio_off = 1,
885 .initial_epoch = 0xfffe,
886 .server_delays = { { 5, 2 } },
887 .write_after_accept = 1,
888 },
889 {
890 .desc = "DTLS with delayed server CCS (initial epoch 0xffff)",
891 .ssl_options = SSL_OP_NO_TICKET,
892 .server_bbio_off = 1,
893 .initial_epoch = 0xffff,
894 .server_delays = { { 5, 2 } },
895 .write_after_accept = 1,
896 },
897 {
898 /* Send Finished after app data - this is currently buffered. */
899 .desc = "DTLS with delayed server Finished",
900 .ssl_options = SSL_OP_NO_TICKET,
901 .server_bbio_off = 1,
902 .server_delays = { { 6, 3 } },
903 .write_after_accept = 1,
904 },
905 {
906 /* Send CCS after server finished and close-notify. */
907 .desc = "DTLS with delayed server CCS (close-notify)",
908 .ssl_options = SSL_OP_NO_TICKET,
909 .server_bbio_off = 1,
910 .server_delays = { { 5, 3 } },
911 .shutdown_after_accept = 1,
912 },
913};
914
915#define N_DTLS_TESTS (sizeof(dtls_tests) / sizeof(*dtls_tests))
916
917static void
918dtlstest_packet_monkey(SSL *ssl, const struct dtls_delay delays[],
919 const uint8_t drops[])
920{
921 BIO *bio_monkey;
922 BIO *bio;
923 int i;
924
925 if ((bio_monkey = BIO_new_packet_monkey()) == NULL)
926 errx(1, "packet monkey");
927
928 for (i = 0; i < MAX_PACKET_DELAYS; i++) {
929 if (delays[i].packet == 0)
930 break;
931 if (!BIO_packet_monkey_delay(bio_monkey, delays[i].packet,
932 delays[i].count))
933 errx(1, "delay failure");
934 }
935
936 for (i = 0; i < MAX_PACKET_DROPS; i++) {
937 if (drops[i] == 0)
938 break;
939 if (!BIO_packet_monkey_drop(bio_monkey, drops[i]))
940 errx(1, "drop failure");
941 }
942
943 if ((bio = SSL_get_wbio(ssl)) == NULL)
944 errx(1, "SSL has NULL bio");
945
946 BIO_up_ref(bio);
947 bio = BIO_push(bio_monkey, bio);
948
949 SSL_set_bio(ssl, bio, bio);
950}
951
952static int
953dtlstest(const struct dtls_test *dt)
954{
955 SSL *client = NULL, *server = NULL;
956 ssl_func *connect_func, *accept_func;
957 struct sockaddr_in server_sin;
958 struct pollfd pfd[2];
959 int client_sock = -1;
960 int server_sock = -1;
961 int failed = 1;
962
963 fprintf(stderr, "\n== Testing %s... ==\n", dt->desc);
964
965 if (!datagram_pair(&client_sock, &server_sock, &server_sin))
966 goto failure;
967
968 if ((client = dtls_client(client_sock, &server_sin, dt->mtu)) == NULL)
969 goto failure;
970
971 if ((server = dtls_server(server_sock, dt->ssl_options, dt->mtu)) == NULL)
972 goto failure;
973
974 tls12_record_layer_set_initial_epoch(client->internal->rl,
975 dt->initial_epoch);
976 tls12_record_layer_set_initial_epoch(server->internal->rl,
977 dt->initial_epoch);
978
979 if (dt->client_bbio_off)
980 SSL_set_info_callback(client, dtls_info_callback);
981 if (dt->server_bbio_off)
982 SSL_set_info_callback(server, dtls_info_callback);
983
984 dtlstest_packet_monkey(client, dt->client_delays, dt->client_drops);
985 dtlstest_packet_monkey(server, dt->server_delays, dt->server_drops);
986
987 pfd[0].fd = client_sock;
988 pfd[0].events = POLLOUT;
989 pfd[1].fd = server_sock;
990 pfd[1].events = POLLIN;
991
992 accept_func = do_accept;
993 connect_func = do_connect;
994
995 if (dt->write_after_accept) {
996 accept_func = do_accept_write;
997 connect_func = do_connect_read;
998 } else if (dt->shutdown_after_accept) {
999 accept_func = do_accept_shutdown;
1000 connect_func = do_connect_shutdown;
1001 }
1002
1003 if (!do_client_server_loop(client, connect_func, server, accept_func, pfd)) {
1004 fprintf(stderr, "FAIL: client and server handshake failed\n");
1005 goto failure;
1006 }
1007
1008 if (dt->write_after_accept || dt->shutdown_after_accept)
1009 goto done;
1010
1011 pfd[0].events = POLLIN;
1012 pfd[1].events = POLLOUT;
1013
1014 if (!do_client_server_loop(client, do_read, server, do_write, pfd)) {
1015 fprintf(stderr, "FAIL: client read and server write I/O failed\n");
1016 goto failure;
1017 }
1018
1019 pfd[0].events = POLLOUT;
1020 pfd[1].events = POLLIN;
1021
1022 if (!do_client_server_loop(client, do_write, server, do_read, pfd)) {
1023 fprintf(stderr, "FAIL: client write and server read I/O failed\n");
1024 goto failure;
1025 }
1026
1027 pfd[0].events = POLLOUT;
1028 pfd[1].events = POLLOUT;
1029
1030 if (!do_client_server_loop(client, do_shutdown, server, do_shutdown, pfd)) {
1031 fprintf(stderr, "FAIL: client and server shutdown failed\n");
1032 goto failure;
1033 }
1034
1035 done:
1036 fprintf(stderr, "INFO: Done!\n");
1037
1038 failed = 0;
1039
1040 failure:
1041 if (client_sock != -1)
1042 close(client_sock);
1043 if (server_sock != -1)
1044 close(server_sock);
1045
1046 SSL_free(client);
1047 SSL_free(server);
1048
1049 return failed;
1050}
1051
1052int
1053main(int argc, char **argv)
1054{
1055 int failed = 0;
1056 size_t i;
1057
1058 if (argc != 4) {
1059 fprintf(stderr, "usage: %s keyfile certfile cafile\n",
1060 argv[0]);
1061 exit(1);
1062 }
1063
1064 server_key_file = argv[1];
1065 server_cert_file = argv[2];
1066 server_ca_file = argv[3];
1067
1068 for (i = 0; i < N_DTLS_TESTS; i++)
1069 failed |= dtlstest(&dtls_tests[i]);
1070
1071 return failed;
1072}