tls: Allow setting both minimum and maximum TLS versions

This allows to increase the initial minimum version and also prevents
sending a list of versions during retries when 1.3 was already
negotiated.
This commit is contained in:
Tobias Brunner
2021-02-12 11:45:44 +01:00
parent 2b6565c236
commit c4576a1f57
5 changed files with 25 additions and 24 deletions
+13 -15
View File
@@ -436,26 +436,24 @@ METHOD(tls_t, get_version_min, tls_version_t,
} }
METHOD(tls_t, set_version, bool, 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; return FALSE;
} }
switch (version)
this->version_min = min_version;
this->version_max = max_version;
if (min_version == max_version)
{ {
case TLS_1_0: this->protection->set_version(this->protection, max_version);
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;
} }
return TRUE;
} }
METHOD(tls_t, get_purpose, tls_purpose_t, METHOD(tls_t, get_purpose, tls_purpose_t,
@@ -545,8 +543,8 @@ tls_t *tls_create(bool is_server, identification_t *server,
.destroy = _destroy, .destroy = _destroy,
}, },
.is_server = is_server, .is_server = is_server,
.version_max = TLS_1_3,
.version_min = TLS_1_0, .version_min = TLS_1_0,
.version_max = TLS_1_3,
.application = application, .application = application,
.purpose = purpose, .purpose = purpose,
); );
+9 -6
View File
@@ -263,26 +263,29 @@ struct tls_t {
identification_t* (*get_peer_id)(tls_t *this); 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 * @return max and negotiated TLS version
*/ */
tls_version_t (*get_version_max)(tls_t *this); tls_version_t (*get_version_max)(tls_t *this);
/** /**
* Get the minimum TLS/SSL version. * Get the minimum TLS version.
* *
* @return min TLS version * @return min TLS version
*/ */
tls_version_t (*get_version_min)(tls_t *this); 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 * @param min_version minimum (or negotiated) TLS version
* @return TRUE if version acceptable * @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. * Get the purpose of this TLS stack instance.
+1 -1
View File
@@ -279,7 +279,7 @@ static status_t process_server_hello(private_tls_peer_t *this,
} }
extensions->destroy(extensions); 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", DBG1(DBG_TLS, "negotiated version %N not supported",
tls_version_names, version); tls_version_names, version);
+1 -1
View File
@@ -282,7 +282,7 @@ static status_t process_client_hello(private_tls_server_t *this,
} }
rng->destroy(rng); 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", DBG1(DBG_TLS, "negotiated version %N not supported",
tls_version_names, version); tls_version_names, version);
+1 -1
View File
@@ -447,7 +447,7 @@ tls_socket_t *tls_socket_create(bool is_server, identification_t *server,
free(this); free(this);
return NULL; return NULL;
} }
this->tls->set_version(this->tls, max_version); this->tls->set_version(this->tls, TLS_1_0, max_version);
return &this->public; return &this->public;
} }