diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | include/openssl/ssl.h | 8 | ||||
-rw-r--r-- | ssl/d1_lib.c | 38 | ||||
-rw-r--r-- | ssl/methods.c | 54 | ||||
-rw-r--r-- | ssl/s3_lib.c | 27 | ||||
-rw-r--r-- | ssl/ssl_cert.c | 24 | ||||
-rw-r--r-- | ssl/ssl_ciph.c | 8 | ||||
-rw-r--r-- | ssl/ssl_conf.c | 32 | ||||
-rw-r--r-- | ssl/ssl_err.c | 14 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 18 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 32 | ||||
-rw-r--r-- | ssl/statem/statem.c | 15 | ||||
-rw-r--r-- | ssl/statem/statem_clnt.c | 246 | ||||
-rw-r--r-- | ssl/statem/statem_lib.c | 385 | ||||
-rw-r--r-- | ssl/statem/statem_srvr.c | 112 | ||||
-rw-r--r-- | ssl/t1_lib.c | 5 |
16 files changed, 543 insertions, 479 deletions
@@ -9,7 +9,9 @@ SSL_set_max_proto_version(), or via the SSL_CONF's MinProtocol and MaxProtcol. It's recommended to use the new APIs to disable protocols instead of disabling individual protocols using - SSL_set_options() or SSL_CONF's Protocol. + SSL_set_options() or SSL_CONF's Protocol. This change also + removes support for disabling TLS 1.2 in the OpenSSL TLS + client at compile time by defining OPENSSL_NO_TLS1_2_CLIENT. [Kurt Roeckx] *) Support for ChaCha20 and Poly1305 added to libcrypto and libssl. diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index a0d66fa0c4..0d22ab7716 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1217,7 +1217,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # define SSL_CTRL_SELECT_CURRENT_CERT 116 # define SSL_CTRL_SET_CURRENT_CERT 117 # define SSL_CTRL_SET_DH_AUTO 118 -# define SSL_CTRL_CHECK_PROTO_VERSION 119 # define DTLS_CTRL_SET_LINK_MTU 120 # define DTLS_CTRL_GET_LINK_MIN_MTU 121 # define SSL_CTRL_GET_EXTMS_SUPPORT 122 @@ -2099,7 +2098,6 @@ void ERR_load_SSL_strings(void); # define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 # define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 # define SSL_F_SSL_SET_TRUST 228 -# define SSL_F_SSL_SET_VERSION 347 # define SSL_F_SSL_SET_WFD 196 # define SSL_F_SSL_SHUTDOWN 224 # define SSL_F_SSL_SRP_CTX_INIT 313 @@ -2170,6 +2168,8 @@ void ERR_load_SSL_strings(void); /* Reason codes. */ # define SSL_R_APP_DATA_IN_HANDSHAKE 100 # define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +# define SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE 143 +# define SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE 158 # define SSL_R_BAD_ALERT_RECORD 101 # define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 # define SSL_R_BAD_DATA 390 @@ -2323,9 +2323,6 @@ void ERR_load_SSL_strings(void); # define SSL_R_NULL_SSL_METHOD_PASSED 196 # define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 # define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 -# define SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE 387 -# define SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE 379 -# define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 # define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG 327 # define SSL_R_PACKET_LENGTH_TOO_LONG 198 # define SSL_R_PARSE_TLSEXT 227 @@ -2443,6 +2440,7 @@ void ERR_load_SSL_strings(void); # define SSL_R_UNSUPPORTED_SSL_VERSION 259 # define SSL_R_UNSUPPORTED_STATUS_TYPE 329 # define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 +# define SSL_R_VERSION_TOO_HIGH 166 # define SSL_R_VERSION_TOO_LOW 396 # define SSL_R_WRONG_CERTIFICATE_TYPE 383 # define SSL_R_WRONG_CIPHER_RETURNED 261 diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index a510b5bebe..3cd4b786e4 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -235,7 +235,7 @@ void dtls1_clear(SSL *s) if (s->options & SSL_OP_CISCO_ANYCONNECT) s->client_version = s->version = DTLS1_BAD_VER; else if (s->method->version == DTLS_ANY_VERSION) - s->version = DTLS1_2_VERSION; + s->version = DTLS_MAX_VERSION; else s->version = s->method->version; } @@ -256,38 +256,6 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) case DTLS_CTRL_LISTEN: ret = dtls1_listen(s, parg); break; - case SSL_CTRL_CHECK_PROTO_VERSION: - /* - * For library-internal use; checks that the current protocol is the - * is the highest enabled version. - */ - if (s->max_proto_version == 0 && s->version == DTLS_MAX_VERSION) - return 1; - if (s->max_proto_version != 0 && s->version == s->max_proto_version) - return 1; - /* We're not limited by the max_proto_version but might still have - * other reasons why we use an older version like not using a - * version-flexible SSL_METHOD. Check s->ctx->method as version - * negotiation may have changed s->method. - * This check can be removed when we only have version-flexible - * SSL_METHODs - */ - if (s->version == s->ctx->method->version) - return 1; - /* - * Apparently we're using a version-flexible SSL_METHOD (not at its - * highest protocol version, not limited by max_proto_version). - */ - if (s->ctx->method->version == DTLS_method()->version) { -#if DTLS_MAX_VERSION != DTLS1_2_VERSION -# error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION. -#endif - if (!(s->options & SSL_OP_NO_DTLSv1_2)) - return s->version == DTLS1_2_VERSION; - if (!(s->options & SSL_OP_NO_DTLSv1)) - return s->version == DTLS1_VERSION; - } - return 0; /* Unexpected state; fail closed. */ case DTLS_CTRL_SET_LINK_MTU: if (larg < (long)dtls1_link_min_mtu()) return 0; @@ -708,8 +676,8 @@ int dtls1_listen(SSL *s, struct sockaddr *client) /* * Verify client version is supported */ - if ((clientvers > (unsigned int)s->method->version && - s->method->version != DTLS_ANY_VERSION)) { + if (DTLS_VERSION_LT(clientvers, (unsigned int)s->method->version) && + s->method->version != DTLS_ANY_VERSION) { SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_WRONG_VERSION_NUMBER); goto end; } diff --git a/ssl/methods.c b/ssl/methods.c index ef20c9ca3e..7a8bb11b77 100644 --- a/ssl/methods.c +++ b/ssl/methods.c @@ -135,19 +135,23 @@ static const SSL_METHOD *tls1_get_method(int ver) return NULL; } -IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, TLS_method, +IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, 0, 0, + TLS_method, ossl_statem_accept, ossl_statem_connect, tls1_get_method, TLSv1_2_enc_data) -IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method, +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, 0, SSL_OP_NO_TLSv1_2, + TLSv1_2_method, ossl_statem_accept, ossl_statem_connect, tls1_get_method, TLSv1_2_enc_data) -IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method, +IMPLEMENT_tls_meth_func(TLS1_1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1_1, + TLSv1_1_method, ossl_statem_accept, ossl_statem_connect, tls1_get_method, TLSv1_1_enc_data) -IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method, +IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1, + TLSv1_method, ossl_statem_accept, ossl_statem_connect, tls1_get_method, TLSv1_enc_data) @@ -178,22 +182,26 @@ static const SSL_METHOD *tls1_get_server_method(int ver) return NULL; } -IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, TLS_server_method, +IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, 0, 0, + TLS_server_method, ossl_statem_accept, ssl_undefined_function, tls1_get_server_method, TLSv1_2_enc_data) -IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method, +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, 0, SSL_OP_NO_TLSv1_2, + TLSv1_2_server_method, ossl_statem_accept, ssl_undefined_function, tls1_get_server_method, TLSv1_2_enc_data) -IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method, +IMPLEMENT_tls_meth_func(TLS1_1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1_1, + TLSv1_1_server_method, ossl_statem_accept, ssl_undefined_function, tls1_get_server_method, TLSv1_1_enc_data) -IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method, +IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1, + TLSv1_server_method, ossl_statem_accept, ssl_undefined_function, tls1_get_server_method, TLSv1_enc_data) @@ -226,22 +234,26 @@ static const SSL_METHOD *tls1_get_client_method(int ver) return NULL; } -IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, TLS_client_method, +IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, 0, 0, + TLS_client_method, ssl_undefined_function, ossl_statem_connect, tls1_get_client_method, TLSv1_2_enc_data) -IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_client_method, +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, 0, SSL_OP_NO_TLSv1_2, + TLSv1_2_client_method, ssl_undefined_function, ossl_statem_connect, tls1_get_client_method, TLSv1_2_enc_data) -IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method, +IMPLEMENT_tls_meth_func(TLS1_1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1_1, + TLSv1_1_client_method, ssl_undefined_function, ossl_statem_connect, tls1_get_client_method, TLSv1_1_enc_data) -IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_client_method, +IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1, + TLSv1_client_method, ssl_undefined_function, ossl_statem_connect, tls1_get_client_method, TLSv1_enc_data) @@ -268,19 +280,19 @@ static const SSL_METHOD *dtls1_get_method(int ver) return NULL; } -IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, +IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1, DTLSv1_method, ossl_statem_accept, ossl_statem_connect, dtls1_get_method, DTLSv1_enc_data) -IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, +IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, DTLSv1_2_method, ossl_statem_accept, ossl_statem_connect, dtls1_get_method, DTLSv1_2_enc_data) -IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, +IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_method, ossl_statem_accept, ossl_statem_connect, @@ -303,19 +315,19 @@ static const SSL_METHOD *dtls1_get_server_method(int ver) return NULL; } -IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, +IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1, DTLSv1_server_method, ossl_statem_accept, ssl_undefined_function, dtls1_get_server_method, DTLSv1_enc_data) -IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, +IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, DTLSv1_2_server_method, ossl_statem_accept, ssl_undefined_function, dtls1_get_server_method, DTLSv1_2_enc_data) -IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, +IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_server_method, ossl_statem_accept, ssl_undefined_function, @@ -338,19 +350,19 @@ static const SSL_METHOD *dtls1_get_client_method(int ver) return NULL; } -IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, +IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1, DTLSv1_client_method, ssl_undefined_function, ossl_statem_connect, dtls1_get_client_method, DTLSv1_enc_data) -IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, +IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, DTLSv1_2_client_method, ssl_undefined_function, ossl_statem_connect, dtls1_get_client_method, DTLSv1_2_enc_data) -IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, +IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_client_method, ssl_undefined_function, ossl_statem_connect, diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index e3e4fd34f8..d307ec05d6 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3777,33 +3777,6 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) } #endif - case SSL_CTRL_CHECK_PROTO_VERSION: - /* - * For library-internal use; checks that the current protocol is the - * highest enabled version (according to s->ctx->method, as version - * negotiation may have changed s->method). - */ - if (s->version == s->ctx->method->version) - return 1; - /* - * Apparently we're using a version-flexible SSL_METHOD (not at its - * highest protocol version). - */ - if (s->ctx->method->version == TLS_method()->version) { -#if TLS_MAX_VERSION != TLS1_2_VERSION -# error Code needs update for TLS_method() support beyond TLS1_2_VERSION. -#endif - if (!(s->options & SSL_OP_NO_TLSv1_2)) - return s->version == TLS1_2_VERSION; - if (!(s->options & SSL_OP_NO_TLSv1_1)) - return s->version == TLS1_1_VERSION; - if (!(s->options & SSL_OP_NO_TLSv1)) - return s->version == TLS1_VERSION; - if (!(s->options & SSL_OP_NO_SSLv3)) - return s->version == SSL3_VERSION; - } - return 0; /* Unexpected state; fail closed. */ - default: break; } diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index f01d3a7835..597de0ad6c 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -1084,15 +1084,21 @@ static int ssl_security_default_callback(SSL *s, SSL_CTX *ctx, int op, break; } case SSL_SECOP_VERSION: - /* SSLv3 not allowed on level 2 */ - if (nid <= SSL3_VERSION && level >= 2) - return 0; - /* TLS v1.1 and above only for level 3 */ - if (nid <= TLS1_VERSION && level >= 3) - return 0; - /* TLS v1.2 only for level 4 and above */ - if (nid <= TLS1_1_VERSION && level >= 4) - return 0; + if (!SSL_IS_DTLS(s)) { + /* SSLv3 not allowed at level 2 */ + if (nid <= SSL3_VERSION && level >= 2) + return 0; + /* TLS v1.1 and above only for level 3 */ + if (nid <= TLS1_VERSION && level >= 3) + return 0; + /* TLS v1.2 only for level 4 and above */ + if (nid <= TLS1_1_VERSION && level >= 4) + return 0; + } else { + /* DTLS v1.2 only for level 4 and above */ + if (DTLS_VERSION_LT(nid, DTLS1_2_VERSION) && level >= 4) + return 0; + } break; case SSL_SECOP_COMPRESSION: diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 65a5bb6c96..a15248d41b 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -1349,12 +1349,8 @@ static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c, /* Check version: if TLS 1.2 ciphers allowed we can use Suite B */ if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)) { - if (meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) - SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - else - SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, - SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); + SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, + SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE); return 0; } # ifndef OPENSSL_NO_EC diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 1e14a4497e..9529d30842 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -347,6 +347,22 @@ static int protocol_from_string(const char *value) return -1; } +static int min_max_proto(SSL_CONF_CTX *cctx, const char *value, int *bound) +{ + int method_version; + int new_version; + + if (cctx->ctx != NULL) + method_version = cctx->ctx->method->version; + else if (cctx->ssl != NULL) + method_version = cctx->ssl->ctx->method->version; + else + return 0; + if ((new_version = protocol_from_string(value)) < 0) + return 0; + return ssl_set_version_bound(method_version, new_version, bound); +} + /* * cmd_MinProtocol - Set min protocol version * @cctx: config structure to save settings in @@ -356,13 +372,7 @@ static int protocol_from_string(const char *value) */ static int cmd_MinProtocol(SSL_CONF_CTX *cctx, const char *value) { - int version = protocol_from_string(value); - - if (version < 0) - return 0; - - *(cctx->min_version) = version; - return 1; + return min_max_proto(cctx, value, cctx->min_version); } /* @@ -374,13 +384,7 @@ static int cmd_MinProtocol(SSL_CONF_CTX *cctx, const char *value) */ static int cmd_MaxProtocol(SSL_CONF_CTX *cctx, const char *value) { - int version = protocol_from_string(value); - - if (version < 0) - return 0; - - *(cctx->max_version) = version; - return 1; + return min_max_proto(cctx, value, cctx->max_version); } static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 0c40b7b3ec..d9dbf99391 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -314,7 +314,6 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), "SSL_set_session_ticket_ext"}, {ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"}, - {ERR_FUNC(SSL_F_SSL_SET_VERSION), "SSL_SET_VERSION"}, {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"}, {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"}, {ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_init"}, @@ -416,6 +415,10 @@ static ERR_STRING_DATA SSL_str_reasons[] = { {ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE), "app data in handshake"}, {ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), "attempt to reuse session in different context"}, + {ERR_REASON(SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE), + "at least TLS 1.0 needed in FIPS mode"}, + {ERR_REASON(SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE), + "at least (D)TLS 1.2 needed in Suite B mode"}, {ERR_REASON(SSL_R_BAD_ALERT_RECORD), "bad alert record"}, {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"}, {ERR_REASON(SSL_R_BAD_DATA), "bad data"}, @@ -603,14 +606,6 @@ static ERR_STRING_DATA SSL_str_reasons[] = { "old session cipher not returned"}, {ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED), "old session compression algorithm not returned"}, - {ERR_REASON(SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE), - "only DTLS 1.2 allowed in Suite B mode"}, - {ERR_REASON(SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE), - "only TLS 1.2 allowed in Suite B mode"}, - {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE), - "only tls allowed in fips mode"}, - {ERR_REASON(SSL_R_OPAQUE_PRF_INPUT_TOO_LONG), - "opaque PRF input too long"}, {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"}, {ERR_REASON(SSL_R_PARSE_TLSEXT), "parse tlsext"}, {ERR_REASON(SSL_R_PATH_TOO_LONG), "path too long"}, @@ -794,6 +789,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = { {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"}, {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"}, {ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"}, + {ERR_REASON(SSL_R_VERSION_TOO_HIGH), "version too high"}, {ERR_REASON(SSL_R_VERSION_TOO_LOW), "version too low"}, {ERR_REASON(SSL_R_WRONG_CERTIFICATE_TYPE), "wrong certificate type"}, {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED), "wrong cipher returned"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index cfc73de9ca..760014d739 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1201,11 +1201,11 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) else return 0; case SSL_CTRL_SET_MIN_PROTO_VERSION: - s->min_proto_version = larg; - return 1; + return ssl_set_version_bound(s->ctx->method->version, (int)larg, + &s->min_proto_version); case SSL_CTRL_SET_MAX_PROTO_VERSION: - s->max_proto_version = larg; - return 1; + return ssl_set_version_bound(s->ctx->method->version, (int)larg, + &s->max_proto_version); default: return (s->method->ssl_ctrl(s, cmd, larg, parg)); } @@ -1323,11 +1323,11 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) case SSL_CTRL_CLEAR_CERT_FLAGS: return (ctx->cert->cert_flags &= ~larg); case SSL_CTRL_SET_MIN_PROTO_VERSION: - ctx->min_proto_version = larg; - return 1; + return ssl_set_version_bound(ctx->method->version, (int)larg, + &ctx->min_proto_version); case SSL_CTRL_SET_MAX_PROTO_VERSION: - ctx->max_proto_version = larg; - return 1; + return ssl_set_version_bound(ctx->method->version, (int)larg, + &ctx->max_proto_version); default: return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg)); } @@ -1795,7 +1795,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) } if (FIPS_mode() && (meth->version < TLS1_VERSION)) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE); return NULL; } diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 9482fc91ad..7e07297f2f 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -471,8 +471,8 @@ * flags because it may not be set to correct version yet. */ # define SSL_CLIENT_USE_TLS1_2_CIPHERS(s) \ - ((SSL_IS_DTLS(s) && s->client_version <= DTLS1_2_VERSION) || \ - (!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION)) + ((!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION) || \ + (SSL_IS_DTLS(s) && DTLS_VERSION_GE(s->client_version, DTLS1_2_VERSION))) # ifdef TLSEXT_TYPE_encrypt_then_mac # define SSL_USE_ETM(s) (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) @@ -535,6 +535,8 @@ struct ssl_cipher_st { /* Used to hold SSL/TLS functions */ struct ssl_method_st { int version; + unsigned flags; + unsigned long mask; int (*ssl_new) (SSL *s); void (*ssl_clear) (SSL *s); void (*ssl_free) (SSL *s); @@ -1685,12 +1687,20 @@ extern const SSL3_ENC_METHOD SSLv3_enc_data; extern const SSL3_ENC_METHOD DTLSv1_enc_data; extern const SSL3_ENC_METHOD DTLSv1_2_enc_data; -# define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \ - s_get_meth, enc_data) \ +/* + * Flags for SSL methods + */ +#define SSL_METHOD_NO_FIPS (1U<<0) +#define SSL_METHOD_NO_SUITEB (1U<<1) + +# define IMPLEMENT_tls_meth_func(version, flags, mask, func_name, s_accept, \ + s_connect, s_get_meth, enc_data) \ const SSL_METHOD *func_name(void) \ { \ static const SSL_METHOD func_name##_data= { \ version, \ + flags, \ + mask, \ tls1_new, \ tls1_clear, \ tls1_free, \ @@ -1727,6 +1737,8 @@ const SSL_METHOD *func_name(void) \ { \ static const SSL_METHOD func_name##_data= { \ SSL3_VERSION, \ + SSL_METHOD_NO_FIPS | SSL_METHOD_NO_SUITEB, \ + SSL_OP_NO_SSLv3, \ ssl3_new, \ ssl3_clear, \ ssl3_free, \ @@ -1758,12 +1770,14 @@ const SSL_METHOD *func_name(void) \ return &func_name##_data; \ } -# define IMPLEMENT_dtls1_meth_func(version, func_name, s_accept, s_connect, \ - s_get_meth, enc_data) \ +# define IMPLEMENT_dtls1_meth_func(version, flags, mask, func_name, s_accept, \ + s_connect, s_get_meth, enc_data) \ const SSL_METHOD *func_name(void) \ { \ static const SSL_METHOD func_name##_data= { \ version, \ + flags, \ + mask, \ dtls1_new, \ dtls1_clear, \ dtls1_free, \ @@ -1911,6 +1925,12 @@ __owur int ssl3_handshake_write(SSL *s); __owur int ssl_allow_compression(SSL *s); +__owur int ssl_set_client_hello_version(SSL *s); +__owur int ssl_check_version_downgrade(SSL *s); +__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_client_version(SSL *s, int version); + __owur long tls1_default_timeout(void); __owur int dtls1_do_write(SSL *s, int type); void dtls1_set_message_header(SSL *s, diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index bc3fc54fab..a03fe32083 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -261,7 +261,8 @@ static void (*get_callback(SSL *s))(const SSL *, int, int) * 1: Success * <=0: NBIO or error */ -static int state_machine(SSL *s, int server) { +static int state_machine(SSL *s, int server) +{ BUF_MEM *buf = NULL; unsigned long Time = (unsigned long)time(NULL); void (*cb) (const SSL *ssl, int type, int val) = NULL; @@ -336,19 +337,15 @@ static int state_machine(SSL *s, int server) { goto end; } } else { - if ((s->version >> 8) != SSL3_VERSION_MAJOR - && s->version != TLS_ANY_VERSION) { + if ((s->version >> 8) != SSL3_VERSION_MAJOR) { SSLerr(SSL_F_STATE_MACHINE, ERR_R_INTERNAL_ERROR); goto end; } } - if (!SSL_IS_DTLS(s)) { - if (s->version != TLS_ANY_VERSION && - !ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) { - SSLerr(SSL_F_STATE_MACHINE, SSL_R_VERSION_TOO_LOW); - goto end; - } + if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) { + SSLerr(SSL_F_STATE_MACHINE, SSL_R_VERSION_TOO_LOW); + goto end; } if (s->init_buf == NULL) { diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 26acdc5488..cfbfa5f8c3 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -166,7 +166,6 @@ static ossl_inline int cert_req_allowed(SSL *s); static int key_exchange_expected(SSL *s); -static int ssl_set_version(SSL *s); static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b); static int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, unsigned char *p); @@ -800,128 +799,12 @@ WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst) return WORK_ERROR; } -/* - * Work out what version we should be using for the initial ClientHello if - * the version is currently set to (D)TLS_ANY_VERSION. - * Returns 1 on success - * Returns 0 on error - */ -static int ssl_set_version(SSL *s) -{ - unsigned long mask, options = s->options; - - if (s->method->version == TLS_ANY_VERSION) { - /* - * SSL_OP_NO_X disables all protocols above X *if* there are - * some protocols below X enabled. This is required in order - * to maintain "version capability" vector contiguous. So - * that if application wants to disable TLS1.0 in favour of - * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the - * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3. - */ - mask = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 -#if !defined(OPENSSL_NO_SSL3) - | SSL_OP_NO_SSLv3 -#endif - ; -#if !defined(OPENSSL_NO_TLS1_2_CLIENT) - if (options & SSL_OP_NO_TLSv1_2) { - if ((options & mask) != mask) { - s->version = TLS1_1_VERSION; - } else { - SSLerr(SSL_F_SSL_SET_VERSION, SSL_R_NO_PROTOCOLS_AVAILABLE); - return 0; - } - } else { - s->version = TLS1_2_VERSION; - } -#else - if ((options & mask) == mask) { - SSLerr(SSL_F_SSL_SET_VERSION, SSL_R_NO_PROTOCOLS_AVAILABLE); - return 0; - } - s->version = TLS1_1_VERSION; -#endif - - mask &= ~SSL_OP_NO_TLSv1_1; - if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) - s->version = TLS1_VERSION; - mask &= ~SSL_OP_NO_TLSv1; -#if !defined(OPENSSL_NO_SSL3) - if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask) - s->version = SSL3_VERSION; -#endif - - if (s->max_proto_version != 0 && (s->version > s->max_proto_version)) - s->version = s->max_proto_version; - if (s->version < s->min_proto_version) - { - SSLerr(SSL_F_SSL_SET_VERSION, SSL_R_NO_PROTOCOLS_AVAILABLE); - return 0; - } - - if (s->version != TLS1_2_VERSION && tls1_suiteb(s)) { - SSLerr(SSL_F_SSL_SET_VERSION, - SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); - return 0; - } - - if (s->version == SSL3_VERSION && FIPS_mode()) { - SSLerr(SSL_F_SSL_SET_VERSION, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - return 0; - } - - } else if (s->method->version == DTLS_ANY_VERSION) { - 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 1.2 disabled correct the version number */ - if (options & SSL_OP_NO_DTLSv1_2 - || DTLS_VERSION_GT(DTLS1_2_VERSION, max_version)) { - if (tls1_suiteb(s)) { - SSLerr(SSL_F_SSL_SET_VERSION, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - return 0; - } - /* - * Disabling all versions is silly: return an error. - */ - if (options & SSL_OP_NO_DTLSv1 - || DTLS_VERSION_GT(min_version, DTLS1_VERSION)) { - SSLerr(SSL_F_SSL_ |