X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=491023f835cd28ce28aa71d18b04969ff036db00;hp=4bcbfa837714a4fe10cd7dcfcf65d70619d79738;hb=5d61491c8816ebad172340aafce713e9654dea94;hpb=9368f86526d9feb1f511fab9c0eee8e8dc869b87 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 4bcbfa8377..491023f835 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -400,6 +400,116 @@ static int dane_tlsa_add(SSL_DANE *dane, return 1; } +/* + * Return 0 if there is only one version configured and it was disabled + * at configure time. Return 1 otherwise. + */ +static int ssl_check_allowed_versions(int min_version, int max_version) +{ + int minisdtls = 0, maxisdtls = 0; + + /* Figure out if we're doing DTLS versions or TLS versions */ + if (min_version == DTLS1_BAD_VER + || min_version >> 8 == DTLS1_VERSION_MAJOR) + minisdtls = 1; + if (max_version == DTLS1_BAD_VER + || max_version >> 8 == DTLS1_VERSION_MAJOR) + maxisdtls = 1; + /* A wildcard version of 0 could be DTLS or TLS. */ + if ((minisdtls && !maxisdtls && max_version != 0) + || (maxisdtls && !minisdtls && min_version != 0)) { + /* Mixing DTLS and TLS versions will lead to sadness; deny it. */ + return 0; + } + + if (minisdtls || maxisdtls) { + /* Do DTLS version checks. */ + if (min_version == 0) + /* Ignore DTLS1_BAD_VER */ + min_version = DTLS1_VERSION; + if (max_version == 0) + max_version = DTLS1_2_VERSION; +#ifdef OPENSSL_NO_DTLS1_2 + if (max_version == DTLS1_2_VERSION) + max_version = DTLS1_VERSION; +#endif +#ifdef OPENSSL_NO_DTLS1 + if (min_version == DTLS1_VERSION) + min_version = DTLS1_2_VERSION; +#endif + /* Done massaging versions; do the check. */ + if (0 +#ifdef OPENSSL_NO_DTLS1 + || (DTLS_VERSION_GE(min_version, DTLS1_VERSION) + && DTLS_VERSION_GE(DTLS1_VERSION, max_version)) +#endif +#ifdef OPENSSL_NO_DTLS1_2 + || (DTLS_VERSION_GE(min_version, DTLS1_2_VERSION) + && DTLS_VERSION_GE(DTLS1_2_VERSION, max_version)) +#endif + ) + return 0; + } else { + /* Regular TLS version checks. */ + if (min_version == 0) + min_version = SSL3_VERSION; + if (max_version == 0) + max_version = TLS1_3_VERSION; +#ifdef OPENSSL_NO_TLS1_3 + if (max_version == TLS1_3_VERSION) + max_version = TLS1_2_VERSION; +#endif +#ifdef OPENSSL_NO_TLS1_2 + if (max_version == TLS1_2_VERSION) + max_version = TLS1_1_VERSION; +#endif +#ifdef OPENSSL_NO_TLS1_1 + if (max_version == TLS1_1_VERSION) + max_version = TLS1_VERSION; +#endif +#ifdef OPENSSL_NO_TLS1 + if (max_version == TLS1_VERSION) + max_version = SSL3_VERSION; +#endif +#ifdef OPENSSL_NO_SSL3 + if (min_version == SSL3_VERSION) + min_version = TLS1_VERSION; +#endif +#ifdef OPENSSL_NO_TLS1 + if (min_version == TLS1_VERSION) + min_version = TLS1_1_VERSION; +#endif +#ifdef OPENSSL_NO_TLS1_1 + if (min_version == TLS1_1_VERSION) + min_version = TLS1_2_VERSION; +#endif +#ifdef OPENSSL_NO_TLS1_2 + if (min_version == TLS1_2_VERSION) + min_version = TLS1_3_VERSION; +#endif + /* Done massaging versions; do the check. */ + if (0 +#ifdef OPENSSL_NO_SSL3 + || (min_version <= SSL3_VERSION && SSL3_VERSION <= max_version) +#endif +#ifdef OPENSSL_NO_TLS1 + || (min_version <= TLS1_VERSION && TLS1_VERSION <= max_version) +#endif +#ifdef OPENSSL_NO_TLS1_1 + || (min_version <= TLS1_1_VERSION && TLS1_1_VERSION <= max_version) +#endif +#ifdef OPENSSL_NO_TLS1_2 + || (min_version <= TLS1_2_VERSION && TLS1_2_VERSION <= max_version) +#endif +#ifdef OPENSSL_NO_TLS1_3 + || (min_version <= TLS1_3_VERSION && TLS1_3_VERSION <= max_version) +#endif + ) + return 0; + } + return 1; +} + static void clear_ciphers(SSL *s) { /* clear the current cipher */ @@ -456,10 +566,9 @@ int SSL_clear(SSL *s) /* * Check to see if we were changed into a different method, if so, revert - * back if we are not doing session-id reuse. + * back. */ - if (!ossl_statem_get_in_handshake(s) && (s->session == NULL) - && (s->method != s->ctx->method)) { + if (s->method != s->ctx->method) { s->method->ssl_free(s); s->method = s->ctx->method; if (!s->method->ssl_new(s)) @@ -636,6 +745,8 @@ SSL *SSL_new(SSL_CTX *ctx) s->psk_client_callback = ctx->psk_client_callback; s->psk_server_callback = ctx->psk_server_callback; #endif + s->psk_find_session_cb = ctx->psk_find_session_cb; + s->psk_use_session_cb = ctx->psk_use_session_cb; s->job = NULL; @@ -2007,11 +2118,13 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) else return 0; case SSL_CTRL_SET_MIN_PROTO_VERSION: - return ssl_set_version_bound(s->ctx->method->version, (int)larg, - &s->min_proto_version); + return ssl_check_allowed_versions(larg, s->max_proto_version) + && ssl_set_version_bound(s->ctx->method->version, (int)larg, + &s->min_proto_version); case SSL_CTRL_SET_MAX_PROTO_VERSION: - return ssl_set_version_bound(s->ctx->method->version, (int)larg, - &s->max_proto_version); + return ssl_check_allowed_versions(s->min_proto_version, larg) + && ssl_set_version_bound(s->ctx->method->version, (int)larg, + &s->max_proto_version); default: return (s->method->ssl_ctrl(s, cmd, larg, parg)); } @@ -2141,11 +2254,13 @@ 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: - return ssl_set_version_bound(ctx->method->version, (int)larg, - &ctx->min_proto_version); + return ssl_check_allowed_versions(larg, ctx->max_proto_version) + && ssl_set_version_bound(ctx->method->version, (int)larg, + &ctx->min_proto_version); case SSL_CTRL_SET_MAX_PROTO_VERSION: - return ssl_set_version_bound(ctx->method->version, (int)larg, - &ctx->max_proto_version); + return ssl_check_allowed_versions(ctx->min_proto_version, larg) + && ssl_set_version_bound(ctx->method->version, (int)larg, + &ctx->max_proto_version); default: return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg)); } @@ -2554,15 +2669,15 @@ void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, const char *label, size_t llen, - const unsigned char *p, size_t plen, + const unsigned char *context, size_t contextlen, int use_context) { if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER) return -1; return s->method->ssl3_enc->export_keying_material(s, out, olen, label, - llen, p, plen, - use_context); + llen, context, + contextlen, use_context); } static unsigned long ssl_session_hash(const SSL_SESSION *a) @@ -3041,10 +3156,11 @@ void ssl_update_cache(SSL *s, int mode) return; i = s->session_ctx->session_cache_mode; - if ((i & mode) && (!s->hit) - && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) + if ((i & mode) != 0 + && (!s->hit || SSL_IS_TLS13(s)) + && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) != 0 || SSL_CTX_add_session(s->session_ctx, s->session)) - && (s->session_ctx->new_session_cb != NULL)) { + && s->session_ctx->new_session_cb != NULL) { SSL_SESSION_up_ref(s->session); if (!s->session_ctx->new_session_cb(s, s->session)) SSL_SESSION_free(s->session); @@ -3200,6 +3316,12 @@ int SSL_do_handshake(SSL *s) s->method->ssl_renegotiate_check(s, 0); + if (SSL_is_server(s)) { + /* clear SNI settings at server-side */ + OPENSSL_free(s->ext.hostname); + s->ext.hostname = NULL; + } + if (SSL_in_init(s) || SSL_in_before(s)) { if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { struct ssl_async_args args; @@ -3723,6 +3845,18 @@ size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, return outlen; } +int SSL_SESSION_set1_master_key(SSL_SESSION *sess, const unsigned char *in, + size_t len) +{ + if (len > sizeof(sess->master_key)) + return 0; + + memcpy(sess->master_key, in, len); + sess->master_key_length = len; + return 1; +} + + int SSL_set_ex_data(SSL *s, int idx, void *arg) { return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); @@ -3858,6 +3992,28 @@ void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, SSL_psk_server_cb_func cb) } #endif +void SSL_set_psk_find_session_callback(SSL *s, SSL_psk_find_session_cb_func cb) +{ + s->psk_find_session_cb = cb; +} + +void SSL_CTX_set_psk_find_session_callback(SSL_CTX *ctx, + SSL_psk_find_session_cb_func cb) +{ + ctx->psk_find_session_cb = cb; +} + +void SSL_set_psk_use_session_callback(SSL *s, SSL_psk_use_session_cb_func cb) +{ + s->psk_use_session_cb = cb; +} + +void SSL_CTX_set_psk_use_session_callback(SSL_CTX *ctx, + SSL_psk_use_session_cb_func cb) +{ + ctx->psk_use_session_cb = cb; +} + void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb) (int write_p, int version, int content_type, const void *buf, @@ -4629,6 +4785,22 @@ int SSL_early_get0_ext(SSL *s, unsigned int type, const unsigned char **out, return 0; } +int SSL_free_buffers(SSL *ssl) +{ + RECORD_LAYER *rl = &ssl->rlayer; + + if (RECORD_LAYER_read_pending(rl) || RECORD_LAYER_write_pending(rl)) + return 0; + + RECORD_LAYER_release(rl); + return 1; +} + +int SSL_alloc_buffers(SSL *ssl) +{ + return ssl3_setup_buffers(ssl); +} + void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb) { ctx->keylog_callback = cb;