[openssl] OpenSSL_1_1_1-stable update
Matt Caswell
matt at openssl.org
Thu Jan 30 16:16:08 UTC 2020
The branch OpenSSL_1_1_1-stable has been updated
via a9a8863b791a54625da2a079a496a31cb7f94482 (commit)
via 721eb8f631882c9b1dbbdc8564f806bb177da4e3 (commit)
via f6f81b2dbc802e41e792003512e7900628f7a7e8 (commit)
via e9cd6e763c1dc036d5216ee0e200afa7ec26c60b (commit)
from 081191e3423ed73b019e7786d68c94c78e61c6d9 (commit)
- Log -----------------------------------------------------------------
commit a9a8863b791a54625da2a079a496a31cb7f94482
Author: Matt Caswell <matt at openssl.org>
Date: Mon Dec 2 17:29:21 2019 +0000
Don't acknowledge a servername following warning alert in servername cb
If the servername cb decides to send back a warning alert then the
handshake continues, but we should not signal to the client that the
servername has been accepted.
Reviewed-by: Ben Kaduk <kaduk at mit.edu>
(Merged from https://github.com/openssl/openssl/pull/10018)
(cherry picked from commit cd624ccd41ac3ac779c1c7a7a1e63427ce9588dd)
commit 721eb8f631882c9b1dbbdc8564f806bb177da4e3
Author: Matt Caswell <matt at openssl.org>
Date: Thu Nov 28 12:03:00 2019 +0000
Provide better documentation for SSL_get_servername()
The behaviour of SSL_get_servername() is quite complicated and depends on
numerous factors such as whether it is called on the client or the server,
whether it is called before or after the handshake, what protocol version
was negotiated, and whether a resumption was attempted or was successful.
We attempt to document the behavior more clearly.
Reviewed-by: Ben Kaduk <kaduk at mit.edu>
(Merged from https://github.com/openssl/openssl/pull/10018)
(cherry picked from commit 0dc7c8e8314f27ac093b2d7bc8f13d0dfd302bdb)
commit f6f81b2dbc802e41e792003512e7900628f7a7e8
Author: Matt Caswell <matt at openssl.org>
Date: Thu Sep 26 16:16:06 2019 +0100
Test that SSL_get_servername returns what we expect
Test this on both the client and the server after a normal handshake,
and after a resumption handshake. We also test what happens if an
inconsistent SNI is set between the original handshake and the resumption
handshake. Finally all of this is also tested in TLSv1.2 and TLSv1.3.
Reviewed-by: Ben Kaduk <kaduk at mit.edu>
(Merged from https://github.com/openssl/openssl/pull/10018)
(cherry picked from commit 49ef3d0719f132629ab76d4bcb4ab0c1e016277a)
commit e9cd6e763c1dc036d5216ee0e200afa7ec26c60b
Author: Matt Caswell <matt at openssl.org>
Date: Wed Sep 25 17:06:06 2019 +0100
Fix SSL_get_servername() and SNI behaviour
The SNI behaviour for TLSv1.3 and the behaviour of SSL_get_servername()
was not quite right, and not entirely consistent with the RFC.
The TLSv1.3 RFC explicitly says that SNI is negotiated on each handshake
and the server is not required to associate it with the session. This was
not quite reflected in the code so we fix that.
Additionally there were some additional checks around early_data checking
that the SNI between the original session and this session were
consistent. In fact the RFC does not require any such checks, so they are
removed.
Finally the behaviour of SSL_get_servername() was not quite right. The
behaviour was not consistent between resumption and normal handshakes,
and also not quite consistent with historical behaviour. We clarify the
behaviour in various scenarios and also attempt to make it match historical
behaviour as closely as possible.
Fixes #8822
Reviewed-by: Ben Kaduk <kaduk at mit.edu>
(Merged from https://github.com/openssl/openssl/pull/10018)
(cherry picked from commit 7955c1f16e72dc944677fd1dbf4b1300e75f1c84)
-----------------------------------------------------------------------
Summary of changes:
.../SSL_CTX_set_tlsext_servername_callback.pod | 120 +++++++++++++--
doc/man3/SSL_SESSION_get0_hostname.pod | 5 +-
ssl/ssl_lib.c | 82 ++++++++--
ssl/statem/extensions.c | 2 +-
ssl/statem/extensions_srvr.c | 25 +++-
test/sslapitest.c | 166 ++++++++++++++++++++-
6 files changed, 363 insertions(+), 37 deletions(-)
diff --git a/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod b/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod
index b1fb5ab7d9..d6af097ae3 100644
--- a/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod
+++ b/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod
@@ -11,7 +11,7 @@ SSL_set_tlsext_host_name - handle server name indication (SNI)
#include <openssl/ssl.h>
long SSL_CTX_set_tlsext_servername_callback(SSL_CTX *ctx,
- int (*cb)(SSL *, int *, void *));
+ int (*cb)(SSL *s, int *al, void *arg));
long SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg);
const char *SSL_get_servername(const SSL *s, const int type);
@@ -21,21 +21,106 @@ SSL_set_tlsext_host_name - handle server name indication (SNI)
=head1 DESCRIPTION
-The functionality provided by the servername callback is superseded by the
-ClientHello callback, which can be set using SSL_CTX_set_client_hello_cb().
-The servername callback is retained for historical compatibility.
+The functionality provided by the servername callback is mostly superseded by
+the ClientHello callback, which can be set using SSL_CTX_set_client_hello_cb().
+However, even where the ClientHello callback is used, the servername callback is
+still necessary in order to acknowledge the servername requested by the client.
SSL_CTX_set_tlsext_servername_callback() sets the application callback B<cb>
used by a server to perform any actions or configuration required based on
the servername extension received in the incoming connection. When B<cb>
-is NULL, SNI is not used. The B<arg> value is a pointer which is passed to
-the application callback.
+is NULL, SNI is not used.
+
+The servername callback should return one of the following values:
+
+=over 4
+
+=item SSL_TLSEXT_ERR_OK
+
+This is used to indicate that the servername requested by the client has been
+accepted. Typically a server will call SSL_set_SSL_CTX() in the callback to set
+up a different configuration for the selected servername in this case.
+
+=item SSL_TLSEXT_ERR_ALERT_FATAL
+
+In this case the servername requested by the client is not accepted and the
+handshake will be aborted. The value of the alert to be used should be stored in
+the location pointed to by the B<al> parameter to the callback. By default this
+value is initialised to SSL_AD_UNRECOGNIZED_NAME.
+
+=item SSL_TLSEXT_ERR_ALERT_WARNING
+
+If this value is returned then the servername is not accepted by the server.
+However the handshake will continue and send a warning alert instead. The value
+of the alert should be stored in the location pointed to by the B<al> parameter
+as for SSL_TLSEXT_ERR_ALERT_FATAL above. Note that TLSv1.3 does not support
+warning alerts, so if TLSv1.3 has been negotiated then this return value is
+treated the same way as SSL_TLSEXT_ERR_NOACK.
+
+=item SSL_TLSEXT_ERR_NOACK
+
+This return value indicates that the servername is not accepted by the server.
+No alerts are sent and the server will not acknowledge the requested servername.
+
+=back
SSL_CTX_set_tlsext_servername_arg() sets a context-specific argument to be
-passed into the callback for this B<SSL_CTX>.
+passed into the callback (via the B<arg> parameter) for this B<SSL_CTX>.
+
+The behaviour of SSL_get_servername() depends on a number of different factors.
+In particular note that in TLSv1.3 the servername is negotiated in every
+handshake. In TLSv1.2 the servername is only negotiated on initial handshakes
+and not on resumption handshakes.
+
+=over 4
+
+=item On the client, before the handshake
+
+If a servername has been set via a call to SSL_set_tlsext_host_name() then it
+will return that servername.
+
+If one has not been set, but a TLSv1.2 resumption is being attempted and the
+session from the original handshake had a servername accepted by the server then
+it will return that servername.
+
+Otherwise it returns NULL.
-SSL_get_servername() returns a servername extension value of the specified
-type if provided in the Client Hello or NULL.
+=item On the client, during or after the handshake and a TLSv1.2 (or below)
+resumption occurred
+
+If the session from the orignal handshake had a servername accepted by the
+server then it will return that servername.
+
+Otherwise it returns the servername set via SSL_set_tlsext_host_name() or NULL
+if it was not called.
+
+=item On the client, during or after the handshake and a TLSv1.2 (or below)
+resumption did not occur
+
+It will return the servername set via SSL_set_tlsext_host_name() or NULL if it
+was not called.
+
+=item On the server, before the handshake
+
+The function will always return NULL before the handshake
+
+=item On the server, after the servername extension has been processed and a
+TLSv1.2 (or below) resumption occurred
+
+If a servername was accepted by the server in the original handshake then it
+will return that servername, or NULL otherwise.
+
+=item On the server, after the servername extension has been processed and a
+TLSv1.2 (or below) resumption did not occur
+
+The function will return the servername requested by the client in this
+handshake or NULL if none was requested.
+
+=back
+
+Note that the ClientHello callback occurs before a servername extension from the
+client is processed. The servername, certificate and ALPN callbacks occur after
+a servername extension from the client is processed.
SSL_get_servername_type() returns the servername type or -1 if no servername
is present. Currently the only supported type (defined in RFC3546) is
@@ -65,6 +150,23 @@ SSL_set_tlsext_host_name() returns 1 on success, 0 in case of error.
L<ssl(7)>, L<SSL_CTX_set_alpn_select_cb(3)>,
L<SSL_get0_alpn_selected(3)>, L<SSL_CTX_set_client_hello_cb(3)>
+=head1 HISTORY
+
+SSL_get_servername() historically provided some unexpected results in certain
+corner cases. This has been fixed from OpenSSL 1.1.1e.
+
+Prior to 1.1.1e, when the client requested a servername in an initial TLSv1.2
+handshake, the server accepted it, and then the client successfully resumed but
+set a different explict servername in the second handshake then when called by
+the client it returned the servername from the second handshake. This has now
+been changed to return the servername requested in the original handshake.
+
+Also prior to 1.1.1e, if the client sent a servername in the first handshake but
+the server did not accept it, and then a second handshake occured where TLSv1.2
+resumption was successful then when called by the server it returned the
+servername requested in the original handshake. This has now been changed to
+NULL.
+
=head1 COPYRIGHT
Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/doc/man3/SSL_SESSION_get0_hostname.pod b/doc/man3/SSL_SESSION_get0_hostname.pod
index 475f700a88..acf1b152bc 100644
--- a/doc/man3/SSL_SESSION_get0_hostname.pod
+++ b/doc/man3/SSL_SESSION_get0_hostname.pod
@@ -24,7 +24,10 @@ SSL_SESSION_set1_alpn_selected
=head1 DESCRIPTION
SSL_SESSION_get0_hostname() retrieves the SNI value that was sent by the
-client when the session was created, or NULL if no value was sent.
+client when the session was created if it was accepted by the server and TLSv1.2
+or below was negotiated. Otherwise NULL is returned. Note that in TLSv1.3 the
+SNI hostname is negotiated with each handshake including resumption handshakes
+and is therefore never associated with the session.
The value returned is a pointer to memory maintained within B<s> and
should not be free'd.
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 0d0c0dbd6a..e7268f5c2d 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2623,31 +2623,85 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size)
return buf;
}
-/** return a servername extension value if provided in Client Hello, or NULL.
- * So far, only host_name types are defined (RFC 3546).
+/**
+ * Return the requested servername (SNI) value. Note that the behaviour varies
+ * depending on:
+ * - whether this is called by the client or the server,
+ * - if we are before or during/after the handshake,
+ * - if a resumption or normal handshake is being attempted/has occurred
+ * - whether we have negotiated TLSv1.2 (or below) or TLSv1.3
+ *
+ * Note that only the host_name type is defined (RFC 3546).
*/
-
const char *SSL_get_servername(const SSL *s, const int type)
{
+ /*
+ * If we don't know if we are the client or the server yet then we assume
+ * client.
+ */
+ int server = s->handshake_func == NULL ? 0 : s->server;
if (type != TLSEXT_NAMETYPE_host_name)
return NULL;
- /*
- * SNI is not negotiated in pre-TLS-1.3 resumption flows, so fake up an
- * SNI value to return if we are resuming/resumed. N.B. that we still
- * call the relevant callbacks for such resumption flows, and callbacks
- * might error out if there is not a SNI value available.
- */
- if (s->hit)
- return s->session->ext.hostname;
+ if (server) {
+ /**
+ * Server side
+ * In TLSv1.3 on the server SNI is not associated with the session
+ * but in TLSv1.2 or below it is.
+ *
+ * Before the handshake:
+ * - return NULL
+ *
+ * During/after the handshake (TLSv1.2 or below resumption occurred):
+ * - If a servername was accepted by the server in the original
+ * handshake then it will return that servername, or NULL otherwise.
+ *
+ * During/after the handshake (TLSv1.2 or below resumption did not occur):
+ * - The function will return the servername requested by the client in
+ * this handshake or NULL if none was requested.
+ */
+ if (s->hit && !SSL_IS_TLS13(s))
+ return s->session->ext.hostname;
+ } else {
+ /**
+ * Client side
+ *
+ * Before the handshake:
+ * - If a servername has been set via a call to
+ * SSL_set_tlsext_host_name() then it will return that servername
+ * - If one has not been set, but a TLSv1.2 resumption is being
+ * attempted and the session from the original handshake had a
+ * servername accepted by the server then it will return that
+ * servername
+ * - Otherwise it returns NULL
+ *
+ * During/after the handshake (TLSv1.2 or below resumption occurred):
+ * - If the session from the orignal handshake had a servername accepted
+ * by the server then it will return that servername.
+ * - Otherwise it returns the servername set via
+ * SSL_set_tlsext_host_name() (or NULL if it was not called).
+ *
+ * During/after the handshake (TLSv1.2 or below resumption did not occur):
+ * - It will return the servername set via SSL_set_tlsext_host_name()
+ * (or NULL if it was not called).
+ */
+ if (SSL_in_before(s)) {
+ if (s->ext.hostname == NULL
+ && s->session != NULL
+ && s->session->ssl_version != TLS1_3_VERSION)
+ return s->session->ext.hostname;
+ } else {
+ if (!SSL_IS_TLS13(s) && s->hit && s->session->ext.hostname != NULL)
+ return s->session->ext.hostname;
+ }
+ }
+
return s->ext.hostname;
}
int SSL_get_servername_type(const SSL *s)
{
- if (s->session
- && (!s->ext.hostname ? s->session->
- ext.hostname : s->ext.hostname))
+ if (SSL_get_servername(s, TLSEXT_NAMETYPE_host_name) != NULL)
return TLSEXT_NAMETYPE_host_name;
return -1;
}
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 86a737a6a0..44d8a2591a 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -949,7 +949,6 @@ static int final_server_name(SSL *s, unsigned int context, int sent)
* was successful.
*/
if (s->server) {
- /* TODO(OpenSSL1.2) revisit !sent case */
if (sent && ret == SSL_TLSEXT_ERR_OK && !s->hit) {
/* Only store the hostname in the session if we accepted it. */
OPENSSL_free(s->session->ext.hostname);
@@ -1011,6 +1010,7 @@ static int final_server_name(SSL *s, unsigned int context, int sent)
/* TLSv1.3 doesn't have warning alerts so we suppress this */
if (!SSL_IS_TLS13(s))
ssl3_send_alert(s, SSL3_AL_WARNING, altmp);
+ s->servername_done = 0;
return 1;
case SSL_TLSEXT_ERR_NOACK:
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index de273a3b96..a775e74686 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -127,6 +127,10 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context,
return 0;
}
+ /*
+ * In TLSv1.2 and below the SNI is associated with the session. In TLSv1.3
+ * we always use the SNI value from the handshake.
+ */
if (!s->hit || SSL_IS_TLS13(s)) {
if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) {
SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME,
@@ -155,8 +159,12 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context,
}
s->servername_done = 1;
- }
- if (s->hit) {
+ } else {
+ /*
+ * In TLSv1.2 and below we should check if the SNI is consistent between
+ * the initial handshake and the resumption. In TLSv1.3 SNI is not
+ * associated with the session.
+ */
/*
* TODO(openssl-team): if the SNI doesn't match, we MUST
* fall back to a full handshake.
@@ -164,9 +172,6 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context,
s->servername_done = (s->session->ext.hostname != NULL)
&& PACKET_equal(&hostname, s->session->ext.hostname,
strlen(s->session->ext.hostname));
-
- if (!s->servername_done && s->session->ext.hostname != NULL)
- s->ext.early_data_ok = 0;
}
return 1;
@@ -1330,8 +1335,14 @@ EXT_RETURN tls_construct_stoc_server_name(SSL *s, WPACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx)
{
- if (s->hit || s->servername_done != 1
- || s->ext.hostname == NULL)
+ if (s->servername_done != 1)
+ return EXT_RETURN_NOT_SENT;
+
+ /*
+ * Prior to TLSv1.3 we ignore any SNI in the current handshake if resuming.
+ * We just use the servername from the initial handshake.
+ */
+ if (s->hit && !SSL_IS_TLS13(s))
return EXT_RETURN_NOT_SENT;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
diff --git a/test/sslapitest.c b/test/sslapitest.c
index 76a8ca23da..fff6d9b5e1 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -2741,7 +2741,8 @@ static int hostname_cb(SSL *s, int *al, void *arg)
{
const char *hostname = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
- if (hostname != NULL && strcmp(hostname, "goodhost") == 0)
+ if (hostname != NULL && (strcmp(hostname, "goodhost") == 0
+ || strcmp(hostname, "altgoodhost") == 0))
return SSL_TLSEXT_ERR_OK;
return SSL_TLSEXT_ERR_NOACK;
@@ -2839,16 +2840,16 @@ static int test_early_data_psk(int idx)
case 3:
/*
- * Set inconsistent SNI (server detected). In this case the connection
- * will succeed but reject early_data.
+ * Set inconsistent SNI (server side). In this case the connection
+ * will succeed and accept early_data. In TLSv1.3 on the server side SNI
+ * is associated with each handshake - not the session. Therefore it
+ * should not matter that we used a different server name last time.
*/
SSL_SESSION_free(serverpsk);
serverpsk = SSL_SESSION_dup(clientpsk);
if (!TEST_ptr(serverpsk)
|| !TEST_true(SSL_SESSION_set1_hostname(serverpsk, "badhost")))
goto end;
- edstatus = SSL_EARLY_DATA_REJECTED;
- readearlyres = SSL_READ_EARLY_DATA_FINISH;
/* Fall through */
case 4:
/* Set consistent SNI */
@@ -6205,6 +6206,160 @@ static int test_ca_names(int tst)
return testresult;
}
+/*
+ * Test 0: Client sets servername and server acknowledges it (TLSv1.2)
+ * Test 1: Client sets servername and server does not acknowledge it (TLSv1.2)
+ * Test 2: Client sets inconsistent servername on resumption (TLSv1.2)
+ * Test 3: Client does not set servername on initial handshake (TLSv1.2)
+ * Test 4: Client does not set servername on resumption handshake (TLSv1.2)
+ * Test 5: Client sets servername and server acknowledges it (TLSv1.3)
+ * Test 6: Client sets servername and server does not acknowledge it (TLSv1.3)
+ * Test 7: Client sets inconsistent servername on resumption (TLSv1.3)
+ * Test 8: Client does not set servername on initial handshake(TLSv1.3)
+ * Test 9: Client does not set servername on resumption handshake (TLSv1.3)
+ */
+static int test_servername(int tst)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0;
+ SSL_SESSION *sess = NULL;
+ const char *sexpectedhost = NULL, *cexpectedhost = NULL;
+
+#ifdef OPENSSL_NO_TLS1_2
+ if (tst <= 4)
+ return 1;
+#endif
+#ifdef OPENSSL_NO_TLS1_3
+ if (tst >= 5)
+ return 1;
+#endif
+
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+ TLS_client_method(),
+ TLS1_VERSION,
+ (tst <= 4) ? TLS1_2_VERSION
+ : TLS1_3_VERSION,
+ &sctx, &cctx, cert, privkey))
+ || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ if (tst != 1 && tst != 6) {
+ if (!TEST_true(SSL_CTX_set_tlsext_servername_callback(sctx,
+ hostname_cb)))
+ goto end;
+ }
+
+ if (tst != 3 && tst != 8) {
+ if (!TEST_true(SSL_set_tlsext_host_name(clientssl, "goodhost")))
+ goto end;
+ sexpectedhost = cexpectedhost = "goodhost";
+ }
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ if (!TEST_str_eq(SSL_get_servername(clientssl, TLSEXT_NAMETYPE_host_name),
+ cexpectedhost)
+ || !TEST_str_eq(SSL_get_servername(serverssl,
+ TLSEXT_NAMETYPE_host_name),
+ sexpectedhost))
+ goto end;
+
+ /* Now repeat with a resumption handshake */
+
+ if (!TEST_int_eq(SSL_shutdown(clientssl), 0)
+ || !TEST_ptr_ne(sess = SSL_get1_session(clientssl), NULL)
+ || !TEST_true(SSL_SESSION_is_resumable(sess))
+ || !TEST_int_eq(SSL_shutdown(serverssl), 0))
+ goto end;
+
+ SSL_free(clientssl);
+ SSL_free(serverssl);
+ clientssl = serverssl = NULL;
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL,
+ NULL)))
+ goto end;
+
+ if (!TEST_true(SSL_set_session(clientssl, sess)))
+ goto end;
+
+ sexpectedhost = cexpectedhost = "goodhost";
+ if (tst == 2 || tst == 7) {
+ /* Set an inconsistent hostname */
+ if (!TEST_true(SSL_set_tlsext_host_name(clientssl, "altgoodhost")))
+ goto end;
+ /*
+ * In TLSv1.2 we expect the hostname from the original handshake, in
+ * TLSv1.3 we expect the hostname from this handshake
+ */
+ if (tst == 7)
+ sexpectedhost = cexpectedhost = "altgoodhost";
+
+ if (!TEST_str_eq(SSL_get_servername(clientssl,
+ TLSEXT_NAMETYPE_host_name),
+ "altgoodhost"))
+ goto end;
+ } else if (tst == 4 || tst == 9) {
+ /*
+ * A TLSv1.3 session does not associate a session with a servername,
+ * but a TLSv1.2 session does.
+ */
+ if (tst == 9)
+ sexpectedhost = cexpectedhost = NULL;
+
+ if (!TEST_str_eq(SSL_get_servername(clientssl,
+ TLSEXT_NAMETYPE_host_name),
+ cexpectedhost))
+ goto end;
+ } else {
+ if (!TEST_true(SSL_set_tlsext_host_name(clientssl, "goodhost")))
+ goto end;
+ /*
+ * In a TLSv1.2 resumption where the hostname was not acknowledged
+ * we expect the hostname on the server to be empty. On the client we
+ * return what was requested in this case.
+ *
+ * Similarly if the client didn't set a hostname on an original TLSv1.2
+ * session but is now, the server hostname will be empty, but the client
+ * is as we set it.
+ */
+ if (tst == 1 || tst == 3)
+ sexpectedhost = NULL;
+
+ if (!TEST_str_eq(SSL_get_servername(clientssl,
+ TLSEXT_NAMETYPE_host_name),
+ "goodhost"))
+ goto end;
+ }
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ if (!TEST_true(SSL_session_reused(clientssl))
+ || !TEST_true(SSL_session_reused(serverssl))
+ || !TEST_str_eq(SSL_get_servername(clientssl,
+ TLSEXT_NAMETYPE_host_name),
+ cexpectedhost)
+ || !TEST_str_eq(SSL_get_servername(serverssl,
+ TLSEXT_NAMETYPE_host_name),
+ sexpectedhost))
+ goto end;
+
+ testresult = 1;
+
+ end:
+ SSL_SESSION_free(sess);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+
int setup_tests(void)
{
if (!TEST_ptr(certsdir = test_get_argument(0))
@@ -6322,6 +6477,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_cert_cb, 6);
ADD_ALL_TESTS(test_client_cert_cb, 2);
ADD_ALL_TESTS(test_ca_names, 3);
+ ADD_ALL_TESTS(test_servername, 10);
return 1;
}
More information about the openssl-commits
mailing list