summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2020-08-21 06:58:42 +0000
committerDaiki Ueno <ueno@gnu.org>2020-08-21 06:58:42 +0000
commitf9e56c3a51f4ba8b91cead5526ff14ec75d2a35d (patch)
treec2d10294f88a75456afc7c6c443f05d4481eca17
parente77ac722063385d7c92ae1c6a0c1473b92cab682 (diff)
parent926e05eba90173afca886e7238da0054507d18ed (diff)
downloadgnutls-f9e56c3a51f4ba8b91cead5526ff14ec75d2a35d.tar.gz
Merge branch 'tmp-tls12-version-checks' into 'master'
handshake: check TLS version against modified server priorities Closes #1054 See merge request gnutls/gnutls!1309
-rw-r--r--lib/handshake.c12
-rw-r--r--tests/post-client-hello-change-prio.c39
2 files changed, 39 insertions, 12 deletions
diff --git a/lib/handshake.c b/lib/handshake.c
index cb215b223c..b40f84b3d9 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -823,7 +823,17 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
return ret;
}
- _gnutls_handshake_log("HSK[%p]: Selected version %s\n", session, session->security_parameters.pversion->name);
+ /* Only at this point we know the version we are actually going to use
+ * ("supported_versions" extension is parsed, user_hello_func is called,
+ * legacy version negotiation is done). */
+ vers = get_version(session);
+ if (unlikely(vers == NULL))
+ return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
+
+ if (_gnutls_version_priority(session, vers->id) < 0)
+ return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
+
+ _gnutls_handshake_log("HSK[%p]: Selected version %s\n", session, vers->name);
/* select appropriate compression method */
ret =
diff --git a/tests/post-client-hello-change-prio.c b/tests/post-client-hello-change-prio.c
index 833a538cf0..be41047a01 100644
--- a/tests/post-client-hello-change-prio.c
+++ b/tests/post-client-hello-change-prio.c
@@ -43,7 +43,9 @@ const char *override_prio = NULL;
static int post_client_hello_callback(gnutls_session_t session)
{
- assert(gnutls_priority_set_direct(session, override_prio, NULL) >= 0);
+ if (override_prio) {
+ assert(gnutls_priority_set_direct(session, override_prio, NULL) >= 0);
+ }
pch_ok = 1;
return 0;
}
@@ -54,7 +56,7 @@ static void tls_log_func(int level, const char *str)
}
static
-void start(const char *name, const char *prio, gnutls_protocol_t exp_version)
+void start(const char *name, const char *client_prio, const char *server_prio, int expected)
{
/* Server stuff. */
gnutls_certificate_credentials_t serverx509cred;
@@ -83,7 +85,7 @@ void start(const char *name, const char *prio, gnutls_protocol_t exp_version)
assert(gnutls_init(&server, GNUTLS_SERVER)>=0);
gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
serverx509cred);
- assert(gnutls_priority_set_direct(server, prio, NULL)>=0);
+ assert(gnutls_priority_set_direct(server, server_prio, NULL)>=0);
gnutls_transport_set_push_function(server, server_push);
gnutls_transport_set_pull_function(server, server_pull);
gnutls_transport_set_ptr(server, server);
@@ -94,15 +96,24 @@ void start(const char *name, const char *prio, gnutls_protocol_t exp_version)
assert(gnutls_init(&client, GNUTLS_CLIENT)>=0);
gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
clientx509cred);
- assert(gnutls_priority_set_direct(client, prio, NULL)>=0);
+ assert(gnutls_priority_set_direct(client, client_prio, NULL)>=0);
gnutls_transport_set_push_function(client, client_push);
gnutls_transport_set_pull_function(client, client_pull);
gnutls_transport_set_ptr(client, client);
- HANDSHAKE(client, server);
+ if (expected > 0) {
+ int ret;
- assert(exp_version == gnutls_protocol_get_version(client));
- assert(exp_version == gnutls_protocol_get_version(server));
+ HANDSHAKE(client, server);
+
+ ret = gnutls_protocol_get_version(client);
+ assert(expected == ret);
+
+ ret = gnutls_protocol_get_version(server);
+ assert(expected == ret);
+ } else {
+ HANDSHAKE_EXPECT(client, server, GNUTLS_E_AGAIN, GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
+ }
gnutls_bye(client, GNUTLS_SHUT_RDWR);
gnutls_bye(server, GNUTLS_SHUT_RDWR);
@@ -124,9 +135,15 @@ void start(const char *name, const char *prio, gnutls_protocol_t exp_version)
void doit(void)
{
override_prio = "NORMAL";
- start("tls1.2-only", "NORMAL:-VERS-ALL:+VERS-TLS1.2", GNUTLS_TLS1_2);
- start("tls1.3-only", "NORMAL:-VERS-ALL:+VERS-TLS1.3", GNUTLS_TLS1_3);
- start("default", "NORMAL", GNUTLS_TLS1_3);
+ start("tls1.2-only", "NORMAL:-VERS-ALL:+VERS-TLS1.2", "NORMAL:-VERS-ALL:+VERS-TLS1.2", GNUTLS_TLS1_2);
+ start("tls1.3-only", "NORMAL:-VERS-ALL:+VERS-TLS1.3", "NORMAL:-VERS-ALL:+VERS-TLS1.3", GNUTLS_TLS1_3);
+ start("default", "NORMAL", "NORMAL", GNUTLS_TLS1_3);
+ override_prio = "NORMAL:-VERS-ALL:+VERS-TLS1.2";
+ start("default overriden to TLS1.2-only", "NORMAL", "NORMAL", GNUTLS_TLS1_2);
+ override_prio = NULL;
+ start("client tls1.2-only, server tls1.2-disabled",
+ "NORMAL:-VERS-ALL:+VERS-TLS1.2", "NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:-VERS-TLS1.0:-VERS-SSL3.0", -1);
override_prio = "NORMAL:-VERS-ALL:+VERS-TLS1.2";
- start("default overriden to TLS1.2-only", "NORMAL", GNUTLS_TLS1_2);
+ start("client tls1.2-only, server tls1.2-disabled initially, but allow it afterwards",
+ "NORMAL:-VERS-ALL:+VERS-TLS1.2", "NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:-VERS-TLS1.0:-VERS-SSL3.0", GNUTLS_TLS1_2);
}