summaryrefslogtreecommitdiff
path: root/lib/priority.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2018-10-31 09:34:52 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2018-10-31 09:34:52 +0000
commitc7cabc18e193d556583d4adb1905d79602d0f8b0 (patch)
treecce748a9d7abc67c77b9f32ef5a62333a710b1a3 /lib/priority.c
parentfd3be4ac1dcc9493eece19db7e3a6f58c1f62776 (diff)
parent3de5abc634d38f5687931f5bfdee4a7d92f2cebd (diff)
downloadgnutls-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.c46
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 */