diff options
Diffstat (limited to 'ssl/statem/statem_srvr.c')
-rw-r--r-- | ssl/statem/statem_srvr.c | 112 |
1 files changed, 15 insertions, 97 deletions
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index a1163ed986..604b36565b 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -970,7 +970,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) SSL_COMP *comp = NULL; #endif STACK_OF(SSL_CIPHER) *ciphers = NULL; - int protverr = 1; + int protverr; /* |cookie| will only be initialized for DTLS. */ PACKET session_id, cipher_suites, compression, extensions, cookie; int is_v2_record; @@ -1037,76 +1037,21 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) } } - /* Do SSL/TLS version negotiation if applicable */ + /* + * Do SSL/TLS version negotiation if applicable. For DTLS we just check + * versions are potentially compatible. Version negotiation comes later. + */ if (!SSL_IS_DTLS(s)) { - if (s->version != TLS_ANY_VERSION) { - if (s->client_version >= s->version) { - protverr = 0; - } - } else if (s->client_version >= SSL3_VERSION) { - int max_version = TLS_MAX_VERSION; - - if (s->max_proto_version != 0) - max_version = s->max_proto_version; - - switch(s->client_version) { - default: - case TLS1_2_VERSION: - if(!(s->options & SSL_OP_NO_TLSv1_2) && - (max_version >= TLS1_2_VERSION) && - (s->min_proto_version <= TLS1_2_VERSION)) { - s->version = TLS1_2_VERSION; - s->method = TLSv1_2_server_method(); - protverr = 0; - break; - } - /* Deliberately fall through */ - case TLS1_1_VERSION: - if(!(s->options & SSL_OP_NO_TLSv1_1) && - (max_version >= TLS1_1_VERSION) && - (s->min_proto_version <= TLS1_1_VERSION)) { - s->version = TLS1_1_VERSION; - s->method = TLSv1_1_server_method(); - protverr = 0; - break; - } - /* Deliberately fall through */ - case TLS1_VERSION: - if(!(s->options & SSL_OP_NO_TLSv1) && - (max_version >= TLS1_VERSION) && - (s->min_proto_version <= TLS1_VERSION)) { - s->version = TLS1_VERSION; - s->method = TLSv1_server_method(); - protverr = 0; - break; - } - /* Deliberately fall through */ - case SSL3_VERSION: -#ifndef OPENSSL_NO_SSL3 - if(!(s->options & SSL_OP_NO_SSLv3) && - (max_version >= SSL3_VERSION) && - (s->min_proto_version <= SSL3_VERSION)) { - s->version = SSL3_VERSION; - s->method = SSLv3_server_method(); - protverr = 0; - break; - } -#else - break; -#endif - } - } - } else if (s->client_version <= s->version - || s->method->version == DTLS_ANY_VERSION) { - /* - * For DTLS we just check versions are potentially compatible. Version - * negotiation comes later. - */ + protverr = ssl_choose_server_version(s); + } else if (s->method->version != DTLS_ANY_VERSION && + DTLS_VERSION_LT(s->client_version, s->version)) { + protverr = SSL_R_VERSION_TOO_LOW; + } else { protverr = 0; } if (protverr) { - SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); + SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, protverr); if ((!s->enc_write_ctx && !s->write_hash)) { /* * similar to ssl3_get_record, send alert using remote version @@ -1266,36 +1211,9 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) s->d1->cookie_verified = 1; } if (s->method->version == DTLS_ANY_VERSION) { - /* Select version to use */ - int max_version = DTLS_MAX_VERSION; - int min_version = DTLS_MIN_VERSION; - - if (s->max_proto_version != 0) - max_version = s->max_proto_version; - if (s->min_proto_version != 0) - min_version = s->min_proto_version; - - if (DTLS_VERSION_GE(s->client_version, DTLS1_2_VERSION) && - !(s->options & SSL_OP_NO_DTLSv1_2) && - DTLS_VERSION_GE(max_version, DTLS1_2_VERSION) && - DTLS_VERSION_LE(min_version, DTLS1_2_VERSION)) { - s->version = DTLS1_2_VERSION; - s->method = DTLSv1_2_server_method(); - } else if (tls1_suiteb(s)) { - SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - s->version = s->client_version; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } else if (DTLS_VERSION_GE(s->client_version, DTLS1_VERSION) && - !(s->options & SSL_OP_NO_DTLSv1) && - DTLS_VERSION_GE(max_version, DTLS1_VERSION) && - DTLS_VERSION_LE(min_version, DTLS1_VERSION)) { - s->version = DTLS1_VERSION; - s->method = DTLSv1_server_method(); - } else { - SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, - SSL_R_WRONG_VERSION_NUMBER); + protverr = ssl_choose_server_version(s); + if (protverr != 0) { + SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, protverr); s->version = s->client_version; al = SSL_AD_PROTOCOL_VERSION; goto f_err; @@ -3303,7 +3221,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, * version. Fail if the current version is an unexpected * downgrade. */ - if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) { + if (!ssl_check_version_downgrade(s)) { SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, SSL_R_INAPPROPRIATE_FALLBACK); *al = SSL_AD_INAPPROPRIATE_FALLBACK; |