]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
tls: Allow setting both minimum and maximum TLS versions
authorTobias Brunner <tobias@strongswan.org>
Wed, 26 Aug 2020 12:37:59 +0000 (14:37 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 12 Feb 2021 10:45:44 +0000 (11:45 +0100)
This allows to increase the initial minimum version and also prevents
sending a list of versions during retries when 1.3 was already
negotiated.

src/libtls/tls.c
src/libtls/tls.h
src/libtls/tls_peer.c
src/libtls/tls_server.c
src/libtls/tls_socket.c

index 30f4786d5c6064bf6b26ec51a57687fa4a2c42e2..fc313e08e210acefca5440a2c2b93f7e5c669daa 100644 (file)
@@ -436,26 +436,24 @@ METHOD(tls_t, get_version_min, tls_version_t,
 }
 
 METHOD(tls_t, set_version, bool,
-       private_tls_t *this, tls_version_t version)
+       private_tls_t *this, tls_version_t min_version, tls_version_t max_version)
 {
-       if (version > this->version_max)
+       if (min_version < this->version_min ||
+               max_version > this->version_max ||
+               min_version > max_version ||
+               min_version < TLS_1_0)
        {
                return FALSE;
        }
-       switch (version)
+
+       this->version_min = min_version;
+       this->version_max = max_version;
+
+       if (min_version == max_version)
        {
-               case TLS_1_0:
-               case TLS_1_1:
-               case TLS_1_2:
-               case TLS_1_3:
-                       this->version_max = version;
-                       this->protection->set_version(this->protection, version);
-                       return TRUE;
-               case SSL_2_0:
-               case SSL_3_0:
-               default:
-                       return FALSE;
+               this->protection->set_version(this->protection, max_version);
        }
+       return TRUE;
 }
 
 METHOD(tls_t, get_purpose, tls_purpose_t,
@@ -545,8 +543,8 @@ tls_t *tls_create(bool is_server, identification_t *server,
                        .destroy = _destroy,
                },
                .is_server = is_server,
-               .version_max = TLS_1_3,
                .version_min = TLS_1_0,
+               .version_max = TLS_1_3,
                .application = application,
                .purpose = purpose,
        );
index 005497f5a9f924c8ed44d660e6ec7bce6129c001..b8903af5d9a78bd3de1afc9858f6596de3480252 100644 (file)
@@ -263,26 +263,29 @@ struct tls_t {
        identification_t* (*get_peer_id)(tls_t *this);
 
        /**
-        * Get the maximum and negotiated TLS/SSL version.
+        * Get the maximum and negotiated TLS version.
         *
         * @return                      max and negotiated TLS version
         */
        tls_version_t (*get_version_max)(tls_t *this);
 
        /**
-       * Get the minimum TLS/SSL version.
+       * Get the minimum TLS version.
        *
        * @return                       min TLS version
        */
        tls_version_t (*get_version_min)(tls_t *this);
 
        /**
-        * Set the negotiated TLS/SSL version.
+        * Set the initial minimum/maximum TLS version, or set both to the same
+        * value once negotiated.
         *
-        * @param version       negotiated TLS version
-        * @return                      TRUE if version acceptable
+        * @param min_version   minimum (or negotiated) TLS version
+        * @param max_version   maximum (or negotiated) TLS version
+        * @return                              TRUE if version(s) acceptable
         */
-       bool (*set_version)(tls_t *this, tls_version_t version);
+       bool (*set_version)(tls_t *this, tls_version_t min_version,
+                                               tls_version_t max_version);
 
        /**
         * Get the purpose of this TLS stack instance.
index bc1857f69a4f6ab8f63092514c607d967000d65f..50326d3f1508e82a943a4b99eeff9e5b9246ae19 100644 (file)
@@ -279,7 +279,7 @@ static status_t process_server_hello(private_tls_peer_t *this,
        }
        extensions->destroy(extensions);
 
-       if (!this->tls->set_version(this->tls, version))
+       if (!this->tls->set_version(this->tls, version, version))
        {
                DBG1(DBG_TLS, "negotiated version %N not supported",
                         tls_version_names, version);
index 3e97d3799671dce2e63f56e94dc77f7cecb580f5..f0bbb1a590e658b76caa102129e6cb4cb99ea6f1 100644 (file)
@@ -282,7 +282,7 @@ static status_t process_client_hello(private_tls_server_t *this,
        }
        rng->destroy(rng);
 
-       if (!this->tls->set_version(this->tls, version))
+       if (!this->tls->set_version(this->tls, version, version))
        {
                DBG1(DBG_TLS, "negotiated version %N not supported",
                         tls_version_names, version);
index d065bdb280980767e94c55365fa6478eaa179807..100475c7dc9d6d3af525299f0ab595bae3eb5e89 100644 (file)
@@ -447,7 +447,7 @@ tls_socket_t *tls_socket_create(bool is_server, identification_t *server,
                free(this);
                return NULL;
        }
-       this->tls->set_version(this->tls, max_version);
+       this->tls->set_version(this->tls, TLS_1_0, max_version);
 
        return &this->public;
 }