Add ssl_get_client_min_max_version() function
Adjust ssl_set_client_hello_version to get both the minimum and maximum and then make ssl_set_client_hello_version use the maximum version. Reviewed-by: Viktor Dukhovni <viktor@openssl.org> MR: #1595
This commit is contained in:
parent
b11836a63a
commit
068c358ac3
2 changed files with 44 additions and 18 deletions
|
@ -1986,6 +1986,7 @@ __owur int ssl_check_version_downgrade(SSL *s);
|
||||||
__owur int ssl_set_version_bound(int method_version, int version, int *bound);
|
__owur int ssl_set_version_bound(int method_version, int version, int *bound);
|
||||||
__owur int ssl_choose_server_version(SSL *s);
|
__owur int ssl_choose_server_version(SSL *s);
|
||||||
__owur int ssl_choose_client_version(SSL *s, int version);
|
__owur int ssl_choose_client_version(SSL *s, int version);
|
||||||
|
int ssl_get_client_min_max_version(const SSL *s, int *min_version, int *max_version);
|
||||||
|
|
||||||
__owur long tls1_default_timeout(void);
|
__owur long tls1_default_timeout(void);
|
||||||
__owur int dtls1_do_write(SSL *s, int type);
|
__owur int dtls1_do_write(SSL *s, int type);
|
||||||
|
|
|
@ -693,7 +693,7 @@ int ssl_allow_compression(SSL *s)
|
||||||
return ssl_security(s, SSL_SECOP_COMPRESSION, 0, 0, NULL);
|
return ssl_security(s, SSL_SECOP_COMPRESSION, 0, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int version_cmp(SSL *s, int a, int b)
|
static int version_cmp(const SSL *s, int a, int b)
|
||||||
{
|
{
|
||||||
int dtls = SSL_IS_DTLS(s);
|
int dtls = SSL_IS_DTLS(s);
|
||||||
|
|
||||||
|
@ -764,7 +764,7 @@ static const version_info dtls_version_table[] = {
|
||||||
*
|
*
|
||||||
* Returns 0 on success, or an SSL error reason on failure.
|
* Returns 0 on success, or an SSL error reason on failure.
|
||||||
*/
|
*/
|
||||||
static int ssl_method_error(SSL *s, const SSL_METHOD *method)
|
static int ssl_method_error(const SSL *s, const SSL_METHOD *method)
|
||||||
{
|
{
|
||||||
int version = method->version;
|
int version = method->version;
|
||||||
|
|
||||||
|
@ -1006,23 +1006,26 @@ int ssl_choose_client_version(SSL *s, int version)
|
||||||
return SSL_R_UNSUPPORTED_PROTOCOL;
|
return SSL_R_UNSUPPORTED_PROTOCOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-
|
/*
|
||||||
* ssl_set_client_hello_version - Work out what version we should be using for
|
* ssl_get_client_min_max_version - get minimum and maximum client version
|
||||||
* the initial ClientHello if the version is initially (D)TLS_ANY_VERSION. We
|
* @s: The SSL connection
|
||||||
* apply any explicit SSL_OP_NO_xxx options, the MinProtocol and MaxProtocol
|
* @min_version: The minimum supported version
|
||||||
* configuration commands, any Suite B or FIPS_mode() constraints and any floor
|
* @max_version: The maximum supported version
|
||||||
* imposed by the security level here, so we don't advertise the wrong protocol
|
*
|
||||||
* version to only reject the outcome later.
|
* Work out what version we should be using for the initial ClientHello if the
|
||||||
|
* version is initially (D)TLS_ANY_VERSION. We apply any explicit SSL_OP_NO_xxx
|
||||||
|
* options, the MinProtocol and MaxProtocol configuration commands, any Suite B
|
||||||
|
* or FIPS_mode() constraints and any floor imposed by the security level here,
|
||||||
|
* so we don't advertise the wrong protocol version to only reject the outcome later.
|
||||||
*
|
*
|
||||||
* Computing the right floor matters. If, e.g., TLS 1.0 and 1.2 are enabled,
|
* Computing the right floor matters. If, e.g., TLS 1.0 and 1.2 are enabled,
|
||||||
* TLS 1.1 is disabled, but the security level, Suite-B and/or MinProtocol
|
* TLS 1.1 is disabled, but the security level, Suite-B and/or MinProtocol
|
||||||
* only allow TLS 1.2, we want to advertise TLS1.2, *not* TLS1.
|
* only allow TLS 1.2, we want to advertise TLS1.2, *not* TLS1.
|
||||||
*
|
*
|
||||||
* @s: client SSL handle.
|
* Returns 0 on success or an SSL error reason number on failure. On failure
|
||||||
*
|
* min_version and max_version will also be set to 0.
|
||||||
* Returns 0 on success or an SSL error reason number on failure.
|
|
||||||
*/
|
*/
|
||||||
int ssl_set_client_hello_version(SSL *s)
|
int ssl_get_client_min_max_version(const SSL *s, int *min_version, int *max_version)
|
||||||
{
|
{
|
||||||
int version;
|
int version;
|
||||||
int hole;
|
int hole;
|
||||||
|
@ -1040,7 +1043,7 @@ int ssl_set_client_hello_version(SSL *s)
|
||||||
* versions they don't want. If not, then easy to fix, just return
|
* versions they don't want. If not, then easy to fix, just return
|
||||||
* ssl_method_error(s, s->method)
|
* ssl_method_error(s, s->method)
|
||||||
*/
|
*/
|
||||||
s->client_version = s->version;
|
*min_version = *max_version = s->version;
|
||||||
return 0;
|
return 0;
|
||||||
case TLS_ANY_VERSION:
|
case TLS_ANY_VERSION:
|
||||||
table = tls_version_table;
|
table = tls_version_table;
|
||||||
|
@ -1071,7 +1074,7 @@ int ssl_set_client_hello_version(SSL *s)
|
||||||
* If we again hit an enabled method after the new hole, it becomes
|
* If we again hit an enabled method after the new hole, it becomes
|
||||||
* selected, as we start from scratch.
|
* selected, as we start from scratch.
|
||||||
*/
|
*/
|
||||||
version = 0;
|
*min_version = version = 0;
|
||||||
hole = 1;
|
hole = 1;
|
||||||
for (vent = table; vent->version != 0; ++vent) {
|
for (vent = table; vent->version != 0; ++vent) {
|
||||||
/*
|
/*
|
||||||
|
@ -1087,18 +1090,40 @@ int ssl_set_client_hello_version(SSL *s)
|
||||||
hole = 1;
|
hole = 1;
|
||||||
} else if (!hole) {
|
} else if (!hole) {
|
||||||
single = NULL;
|
single = NULL;
|
||||||
|
*min_version = method->version;
|
||||||
} else {
|
} else {
|
||||||
version = (single = method)->version;
|
version = (single = method)->version;
|
||||||
|
*min_version = version;
|
||||||
hole = 0;
|
hole = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*max_version = version;
|
||||||
|
|
||||||
/* Fail if everything is disabled */
|
/* Fail if everything is disabled */
|
||||||
if (version == 0)
|
if (version == 0)
|
||||||
return SSL_R_NO_PROTOCOLS_AVAILABLE;
|
return SSL_R_NO_PROTOCOLS_AVAILABLE;
|
||||||
|
|
||||||
if (single != NULL)
|
return 0;
|
||||||
s->method = single;
|
}
|
||||||
s->client_version = s->version = version;
|
|
||||||
|
/*
|
||||||
|
* ssl_set_client_hello_version - Work out what version we should be using for
|
||||||
|
* the initial ClientHello.
|
||||||
|
*
|
||||||
|
* @s: client SSL handle.
|
||||||
|
*
|
||||||
|
* Returns 0 on success or an SSL error reason number on failure.
|
||||||
|
*/
|
||||||
|
int ssl_set_client_hello_version(SSL *s)
|
||||||
|
{
|
||||||
|
int min, max, ret;
|
||||||
|
|
||||||
|
ret = ssl_get_client_min_max_version(s, &min, &max);
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
s->client_version = s->version = max;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue