diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-10-31 09:34:52 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-10-31 09:34:52 +0000 |
commit | c7cabc18e193d556583d4adb1905d79602d0f8b0 (patch) | |
tree | cce748a9d7abc67c77b9f32ef5a62333a710b1a3 /lib/priority.c | |
parent | fd3be4ac1dcc9493eece19db7e3a6f58c1f62776 (diff) | |
parent | 3de5abc634d38f5687931f5bfdee4a7d92f2cebd (diff) | |
download | gnutls-c7cabc18e193d556583d4adb1905d79602d0f8b0.tar.gz |
Merge branch 'tmp-fix-priority-set' into 'master'
gnutls_priority_set: do not override the version after handshake is complete
See merge request gnutls/gnutls!777
Diffstat (limited to 'lib/priority.c')
-rw-r--r-- | lib/priority.c | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/lib/priority.c b/lib/priority.c index 17049d5327..33d164f214 100644 --- a/lib/priority.c +++ b/lib/priority.c @@ -573,45 +573,47 @@ static void prio_add(priority_st * priority_list, unsigned int algo) * @priority: is a #gnutls_priority_t type. * * Sets the priorities to use on the ciphers, key exchange methods, - * and macs. + * and macs. Note that this function is expected to be called once + * per session; when called multiple times (e.g., before a re-handshake, + * the caller should make sure that any new settings are not incompatible + * with the original session). * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. + * Returns: %GNUTLS_E_SUCCESS on success, or an error code on error. **/ int gnutls_priority_set(gnutls_session_t session, gnutls_priority_t priority) { - if (priority == NULL) { - gnutls_assert(); - return GNUTLS_E_NO_CIPHER_SUITES; + int ret; + + if (priority == NULL || priority->protocol.num_priorities == 0 || + priority->cs.size == 0) + return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET); + + /* set the current version to the first in the chain, if this is + * the call before the initial handshake. During a re-handshake + * we do not set the version to avoid overriding the currently + * negotiated version. */ + if (!session->internals.handshake_in_progress && + !session->internals.initial_negotiation_completed) { + ret = _gnutls_set_current_version(session, + priority->protocol.priorities[0]); + if (ret < 0) + return gnutls_assert_val(ret); } + /* At this point the provided priorities passed the sanity tests */ + if (session->internals.priorities) gnutls_priority_deinit(session->internals.priorities); - session->internals.priorities = priority; gnutls_atomic_increment(&priority->usage_cnt); - - /* set the current version to the first in the chain. - * This will be overridden later. - */ - if (session->internals.priorities->protocol.num_priorities > 0 && - !session->internals.handshake_in_progress) { - if (_gnutls_set_current_version(session, - session->internals.priorities-> - protocol.priorities[0]) < 0) { - return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); - } - } + session->internals.priorities = priority; if (priority->no_tickets != 0) { /* when PFS is explicitly requested, disable session tickets */ session->internals.flags |= GNUTLS_NO_TICKETS; } - if (session->internals.priorities->protocol.num_priorities == 0 || - session->internals.priorities->cs.size == 0) - return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET); - ADD_PROFILE_VFLAGS(session, priority->additional_verify_flags); /* mirror variables */ |