]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
handshake: simplified protocol version checking functions
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Fri, 17 Aug 2018 10:57:25 +0000 (12:57 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 20 Aug 2018 19:49:28 +0000 (21:49 +0200)
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
lib/algorithms.h
lib/algorithms/protocols.c
lib/ext/supported_versions.c
lib/handshake.c
lib/handshake.h
lib/sslv2_compat.c

index cff79348cb8bb8d736049ba0162628b619d94aaf..46faa8d378129762cc1b8debf9d93b2b3dcdac8f 100644 (file)
@@ -59,8 +59,8 @@ const version_entry_st *_gnutls_legacy_version_max(gnutls_session_t session);
 const version_entry_st *_gnutls_version_max(gnutls_session_t session);
 int _gnutls_version_priority(gnutls_session_t session,
                             gnutls_protocol_t version);
-int _gnutls_version_is_supported(gnutls_session_t session,
-                                const gnutls_protocol_t version);
+int _gnutls_nversion_is_supported(gnutls_session_t session,
+                                 unsigned char major, unsigned char minor);
 gnutls_protocol_t _gnutls_version_get(uint8_t major, uint8_t minor);
 unsigned _gnutls_version_is_too_high(gnutls_session_t session, uint8_t major, uint8_t minor);
 
index 12907190df957a7ebde32573f85556e3b5c6fd29..f2277a9e2895f2cd2ee410538cf46099ab57db75 100644 (file)
@@ -463,26 +463,29 @@ gnutls_protocol_t _gnutls_version_get(uint8_t major, uint8_t minor)
 /* Version Functions */
 
 int
-_gnutls_version_is_supported(gnutls_session_t session,
-                            const gnutls_protocol_t version)
+_gnutls_nversion_is_supported(gnutls_session_t session,
+                             unsigned char major, unsigned char minor)
 {
        const version_entry_st *p;
-       int ret = 0;
+       int version = 0;
 
        for (p = sup_versions; p->name != NULL; p++) {
-               if(p->id == version) {
+               if(p->major == major && p->minor == minor) {
 #ifndef ENABLE_SSL3
                        if (p->obsolete != 0) return 0;
 #endif
                        if (p->tls13_sem && (session->internals.flags & INT_FLAG_NO_TLS13))
                                return 0;
 
-                       ret = p->supported && p->transport == session->internals.transport;
+                       if (!p->supported || p->transport != session->internals.transport)
+                               return 0;
+
+                       version = p->id;
                        break;
                }
        }
 
-       if (ret == 0)
+       if (version == 0)
                return 0;
 
        if (_gnutls_version_priority(session, version) < 0)
@@ -490,4 +493,3 @@ _gnutls_version_is_supported(gnutls_session_t session,
        else
                return 1;
 }
-
index b637ec663713e2b09a81bd85f361bb39e69213fe..3a11b39bd40202800a74d74c337e7fb0bafefd91 100644 (file)
@@ -59,7 +59,6 @@ supported_versions_recv_params(gnutls_session_t session,
        const version_entry_st *vers;
        ssize_t data_size = _data_size;
        uint8_t major, minor;
-       gnutls_protocol_t proto;
        ssize_t bytes;
        int ret;
 
@@ -90,15 +89,11 @@ supported_versions_recv_params(gnutls_session_t session,
                        data += 2;
                        bytes -= 2;
 
-                       proto = _gnutls_version_get(major, minor);
-
                        _gnutls_handshake_log("EXT[%p]: Found version: %d.%d\n",
                                              session, (int)major, (int)minor);
 
-                       if (_gnutls_version_is_supported(session, proto)) {
-                               ret = _gnutls_set_current_version(session, proto);
-                               if (ret < 0)
-                                       return gnutls_assert_val(ret);
+                       if (_gnutls_nversion_is_supported(session, major, minor)) {
+                               session->security_parameters.pversion = nversion_to_entry(major, minor);
 
                                _gnutls_handshake_log("EXT[%p]: Negotiated version: %d.%d\n",
                                                      session, (int)major, (int)minor);
@@ -131,7 +126,6 @@ supported_versions_recv_params(gnutls_session_t session,
                        return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
 
                set_adv_version(session, major, minor);
-               proto = _gnutls_version_get(major, minor);
 
                _gnutls_handshake_log("EXT[%p]: Negotiated version: %d.%d\n",
                                      session, (int)major, (int)minor);
@@ -139,7 +133,7 @@ supported_versions_recv_params(gnutls_session_t session,
                if (!vers->tls13_sem)
                        return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
 
-               ret = _gnutls_negotiate_version(session, proto, major, minor);
+               ret = _gnutls_negotiate_version(session, major, minor);
                if (ret < 0) {
                        gnutls_assert();
                        return ret;
index 914f8ecacc0a6746d20d07cc7bbc6b1f1162486e..ccf829916585e366f9351e38f3d6b04f5d1bdc1f 100644 (file)
@@ -431,21 +431,21 @@ _gnutls_finished(gnutls_session_t session, int type, void *ret,
  */
 int
 _gnutls_negotiate_version(gnutls_session_t session,
-                         gnutls_protocol_t adv_version, uint8_t major, uint8_t minor)
+                         uint8_t major, uint8_t minor)
 {
        const version_entry_st *vers;
+       const version_entry_st *aversion = nversion_to_entry(major, minor);
 
        /* if we do not support that version, unless that version is TLS 1.2;
         * TLS 1.2 is handled separately because it is always advertized under TLS 1.3 or later */
-       if (adv_version == GNUTLS_VERSION_UNKNOWN ||
-           _gnutls_version_is_supported(session, adv_version) == 0) {
+       if (aversion == NULL ||
+           _gnutls_nversion_is_supported(session, major, minor) == 0) {
 
-               if (adv_version == GNUTLS_TLS1_2) {
+               if (aversion && aversion->id == GNUTLS_TLS1_2) {
                        vers = _gnutls_version_max(session);
                        if (vers->id >= GNUTLS_TLS1_2) {
-                               if (_gnutls_set_current_version(session, adv_version) < 0)
-                                       return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
-                               return adv_version;
+                               session->security_parameters.pversion = aversion;
+                               return 0;
                        }
                }
 
@@ -467,12 +467,11 @@ _gnutls_negotiate_version(gnutls_session_t session,
 
                session->security_parameters.pversion = vers;
 
-               return vers->id;
+               return 0;
        } else {
-               if (_gnutls_set_current_version(session, adv_version) < 0)
-                       return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
+               session->security_parameters.pversion = aversion;
 
-               return adv_version;
+               return 0;
        }
 }
 
@@ -483,7 +482,7 @@ _gnutls_negotiate_version(gnutls_session_t session,
  */
 int
 _gnutls_user_hello_func(gnutls_session_t session,
-                       gnutls_protocol_t adv_version, uint8_t major, uint8_t minor)
+                       uint8_t major, uint8_t minor)
 {
        int ret, sret = 0;
        const version_entry_st *vers;
@@ -506,7 +505,7 @@ _gnutls_user_hello_func(gnutls_session_t session,
                         * earlier, as TLS1.3 uses a different set of ciphersuites, and
                         * thus we cannot fallback.
                         */
-                       ret = _gnutls_negotiate_version(session, adv_version, major, minor);
+                       ret = _gnutls_negotiate_version(session, major, minor);
                        if (ret < 0) {
                                gnutls_assert();
                                return ret;
@@ -551,7 +550,6 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
        int pos = 0, ret;
        uint16_t suite_size, comp_size;
        int ext_size;
-       gnutls_protocol_t adv_version;
        int neg_version, sret = 0;
        int len = datalen;
        uint8_t major, minor;
@@ -562,17 +560,16 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
        _gnutls_handshake_log("HSK[%p]: Client's version: %d.%d\n",
                              session, data[pos], data[pos + 1]);
 
-       adv_version = _gnutls_version_get(data[pos], data[pos + 1]);
-
        major = data[pos];
        minor = data[pos+1];
+
        set_adv_version(session, major, minor);
 
-       neg_version = _gnutls_negotiate_version(session, adv_version, major, minor);
-       if (neg_version < 0) {
-               gnutls_assert();
-               return neg_version;
-       }
+       ret = _gnutls_negotiate_version(session, major, minor);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
+
+       neg_version = get_num_version(session);
 
        pos += 2;
 
@@ -677,7 +674,7 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
 
                        session->internals.resumed = RESUME_TRUE;
 
-                       return _gnutls_user_hello_func(session, adv_version, major, minor);
+                       return _gnutls_user_hello_func(session, major, minor);
                } else {
                        ret = _gnutls_generate_session_id(session->security_parameters.
                                                          session_id,
@@ -711,7 +708,7 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
        }
 
        /* we cache this error code */
-       sret = _gnutls_user_hello_func(session, adv_version, major, minor);
+       sret = _gnutls_user_hello_func(session, major, minor);
        if (sret < 0 && sret != GNUTLS_E_INT_RET_0) {
                gnutls_assert();
                return sret;
@@ -1824,7 +1821,7 @@ read_server_hello(gnutls_session_t session,
                        return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
        }
 
-       if (_gnutls_version_is_supported(session, vers->id) == 0)
+       if (_gnutls_nversion_is_supported(session, vers->major, vers->minor) == 0)
                return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
 
        /* set server random - done after final version is selected */
index e32de894f2a85162e0fecb38fc16c0d985ba70d5..0d617213c56dca91909f9a18099a8f1fbf9cf7da 100644 (file)
@@ -94,9 +94,9 @@ int _gnutls_server_select_suite(gnutls_session_t session, uint8_t * data,
                                unsigned int datalen, unsigned int scsv_only);
 
 int _gnutls_negotiate_version(gnutls_session_t session,
-                             gnutls_protocol_t adv_version, uint8_t major, uint8_t minor);
+                             uint8_t major, uint8_t minor);
 int _gnutls_user_hello_func(gnutls_session_t session,
-                           gnutls_protocol_t adv_version, uint8_t major, uint8_t minor);
+                           uint8_t major, uint8_t minor);
 
 void _gnutls_handshake_hash_buffers_clear(gnutls_session_t session);
 
index d466cc30f1575c80cb3969a4789a7bd5f4226c8d..de762a5674b4886f2158a31c73d8567e57e815bc 100644 (file)
@@ -93,7 +93,6 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data,
        int pos = 0;
        int ret = 0, sret = 0;
        uint16_t sizeOfSuites;
-       gnutls_protocol_t adv_version;
        uint8_t rnd[GNUTLS_RANDOM_SIZE], major, minor;
        int len = datalen;
        int neg_version;
@@ -110,9 +109,7 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data,
        minor = data[pos + 1];
        set_adv_version(session, major, minor);
 
-       adv_version = _gnutls_version_get(major, minor);
-
-       ret = _gnutls_negotiate_version(session, adv_version, major, minor);
+       ret = _gnutls_negotiate_version(session, major, minor);
        if (ret < 0) {
                gnutls_assert();
                return ret;
@@ -148,7 +145,7 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data,
 
        /* call the user hello callback
         */
-       ret = _gnutls_user_hello_func(session, adv_version, major, minor);
+       ret = _gnutls_user_hello_func(session, major, minor);
        if (ret < 0) {
                if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) {
                        sret = GNUTLS_E_INT_RET_0;