summaryrefslogtreecommitdiffstats
path: root/ssl/statem/statem_srvr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssl/statem/statem_srvr.c')
-rw-r--r--ssl/statem/statem_srvr.c112
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;