diff --git a/CHANGES b/CHANGES index 645fafb82..54fa50839 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,8 @@ Changes between 8.4.0 and 8.5.0 [xx XXX xxxx] + *) 修复CVE-2024-5535 + *) 修复CVE-2024-4741 *) 修复CVE-2024-4603 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 6b0b21d0b..75d297275 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -3010,37 +3010,54 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, unsigned int server_len, const unsigned char *client, unsigned int client_len) { - unsigned int i, j; - const unsigned char *result; - int status = OPENSSL_NPN_UNSUPPORTED; + PACKET cpkt, csubpkt, spkt, ssubpkt; + + if (!PACKET_buf_init(&cpkt, client, client_len) + || !PACKET_get_length_prefixed_1(&cpkt, &csubpkt) + || PACKET_remaining(&csubpkt) == 0) { + *out = NULL; + *outlen = 0; + return OPENSSL_NPN_NO_OVERLAP; + } + + /* + * Set the default opportunistic protocol. Will be overwritten if we find + * a match. + */ + *out = (unsigned char *)PACKET_data(&csubpkt); + *outlen = (unsigned char)PACKET_remaining(&csubpkt); /* * For each protocol in server preference order, see if we support it. */ - for (i = 0; i < server_len;) { - for (j = 0; j < client_len;) { - if (server[i] == client[j] && - memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) { - /* We found a match */ - result = &server[i]; - status = OPENSSL_NPN_NEGOTIATED; - goto found; + if (PACKET_buf_init(&spkt, server, server_len)) { + while (PACKET_get_length_prefixed_1(&spkt, &ssubpkt)) { + if (PACKET_remaining(&ssubpkt) == 0) + continue; /* Invalid - ignore it */ + if (PACKET_buf_init(&cpkt, client, client_len)) { + while (PACKET_get_length_prefixed_1(&cpkt, &csubpkt)) { + if (PACKET_equal(&csubpkt, PACKET_data(&ssubpkt), + PACKET_remaining(&ssubpkt))) { + /* We found a match */ + *out = (unsigned char *)PACKET_data(&ssubpkt); + *outlen = (unsigned char)PACKET_remaining(&ssubpkt); + return OPENSSL_NPN_NEGOTIATED; + } + } + /* Ignore spurious trailing bytes in the client list */ + } else { + /* This should never happen */ + return OPENSSL_NPN_NO_OVERLAP; } - j += client[j]; - j++; } - i += server[i]; - i++; + /* Ignore spurious trailing bytes in the server list */ } - /* There's no overlap between our protocols and the server's list. */ - result = client; - status = OPENSSL_NPN_NO_OVERLAP; - - found: - *out = (unsigned char *)result + 1; - *outlen = result[0]; - return status; + /* + * There's no overlap between our protocols and the server's list. We use + * the default opportunistic protocol selected earlier + */ + return OPENSSL_NPN_NO_OVERLAP; } #ifndef OPENSSL_NO_NEXTPROTONEG diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 3f914dba5..3efeb9ce0 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -1650,7 +1650,8 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, PACKET_data(pkt), PACKET_remaining(pkt), s->ctx->ext.npn_select_cb_arg) != - SSL_TLSEXT_ERR_OK) { + SSL_TLSEXT_ERR_OK + || selected_len == 0) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_EXTENSION); return 0; } @@ -1679,6 +1680,8 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { size_t len; + PACKET confpkt, protpkt; + int valid = 0; /* We must have requested it. */ if (!s->s3.alpn_sent) { @@ -1697,6 +1700,28 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } + + /* It must be a protocol that we sent */ + if (!PACKET_buf_init(&confpkt, s->ext.alpn, s->ext.alpn_len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + while (PACKET_get_length_prefixed_1(&confpkt, &protpkt)) { + if (PACKET_remaining(&protpkt) != len) + continue; + if (memcmp(PACKET_data(pkt), PACKET_data(&protpkt), len) == 0) { + /* Valid protocol found */ + valid = 1; + break; + } + } + + if (!valid) { + /* The protocol sent from the server does not match one we advertised */ + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + OPENSSL_free(s->s3.alpn_selected); s->s3.alpn_selected = OPENSSL_malloc(len); if (s->s3.alpn_selected == NULL) { diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 84bc87f2e..b386cfa90 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1566,9 +1566,10 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, return EXT_RETURN_FAIL; } s->s3.npn_seen = 1; + return EXT_RETURN_SENT; } - return EXT_RETURN_SENT; + return EXT_RETURN_NOT_SENT; } #endif diff --git a/ssl/statem_ntls/ntls_extensions_clnt.c b/ssl/statem_ntls/ntls_extensions_clnt.c index 75c0812f1..3a27dbc97 100644 --- a/ssl/statem_ntls/ntls_extensions_clnt.c +++ b/ssl/statem_ntls/ntls_extensions_clnt.c @@ -644,7 +644,8 @@ int tls_parse_stoc_npn_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, PACKET_data(pkt), PACKET_remaining(pkt), s->ctx->ext.npn_select_cb_arg) != - SSL_TLSEXT_ERR_OK) { + SSL_TLSEXT_ERR_OK + || selected_len == 0) { SSLfatal_ntls(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_EXTENSION); return 0; } @@ -673,6 +674,8 @@ int tls_parse_stoc_alpn_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { size_t len; + PACKET confpkt, protpkt; + int valid = 0; /* We must have requested it. */ if (!s->s3.alpn_sent) { @@ -691,6 +694,28 @@ int tls_parse_stoc_alpn_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } + + /* It must be a protocol that we sent */ + if (!PACKET_buf_init(&confpkt, s->ext.alpn, s->ext.alpn_len)) { + SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + while (PACKET_get_length_prefixed_1(&confpkt, &protpkt)) { + if (PACKET_remaining(&protpkt) != len) + continue; + if (memcmp(PACKET_data(pkt), PACKET_data(&protpkt), len) == 0) { + /* Valid protocol found */ + valid = 1; + break; + } + } + + if (!valid) { + /* The protocol sent from the server does not match one we advertised */ + SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + OPENSSL_free(s->s3.alpn_selected); s->s3.alpn_selected = OPENSSL_malloc(len); if (s->s3.alpn_selected == NULL) { diff --git a/ssl/statem_ntls/ntls_extensions_srvr.c b/ssl/statem_ntls/ntls_extensions_srvr.c index 0c4e4d60d..38db60294 100644 --- a/ssl/statem_ntls/ntls_extensions_srvr.c +++ b/ssl/statem_ntls/ntls_extensions_srvr.c @@ -587,9 +587,10 @@ EXT_RETURN tls_construct_stoc_next_proto_neg_ntls(SSL *s, WPACKET *pkt, return EXT_RETURN_FAIL; } s->s3.npn_seen = 1; + return EXT_RETURN_SENT; } - return EXT_RETURN_SENT; + return EXT_RETURN_NOT_SENT; } #endif diff --git a/test/helpers/handshake.c b/test/helpers/handshake.c index 3697a5fc7..190b69c8b 100644 --- a/test/helpers/handshake.c +++ b/test/helpers/handshake.c @@ -349,6 +349,12 @@ static int parse_protos(const char *protos, unsigned char **out, size_t *outlen) len = strlen(protos); + if (len == 0) { + *out = NULL; + *outlen = 0; + return 1; + } + /* Should never have reuse. */ if (!TEST_ptr_null(*out) /* Test values are small, so we omit length limit checks. */ diff --git a/test/recipes/70-test_npn.t b/test/recipes/70-test_npn.t new file mode 100644 index 000000000..f82e71af6 --- /dev/null +++ b/test/recipes/70-test_npn.t @@ -0,0 +1,73 @@ +#! /usr/bin/env perl +# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (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 + +use strict; +use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file/; +use OpenSSL::Test::Utils; + +use TLSProxy::Proxy; + +my $test_name = "test_npn"; +setup($test_name); + +plan skip_all => "TLSProxy isn't usable on $^O" + if $^O =~ /^(VMS)$/; + +plan skip_all => "$test_name needs the dynamic engine feature enabled" + if disabled("engine") || disabled("dynamic-engine"); + +plan skip_all => "$test_name needs the sock feature enabled" + if disabled("sock"); + +plan skip_all => "$test_name needs NPN enabled" + if disabled("nextprotoneg"); + +plan skip_all => "$test_name needs TLSv1.2 enabled" + if disabled("tls1_2"); + +my $proxy = TLSProxy::Proxy->new( + undef, + cmdstr(app(["openssl"]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}) +); + +$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; +plan tests => 1; + +my $npnseen = 0; + +# Test 1: Check sending an empty NextProto message from the client works. This is +# valid as per the spec, but OpenSSL does not allow you to send it. +# Therefore we must be prepared to receive such a message but we cannot +# generate it except via TLSProxy +$proxy->clear(); +$proxy->filter(\&npn_filter); +$proxy->clientflags("-nextprotoneg foo -no_tls1_3"); +$proxy->serverflags("-nextprotoneg foo"); +$proxy->start(); +ok($npnseen && TLSProxy::Message->success(), "Empty NPN message"); + +sub npn_filter +{ + my $proxy = shift; + my $message; + + # The NextProto message always appears in flight 2 + return if $proxy->flight != 2; + + foreach my $message (@{$proxy->message_list}) { + if ($message->mt == TLSProxy::Message::MT_NEXT_PROTO) { + # Our TLSproxy NextProto message support doesn't support parsing of + # the message. If we repack it just creates an empty NextProto + # message - which is exactly the scenario we want to test here. + $message->repack(); + $npnseen = 1; + } + } +} diff --git a/test/ssl-tests/08-npn.cnf b/test/ssl-tests/08-npn.cnf index f38b3f697..1931d02de 100644 --- a/test/ssl-tests/08-npn.cnf +++ b/test/ssl-tests/08-npn.cnf @@ -1,6 +1,6 @@ # Generated with generate_ssl_tests.pl -num_tests = 20 +num_tests = 22 test-0 = 0-npn-simple test-1 = 1-npn-client-finds-match @@ -8,20 +8,22 @@ test-2 = 2-npn-client-honours-server-pref test-3 = 3-npn-client-first-pref-on-mismatch test-4 = 4-npn-no-server-support test-5 = 5-npn-no-client-support -test-6 = 6-npn-with-sni-no-context-switch -test-7 = 7-npn-with-sni-context-switch -test-8 = 8-npn-selected-sni-server-supports-npn -test-9 = 9-npn-selected-sni-server-does-not-support-npn -test-10 = 10-alpn-preferred-over-npn -test-11 = 11-sni-npn-preferred-over-alpn -test-12 = 12-npn-simple-resumption -test-13 = 13-npn-server-switch-resumption -test-14 = 14-npn-client-switch-resumption -test-15 = 15-npn-client-first-pref-on-mismatch-resumption -test-16 = 16-npn-no-server-support-resumption -test-17 = 17-npn-no-client-support-resumption -test-18 = 18-alpn-preferred-over-npn-resumption -test-19 = 19-npn-used-if-alpn-not-supported-resumption +test-6 = 6-npn-empty-client-list +test-7 = 7-npn-empty-server-list +test-8 = 8-npn-with-sni-no-context-switch +test-9 = 9-npn-with-sni-context-switch +test-10 = 10-npn-selected-sni-server-supports-npn +test-11 = 11-npn-selected-sni-server-does-not-support-npn +test-12 = 12-alpn-preferred-over-npn +test-13 = 13-sni-npn-preferred-over-alpn +test-14 = 14-npn-simple-resumption +test-15 = 15-npn-server-switch-resumption +test-16 = 16-npn-client-switch-resumption +test-17 = 17-npn-client-first-pref-on-mismatch-resumption +test-18 = 18-npn-no-server-support-resumption +test-19 = 19-npn-no-client-support-resumption +test-20 = 20-alpn-preferred-over-npn-resumption +test-21 = 21-npn-used-if-alpn-not-supported-resumption # =========================================================== [0-npn-simple] @@ -206,253 +208,318 @@ NPNProtocols = foo # =========================================================== -[6-npn-with-sni-no-context-switch] -ssl_conf = 6-npn-with-sni-no-context-switch-ssl +[6-npn-empty-client-list] +ssl_conf = 6-npn-empty-client-list-ssl -[6-npn-with-sni-no-context-switch-ssl] -server = 6-npn-with-sni-no-context-switch-server -client = 6-npn-with-sni-no-context-switch-client -server2 = 6-npn-with-sni-no-context-switch-server2 +[6-npn-empty-client-list-ssl] +server = 6-npn-empty-client-list-server +client = 6-npn-empty-client-list-client -[6-npn-with-sni-no-context-switch-server] +[6-npn-empty-client-list-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[6-npn-with-sni-no-context-switch-server2] +[6-npn-empty-client-list-client] +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-6] +ExpectedClientAlert = HandshakeFailure +ExpectedResult = ClientFail +server = 6-npn-empty-client-list-server-extra +client = 6-npn-empty-client-list-client-extra + +[6-npn-empty-client-list-server-extra] +NPNProtocols = foo + +[6-npn-empty-client-list-client-extra] +NPNProtocols = + + +# =========================================================== + +[7-npn-empty-server-list] +ssl_conf = 7-npn-empty-server-list-ssl + +[7-npn-empty-server-list-ssl] +server = 7-npn-empty-server-list-server +client = 7-npn-empty-server-list-client + +[7-npn-empty-server-list-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[6-npn-with-sni-no-context-switch-client] +[7-npn-empty-server-list-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-6] +[test-7] +ExpectedNPNProtocol = foo +server = 7-npn-empty-server-list-server-extra +client = 7-npn-empty-server-list-client-extra + +[7-npn-empty-server-list-server-extra] +NPNProtocols = + +[7-npn-empty-server-list-client-extra] +NPNProtocols = foo + + +# =========================================================== + +[8-npn-with-sni-no-context-switch] +ssl_conf = 8-npn-with-sni-no-context-switch-ssl + +[8-npn-with-sni-no-context-switch-ssl] +server = 8-npn-with-sni-no-context-switch-server +client = 8-npn-with-sni-no-context-switch-client +server2 = 8-npn-with-sni-no-context-switch-server2 + +[8-npn-with-sni-no-context-switch-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[8-npn-with-sni-no-context-switch-server2] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[8-npn-with-sni-no-context-switch-client] +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-8] ExpectedNPNProtocol = foo ExpectedServerName = server1 -server = 6-npn-with-sni-no-context-switch-server-extra -server2 = 6-npn-with-sni-no-context-switch-server2-extra -client = 6-npn-with-sni-no-context-switch-client-extra +server = 8-npn-with-sni-no-context-switch-server-extra +server2 = 8-npn-with-sni-no-context-switch-server2-extra +client = 8-npn-with-sni-no-context-switch-client-extra -[6-npn-with-sni-no-context-switch-server-extra] +[8-npn-with-sni-no-context-switch-server-extra] NPNProtocols = foo ServerNameCallback = IgnoreMismatch -[6-npn-with-sni-no-context-switch-server2-extra] +[8-npn-with-sni-no-context-switch-server2-extra] NPNProtocols = bar -[6-npn-with-sni-no-context-switch-client-extra] +[8-npn-with-sni-no-context-switch-client-extra] NPNProtocols = foo,bar ServerName = server1 # =========================================================== -[7-npn-with-sni-context-switch] -ssl_conf = 7-npn-with-sni-context-switch-ssl +[9-npn-with-sni-context-switch] +ssl_conf = 9-npn-with-sni-context-switch-ssl -[7-npn-with-sni-context-switch-ssl] -server = 7-npn-with-sni-context-switch-server -client = 7-npn-with-sni-context-switch-client -server2 = 7-npn-with-sni-context-switch-server2 +[9-npn-with-sni-context-switch-ssl] +server = 9-npn-with-sni-context-switch-server +client = 9-npn-with-sni-context-switch-client +server2 = 9-npn-with-sni-context-switch-server2 -[7-npn-with-sni-context-switch-server] +[9-npn-with-sni-context-switch-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[7-npn-with-sni-context-switch-server2] +[9-npn-with-sni-context-switch-server2] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[7-npn-with-sni-context-switch-client] +[9-npn-with-sni-context-switch-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-7] +[test-9] ExpectedNPNProtocol = bar ExpectedServerName = server2 -server = 7-npn-with-sni-context-switch-server-extra -server2 = 7-npn-with-sni-context-switch-server2-extra -client = 7-npn-with-sni-context-switch-client-extra +server = 9-npn-with-sni-context-switch-server-extra +server2 = 9-npn-with-sni-context-switch-server2-extra +client = 9-npn-with-sni-context-switch-client-extra -[7-npn-with-sni-context-switch-server-extra] +[9-npn-with-sni-context-switch-server-extra] NPNProtocols = foo ServerNameCallback = IgnoreMismatch -[7-npn-with-sni-context-switch-server2-extra] +[9-npn-with-sni-context-switch-server2-extra] NPNProtocols = bar -[7-npn-with-sni-context-switch-client-extra] +[9-npn-with-sni-context-switch-client-extra] NPNProtocols = foo,bar ServerName = server2 # =========================================================== -[8-npn-selected-sni-server-supports-npn] -ssl_conf = 8-npn-selected-sni-server-supports-npn-ssl +[10-npn-selected-sni-server-supports-npn] +ssl_conf = 10-npn-selected-sni-server-supports-npn-ssl -[8-npn-selected-sni-server-supports-npn-ssl] -server = 8-npn-selected-sni-server-supports-npn-server -client = 8-npn-selected-sni-server-supports-npn-client -server2 = 8-npn-selected-sni-server-supports-npn-server2 +[10-npn-selected-sni-server-supports-npn-ssl] +server = 10-npn-selected-sni-server-supports-npn-server +client = 10-npn-selected-sni-server-supports-npn-client +server2 = 10-npn-selected-sni-server-supports-npn-server2 -[8-npn-selected-sni-server-supports-npn-server] +[10-npn-selected-sni-server-supports-npn-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[8-npn-selected-sni-server-supports-npn-server2] +[10-npn-selected-sni-server-supports-npn-server2] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[8-npn-selected-sni-server-supports-npn-client] +[10-npn-selected-sni-server-supports-npn-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-8] +[test-10] ExpectedNPNProtocol = bar ExpectedServerName = server2 -server = 8-npn-selected-sni-server-supports-npn-server-extra -server2 = 8-npn-selected-sni-server-supports-npn-server2-extra -client = 8-npn-selected-sni-server-supports-npn-client-extra +server = 10-npn-selected-sni-server-supports-npn-server-extra +server2 = 10-npn-selected-sni-server-supports-npn-server2-extra +client = 10-npn-selected-sni-server-supports-npn-client-extra -[8-npn-selected-sni-server-supports-npn-server-extra] +[10-npn-selected-sni-server-supports-npn-server-extra] ServerNameCallback = IgnoreMismatch -[8-npn-selected-sni-server-supports-npn-server2-extra] +[10-npn-selected-sni-server-supports-npn-server2-extra] NPNProtocols = bar -[8-npn-selected-sni-server-supports-npn-client-extra] +[10-npn-selected-sni-server-supports-npn-client-extra] NPNProtocols = foo,bar ServerName = server2 # =========================================================== -[9-npn-selected-sni-server-does-not-support-npn] -ssl_conf = 9-npn-selected-sni-server-does-not-support-npn-ssl +[11-npn-selected-sni-server-does-not-support-npn] +ssl_conf = 11-npn-selected-sni-server-does-not-support-npn-ssl -[9-npn-selected-sni-server-does-not-support-npn-ssl] -server = 9-npn-selected-sni-server-does-not-support-npn-server -client = 9-npn-selected-sni-server-does-not-support-npn-client -server2 = 9-npn-selected-sni-server-does-not-support-npn-server2 +[11-npn-selected-sni-server-does-not-support-npn-ssl] +server = 11-npn-selected-sni-server-does-not-support-npn-server +client = 11-npn-selected-sni-server-does-not-support-npn-client +server2 = 11-npn-selected-sni-server-does-not-support-npn-server2 -[9-npn-selected-sni-server-does-not-support-npn-server] +[11-npn-selected-sni-server-does-not-support-npn-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[9-npn-selected-sni-server-does-not-support-npn-server2] +[11-npn-selected-sni-server-does-not-support-npn-server2] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[9-npn-selected-sni-server-does-not-support-npn-client] +[11-npn-selected-sni-server-does-not-support-npn-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-9] +[test-11] ExpectedServerName = server2 -server = 9-npn-selected-sni-server-does-not-support-npn-server-extra -client = 9-npn-selected-sni-server-does-not-support-npn-client-extra +server = 11-npn-selected-sni-server-does-not-support-npn-server-extra +client = 11-npn-selected-sni-server-does-not-support-npn-client-extra -[9-npn-selected-sni-server-does-not-support-npn-server-extra] +[11-npn-selected-sni-server-does-not-support-npn-server-extra] NPNProtocols = bar ServerNameCallback = IgnoreMismatch -[9-npn-selected-sni-server-does-not-support-npn-client-extra] +[11-npn-selected-sni-server-does-not-support-npn-client-extra] NPNProtocols = foo,bar ServerName = server2 # =========================================================== -[10-alpn-preferred-over-npn] -ssl_conf = 10-alpn-preferred-over-npn-ssl +[12-alpn-preferred-over-npn] +ssl_conf = 12-alpn-preferred-over-npn-ssl -[10-alpn-preferred-over-npn-ssl] -server = 10-alpn-preferred-over-npn-server -client = 10-alpn-preferred-over-npn-client +[12-alpn-preferred-over-npn-ssl] +server = 12-alpn-preferred-over-npn-server +client = 12-alpn-preferred-over-npn-client -[10-alpn-preferred-over-npn-server] +[12-alpn-preferred-over-npn-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[10-alpn-preferred-over-npn-client] +[12-alpn-preferred-over-npn-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-10] +[test-12] ExpectedALPNProtocol = foo -server = 10-alpn-preferred-over-npn-server-extra -client = 10-alpn-preferred-over-npn-client-extra +server = 12-alpn-preferred-over-npn-server-extra +client = 12-alpn-preferred-over-npn-client-extra -[10-alpn-preferred-over-npn-server-extra] +[12-alpn-preferred-over-npn-server-extra] ALPNProtocols = foo NPNProtocols = bar -[10-alpn-preferred-over-npn-client-extra] +[12-alpn-preferred-over-npn-client-extra] ALPNProtocols = foo NPNProtocols = bar # =========================================================== -[11-sni-npn-preferred-over-alpn] -ssl_conf = 11-sni-npn-preferred-over-alpn-ssl +[13-sni-npn-preferred-over-alpn] +ssl_conf = 13-sni-npn-preferred-over-alpn-ssl -[11-sni-npn-preferred-over-alpn-ssl] -server = 11-sni-npn-preferred-over-alpn-server -client = 11-sni-npn-preferred-over-alpn-client -server2 = 11-sni-npn-preferred-over-alpn-server2 +[13-sni-npn-preferred-over-alpn-ssl] +server = 13-sni-npn-preferred-over-alpn-server +client = 13-sni-npn-preferred-over-alpn-client +server2 = 13-sni-npn-preferred-over-alpn-server2 -[11-sni-npn-preferred-over-alpn-server] +[13-sni-npn-preferred-over-alpn-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[11-sni-npn-preferred-over-alpn-server2] +[13-sni-npn-preferred-over-alpn-server2] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[11-sni-npn-preferred-over-alpn-client] +[13-sni-npn-preferred-over-alpn-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-11] +[test-13] ExpectedNPNProtocol = bar ExpectedServerName = server2 -server = 11-sni-npn-preferred-over-alpn-server-extra -server2 = 11-sni-npn-preferred-over-alpn-server2-extra -client = 11-sni-npn-preferred-over-alpn-client-extra +server = 13-sni-npn-preferred-over-alpn-server-extra +server2 = 13-sni-npn-preferred-over-alpn-server2-extra +client = 13-sni-npn-preferred-over-alpn-client-extra -[11-sni-npn-preferred-over-alpn-server-extra] +[13-sni-npn-preferred-over-alpn-server-extra] ALPNProtocols = foo ServerNameCallback = IgnoreMismatch -[11-sni-npn-preferred-over-alpn-server2-extra] +[13-sni-npn-preferred-over-alpn-server2-extra] NPNProtocols = bar -[11-sni-npn-preferred-over-alpn-client-extra] +[13-sni-npn-preferred-over-alpn-client-extra] ALPNProtocols = foo NPNProtocols = bar ServerName = server2 @@ -460,356 +527,356 @@ ServerName = server2 # =========================================================== -[12-npn-simple-resumption] -ssl_conf = 12-npn-simple-resumption-ssl +[14-npn-simple-resumption] +ssl_conf = 14-npn-simple-resumption-ssl -[12-npn-simple-resumption-ssl] -server = 12-npn-simple-resumption-server -client = 12-npn-simple-resumption-client -resume-server = 12-npn-simple-resumption-server -resume-client = 12-npn-simple-resumption-client +[14-npn-simple-resumption-ssl] +server = 14-npn-simple-resumption-server +client = 14-npn-simple-resumption-client +resume-server = 14-npn-simple-resumption-server +resume-client = 14-npn-simple-resumption-client -[12-npn-simple-resumption-server] +[14-npn-simple-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[12-npn-simple-resumption-client] +[14-npn-simple-resumption-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-12] +[test-14] ExpectedNPNProtocol = foo HandshakeMode = Resume ResumptionExpected = Yes -server = 12-npn-simple-resumption-server-extra -resume-server = 12-npn-simple-resumption-server-extra -client = 12-npn-simple-resumption-client-extra -resume-client = 12-npn-simple-resumption-client-extra +server = 14-npn-simple-resumption-server-extra +resume-server = 14-npn-simple-resumption-server-extra +client = 14-npn-simple-resumption-client-extra +resume-client = 14-npn-simple-resumption-client-extra -[12-npn-simple-resumption-server-extra] +[14-npn-simple-resumption-server-extra] NPNProtocols = foo -[12-npn-simple-resumption-client-extra] +[14-npn-simple-resumption-client-extra] NPNProtocols = foo # =========================================================== -[13-npn-server-switch-resumption] -ssl_conf = 13-npn-server-switch-resumption-ssl +[15-npn-server-switch-resumption] +ssl_conf = 15-npn-server-switch-resumption-ssl -[13-npn-server-switch-resumption-ssl] -server = 13-npn-server-switch-resumption-server -client = 13-npn-server-switch-resumption-client -resume-server = 13-npn-server-switch-resumption-resume-server -resume-client = 13-npn-server-switch-resumption-client +[15-npn-server-switch-resumption-ssl] +server = 15-npn-server-switch-resumption-server +client = 15-npn-server-switch-resumption-client +resume-server = 15-npn-server-switch-resumption-resume-server +resume-client = 15-npn-server-switch-resumption-client -[13-npn-server-switch-resumption-server] +[15-npn-server-switch-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[13-npn-server-switch-resumption-resume-server] +[15-npn-server-switch-resumption-resume-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[13-npn-server-switch-resumption-client] +[15-npn-server-switch-resumption-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-13] +[test-15] ExpectedNPNProtocol = baz HandshakeMode = Resume ResumptionExpected = Yes -server = 13-npn-server-switch-resumption-server-extra -resume-server = 13-npn-server-switch-resumption-resume-server-extra -client = 13-npn-server-switch-resumption-client-extra -resume-client = 13-npn-server-switch-resumption-client-extra +server = 15-npn-server-switch-resumption-server-extra +resume-server = 15-npn-server-switch-resumption-resume-server-extra +client = 15-npn-server-switch-resumption-client-extra +resume-client = 15-npn-server-switch-resumption-client-extra -[13-npn-server-switch-resumption-server-extra] +[15-npn-server-switch-resumption-server-extra] NPNProtocols = bar,foo -[13-npn-server-switch-resumption-resume-server-extra] +[15-npn-server-switch-resumption-resume-server-extra] NPNProtocols = baz,foo -[13-npn-server-switch-resumption-client-extra] +[15-npn-server-switch-resumption-client-extra] NPNProtocols = foo,bar,baz # =========================================================== -[14-npn-client-switch-resumption] -ssl_conf = 14-npn-client-switch-resumption-ssl +[16-npn-client-switch-resumption] +ssl_conf = 16-npn-client-switch-resumption-ssl -[14-npn-client-switch-resumption-ssl] -server = 14-npn-client-switch-resumption-server -client = 14-npn-client-switch-resumption-client -resume-server = 14-npn-client-switch-resumption-server -resume-client = 14-npn-client-switch-resumption-resume-client +[16-npn-client-switch-resumption-ssl] +server = 16-npn-client-switch-resumption-server +client = 16-npn-client-switch-resumption-client +resume-server = 16-npn-client-switch-resumption-server +resume-client = 16-npn-client-switch-resumption-resume-client -[14-npn-client-switch-resumption-server] +[16-npn-client-switch-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[14-npn-client-switch-resumption-client] +[16-npn-client-switch-resumption-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[14-npn-client-switch-resumption-resume-client] +[16-npn-client-switch-resumption-resume-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-14] +[test-16] ExpectedNPNProtocol = bar HandshakeMode = Resume ResumptionExpected = Yes -server = 14-npn-client-switch-resumption-server-extra -resume-server = 14-npn-client-switch-resumption-server-extra -client = 14-npn-client-switch-resumption-client-extra -resume-client = 14-npn-client-switch-resumption-resume-client-extra +server = 16-npn-client-switch-resumption-server-extra +resume-server = 16-npn-client-switch-resumption-server-extra +client = 16-npn-client-switch-resumption-client-extra +resume-client = 16-npn-client-switch-resumption-resume-client-extra -[14-npn-client-switch-resumption-server-extra] +[16-npn-client-switch-resumption-server-extra] NPNProtocols = foo,bar,baz -[14-npn-client-switch-resumption-client-extra] +[16-npn-client-switch-resumption-client-extra] NPNProtocols = foo,baz -[14-npn-client-switch-resumption-resume-client-extra] +[16-npn-client-switch-resumption-resume-client-extra] NPNProtocols = bar,baz # =========================================================== -[15-npn-client-first-pref-on-mismatch-resumption] -ssl_conf = 15-npn-client-first-pref-on-mismatch-resumption-ssl +[17-npn-client-first-pref-on-mismatch-resumption] +ssl_conf = 17-npn-client-first-pref-on-mismatch-resumption-ssl -[15-npn-client-first-pref-on-mismatch-resumption-ssl] -server = 15-npn-client-first-pref-on-mismatch-resumption-server -client = 15-npn-client-first-pref-on-mismatch-resumption-client -resume-server = 15-npn-client-first-pref-on-mismatch-resumption-resume-server -resume-client = 15-npn-client-first-pref-on-mismatch-resumption-client +[17-npn-client-first-pref-on-mismatch-resumption-ssl] +server = 17-npn-client-first-pref-on-mismatch-resumption-server +client = 17-npn-client-first-pref-on-mismatch-resumption-client +resume-server = 17-npn-client-first-pref-on-mismatch-resumption-resume-server +resume-client = 17-npn-client-first-pref-on-mismatch-resumption-client -[15-npn-client-first-pref-on-mismatch-resumption-server] +[17-npn-client-first-pref-on-mismatch-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[15-npn-client-first-pref-on-mismatch-resumption-resume-server] +[17-npn-client-first-pref-on-mismatch-resumption-resume-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[15-npn-client-first-pref-on-mismatch-resumption-client] +[17-npn-client-first-pref-on-mismatch-resumption-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-15] +[test-17] ExpectedNPNProtocol = foo HandshakeMode = Resume ResumptionExpected = Yes -server = 15-npn-client-first-pref-on-mismatch-resumption-server-extra -resume-server = 15-npn-client-first-pref-on-mismatch-resumption-resume-server-extra -client = 15-npn-client-first-pref-on-mismatch-resumption-client-extra -resume-client = 15-npn-client-first-pref-on-mismatch-resumption-client-extra +server = 17-npn-client-first-pref-on-mismatch-resumption-server-extra +resume-server = 17-npn-client-first-pref-on-mismatch-resumption-resume-server-extra +client = 17-npn-client-first-pref-on-mismatch-resumption-client-extra +resume-client = 17-npn-client-first-pref-on-mismatch-resumption-client-extra -[15-npn-client-first-pref-on-mismatch-resumption-server-extra] +[17-npn-client-first-pref-on-mismatch-resumption-server-extra] NPNProtocols = bar -[15-npn-client-first-pref-on-mismatch-resumption-resume-server-extra] +[17-npn-client-first-pref-on-mismatch-resumption-resume-server-extra] NPNProtocols = baz -[15-npn-client-first-pref-on-mismatch-resumption-client-extra] +[17-npn-client-first-pref-on-mismatch-resumption-client-extra] NPNProtocols = foo,bar # =========================================================== -[16-npn-no-server-support-resumption] -ssl_conf = 16-npn-no-server-support-resumption-ssl +[18-npn-no-server-support-resumption] +ssl_conf = 18-npn-no-server-support-resumption-ssl -[16-npn-no-server-support-resumption-ssl] -server = 16-npn-no-server-support-resumption-server -client = 16-npn-no-server-support-resumption-client -resume-server = 16-npn-no-server-support-resumption-resume-server -resume-client = 16-npn-no-server-support-resumption-client +[18-npn-no-server-support-resumption-ssl] +server = 18-npn-no-server-support-resumption-server +client = 18-npn-no-server-support-resumption-client +resume-server = 18-npn-no-server-support-resumption-resume-server +resume-client = 18-npn-no-server-support-resumption-client -[16-npn-no-server-support-resumption-server] +[18-npn-no-server-support-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[16-npn-no-server-support-resumption-resume-server] +[18-npn-no-server-support-resumption-resume-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[16-npn-no-server-support-resumption-client] +[18-npn-no-server-support-resumption-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-16] +[test-18] HandshakeMode = Resume ResumptionExpected = Yes -server = 16-npn-no-server-support-resumption-server-extra -client = 16-npn-no-server-support-resumption-client-extra -resume-client = 16-npn-no-server-support-resumption-client-extra +server = 18-npn-no-server-support-resumption-server-extra +client = 18-npn-no-server-support-resumption-client-extra +resume-client = 18-npn-no-server-support-resumption-client-extra -[16-npn-no-server-support-resumption-server-extra] +[18-npn-no-server-support-resumption-server-extra] NPNProtocols = foo -[16-npn-no-server-support-resumption-client-extra] +[18-npn-no-server-support-resumption-client-extra] NPNProtocols = foo # =========================================================== -[17-npn-no-client-support-resumption] -ssl_conf = 17-npn-no-client-support-resumption-ssl +[19-npn-no-client-support-resumption] +ssl_conf = 19-npn-no-client-support-resumption-ssl -[17-npn-no-client-support-resumption-ssl] -server = 17-npn-no-client-support-resumption-server -client = 17-npn-no-client-support-resumption-client -resume-server = 17-npn-no-client-support-resumption-server -resume-client = 17-npn-no-client-support-resumption-resume-client +[19-npn-no-client-support-resumption-ssl] +server = 19-npn-no-client-support-resumption-server +client = 19-npn-no-client-support-resumption-client +resume-server = 19-npn-no-client-support-resumption-server +resume-client = 19-npn-no-client-support-resumption-resume-client -[17-npn-no-client-support-resumption-server] +[19-npn-no-client-support-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[17-npn-no-client-support-resumption-client] +[19-npn-no-client-support-resumption-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[17-npn-no-client-support-resumption-resume-client] +[19-npn-no-client-support-resumption-resume-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-17] +[test-19] HandshakeMode = Resume ResumptionExpected = Yes -server = 17-npn-no-client-support-resumption-server-extra -resume-server = 17-npn-no-client-support-resumption-server-extra -client = 17-npn-no-client-support-resumption-client-extra +server = 19-npn-no-client-support-resumption-server-extra +resume-server = 19-npn-no-client-support-resumption-server-extra +client = 19-npn-no-client-support-resumption-client-extra -[17-npn-no-client-support-resumption-server-extra] +[19-npn-no-client-support-resumption-server-extra] NPNProtocols = foo -[17-npn-no-client-support-resumption-client-extra] +[19-npn-no-client-support-resumption-client-extra] NPNProtocols = foo # =========================================================== -[18-alpn-preferred-over-npn-resumption] -ssl_conf = 18-alpn-preferred-over-npn-resumption-ssl +[20-alpn-preferred-over-npn-resumption] +ssl_conf = 20-alpn-preferred-over-npn-resumption-ssl -[18-alpn-preferred-over-npn-resumption-ssl] -server = 18-alpn-preferred-over-npn-resumption-server -client = 18-alpn-preferred-over-npn-resumption-client -resume-server = 18-alpn-preferred-over-npn-resumption-resume-server -resume-client = 18-alpn-preferred-over-npn-resumption-client +[20-alpn-preferred-over-npn-resumption-ssl] +server = 20-alpn-preferred-over-npn-resumption-server +client = 20-alpn-preferred-over-npn-resumption-client +resume-server = 20-alpn-preferred-over-npn-resumption-resume-server +resume-client = 20-alpn-preferred-over-npn-resumption-client -[18-alpn-preferred-over-npn-resumption-server] +[20-alpn-preferred-over-npn-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[18-alpn-preferred-over-npn-resumption-resume-server] +[20-alpn-preferred-over-npn-resumption-resume-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[18-alpn-preferred-over-npn-resumption-client] +[20-alpn-preferred-over-npn-resumption-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-18] +[test-20] ExpectedALPNProtocol = foo HandshakeMode = Resume ResumptionExpected = Yes -server = 18-alpn-preferred-over-npn-resumption-server-extra -resume-server = 18-alpn-preferred-over-npn-resumption-resume-server-extra -client = 18-alpn-preferred-over-npn-resumption-client-extra -resume-client = 18-alpn-preferred-over-npn-resumption-client-extra +server = 20-alpn-preferred-over-npn-resumption-server-extra +resume-server = 20-alpn-preferred-over-npn-resumption-resume-server-extra +client = 20-alpn-preferred-over-npn-resumption-client-extra +resume-client = 20-alpn-preferred-over-npn-resumption-client-extra -[18-alpn-preferred-over-npn-resumption-server-extra] +[20-alpn-preferred-over-npn-resumption-server-extra] NPNProtocols = bar -[18-alpn-preferred-over-npn-resumption-resume-server-extra] +[20-alpn-preferred-over-npn-resumption-resume-server-extra] ALPNProtocols = foo NPNProtocols = baz -[18-alpn-preferred-over-npn-resumption-client-extra] +[20-alpn-preferred-over-npn-resumption-client-extra] ALPNProtocols = foo NPNProtocols = bar,baz # =========================================================== -[19-npn-used-if-alpn-not-supported-resumption] -ssl_conf = 19-npn-used-if-alpn-not-supported-resumption-ssl +[21-npn-used-if-alpn-not-supported-resumption] +ssl_conf = 21-npn-used-if-alpn-not-supported-resumption-ssl -[19-npn-used-if-alpn-not-supported-resumption-ssl] -server = 19-npn-used-if-alpn-not-supported-resumption-server -client = 19-npn-used-if-alpn-not-supported-resumption-client -resume-server = 19-npn-used-if-alpn-not-supported-resumption-resume-server -resume-client = 19-npn-used-if-alpn-not-supported-resumption-client +[21-npn-used-if-alpn-not-supported-resumption-ssl] +server = 21-npn-used-if-alpn-not-supported-resumption-server +client = 21-npn-used-if-alpn-not-supported-resumption-client +resume-server = 21-npn-used-if-alpn-not-supported-resumption-resume-server +resume-client = 21-npn-used-if-alpn-not-supported-resumption-client -[19-npn-used-if-alpn-not-supported-resumption-server] +[21-npn-used-if-alpn-not-supported-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[19-npn-used-if-alpn-not-supported-resumption-resume-server] +[21-npn-used-if-alpn-not-supported-resumption-resume-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[19-npn-used-if-alpn-not-supported-resumption-client] +[21-npn-used-if-alpn-not-supported-resumption-client] CipherString = DEFAULT MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-19] +[test-21] ExpectedNPNProtocol = baz HandshakeMode = Resume ResumptionExpected = Yes -server = 19-npn-used-if-alpn-not-supported-resumption-server-extra -resume-server = 19-npn-used-if-alpn-not-supported-resumption-resume-server-extra -client = 19-npn-used-if-alpn-not-supported-resumption-client-extra -resume-client = 19-npn-used-if-alpn-not-supported-resumption-client-extra +server = 21-npn-used-if-alpn-not-supported-resumption-server-extra +resume-server = 21-npn-used-if-alpn-not-supported-resumption-resume-server-extra +client = 21-npn-used-if-alpn-not-supported-resumption-client-extra +resume-client = 21-npn-used-if-alpn-not-supported-resumption-client-extra -[19-npn-used-if-alpn-not-supported-resumption-server-extra] +[21-npn-used-if-alpn-not-supported-resumption-server-extra] ALPNProtocols = foo NPNProtocols = bar -[19-npn-used-if-alpn-not-supported-resumption-resume-server-extra] +[21-npn-used-if-alpn-not-supported-resumption-resume-server-extra] NPNProtocols = baz -[19-npn-used-if-alpn-not-supported-resumption-client-extra] +[21-npn-used-if-alpn-not-supported-resumption-client-extra] ALPNProtocols = foo NPNProtocols = bar,baz diff --git a/test/ssl-tests/08-npn.cnf.in b/test/ssl-tests/08-npn.cnf.in index 30783e45e..1dc2704bd 100644 --- a/test/ssl-tests/08-npn.cnf.in +++ b/test/ssl-tests/08-npn.cnf.in @@ -110,6 +110,41 @@ our @tests = ( "ExpectedNPNProtocol" => undef, }, }, + { + name => "npn-empty-client-list", + server => { + extra => { + "NPNProtocols" => "foo", + }, + }, + client => { + extra => { + "NPNProtocols" => "", + }, + "MaxProtocol" => "TLSv1.2" + }, + test => { + "ExpectedResult" => "ClientFail", + "ExpectedClientAlert" => "HandshakeFailure" + }, + }, + { + name => "npn-empty-server-list", + server => { + extra => { + "NPNProtocols" => "", + }, + }, + client => { + extra => { + "NPNProtocols" => "foo", + }, + "MaxProtocol" => "TLSv1.2" + }, + test => { + "ExpectedNPNProtocol" => "foo" + }, + }, { name => "npn-with-sni-no-context-switch", server => { diff --git a/test/ssl-tests/09-alpn.cnf b/test/ssl-tests/09-alpn.cnf index e7e6cb953..dd668739a 100644 --- a/test/ssl-tests/09-alpn.cnf +++ b/test/ssl-tests/09-alpn.cnf @@ -1,6 +1,6 @@ # Generated with generate_ssl_tests.pl -num_tests = 16 +num_tests = 18 test-0 = 0-alpn-simple test-1 = 1-alpn-server-finds-match @@ -18,6 +18,8 @@ test-12 = 12-alpn-client-switch-resumption test-13 = 13-alpn-alert-on-mismatch-resumption test-14 = 14-alpn-no-server-support-resumption test-15 = 15-alpn-no-client-support-resumption +test-16 = 16-alpn-empty-client-list +test-17 = 17-alpn-empty-server-list # =========================================================== [0-alpn-simple] @@ -617,3 +619,65 @@ ALPNProtocols = foo ALPNProtocols = foo +# =========================================================== + +[16-alpn-empty-client-list] +ssl_conf = 16-alpn-empty-client-list-ssl + +[16-alpn-empty-client-list-ssl] +server = 16-alpn-empty-client-list-server +client = 16-alpn-empty-client-list-client + +[16-alpn-empty-client-list-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[16-alpn-empty-client-list-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-16] +server = 16-alpn-empty-client-list-server-extra +client = 16-alpn-empty-client-list-client-extra + +[16-alpn-empty-client-list-server-extra] +ALPNProtocols = foo + +[16-alpn-empty-client-list-client-extra] +ALPNProtocols = + + +# =========================================================== + +[17-alpn-empty-server-list] +ssl_conf = 17-alpn-empty-server-list-ssl + +[17-alpn-empty-server-list-ssl] +server = 17-alpn-empty-server-list-server +client = 17-alpn-empty-server-list-client + +[17-alpn-empty-server-list-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[17-alpn-empty-server-list-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-17] +ExpectedResult = ServerFail +ExpectedServerAlert = NoApplicationProtocol +server = 17-alpn-empty-server-list-server-extra +client = 17-alpn-empty-server-list-client-extra + +[17-alpn-empty-server-list-server-extra] +ALPNProtocols = + +[17-alpn-empty-server-list-client-extra] +ALPNProtocols = foo + + diff --git a/test/ssl-tests/09-alpn.cnf.in b/test/ssl-tests/09-alpn.cnf.in index 81330756c..322b7096a 100644 --- a/test/ssl-tests/09-alpn.cnf.in +++ b/test/ssl-tests/09-alpn.cnf.in @@ -322,4 +322,37 @@ our @tests = ( "ExpectedALPNProtocol" => undef, }, }, + { + name => "alpn-empty-client-list", + server => { + extra => { + "ALPNProtocols" => "foo", + }, + }, + client => { + extra => { + "ALPNProtocols" => "", + }, + }, + test => { + "ExpectedALPNProtocol" => undef, + }, + }, + { + name => "alpn-empty-server-list", + server => { + extra => { + "ALPNProtocols" => "", + }, + }, + client => { + extra => { + "ALPNProtocols" => "foo", + }, + }, + test => { + "ExpectedResult" => "ServerFail", + "ExpectedServerAlert" => "NoApplicationProtocol", + }, + }, ); diff --git a/test/sslapitest.c b/test/sslapitest.c index aa65d2cd4..ca2caed2e 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -10533,6 +10533,367 @@ static int test_multi_resume(int idx) return testresult; } +static struct next_proto_st { + int serverlen; + unsigned char server[40]; + int clientlen; + unsigned char client[40]; + int expected_ret; + size_t selectedlen; + unsigned char selected[40]; +} next_proto_tests[] = { + { + 4, { 3, 'a', 'b', 'c' }, + 4, { 3, 'a', 'b', 'c' }, + OPENSSL_NPN_NEGOTIATED, + 3, { 'a', 'b', 'c' } + }, + { + 7, { 3, 'a', 'b', 'c', 2, 'a', 'b' }, + 4, { 3, 'a', 'b', 'c' }, + OPENSSL_NPN_NEGOTIATED, + 3, { 'a', 'b', 'c' } + }, + { + 7, { 2, 'a', 'b', 3, 'a', 'b', 'c', }, + 4, { 3, 'a', 'b', 'c' }, + OPENSSL_NPN_NEGOTIATED, + 3, { 'a', 'b', 'c' } + }, + { + 4, { 3, 'a', 'b', 'c' }, + 7, { 3, 'a', 'b', 'c', 2, 'a', 'b', }, + OPENSSL_NPN_NEGOTIATED, + 3, { 'a', 'b', 'c' } + }, + { + 4, { 3, 'a', 'b', 'c' }, + 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'}, + OPENSSL_NPN_NEGOTIATED, + 3, { 'a', 'b', 'c' } + }, + { + 7, { 2, 'b', 'c', 3, 'a', 'b', 'c' }, + 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'}, + OPENSSL_NPN_NEGOTIATED, + 3, { 'a', 'b', 'c' } + }, + { + 10, { 2, 'b', 'c', 3, 'a', 'b', 'c', 2, 'a', 'b' }, + 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'}, + OPENSSL_NPN_NEGOTIATED, + 3, { 'a', 'b', 'c' } + }, + { + 4, { 3, 'b', 'c', 'd' }, + 4, { 3, 'a', 'b', 'c' }, + OPENSSL_NPN_NO_OVERLAP, + 3, { 'a', 'b', 'c' } + }, + { + 0, { 0 }, + 4, { 3, 'a', 'b', 'c' }, + OPENSSL_NPN_NO_OVERLAP, + 3, { 'a', 'b', 'c' } + }, + { + -1, { 0 }, + 4, { 3, 'a', 'b', 'c' }, + OPENSSL_NPN_NO_OVERLAP, + 3, { 'a', 'b', 'c' } + }, + { + 4, { 3, 'a', 'b', 'c' }, + 0, { 0 }, + OPENSSL_NPN_NO_OVERLAP, + 0, { 0 } + }, + { + 4, { 3, 'a', 'b', 'c' }, + -1, { 0 }, + OPENSSL_NPN_NO_OVERLAP, + 0, { 0 } + }, + { + 3, { 3, 'a', 'b', 'c' }, + 4, { 3, 'a', 'b', 'c' }, + OPENSSL_NPN_NO_OVERLAP, + 3, { 'a', 'b', 'c' } + }, + { + 4, { 3, 'a', 'b', 'c' }, + 3, { 3, 'a', 'b', 'c' }, + OPENSSL_NPN_NO_OVERLAP, + 0, { 0 } + } +}; + +static int test_select_next_proto(int idx) +{ + struct next_proto_st *np = &next_proto_tests[idx]; + int ret = 0; + unsigned char *out, *client, *server; + unsigned char outlen; + unsigned int clientlen, serverlen; + + if (np->clientlen == -1) { + client = NULL; + clientlen = 0; + } else { + client = np->client; + clientlen = (unsigned int)np->clientlen; + } + if (np->serverlen == -1) { + server = NULL; + serverlen = 0; + } else { + server = np->server; + serverlen = (unsigned int)np->serverlen; + } + + if (!TEST_int_eq(SSL_select_next_proto(&out, &outlen, server, serverlen, + client, clientlen), + np->expected_ret)) + goto err; + + if (np->selectedlen == 0) { + if (!TEST_ptr_null(out) || !TEST_uchar_eq(outlen, 0)) + goto err; + } else { + if (!TEST_mem_eq(out, outlen, np->selected, np->selectedlen)) + goto err; + } + + ret = 1; + err: + return ret; +} + +static const unsigned char fooprot[] = {3, 'f', 'o', 'o' }; +static const unsigned char barprot[] = {3, 'b', 'a', 'r' }; + +#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG) +static int npn_advert_cb(SSL *ssl, const unsigned char **out, + unsigned int *outlen, void *arg) +{ + int *idx = (int *)arg; + + switch (*idx) { + default: + case 0: + *out = fooprot; + *outlen = sizeof(fooprot); + return SSL_TLSEXT_ERR_OK; + + case 1: + *outlen = 0; + return SSL_TLSEXT_ERR_OK; + + case 2: + return SSL_TLSEXT_ERR_NOACK; + } +} + +static int npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, void *arg) +{ + int *idx = (int *)arg; + + switch (*idx) { + case 0: + case 1: + *out = (unsigned char *)(fooprot + 1); + *outlen = *fooprot; + return SSL_TLSEXT_ERR_OK; + + case 3: + *out = (unsigned char *)(barprot + 1); + *outlen = *barprot; + return SSL_TLSEXT_ERR_OK; + + case 4: + *outlen = 0; + return SSL_TLSEXT_ERR_OK; + + default: + case 2: + return SSL_TLSEXT_ERR_ALERT_FATAL; + } +} + +/* + * Test the NPN callbacks + * Test 0: advert = foo, select = foo + * Test 1: advert = , select = foo + * Test 2: no advert + * Test 3: advert = foo, select = bar + * Test 4: advert = foo, select = (should fail) + */ +static int test_npn(int idx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), 0, TLS1_2_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + SSL_CTX_set_next_protos_advertised_cb(sctx, npn_advert_cb, &idx); + SSL_CTX_set_next_proto_select_cb(cctx, npn_select_cb, &idx); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, + NULL))) + goto end; + + if (idx == 4) { + /* We don't allow empty selection of NPN, so this should fail */ + if (!TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + } else { + const unsigned char *prot; + unsigned int protlen; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + SSL_get0_next_proto_negotiated(serverssl, &prot, &protlen); + switch (idx) { + case 0: + case 1: + if (!TEST_mem_eq(prot, protlen, fooprot + 1, *fooprot)) + goto end; + break; + case 2: + if (!TEST_uint_eq(protlen, 0)) + goto end; + break; + case 3: + if (!TEST_mem_eq(prot, protlen, barprot + 1, *barprot)) + goto end; + break; + default: + TEST_error("Should not get here"); + goto end; + } + } + + testresult = 1; + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} +#endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG) */ + +static int alpn_select_cb2(SSL *ssl, const unsigned char **out, + unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg) +{ + int *idx = (int *)arg; + + switch (*idx) { + case 0: + *out = (unsigned char *)(fooprot + 1); + *outlen = *fooprot; + return SSL_TLSEXT_ERR_OK; + + case 2: + *out = (unsigned char *)(barprot + 1); + *outlen = *barprot; + return SSL_TLSEXT_ERR_OK; + + case 3: + *outlen = 0; + return SSL_TLSEXT_ERR_OK; + + default: + case 1: + return SSL_TLSEXT_ERR_ALERT_FATAL; + } + return 0; +} + +/* + * Test the ALPN callbacks + * Test 0: client = foo, select = foo + * Test 1: client = , select = none + * Test 2: client = foo, select = bar (should fail) + * Test 3: client = foo, select = (should fail) + */ +static int test_alpn(int idx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + int testresult = 0; + const unsigned char *prots = fooprot; + unsigned int protslen = sizeof(fooprot); + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + SSL_CTX_set_alpn_select_cb(sctx, alpn_select_cb2, &idx); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, + NULL))) + goto end; + + if (idx == 1) { + prots = NULL; + protslen = 0; + } + + /* SSL_set_alpn_protos returns 0 for success! */ + if (!TEST_false(SSL_set_alpn_protos(clientssl, prots, protslen))) + goto end; + + if (idx == 2 || idx == 3) { + /* We don't allow empty selection of NPN, so this should fail */ + if (!TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + } else { + const unsigned char *prot; + unsigned int protlen; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + SSL_get0_alpn_selected(clientssl, &prot, &protlen); + switch (idx) { + case 0: + if (!TEST_mem_eq(prot, protlen, fooprot + 1, *fooprot)) + goto end; + break; + case 1: + if (!TEST_uint_eq(protlen, 0)) + goto end; + break; + default: + TEST_error("Should not get here"); + goto end; + } + } + + testresult = 1; + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n") int setup_tests(void) @@ -10808,6 +11169,11 @@ int setup_tests(void) ADD_ALL_TESTS(test_pipelining, 7); #endif ADD_ALL_TESTS(test_multi_resume, 5); + ADD_ALL_TESTS(test_select_next_proto, OSSL_NELEM(next_proto_tests)); +#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG) + ADD_ALL_TESTS(test_npn, 5); +#endif + ADD_ALL_TESTS(test_alpn, 4); return 1; err: diff --git a/util/perl/TLSProxy/Message.pm b/util/perl/TLSProxy/Message.pm index 55af352a4..2457834fb 100644 --- a/util/perl/TLSProxy/Message.pm +++ b/util/perl/TLSProxy/Message.pm @@ -378,6 +378,15 @@ sub create_message [@message_frag_lens] ); $message->parse(); + } elsif ($mt == MT_NEXT_PROTO) { + $message = TLSProxy::NextProto->new( + $server, + $data, + [@message_rec_list], + $startoffset, + [@message_frag_lens] + ); + $message->parse(); } else { #Unknown message type $message = TLSProxy::Message->new( diff --git a/util/perl/TLSProxy/NextProto.pm b/util/perl/TLSProxy/NextProto.pm new file mode 100644 index 000000000..0e1834754 --- /dev/null +++ b/util/perl/TLSProxy/NextProto.pm @@ -0,0 +1,54 @@ +# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (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 + +use strict; + +package TLSProxy::NextProto; + +use vars '@ISA'; +push @ISA, 'TLSProxy::Message'; + +sub new +{ + my $class = shift; + my ($server, + $data, + $records, + $startoffset, + $message_frag_lens) = @_; + + my $self = $class->SUPER::new( + $server, + TLSProxy::Message::MT_NEXT_PROTO, + $data, + $records, + $startoffset, + $message_frag_lens); + + return $self; +} + +sub parse +{ + # We don't support parsing at the moment +} + +# This is supposed to reconstruct the on-the-wire message data following changes. +# For now though since we don't support parsing we just create an empty NextProto +# message - this capability is used in test_npn +sub set_message_contents +{ + my $self = shift; + my $data; + + $data = pack("C32", 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00); + $self->data($data); +} +1; diff --git a/util/perl/TLSProxy/Proxy.pm b/util/perl/TLSProxy/Proxy.pm index 3de10eccb..b707722b6 100644 --- a/util/perl/TLSProxy/Proxy.pm +++ b/util/perl/TLSProxy/Proxy.pm @@ -23,6 +23,7 @@ use TLSProxy::CertificateRequest; use TLSProxy::CertificateVerify; use TLSProxy::ServerKeyExchange; use TLSProxy::NewSessionTicket; +use TLSProxy::NextProto; my $have_IPv6; my $IP_factory;