diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-09-30 22:05:59 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-10-03 14:46:27 +0200 |
commit | 368c74fa02a77b1a4d40f385745264a3d25b4358 (patch) | |
tree | 1062b6ebc52c6db4f63f85191296b530ca187c38 /lib/handshake.c | |
parent | 990ec00b5b2042e60ad331d93d64b0abd72defac (diff) | |
download | gnutls-368c74fa02a77b1a4d40f385745264a3d25b4358.tar.gz |
gnutls_priority_set: do not override version on handshaketmp-fix-priority-set-call
When handshake is in progress, do not override the default TLS
version in the session. This allows gnutls_priority_set to be called
in the post_client_hello function without breaking the handshake.
Resolves #580
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Diffstat (limited to 'lib/handshake.c')
-rw-r--r-- | lib/handshake.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/lib/handshake.c b/lib/handshake.c index 08481cca07..b513872ec3 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -491,7 +491,8 @@ _gnutls_user_hello_func(gnutls_session_t session, uint8_t major, uint8_t minor) { int ret, sret = 0; - const version_entry_st *vers; + const version_entry_st *vers, *old_vers; + const version_entry_st *new_max; if (session->internals.user_hello_func != NULL) { ret = session->internals.user_hello_func(session); @@ -504,17 +505,34 @@ _gnutls_user_hello_func(gnutls_session_t session, return ret; } - vers = get_version(session); - if (!vers->tls13_sem) { - /* Here we need to renegotiate the version since the callee might - * have disabled some TLS versions. We only do it for TLS1.2 or - * earlier, as TLS1.3 uses a different set of ciphersuites, and - * thus we cannot fallback. - */ - ret = _gnutls_negotiate_version(session, major, minor, 0); - if (ret < 0) { - gnutls_assert(); - return ret; + /* This callback is often used to switch the priority string of the + * server, and that includes switching version which we have already + * negotiated; note that this doesn't apply when resuming as the version + * negotiation is already complete. */ + if (session->internals.resumed != RESUME_TRUE) { + new_max = _gnutls_version_max(session); + old_vers = get_version(session); + + if (!old_vers->tls13_sem || (new_max && !new_max->tls13_sem)) { +#if GNUTLS_TLS_VERSION_MAX != GNUTLS_TLS1_3 +# error "Need to update the following logic" +#endif + /* Here we need to renegotiate the version since the callee might + * have disabled some TLS versions. This logic does not cope for + * protocols later than TLS1.3 if they have the tls13_sem set */ + ret = _gnutls_negotiate_version(session, major, minor, 0); + if (ret < 0) + return gnutls_assert_val(ret); + + vers = get_version(session); + if (old_vers != vers) { + /* at this point we need to regenerate the random value to + * avoid the peer detecting this session as a rollback + * attempt. */ + ret = _gnutls_gen_server_random(session, vers->id); + if (ret < 0) + return gnutls_assert_val(ret); + } } } } |