From 590ed3d7ea555b877859f6b491020112588fe1be Mon Sep 17 00:00:00 2001 From: Emilia Kasper Date: Tue, 5 Jul 2016 19:06:23 +0200 Subject: [PATCH] SSL test framework: port resumption tests Systematically test every server-side version downgrade or upgrade. Client version upgrade or downgrade could be tested analogously but will be done in a later change. Reviewed-by: Rich Salz Reviewed-by: Matt Caswell --- test/README.ssltest.md | 28 +- test/generate_ssl_tests.pl | 17 +- test/handshake_helper.c | 98 ++- test/handshake_helper.h | 6 +- test/recipes/80-test_ssl_new.t | 5 +- test/recipes/80-test_ssl_old.t | 48 +- test/ssl-tests/02-protocol-version.conf.in | 2 +- test/ssl-tests/05-sni.conf.in | 5 - .../07-dtls-protocol-version.conf.in | 2 +- test/ssl-tests/10-resumption.conf | 652 ++++++++++++++++++ test/ssl-tests/10-resumption.conf.in | 19 + test/ssl-tests/11-dtls_resumption.conf | 300 ++++++++ test/ssl-tests/11-dtls_resumption.conf.in | 19 + test/ssl-tests/protocol_version.pm | 69 +- test/ssl_test.c | 35 +- test/ssl_test.tmpl | 11 +- test/ssl_test_ctx.c | 52 +- test/ssl_test_ctx.h | 17 +- test/ssl_test_ctx_test.c | 22 +- test/ssl_test_ctx_test.conf | 8 + 20 files changed, 1330 insertions(+), 85 deletions(-) create mode 100644 test/ssl-tests/10-resumption.conf create mode 100644 test/ssl-tests/10-resumption.conf.in create mode 100644 test/ssl-tests/11-dtls_resumption.conf create mode 100644 test/ssl-tests/11-dtls_resumption.conf.in diff --git a/test/README.ssltest.md b/test/README.ssltest.md index 9d828b5146..8cd55ed2c3 100644 --- a/test/README.ssltest.md +++ b/test/README.ssltest.md @@ -82,7 +82,20 @@ The test section supports the following options: - Ignore - do not check for a session ticket (default) - Yes - a session ticket is expected - No - a session ticket is not expected - - Broken - a special test case where the session ticket callback does not initialize crypto + - Broken - a special test case where the session ticket callback does not + initialize crypto + +* HandshakeMode - which handshake flavour to test: + - Simple - plain handshake (default) + - Resume - test resumption + - (Renegotiate - test renegotiation, not yet implemented) + +* ResumptionExpected - whether or not resumption is expected (Resume mode only) + - Yes - resumed handshake + - No - full handshake (default) + +When HandshakeMode is Resume or Renegotiate, the original handshake is expected +to succeed. All configured test expectations are verified against the second handshake. * ServerNPNProtocols, Server2NPNProtocols, ClientNPNProtocols, ExpectedNPNProtocol, ServerALPNProtocols, Server2ALPNProtocols, ClientALPNProtocols, ExpectedALPNProtocol - @@ -103,9 +116,16 @@ server => { } ``` -A server2 section may optionally be defined to configure a secondary -context that is selected via the ServerName test option. If the server2 -section is not configured, then the configuration matches server. +The following sections may optionally be defined: + +* server2 - this section configures a secondary context that is selected via the + ServerName test option. This context is used whenever a ServerNameCallback is + specified. If the server2 section is not present, then the configuration + matches server. +* resume_server - this section configures the client to resume its session + against a different server. This context is used whenever HandshakeMode is + Resume. If the resume-server section is not present, then the configuration + matches server. ### Default server and client configurations diff --git a/test/generate_ssl_tests.pl b/test/generate_ssl_tests.pl index 7a016d1fd9..a2f4714587 100644 --- a/test/generate_ssl_tests.pl +++ b/test/generate_ssl_tests.pl @@ -43,12 +43,25 @@ sub print_templates { # Add the implicit base configuration. foreach my $test (@ssltests::tests) { $test->{"server"} = { (%ssltests::base_server, %{$test->{"server"}}) }; - # Do not emit an empty "server2" section. - if (defined $test->{"server2"}) { + if (defined $test->{"server2"}) { $test->{"server2"} = { (%ssltests::base_server, %{$test->{"server2"}}) }; + } elsif (defined $test->{"test"}->{"ServerNameCallback"}) { + # Default is the same as server. + $test->{"server2"} = { (%ssltests::base_server, %{$test->{"server"}}) }; } else { + # Do not emit an empty "server2" section. $test->{"server2"} = { }; } + if (defined $test->{"resume_server"}) { + $test->{"resume_server"} = { (%ssltests::base_server, %{$test->{"resume_server"}}) }; + } elsif (defined $test->{"test"}->{"HandshakeMode"} && + $test->{"test"}->{"HandshakeMode"} eq "Resume") { + # Default is the same as server. + $test->{"resume_server"} = { (%ssltests::base_server, %{$test->{"server"}}) }; + } else { + # Do not emit an empty "resume-server" section. + $test->{"resume_server"} = { }; + } $test->{"client"} = { (%ssltests::base_client, %{$test->{"client"}}) }; } diff --git a/test/handshake_helper.c b/test/handshake_helper.c index 77852ad586..c4f298e945 100644 --- a/test/handshake_helper.c +++ b/test/handshake_helper.c @@ -273,6 +273,9 @@ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, CTX_DATA *server2_ctx_data, CTX_DATA *client_ctx_data) { + unsigned char *ticket_keys; + size_t ticket_key_len; + switch (test_ctx->client_verify_callback) { case SSL_TEST_VERIFY_ACCEPT_ALL: SSL_CTX_set_cert_verify_callback(client_ctx, &verify_accept_cb, @@ -312,7 +315,6 @@ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, if (test_ctx->session_ticket_expected == SSL_TEST_SESSION_TICKET_BROKEN) { SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, broken_session_ticket_cb); } - if (test_ctx->server_npn_protocols != NULL) { parse_protos(test_ctx->server_npn_protocols, &server_ctx_data->npn_protocols, @@ -358,6 +360,16 @@ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, alpn_protos_len) == 0); OPENSSL_free(alpn_protos); } + /* + * Use fixed session ticket keys so that we can decrypt a ticket created with + * one CTX in another CTX. Don't address server2 for the moment. + */ + ticket_key_len = SSL_CTX_set_tlsext_ticket_keys(server_ctx, NULL, 0); + ticket_keys = OPENSSL_zalloc(ticket_key_len); + OPENSSL_assert(ticket_keys != NULL); + OPENSSL_assert(SSL_CTX_set_tlsext_ticket_keys(server_ctx, ticket_keys, + ticket_key_len) == 1); + OPENSSL_free(ticket_keys); } /* Configure per-SSL callbacks and other properties. */ @@ -376,16 +388,31 @@ typedef enum { PEER_ERROR } peer_status_t; -static peer_status_t do_handshake_step(SSL *ssl) +/* + * RFC 5246 says: + * + * Note that as of TLS 1.1, + * failure to properly close a connection no longer requires that a + * session not be resumed. This is a change from TLS 1.0 to conform + * with widespread implementation practice. + * + * However, + * (a) OpenSSL requires that a connection be shutdown for all protocol versions. + * (b) We test lower versions, too. + * So we just implement shutdown. We do a full bidirectional shutdown so that we + * can compare sent and received close_notify alerts and get some test coverage + * for SSL_shutdown as a bonus. + */ +static peer_status_t do_handshake_step(SSL *ssl, int shutdown) { int ret; - ret = SSL_do_handshake(ssl); + ret = shutdown ? SSL_shutdown(ssl) : SSL_do_handshake(ssl); if (ret == 1) { return PEER_SUCCESS; } else if (ret == 0) { - return PEER_ERROR; + return shutdown ? PEER_RETRY : PEER_ERROR; } else { int error = SSL_get_error(ssl, ret); /* Memory bios should never block with SSL_ERROR_WANT_WRITE. */ @@ -484,15 +511,17 @@ static char *dup_str(const unsigned char *in, size_t len) return ret; } -HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, - SSL_CTX *client_ctx, const SSL_TEST_CTX *test_ctx) +static HANDSHAKE_RESULT *do_handshake_internal( + SSL_CTX *server_ctx, SSL_CTX *server2_ctx, SSL_CTX *client_ctx, + const SSL_TEST_CTX *test_ctx, SSL_SESSION *session_in, + SSL_SESSION **session_out) { SSL *server, *client; BIO *client_to_server, *server_to_client; HANDSHAKE_EX_DATA server_ex_data, client_ex_data; CTX_DATA client_ctx_data, server_ctx_data, server2_ctx_data; HANDSHAKE_RESULT *ret = HANDSHAKE_RESULT_new(); - int client_turn = 1; + int client_turn = 1, shutdown = 0; peer_status_t client_status = PEER_RETRY, server_status = PEER_RETRY; handshake_status_t status = HANDSHAKE_RETRY; unsigned char* tick = NULL; @@ -514,6 +543,11 @@ HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, OPENSSL_assert(server != NULL && client != NULL); configure_handshake_ssl(server, client, test_ctx); + if (session_in != NULL) { + /* In case we're testing resumption without tickets. */ + OPENSSL_assert(SSL_CTX_add_session(server_ctx, session_in)); + OPENSSL_assert(SSL_set_session(client, session_in)); + } memset(&server_ex_data, 0, sizeof(server_ex_data)); memset(&client_ex_data, 0, sizeof(client_ex_data)); @@ -559,19 +593,26 @@ HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, */ for(;;) { if (client_turn) { - client_status = do_handshake_step(client); + client_status = do_handshake_step(client, shutdown); status = handshake_status(client_status, server_status, 1 /* client went last */); } else { - server_status = do_handshake_step(server); + server_status = do_handshake_step(server, shutdown); status = handshake_status(server_status, client_status, 0 /* server went last */); } switch (status) { case HANDSHAKE_SUCCESS: - ret->result = SSL_TEST_SUCCESS; - goto err; + if (shutdown) { + ret->result = SSL_TEST_SUCCESS; + goto err; + } else { + client_status = server_status = PEER_RETRY; + shutdown = 1; + client_turn = 1; + break; + } case CLIENT_ERROR: ret->result = SSL_TEST_CLIENT_FAIL; goto err; @@ -615,10 +656,45 @@ HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, SSL_get0_alpn_selected(server, &proto, &proto_len); ret->server_alpn_negotiated = dup_str(proto, proto_len); + ret->client_resumed = SSL_session_reused(client); + ret->server_resumed = SSL_session_reused(server); + + if (session_out != NULL) + *session_out = SSL_get1_session(client); + ctx_data_free_data(&server_ctx_data); ctx_data_free_data(&server2_ctx_data); ctx_data_free_data(&client_ctx_data); + SSL_free(server); SSL_free(client); return ret; } + +HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, + SSL_CTX *client_ctx, SSL_CTX *resume_server_ctx, + const SSL_TEST_CTX *test_ctx) +{ + HANDSHAKE_RESULT *result; + SSL_SESSION *session = NULL; + + result = do_handshake_internal(server_ctx, server2_ctx, client_ctx, + test_ctx, NULL, &session); + if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_SIMPLE) + goto end; + + OPENSSL_assert(test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME); + + if (result->result != SSL_TEST_SUCCESS) { + result->result = SSL_TEST_FIRST_HANDSHAKE_FAILED; + return result; + } + + HANDSHAKE_RESULT_free(result); + /* We don't support SNI on second handshake yet, so server2_ctx is NULL. */ + result = do_handshake_internal(resume_server_ctx, NULL, client_ctx, test_ctx, + session, NULL); + end: + SSL_SESSION_free(session); + return result; +} diff --git a/test/handshake_helper.h b/test/handshake_helper.h index 56c0aac28a..5027bef025 100644 --- a/test/handshake_helper.h +++ b/test/handshake_helper.h @@ -36,6 +36,9 @@ typedef struct handshake_result { char *server_npn_negotiated; char *client_alpn_negotiated; char *server_alpn_negotiated; + /* Was the handshake resumed? */ + int client_resumed; + int server_resumed; } HANDSHAKE_RESULT; HANDSHAKE_RESULT *HANDSHAKE_RESULT_new(void); @@ -43,6 +46,7 @@ void HANDSHAKE_RESULT_free(HANDSHAKE_RESULT *result); /* Do a handshake and report some information about the result. */ HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, - SSL_CTX *client_ctx, const SSL_TEST_CTX *test_ctx); + SSL_CTX *client_ctx, SSL_CTX *resume_server_ctx, + const SSL_TEST_CTX *test_ctx); #endif /* HEADER_HANDSHAKE_HELPER_H */ diff --git a/test/recipes/80-test_ssl_new.t b/test/recipes/80-test_ssl_new.t index 56afb6463c..6867cc3dfc 100644 --- a/test/recipes/80-test_ssl_new.t +++ b/test/recipes/80-test_ssl_new.t @@ -42,12 +42,15 @@ my %conf_dependent_tests = ( "02-protocol-version.conf" => !$is_default_tls, "04-client_auth.conf" => !$is_default_tls, "05-dtls-protocol-version.conf" => !$is_default_dtls, + "10-resumption.conf" => !$is_default_tls, + "11-dtls_resumption.conf" => !$is_default_dtls, ); # Default is $no_tls but some tests have different skip conditions. my %skip = ( "05-dtls-protocol-version.conf" => $no_dtls, "08-npn.conf" => $no_tls || $no_npn, + "11-dtls_resumption.conf" => $no_dtls, ); foreach my $conf (@conf_files) { @@ -60,7 +63,7 @@ foreach my $conf (@conf_files) { # We hard-code the number of tests to double-check that the globbing above # finds all files as expected. -plan tests => 9; # = scalar @conf_srcs +plan tests => 11; # = scalar @conf_srcs sub test_conf { plan tests => 3; diff --git a/test/recipes/80-test_ssl_old.t b/test/recipes/80-test_ssl_old.t index 5228112e16..8f43d6b691 100644 --- a/test/recipes/80-test_ssl_old.t +++ b/test/recipes/80-test_ssl_old.t @@ -79,7 +79,7 @@ my $client_sess="client.ss"; # new format in ssl_test.c and add recipes to 80-test_ssl_new.t instead. plan tests => 1 # For testss - + 11 # For the first testssl + +9 # For the first testssl ; subtest 'test_ss' => sub { @@ -618,52 +618,6 @@ sub testssl { } }; - subtest 'TLS session reuse' => sub { - plan tests => 12; - - SKIP: { - skip "TLS1.1 or TLS1.2 disabled", 12 if $no_tls1_1 || $no_tls1_2; - ok(run(test([@ssltest, "-server_sess_out", $server_sess, "-client_sess_out", $client_sess]))); - ok(run(test([@ssltest, "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "1", "-should_negotiate", "tls1.2"]))); - ok(run(test([@ssltest, "-server_max_proto", "tls1.1", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "0", "-should_negotiate", "tls1.1"]))); - - ok(run(test([@ssltest, "-server_max_proto", "tls1.1", "-server_sess_out", $server_sess, "-client_sess_out", $client_sess]))); - ok(run(test([@ssltest, "-server_max_proto", "tls1.1", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "1", "-should_negotiate", "tls1.1"]))); - ok(run(test([@ssltest, "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "0", "-should_negotiate", "tls1.2"]))); - - ok(run(test([@ssltest, "-no_ticket", "-server_sess_out", $server_sess, "-client_sess_out", $client_sess]))); - ok(run(test([@ssltest, "-no_ticket", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "1", "-should_negotiate", "tls1.2"]))); - ok(run(test([@ssltest, "-no_ticket", "-server_max_proto", "tls1.1", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "0", "-should_negotiate", "tls1.1"]))); - - ok(run(test([@ssltest, "-no_ticket", "-server_max_proto", "tls1.1", "-server_sess_out", $server_sess, "-client_sess_out", $client_sess]))); - ok(run(test([@ssltest, "-no_ticket", "-server_max_proto", "tls1.1", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "1", "-should_negotiate", "tls1.1"]))); - ok(run(test([@ssltest, "-no_ticket", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "0", "-should_negotiate", "tls1.2"]))); - } - }; - - subtest 'DTLS session reuse' => sub { - plan tests => 12; - SKIP: { - skip "DTLS1.0 or DTLS1.2 disabled", 12 if $no_dtls1 || $no_dtls1_2; - - ok(run(test([@ssltest, "-dtls", "-server_sess_out", $server_sess, "-client_sess_out", $client_sess]))); - ok(run(test([@ssltest, "-dtls", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "1", "-should_negotiate", "dtls1.2"]))); - ok(run(test([@ssltest, "-dtls", "-server_max_proto", "dtls1", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "0", "-should_negotiate", "dtls1"]))); - - ok(run(test([@ssltest, "-dtls", "-server_max_proto", "dtls1", "-server_sess_out", $server_sess, "-client_sess_out", $client_sess]))); - ok(run(test([@ssltest, "-dtls", "-server_max_proto", "dtls1", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "1", "-should_negotiate", "dtls1"]))); - ok(run(test([@ssltest, "-dtls", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "0", "-should_negotiate", "dtls1.2"]))); - - ok(run(test([@ssltest, "-dtls", "-no_ticket", "-server_sess_out", $server_sess, "-client_sess_out", $client_sess]))); - ok(run(test([@ssltest, "-dtls", "-no_ticket", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "1", "-should_negotiate", "dtls1.2"]))); - ok(run(test([@ssltest, "-dtls", "-no_ticket", "-server_max_proto", "dtls1", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "0", "-should_negotiate", "dtls1"]))); - - ok(run(test([@ssltest, "-dtls", "-no_ticket", "-server_max_proto", "dtls1", "-server_sess_out", $server_sess, "-client_sess_out", $client_sess]))); - ok(run(test([@ssltest, "-dtls", "-no_ticket", "-server_max_proto", "dtls1", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "1", "-should_negotiate", "dtls1"]))); - ok(run(test([@ssltest, "-dtls", "-no_ticket", "-server_sess_in", $server_sess, "-client_sess_in", $client_sess, "-should_reuse", "0", "-should_negotiate", "dtls1.2"]))); - } - }; - subtest 'Certificate Transparency tests' => sub { ###################################################################### diff --git a/test/ssl-tests/02-protocol-version.conf.in b/test/ssl-tests/02-protocol-version.conf.in index 46851c94fb..26d64b5f88 100644 --- a/test/ssl-tests/02-protocol-version.conf.in +++ b/test/ssl-tests/02-protocol-version.conf.in @@ -16,4 +16,4 @@ use warnings; use protocol_version; -our @tests = generate_tests("TLS"); +our @tests = generate_version_tests("TLS"); diff --git a/test/ssl-tests/05-sni.conf.in b/test/ssl-tests/05-sni.conf.in index 635ce9ae47..0a8378e7a0 100644 --- a/test/ssl-tests/05-sni.conf.in +++ b/test/ssl-tests/05-sni.conf.in @@ -18,7 +18,6 @@ our @tests = ( { name => "SNI-switch-context", server => { }, - server2 => { }, client => { }, test => { "ServerName" => "server2", "ExpectedServerName" => "server2", @@ -28,7 +27,6 @@ our @tests = ( { name => "SNI-keep-context", server => { }, - server2 => { }, client => { }, test => { "ServerName" => "server1", "ExpectedServerName" => "server1", @@ -45,7 +43,6 @@ our @tests = ( { name => "SNI-no-client-support", server => { }, - server2 => { }, client => { }, test => { # We expect that the callback is still called @@ -59,7 +56,6 @@ our @tests = ( { name => "SNI-bad-sni-ignore-mismatch", server => { }, - server2 => { }, client => { }, test => { "ServerName" => "invalid", "ExpectedServerName" => "server1", @@ -69,7 +65,6 @@ our @tests = ( { name => "SNI-bad-sni-reject-mismatch", server => { }, - server2 => { }, client => { }, test => { "ServerName" => "invalid", "ServerNameCallback" => "RejectMismatch", diff --git a/test/ssl-tests/07-dtls-protocol-version.conf.in b/test/ssl-tests/07-dtls-protocol-version.conf.in index 965ed3ed0c..fb3c44a53c 100644 --- a/test/ssl-tests/07-dtls-protocol-version.conf.in +++ b/test/ssl-tests/07-dtls-protocol-version.conf.in @@ -16,4 +16,4 @@ use warnings; use protocol_version; -our @tests = generate_tests("DTLS"); +our @tests = generate_version_tests("DTLS"); diff --git a/test/ssl-tests/10-resumption.conf b/test/ssl-tests/10-resumption.conf new file mode 100644 index 0000000000..899f32166f --- /dev/null +++ b/test/ssl-tests/10-resumption.conf @@ -0,0 +1,652 @@ +# Generated with generate_ssl_tests.pl + +num_tests = 18 + +test-0 = 0-resumption +test-1 = 1-resumption +test-2 = 2-resumption +test-3 = 3-resumption +test-4 = 4-resumption +test-5 = 5-resumption +test-6 = 6-resumption +test-7 = 7-resumption +test-8 = 8-resumption +test-9 = 9-resumption +test-10 = 10-resumption +test-11 = 11-resumption +test-12 = 12-resumption +test-13 = 13-resumption +test-14 = 14-resumption +test-15 = 15-resumption +test-16 = 16-resumption +test-17 = 17-resumption +# =========================================================== + +[0-resumption] +ssl_conf = 0-resumption-ssl + +[0-resumption-ssl] +server = 0-resumption-server +resume-server = 0-resumption-resume-server +client = 0-resumption-client + +[0-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +MinProtocol = TLSv1 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[0-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[0-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-0] +HandshakeMode = Resume +Protocol = TLSv1 +ResumptionExpected = Yes + + +# =========================================================== + +[1-resumption] +ssl_conf = 1-resumption-ssl + +[1-resumption-ssl] +server = 1-resumption-server +resume-server = 1-resumption-resume-server +client = 1-resumption-client + +[1-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +MinProtocol = TLSv1 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[1-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[1-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-1] +HandshakeMode = Resume +Protocol = TLSv1 +ResumptionExpected = Yes + + +# =========================================================== + +[2-resumption] +ssl_conf = 2-resumption-ssl + +[2-resumption-ssl] +server = 2-resumption-server +resume-server = 2-resumption-resume-server +client = 2-resumption-client + +[2-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +MinProtocol = TLSv1 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[2-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[2-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-2] +HandshakeMode = Resume +Protocol = TLSv1.1 +ResumptionExpected = No + + +# =========================================================== + +[3-resumption] +ssl_conf = 3-resumption-ssl + +[3-resumption-ssl] +server = 3-resumption-server +resume-server = 3-resumption-resume-server +client = 3-resumption-client + +[3-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +MinProtocol = TLSv1 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[3-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[3-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-3] +HandshakeMode = Resume +Protocol = TLSv1.1 +ResumptionExpected = No + + +# =========================================================== + +[4-resumption] +ssl_conf = 4-resumption-ssl + +[4-resumption-ssl] +server = 4-resumption-server +resume-server = 4-resumption-resume-server +client = 4-resumption-client + +[4-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +MinProtocol = TLSv1 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[4-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[4-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-4] +HandshakeMode = Resume +Protocol = TLSv1.2 +ResumptionExpected = No + + +# =========================================================== + +[5-resumption] +ssl_conf = 5-resumption-ssl + +[5-resumption-ssl] +server = 5-resumption-server +resume-server = 5-resumption-resume-server +client = 5-resumption-client + +[5-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +MinProtocol = TLSv1 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[5-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[5-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-5] +HandshakeMode = Resume +Protocol = TLSv1.2 +ResumptionExpected = No + + +# =========================================================== + +[6-resumption] +ssl_conf = 6-resumption-ssl + +[6-resumption-ssl] +server = 6-resumption-server +resume-server = 6-resumption-resume-server +client = 6-resumption-client + +[6-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +MinProtocol = TLSv1.1 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[6-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[6-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-6] +HandshakeMode = Resume +Protocol = TLSv1 +ResumptionExpected = No + + +# =========================================================== + +[7-resumption] +ssl_conf = 7-resumption-ssl + +[7-resumption-ssl] +server = 7-resumption-server +resume-server = 7-resumption-resume-server +client = 7-resumption-client + +[7-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +MinProtocol = TLSv1.1 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[7-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[7-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-7] +HandshakeMode = Resume +Protocol = TLSv1 +ResumptionExpected = No + + +# =========================================================== + +[8-resumption] +ssl_conf = 8-resumption-ssl + +[8-resumption-ssl] +server = 8-resumption-server +resume-server = 8-resumption-resume-server +client = 8-resumption-client + +[8-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +MinProtocol = TLSv1.1 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[8-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[8-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-8] +HandshakeMode = Resume +Protocol = TLSv1.1 +ResumptionExpected = Yes + + +# =========================================================== + +[9-resumption] +ssl_conf = 9-resumption-ssl + +[9-resumption-ssl] +server = 9-resumption-server +resume-server = 9-resumption-resume-server +client = 9-resumption-client + +[9-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +MinProtocol = TLSv1.1 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[9-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[9-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-9] +HandshakeMode = Resume +Protocol = TLSv1.1 +ResumptionExpected = Yes + + +# =========================================================== + +[10-resumption] +ssl_conf = 10-resumption-ssl + +[10-resumption-ssl] +server = 10-resumption-server +resume-server = 10-resumption-resume-server +client = 10-resumption-client + +[10-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +MinProtocol = TLSv1.1 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[10-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[10-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-10] +HandshakeMode = Resume +Protocol = TLSv1.2 +ResumptionExpected = No + + +# =========================================================== + +[11-resumption] +ssl_conf = 11-resumption-ssl + +[11-resumption-ssl] +server = 11-resumption-server +resume-server = 11-resumption-resume-server +client = 11-resumption-client + +[11-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +MinProtocol = TLSv1.1 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[11-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[11-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-11] +HandshakeMode = Resume +Protocol = TLSv1.2 +ResumptionExpected = No + + +# =========================================================== + +[12-resumption] +ssl_conf = 12-resumption-ssl + +[12-resumption-ssl] +server = 12-resumption-server +resume-server = 12-resumption-resume-server +client = 12-resumption-client + +[12-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +MinProtocol = TLSv1.2 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[12-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[12-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-12] +HandshakeMode = Resume +Protocol = TLSv1 +ResumptionExpected = No + + +# =========================================================== + +[13-resumption] +ssl_conf = 13-resumption-ssl + +[13-resumption-ssl] +server = 13-resumption-server +resume-server = 13-resumption-resume-server +client = 13-resumption-client + +[13-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +MinProtocol = TLSv1.2 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[13-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[13-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-13] +HandshakeMode = Resume +Protocol = TLSv1 +ResumptionExpected = No + + +# =========================================================== + +[14-resumption] +ssl_conf = 14-resumption-ssl + +[14-resumption-ssl] +server = 14-resumption-server +resume-server = 14-resumption-resume-server +client = 14-resumption-client + +[14-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +MinProtocol = TLSv1.2 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[14-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[14-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-14] +HandshakeMode = Resume +Protocol = TLSv1.1 +ResumptionExpected = No + + +# =========================================================== + +[15-resumption] +ssl_conf = 15-resumption-ssl + +[15-resumption-ssl] +server = 15-resumption-server +resume-server = 15-resumption-resume-server +client = 15-resumption-client + +[15-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +MinProtocol = TLSv1.2 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[15-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[15-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-15] +HandshakeMode = Resume +Protocol = TLSv1.1 +ResumptionExpected = No + + +# =========================================================== + +[16-resumption] +ssl_conf = 16-resumption-ssl + +[16-resumption-ssl] +server = 16-resumption-server +resume-server = 16-resumption-resume-server +client = 16-resumption-client + +[16-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +MinProtocol = TLSv1.2 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[16-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[16-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-16] +HandshakeMode = Resume +Protocol = TLSv1.2 +ResumptionExpected = Yes + + +# =========================================================== + +[17-resumption] +ssl_conf = 17-resumption-ssl + +[17-resumption-ssl] +server = 17-resumption-server +resume-server = 17-resumption-resume-server +client = 17-resumption-client + +[17-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +MinProtocol = TLSv1.2 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[17-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[17-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-17] +HandshakeMode = Resume +Protocol = TLSv1.2 +ResumptionExpected = Yes + + diff --git a/test/ssl-tests/10-resumption.conf.in b/test/ssl-tests/10-resumption.conf.in new file mode 100644 index 0000000000..989135f2fb --- /dev/null +++ b/test/ssl-tests/10-resumption.conf.in @@ -0,0 +1,19 @@ +# -*- mode: perl; -*- +# Copyright 2016-2016 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +## Test version negotiation upon resumption. + +use strict; +use warnings; + +package ssltests; + +use protocol_version; + +our @tests = generate_resumption_tests("TLS"); diff --git a/test/ssl-tests/11-dtls_resumption.conf b/test/ssl-tests/11-dtls_resumption.conf new file mode 100644 index 0000000000..34339448f8 --- /dev/null +++ b/test/ssl-tests/11-dtls_resumption.conf @@ -0,0 +1,300 @@ +# Generated with generate_ssl_tests.pl + +num_tests = 8 + +test-0 = 0-resumption +test-1 = 1-resumption +test-2 = 2-resumption +test-3 = 3-resumption +test-4 = 4-resumption +test-5 = 5-resumption +test-6 = 6-resumption +test-7 = 7-resumption +# =========================================================== + +[0-resumption] +ssl_conf = 0-resumption-ssl + +[0-resumption-ssl] +server = 0-resumption-server +resume-server = 0-resumption-resume-server +client = 0-resumption-client + +[0-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[0-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[0-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-0] +HandshakeMode = Resume +Method = DTLS +Protocol = DTLSv1 +ResumptionExpected = Yes + + +# =========================================================== + +[1-resumption] +ssl_conf = 1-resumption-ssl + +[1-resumption-ssl] +server = 1-resumption-server +resume-server = 1-resumption-resume-server +client = 1-resumption-client + +[1-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[1-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[1-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-1] +HandshakeMode = Resume +Method = DTLS +Protocol = DTLSv1 +ResumptionExpected = Yes + + +# =========================================================== + +[2-resumption] +ssl_conf = 2-resumption-ssl + +[2-resumption-ssl] +server = 2-resumption-server +resume-server = 2-resumption-resume-server +client = 2-resumption-client + +[2-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[2-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[2-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-2] +HandshakeMode = Resume +Method = DTLS +Protocol = DTLSv1.2 +ResumptionExpected = No + + +# =========================================================== + +[3-resumption] +ssl_conf = 3-resumption-ssl + +[3-resumption-ssl] +server = 3-resumption-server +resume-server = 3-resumption-resume-server +client = 3-resumption-client + +[3-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[3-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[3-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-3] +HandshakeMode = Resume +Method = DTLS +Protocol = DTLSv1.2 +ResumptionExpected = No + + +# =========================================================== + +[4-resumption] +ssl_conf = 4-resumption-ssl + +[4-resumption-ssl] +server = 4-resumption-server +resume-server = 4-resumption-resume-server +client = 4-resumption-client + +[4-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[4-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[4-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-4] +HandshakeMode = Resume +Method = DTLS +Protocol = DTLSv1 +ResumptionExpected = No + + +# =========================================================== + +[5-resumption] +ssl_conf = 5-resumption-ssl + +[5-resumption-ssl] +server = 5-resumption-server +resume-server = 5-resumption-resume-server +client = 5-resumption-client + +[5-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[5-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[5-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-5] +HandshakeMode = Resume +Method = DTLS +Protocol = DTLSv1 +ResumptionExpected = No + + +# =========================================================== + +[6-resumption] +ssl_conf = 6-resumption-ssl + +[6-resumption-ssl] +server = 6-resumption-server +resume-server = 6-resumption-resume-server +client = 6-resumption-client + +[6-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[6-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[6-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-6] +HandshakeMode = Resume +Method = DTLS +Protocol = DTLSv1.2 +ResumptionExpected = Yes + + +# =========================================================== + +[7-resumption] +ssl_conf = 7-resumption-ssl + +[7-resumption-ssl] +server = 7-resumption-server +resume-server = 7-resumption-resume-server +client = 7-resumption-client + +[7-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[7-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[7-resumption-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-7] +HandshakeMode = Resume +Method = DTLS +Protocol = DTLSv1.2 +ResumptionExpected = Yes + + diff --git a/test/ssl-tests/11-dtls_resumption.conf.in b/test/ssl-tests/11-dtls_resumption.conf.in new file mode 100644 index 0000000000..16dec1d56f --- /dev/null +++ b/test/ssl-tests/11-dtls_resumption.conf.in @@ -0,0 +1,19 @@ +# -*- mode: perl; -*- +# Copyright 2016-2016 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +## Test version negotiation upon resumption. + +use strict; +use warnings; + +package ssltests; + +use protocol_version; + +our @tests = generate_resumption_tests("DTLS"); diff --git a/test/ssl-tests/protocol_version.pm b/test/ssl-tests/protocol_version.pm index cb9975678e..276adfd44d 100644 --- a/test/ssl-tests/protocol_version.pm +++ b/test/ssl-tests/protocol_version.pm @@ -71,12 +71,18 @@ foreach my $i (0..$#dtls_protocols) { } } -sub generate_tests { +sub no_tests { + my ($dtls) = @_; + return $dtls ? alldisabled("dtls1", "dtls1_2") : + alldisabled("ssl3", "tls1", "tls1_1", "tls1_2"); +} + +sub generate_version_tests { my ($method) = @_; my $dtls = $method eq "DTLS"; # Don't write the redundant "Method = TLS" into the configuration. - undef $method if !$dtls; + undef $method if !$dtls; my @protocols = $dtls ? @dtls_protocols : @tls_protocols; my @min_protocols = $dtls ? @min_dtls_protocols : @min_tls_protocols; @@ -84,9 +90,7 @@ sub generate_tests { my $min_enabled = $dtls ? $min_dtls_enabled : $min_tls_enabled; my $max_enabled = $dtls ? $max_dtls_enabled : $max_tls_enabled; - my $no_tests = $dtls ? alldisabled("dtls1", "dtls1_2") : - alldisabled("ssl3", "tls1", "tls1_1", "tls1_2"); - if ($no_tests) { + if (no_tests($dtls)) { return; } @@ -124,6 +128,61 @@ sub generate_tests { return @tests; } +sub generate_resumption_tests { + my ($method) = @_; + + my $dtls = $method eq "DTLS"; + # Don't write the redundant "Method = TLS" into the configuration. + undef $method if !$dtls; + + my @protocols = $dtls ? @dtls_protocols : @tls_protocols; + my $min_enabled = $dtls ? $min_dtls_enabled : $min_tls_enabled; + + if (no_tests($dtls)) { + return; + } + + my @tests = (); + + # Obtain the first session against a fixed-version server. + foreach my $original_protocol($min_enabled..$#protocols) { + # Upgrade or downgrade the server max version support and test + # that it upgrades, downgrades or resumes the session as well. + foreach my $resume_protocol($min_enabled..$#protocols) { + my $resumption_expected; + # We should only resume on exact version match. + if ($original_protocol eq $resume_protocol) { + $resumption_expected = "Yes"; + } else { + $resumption_expected = "No"; + } + + foreach my $ticket ("SessionTicket", "-SessionTicket") { + push @tests, { + "name" => "resumption", + "client" => { }, + "server" => { + "MinProtocol" => $protocols[$original_protocol], + "MaxProtocol" => $protocols[$original_protocol], + "Options" => $ticket, + }, + "resume_server" => { + "MaxProtocol" => $protocols[$resume_protocol], + }, + "test" => { + "Protocol" => $protocols[$resume_protocol], + "Method" => $method, + "HandshakeMode" => "Resume", + "ResumptionExpected" => $resumption_expected, + } + }; + } + } + } + + return @tests; +} + sub expected_result { my ($c_min, $c_max, $s_min, $s_max, $min_enabled, $max_enabled, $protocols) = @_; diff --git a/test/ssl_test.c b/test/ssl_test.c index 5a3aaa8d08..c5deeb209b 100644 --- a/test/ssl_test.c +++ b/test/ssl_test.c @@ -174,6 +174,21 @@ static int check_alpn(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) return ret; } +static int check_resumption(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) +{ + if (result->client_resumed != result->server_resumed) { + fprintf(stderr, "Resumption mismatch (client vs server): %d vs %d\n", + result->client_resumed, result->server_resumed); + return 0; + } + if (result->client_resumed != test_ctx->resumption_expected) { + fprintf(stderr, "ResumptionExpected mismatch: %d vs %d\n", + test_ctx->resumption_expected, result->client_resumed); + return 0; + } + return 1; +} + /* * This could be further simplified by constructing an expected * HANDSHAKE_RESULT, and implementing comparison methods for @@ -191,6 +206,7 @@ static int check_test(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) ret &= (result->session_ticket_do_not_call == 0); ret &= check_npn(result, test_ctx); ret &= check_alpn(result, test_ctx); + ret &= check_resumption(result, test_ctx); } return ret; } @@ -198,7 +214,8 @@ static int check_test(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) static int execute_test(SSL_TEST_FIXTURE fixture) { int ret = 0; - SSL_CTX *server_ctx = NULL, *server2_ctx = NULL, *client_ctx = NULL; + SSL_CTX *server_ctx = NULL, *server2_ctx = NULL, *client_ctx = NULL, + *resume_server_ctx = NULL; SSL_TEST_CTX *test_ctx = NULL; HANDSHAKE_RESULT *result = NULL; @@ -214,6 +231,10 @@ static int execute_test(SSL_TEST_FIXTURE fixture) OPENSSL_assert(server2_ctx != NULL); } client_ctx = SSL_CTX_new(DTLS_client_method()); + if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) { + resume_server_ctx = SSL_CTX_new(DTLS_server_method()); + OPENSSL_assert(resume_server_ctx != NULL); + } } #endif if (test_ctx->method == SSL_TEST_METHOD_TLS) { @@ -223,6 +244,11 @@ static int execute_test(SSL_TEST_FIXTURE fixture) OPENSSL_assert(server2_ctx != NULL); } client_ctx = SSL_CTX_new(TLS_client_method()); + + if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) { + resume_server_ctx = SSL_CTX_new(TLS_server_method()); + OPENSSL_assert(resume_server_ctx != NULL); + } } OPENSSL_assert(server_ctx != NULL && client_ctx != NULL); @@ -236,8 +262,12 @@ static int execute_test(SSL_TEST_FIXTURE fixture) if (server2_ctx != NULL && !SSL_CTX_config(server2_ctx, "server2")) goto err; + if (resume_server_ctx != NULL + && !SSL_CTX_config(resume_server_ctx, "resume-server")) + goto err; - result = do_handshake(server_ctx, server2_ctx, client_ctx, test_ctx); + result = do_handshake(server_ctx, server2_ctx, client_ctx, + resume_server_ctx, test_ctx); ret = check_test(result, test_ctx); @@ -246,6 +276,7 @@ err: SSL_CTX_free(server_ctx); SSL_CTX_free(server2_ctx); SSL_CTX_free(client_ctx); + SSL_CTX_free(resume_server_ctx); SSL_TEST_CTX_free(test_ctx); if (ret != 1) ERR_print_errors_fp(stderr); diff --git a/test/ssl_test.tmpl b/test/ssl_test.tmpl index 6a5333e9f4..31699183a1 100644 --- a/test/ssl_test.tmpl +++ b/test/ssl_test.tmpl @@ -3,11 +3,14 @@ ssl_conf = {-$testname-}-ssl [{-$testname-}-ssl] server = {-$testname-}-server{- - # The server2 section is optional. + # The following sections are optional. $OUT = ""; if (%server2) { $OUT .= "\nserver2 = $testname-server2"; } + if (%resume_server) { + $OUT .= "\nresume-server = $testname-resume-server"; + } -} client = {-$testname-}-client @@ -22,6 +25,12 @@ client = {-$testname-}-client $OUT .= qq{$key} . " = " . qq{$server2{$key}\n} if defined $server2{$key}; } } + if (%resume_server) { + $OUT .= "\n[$testname-resume-server]\n"; + foreach my $key (sort keys %resume_server) { + $OUT .= qq{$key} . " = " . qq{$resume_server{$key}\n} if defined $resume_server{$key}; + } + } -} [{-$testname-}-client] {- diff --git a/test/ssl_test_ctx.c b/test/ssl_test_ctx.c index 090e1a330e..8dd63ae7dc 100644 --- a/test/ssl_test_ctx.c +++ b/test/ssl_test_ctx.c @@ -304,6 +304,54 @@ IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(server_alpn_protocols) IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(server2_alpn_protocols) IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(expected_alpn_protocol) +/***********************/ +/* Handshake mode */ +/***********************/ + +static const test_enum ssl_handshake_modes[] = { + {"Simple", SSL_TEST_HANDSHAKE_SIMPLE}, + {"Resume", SSL_TEST_HANDSHAKE_RESUME}, + {"Renegotiate", SSL_TEST_HANDSHAKE_RENEGOTIATE}, +}; + +__owur static int parse_handshake_mode(SSL_TEST_CTX *test_ctx, const char *value) +{ + int ret_value; + if (!parse_enum(ssl_handshake_modes, OSSL_NELEM(ssl_handshake_modes), + &ret_value, value)) { + return 0; + } + test_ctx->handshake_mode = ret_value; + return 1; +} + +const char *ssl_handshake_mode_name(ssl_handshake_mode_t mode) +{ + return enum_name(ssl_handshake_modes, OSSL_NELEM(ssl_handshake_modes), + mode); +} + +static int parse_boolean(const char *value, int *result) +{ + if (strcmp(value, "Yes") == 0) { + *result = 1; + return 1; + } + else if (strcmp(value, "No") == 0) { + *result = 0; + return 1; + } + return 0; +} + +#define IMPLEMENT_SSL_TEST_CTX_BOOL_OPTION(field) \ + static int parse_##field(SSL_TEST_CTX *test_ctx, const char *value) \ + { \ + return parse_boolean(value, &test_ctx->field); \ + } + +IMPLEMENT_SSL_TEST_CTX_BOOL_OPTION(resumption_expected) + /*************************************************************/ /* Known test options and their corresponding parse methods. */ /*************************************************************/ @@ -332,6 +380,8 @@ static const ssl_test_ctx_option ssl_test_ctx_options[] = { { "ServerALPNProtocols", &parse_server_alpn_protocols }, { "Server2ALPNProtocols", &parse_server2_alpn_protocols }, { "ExpectedALPNProtocol", &parse_expected_alpn_protocol }, + { "HandshakeMode", &parse_handshake_mode }, + { "ResumptionExpected", &parse_resumption_expected }, }; /* @@ -377,7 +427,7 @@ SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section) int found = 0; const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i); for (j = 0; j < OSSL_NELEM(ssl_test_ctx_options); j++) { - if (strcmp(option->name, ssl_test_ctx_options[j].name) == 0) { + if (strcasecmp(option->name, ssl_test_ctx_options[j].name) == 0) { if (!ssl_test_ctx_options[j].parse(ctx, option->value)) { fprintf(stderr, "Bad value %s for option %s\n", option->value, option->name); diff --git a/test/ssl_test_ctx.h b/test/ssl_test_ctx.h index a96245eec7..d3d86e7fee 100644 --- a/test/ssl_test_ctx.h +++ b/test/ssl_test_ctx.h @@ -17,7 +17,9 @@ typedef enum { SSL_TEST_SUCCESS = 0, /* Default */ SSL_TEST_SERVER_FAIL, SSL_TEST_CLIENT_FAIL, - SSL_TEST_INTERNAL_ERROR + SSL_TEST_INTERNAL_ERROR, + /* Couldn't test resumption/renegotiation: original handshake failed. */ + SSL_TEST_FIRST_HANDSHAKE_FAILED } ssl_test_result_t; typedef enum { @@ -39,7 +41,6 @@ typedef enum { SSL_TEST_SERVERNAME_REJECT_MISMATCH } ssl_servername_callback_t; - typedef enum { SSL_TEST_SESSION_TICKET_IGNORE = 0, /* Default */ SSL_TEST_SESSION_TICKET_YES, @@ -52,6 +53,13 @@ typedef enum { SSL_TEST_METHOD_DTLS } ssl_test_method_t; +typedef enum { + SSL_TEST_HANDSHAKE_SIMPLE = 0, /* Default */ + SSL_TEST_HANDSHAKE_RESUME, + /* Not yet implemented */ + SSL_TEST_HANDSHAKE_RENEGOTIATE +} ssl_handshake_mode_t; + typedef struct ssl_test_ctx { /* Test expectations. */ /* Defaults to SUCCESS. */ @@ -96,6 +104,10 @@ typedef struct ssl_test_ctx { char *server_alpn_protocols; char *server2_alpn_protocols; char *expected_alpn_protocol; + /* Whether to test a resumed/renegotiated handshake. */ + ssl_handshake_mode_t handshake_mode; + /* Whether the second handshake is resumed or a full handshake (boolean). */ + int resumption_expected; } SSL_TEST_CTX; const char *ssl_test_result_name(ssl_test_result_t result); @@ -107,6 +119,7 @@ const char *ssl_servername_callback_name(ssl_servername_callback_t servername_callback); const char *ssl_session_ticket_name(ssl_session_ticket_t server); const char *ssl_test_method_name(ssl_test_method_t method); +const char *ssl_handshake_mode_name(ssl_handshake_mode_t mode); /* * Load the test case context from |conf|. diff --git a/test/ssl_test_ctx_test.c b/test/ssl_test_ctx_test.c index b3e2e705a3..6366e0ad59 100644 --- a/test/ssl_test_ctx_test.c +++ b/test/ssl_test_ctx_test.c @@ -92,7 +92,12 @@ static int SSL_TEST_CTX_equal(SSL_TEST_CTX *ctx, SSL_TEST_CTX *ctx2) if (!strings_equal("ClientNPNProtocols", ctx->client_npn_protocols, ctx2->client_npn_protocols)) return 0; - + if (ctx->method != ctx2->method) { + fprintf(stderr, "Method mismatch: %s vs %s.\n", + ssl_test_method_name(ctx->method), + ssl_test_method_name(ctx2->method)); + return 0; + } if (!strings_equal("ServerNPNProtocols", ctx->server_npn_protocols, ctx2->server_npn_protocols)) return 0; @@ -115,6 +120,17 @@ static int SSL_TEST_CTX_equal(SSL_TEST_CTX *ctx, SSL_TEST_CTX *ctx2) if (!strings_equal("ExpectedALPNProtocol", ctx->expected_alpn_protocol, ctx2->expected_alpn_protocol)) return 0; + if (ctx->handshake_mode != ctx2->handshake_mode) { + fprintf(stderr, "HandshakeMode mismatch: %s vs %s.\n", + ssl_handshake_mode_name(ctx->handshake_mode), + ssl_handshake_mode_name(ctx2->handshake_mode)); + return 0; + } + if (ctx->resumption_expected != ctx2->resumption_expected) { + fprintf(stderr, "ResumptionExpected mismatch: %d vs %d.\n", + ctx->resumption_expected, ctx2->resumption_expected); + return 0; + } return 1; } @@ -202,6 +218,8 @@ static int test_good_configuration() fixture.expected_ctx->server2_alpn_protocols = OPENSSL_strdup("baz"); OPENSSL_assert(fixture.expected_ctx->client_npn_protocols != NULL); OPENSSL_assert(fixture.expected_ctx->server2_alpn_protocols != NULL); + fixture.expected_ctx->handshake_mode = SSL_TEST_HANDSHAKE_RESUME; + fixture.expected_ctx->resumption_expected = 1; EXECUTE_SSL_TEST_CTX_TEST(); } @@ -215,6 +233,8 @@ static const char *bad_configurations[] = { "ssltest_unknown_servername_callback", "ssltest_unknown_session_ticket_expected", "ssltest_unknown_method", + "ssltest_unknown_handshake_mode", + "ssltest_unknown_resumption_expected", }; static int test_bad_configuration(int idx) diff --git a/test/ssl_test_ctx_test.conf b/test/ssl_test_ctx_test.conf index 17925b5c7a..1f76155b37 100644 --- a/test/ssl_test_ctx_test.conf +++ b/test/ssl_test_ctx_test.conf @@ -12,6 +12,8 @@ SessionTicketExpected = Yes Method = DTLS ClientNPNProtocols = foo,bar Server2ALPNProtocols = baz +HandshakeMode = Resume +ResumptionExpected = Yes [ssltest_unknown_option] UnknownOption = Foo @@ -39,3 +41,9 @@ SessionTicketExpected = Foo [ssltest_unknown_method] Method = TLS2 + +[ssltest_unknown_handshake_mode] +HandshakeMode = Foo + +[ssltest_unknown_resumption_expected] +ResumptionExpected = Foo -- 2.34.1