summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2024-01-30 14:46:46 +0000
committerjsing <>2024-01-30 14:46:46 +0000
commit3339ea5d77ded48e0e41a12720882846912c2306 (patch)
tree5a80f006dd1186e196c14e6a59f87e3b8f50ccbc
parent30d39d87f7d79b965a5739bbd0f60511c67b140f (diff)
downloadopenbsd-3339ea5d77ded48e0e41a12720882846912c2306.tar.gz
openbsd-3339ea5d77ded48e0e41a12720882846912c2306.tar.bz2
openbsd-3339ea5d77ded48e0e41a12720882846912c2306.zip
Add a shutdown sequence regress test.
Some software relies on SSL_shutdown() returning 0 (indicating close-notify sent) before returning 1 on a subsequent call (indicating close-notify sent and received). It is worth noting that there is no guarantee that this will occur in normal operation, as the peer could send a close-notify prior to SSL_shutdown() being called. This is currently failing for TLSv1.3.
-rw-r--r--src/regress/lib/libssl/shutdown/shutdowntest.c136
1 files changed, 133 insertions, 3 deletions
diff --git a/src/regress/lib/libssl/shutdown/shutdowntest.c b/src/regress/lib/libssl/shutdown/shutdowntest.c
index 749ccaa435..5b83add359 100644
--- a/src/regress/lib/libssl/shutdown/shutdowntest.c
+++ b/src/regress/lib/libssl/shutdown/shutdowntest.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: shutdowntest.c,v 1.2 2024/01/27 14:35:13 jsing Exp $ */ 1/* $OpenBSD: shutdowntest.c,v 1.3 2024/01/30 14:46:46 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2020, 2021, 2024 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2020, 2021, 2024 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -360,7 +360,7 @@ static const struct shutdown_test shutdown_tests[] = {
360#define N_TLS_TESTS (sizeof(shutdown_tests) / sizeof(*shutdown_tests)) 360#define N_TLS_TESTS (sizeof(shutdown_tests) / sizeof(*shutdown_tests))
361 361
362static int 362static int
363shutdowntest(uint16_t ssl_version, const char *ssl_version_name, 363shutdown_test(uint16_t ssl_version, const char *ssl_version_name,
364 const struct shutdown_test *st) 364 const struct shutdown_test *st)
365{ 365{
366 BIO *client_wbio = NULL, *server_wbio = NULL; 366 BIO *client_wbio = NULL, *server_wbio = NULL;
@@ -479,6 +479,135 @@ shutdowntest(uint16_t ssl_version, const char *ssl_version_name,
479 return failed; 479 return failed;
480} 480}
481 481
482static int
483shutdown_sequence_test(uint16_t ssl_version, const char *ssl_version_name)
484{
485 BIO *client_wbio = NULL, *server_wbio = NULL;
486 SSL *client = NULL, *server = NULL;
487 int shutdown, ret;
488 int failed = 1;
489
490 fprintf(stderr, "\n== Testing %s, shutdown sequence... ==\n",
491 ssl_version_name);
492
493 if ((client_wbio = BIO_new(BIO_s_mem())) == NULL)
494 goto failure;
495 if (BIO_set_mem_eof_return(client_wbio, -1) <= 0)
496 goto failure;
497
498 if ((server_wbio = BIO_new(BIO_s_mem())) == NULL)
499 goto failure;
500 if (BIO_set_mem_eof_return(server_wbio, -1) <= 0)
501 goto failure;
502
503 if ((client = tls_client(server_wbio, client_wbio)) == NULL)
504 goto failure;
505 if (!SSL_set_min_proto_version(client, ssl_version))
506 goto failure;
507 if (!SSL_set_max_proto_version(client, ssl_version))
508 goto failure;
509
510 if ((server = tls_server(client_wbio, server_wbio)) == NULL)
511 goto failure;
512 if (!SSL_set_min_proto_version(server, ssl_version))
513 goto failure;
514 if (!SSL_set_max_proto_version(server, ssl_version))
515 goto failure;
516
517 if (!do_client_server_loop(client, do_connect, server, do_accept)) {
518 fprintf(stderr, "FAIL: client and server handshake failed\n");
519 goto failure;
520 }
521
522 if (!do_client_server_loop(client, do_write, server, do_read)) {
523 fprintf(stderr, "FAIL: client write and server read I/O failed\n");
524 goto failure;
525 }
526
527 if (!do_client_server_loop(client, do_read, server, do_write)) {
528 fprintf(stderr, "FAIL: client read and server write I/O failed\n");
529 goto failure;
530 }
531
532 /*
533 * Shutdown in lock step and check return value and shutdown flags.
534 *
535 * It is not documented, however some software relies on SSL_shutdown()
536 * to only send a close-notify on the first call, then indicate that a
537 * close-notify was received on a second (or later) call.
538 */
539
540 if ((shutdown = SSL_get_shutdown(client)) != 0) {
541 fprintf(stderr, "FAIL: client shutdown flags = %x, want %x\n",
542 shutdown, 0);
543 goto failure;
544 }
545 if ((shutdown = SSL_get_shutdown(server)) != 0) {
546 fprintf(stderr, "FAIL: server shutdown flags = %x, want %x\n",
547 shutdown, 0);
548 goto failure;
549 }
550
551 if ((ret = SSL_shutdown(client)) != 0) {
552 fprintf(stderr, "FAIL: client SSL_shutdown() = %d, want %d\n",
553 ret, 0);
554 goto failure;
555 }
556 if ((shutdown = SSL_get_shutdown(client)) != SSL_SENT_SHUTDOWN) {
557 fprintf(stderr, "FAIL: client shutdown flags = %x, want %x\n",
558 shutdown, SSL_SENT_SHUTDOWN);
559 goto failure;
560 }
561
562 if ((ret = SSL_shutdown(server)) != 0) {
563 fprintf(stderr, "FAIL: server SSL_shutdown() = %d, want %d\n",
564 ret, 0);
565 goto failure;
566 }
567 if ((shutdown = SSL_get_shutdown(server)) != SSL_SENT_SHUTDOWN) {
568 fprintf(stderr, "FAIL: server shutdown flags = %x, want %x\n",
569 shutdown, SSL_SENT_SHUTDOWN);
570 goto failure;
571 }
572
573 if ((ret = SSL_shutdown(client)) != 1) {
574 fprintf(stderr, "FAIL: client SSL_shutdown() = %d, want %d\n",
575 ret, 0);
576 goto failure;
577 }
578 if ((shutdown = SSL_get_shutdown(client)) !=
579 (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) {
580 fprintf(stderr, "FAIL: client shutdown flags = %x, want %x\n",
581 shutdown, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
582 goto failure;
583 }
584
585 if ((ret = SSL_shutdown(server)) != 1) {
586 fprintf(stderr, "FAIL: server SSL_shutdown() = %d, want %d\n",
587 ret, 0);
588 goto failure;
589 }
590 if ((shutdown = SSL_get_shutdown(server)) !=
591 (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) {
592 fprintf(stderr, "FAIL: server shutdown flags = %x, want %x\n",
593 shutdown, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
594 goto failure;
595 }
596
597 fprintf(stderr, "INFO: Done!\n");
598
599 failed = 0;
600
601 failure:
602 BIO_free(client_wbio);
603 BIO_free(server_wbio);
604
605 SSL_free(client);
606 SSL_free(server);
607
608 return failed;
609}
610
482struct ssl_version { 611struct ssl_version {
483 uint16_t version; 612 uint16_t version;
484 const char *name; 613 const char *name;
@@ -517,9 +646,10 @@ main(int argc, char **argv)
517 for (i = 0; i < N_SSL_VERSIONS; i++) { 646 for (i = 0; i < N_SSL_VERSIONS; i++) {
518 sv = &ssl_versions[i]; 647 sv = &ssl_versions[i];
519 for (j = 0; j < N_TLS_TESTS; j++) { 648 for (j = 0; j < N_TLS_TESTS; j++) {
520 failed |= shutdowntest(sv->version, sv->name, 649 failed |= shutdown_test(sv->version, sv->name,
521 &shutdown_tests[j]); 650 &shutdown_tests[j]);
522 } 651 }
652 failed |= shutdown_sequence_test(sv->version, sv->name);
523 } 653 }
524 654
525 return failed; 655 return failed;