aboutsummaryrefslogtreecommitdiff
path: root/ssl/statem/statem_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssl/statem/statem_lib.c')
-rw-r--r--ssl/statem/statem_lib.c80
1 files changed, 46 insertions, 34 deletions
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index b8e094b..7b18115 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -1739,21 +1739,31 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd)
*
* @s: client SSL handle.
* @version: The proposed version from the server's HELLO.
- * @checkdgrd: Whether to check the downgrade sentinels in the server_random
+ * @extensions: The extensions received
*
* Returns 1 on success or 0 on error.
*/
-int ssl_choose_client_version(SSL *s, int version, int checkdgrd)
+int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions)
{
const version_info *vent;
const version_info *table;
int highver = 0;
+ int origv;
- /* TODO(TLS1.3): Remove this before release */
- if (version == TLS1_3_VERSION_DRAFT)
- version = TLS1_3_VERSION;
+ origv = s->version;
+ s->version = version;
- if (s->hello_retry_request && version != TLS1_3_VERSION) {
+ /* This will overwrite s->version if the extension is present */
+ if (!tls_parse_extension(s, TLSEXT_IDX_supported_versions,
+ SSL_EXT_TLS1_2_SERVER_HELLO
+ | SSL_EXT_TLS1_3_SERVER_HELLO, extensions,
+ NULL, 0)) {
+ s->version = origv;
+ return 0;
+ }
+
+ if (s->hello_retry_request && s->version != TLS1_3_VERSION) {
+ s->version = origv;
SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_F_SSL_CHOOSE_CLIENT_VERSION,
SSL_R_WRONG_SSL_VERSION);
return 0;
@@ -1761,7 +1771,8 @@ int ssl_choose_client_version(SSL *s, int version, int checkdgrd)
switch (s->method->version) {
default:
- if (version != s->version) {
+ if (s->version != s->method->version) {
+ s->version = origv;
SSLfatal(s, SSL_AD_PROTOCOL_VERSION,
SSL_F_SSL_CHOOSE_CLIENT_VERSION,
SSL_R_WRONG_SSL_VERSION);
@@ -1790,13 +1801,14 @@ int ssl_choose_client_version(SSL *s, int version, int checkdgrd)
if (vent->cmeth == NULL)
continue;
- if (highver != 0 && version != vent->version)
+ if (highver != 0 && s->version != vent->version)
continue;
method = vent->cmeth();
err = ssl_method_error(s, method);
if (err != 0) {
- if (version == vent->version) {
+ if (s->version == vent->version) {
+ s->version = origv;
SSLfatal(s, SSL_AD_PROTOCOL_VERSION,
SSL_F_SSL_CHOOSE_CLIENT_VERSION, err);
return 0;
@@ -1807,43 +1819,43 @@ int ssl_choose_client_version(SSL *s, int version, int checkdgrd)
if (highver == 0)
highver = vent->version;
- if (version != vent->version)
+ if (s->version != vent->version)
continue;
#ifndef OPENSSL_NO_TLS13DOWNGRADE
/* Check for downgrades */
- if (checkdgrd) {
- if (version == TLS1_2_VERSION && highver > version) {
- if (memcmp(tls12downgrade,
- s->s3->server_random + SSL3_RANDOM_SIZE
- - sizeof(tls12downgrade),
- sizeof(tls12downgrade)) == 0) {
- SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
- SSL_F_SSL_CHOOSE_CLIENT_VERSION,
- SSL_R_INAPPROPRIATE_FALLBACK);
- return 0;
- }
- } else if (!SSL_IS_DTLS(s)
- && version < TLS1_2_VERSION
- && highver > version) {
- if (memcmp(tls11downgrade,
- s->s3->server_random + SSL3_RANDOM_SIZE
- - sizeof(tls11downgrade),
- sizeof(tls11downgrade)) == 0) {
- SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
- SSL_F_SSL_CHOOSE_CLIENT_VERSION,
- SSL_R_INAPPROPRIATE_FALLBACK);
- return 0;
- }
+ if (s->version == TLS1_2_VERSION && highver > s->version) {
+ if (memcmp(tls12downgrade,
+ s->s3->server_random + SSL3_RANDOM_SIZE
+ - sizeof(tls12downgrade),
+ sizeof(tls12downgrade)) == 0) {
+ s->version = origv;
+ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
+ SSL_F_SSL_CHOOSE_CLIENT_VERSION,
+ SSL_R_INAPPROPRIATE_FALLBACK);
+ return 0;
+ }
+ } else if (!SSL_IS_DTLS(s)
+ && s->version < TLS1_2_VERSION
+ && highver > s->version) {
+ if (memcmp(tls11downgrade,
+ s->s3->server_random + SSL3_RANDOM_SIZE
+ - sizeof(tls11downgrade),
+ sizeof(tls11downgrade)) == 0) {
+ s->version = origv;
+ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
+ SSL_F_SSL_CHOOSE_CLIENT_VERSION,
+ SSL_R_INAPPROPRIATE_FALLBACK);
+ return 0;
}
}
#endif
s->method = method;
- s->version = version;
return 1;
}
+ s->version = origv;
SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_F_SSL_CHOOSE_CLIENT_VERSION,
SSL_R_UNSUPPORTED_PROTOCOL);
return 0;