X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=1dd355d0dadd4357480b490deb2b38496c5c0fb3;hp=f68031e57167d8dc295ac9b7dfdbbb611d5a923c;hb=ee94ec2ef88e0ec25dedf2829d8e48dff0aa1c50;hpb=d6bb50a5f9201aab638ddf9131a6754cca0ef842 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index f68031e571..1dd355d0da 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -14,13 +14,13 @@ #include #include #include +#include #include #include #include #include #include #include "internal/cryptlib.h" -#include "internal/rand.h" #include "internal/refcount.h" const char SSL_version_str[] = OPENSSL_VERSION_TEXT; @@ -591,6 +591,7 @@ int SSL_clear(SSL *s) s->psksession_id = NULL; s->psksession_id_len = 0; s->hello_retry_request = 0; + s->sent_tickets = 0; s->error = 0; s->hit = 0; @@ -614,6 +615,9 @@ int SSL_clear(SSL *s) s->key_update = SSL_KEY_UPDATE_NONE; + EVP_MD_CTX_free(s->pha_dgst); + s->pha_dgst = NULL; + /* Reset DANE verification result state */ s->dane.mdpth = -1; s->dane.pdpth = -1; @@ -650,7 +654,9 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) ctx->method = meth; - sk = ssl_create_cipher_list(ctx->method, &(ctx->cipher_list), + sk = ssl_create_cipher_list(ctx->method, + ctx->tls13_ciphersuites, + &(ctx->cipher_list), &(ctx->cipher_list_by_id), SSL_DEFAULT_CIPHER_LIST, ctx->cert); if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) { @@ -685,21 +691,6 @@ SSL *SSL_new(SSL_CTX *ctx) goto err; } - /* - * If not using the standard RAND (say for fuzzing), then don't use a - * chained DRBG. - */ - if (RAND_get_rand_method() == RAND_OpenSSL()) { - s->drbg = - RAND_DRBG_new(RAND_DRBG_NID, RAND_DRBG_FLAG_CTR_USE_DF, - RAND_DRBG_get0_public()); - if (s->drbg == NULL - || RAND_DRBG_instantiate(s->drbg, - (const unsigned char *) SSL_version_str, - sizeof(SSL_version_str) - 1) == 0) - goto err; - } - RECORD_LAYER_init(&s->rlayer, s); s->options = ctx->options; @@ -709,6 +700,12 @@ SSL *SSL_new(SSL_CTX *ctx) s->mode = ctx->mode; s->max_cert_list = ctx->max_cert_list; s->max_early_data = ctx->max_early_data; + s->num_tickets = ctx->num_tickets; + + /* Shallow copy of the ciphersuites stack */ + s->tls13_ciphersuites = sk_SSL_CIPHER_dup(ctx->tls13_ciphersuites); + if (s->tls13_ciphersuites == NULL) + goto err; /* * Earlier library versions used to copy the pointer to the CERT, not @@ -1132,7 +1129,6 @@ void SSL_free(SSL *s) if (s == NULL) return; - CRYPTO_DOWN_REF(&s->references, &i, s->lock); REF_PRINT_COUNT("SSL", s); if (i > 0) @@ -1154,6 +1150,7 @@ void SSL_free(SSL *s) /* add extra stuff */ sk_SSL_CIPHER_free(s->cipher_list); sk_SSL_CIPHER_free(s->cipher_list_by_id); + sk_SSL_CIPHER_free(s->tls13_ciphersuites); /* Make the next call work :-) */ if (s->session != NULL) { @@ -1186,6 +1183,8 @@ void SSL_free(SSL *s) OPENSSL_free(s->ext.alpn); OPENSSL_free(s->ext.tls13_cookie); OPENSSL_free(s->clienthello); + OPENSSL_free(s->pha_context); + EVP_MD_CTX_free(s->pha_dgst); sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free); @@ -1208,7 +1207,6 @@ void SSL_free(SSL *s) sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); #endif - RAND_DRBG_free(s->drbg); CRYPTO_THREAD_lock_free(s->lock); OPENSSL_free(s); @@ -2027,6 +2025,9 @@ int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written) /* We are a server writing to an unauthenticated client */ s->early_data_state = SSL_EARLY_DATA_UNAUTH_WRITING; ret = SSL_write_ex(s, buf, num, written); + /* The buffering BIO is still in place */ + if (ret) + (void)BIO_flush(s->wbio); s->early_data_state = early_data_state; return ret; @@ -2449,10 +2450,12 @@ STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s) { STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers; int i; + ciphers = SSL_get_ciphers(s); if (!ciphers) return NULL; - ssl_set_client_disabled(s); + if (!ssl_set_client_disabled(s)) + return NULL; for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i); if (!ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) { @@ -2514,8 +2517,9 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) { STACK_OF(SSL_CIPHER) *sk; - sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list, - &ctx->cipher_list_by_id, str, ctx->cert); + sk = ssl_create_cipher_list(ctx->method, ctx->tls13_ciphersuites, + &ctx->cipher_list, &ctx->cipher_list_by_id, str, + ctx->cert); /* * ssl_create_cipher_list may return an empty stack if it was unable to * find a cipher matching the given rule string (for example if the rule @@ -2537,8 +2541,9 @@ int SSL_set_cipher_list(SSL *s, const char *str) { STACK_OF(SSL_CIPHER) *sk; - sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list, - &s->cipher_list_by_id, str, s->cert); + sk = ssl_create_cipher_list(s->ctx->method, s->tls13_ciphersuites, + &s->cipher_list, &s->cipher_list_by_id, str, + s->cert); /* see comment in SSL_CTX_set_cipher_list */ if (sk == NULL) return 0; @@ -2549,28 +2554,37 @@ int SSL_set_cipher_list(SSL *s, const char *str) return 1; } -char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len) +char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size) { char *p; - STACK_OF(SSL_CIPHER) *sk; + STACK_OF(SSL_CIPHER) *clntsk, *srvrsk; const SSL_CIPHER *c; int i; - if ((s->session == NULL) || (s->session->ciphers == NULL) || (len < 2)) + if (!s->server + || s->session == NULL + || s->session->ciphers == NULL + || size < 2) return NULL; p = buf; - sk = s->session->ciphers; + clntsk = s->session->ciphers; + srvrsk = SSL_get_ciphers(s); + if (clntsk == NULL || srvrsk == NULL) + return NULL; - if (sk_SSL_CIPHER_num(sk) == 0) + if (sk_SSL_CIPHER_num(clntsk) == 0 || sk_SSL_CIPHER_num(srvrsk) == 0) return NULL; - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + for (i = 0; i < sk_SSL_CIPHER_num(clntsk); i++) { int n; - c = sk_SSL_CIPHER_value(sk, i); + c = sk_SSL_CIPHER_value(clntsk, i); + if (sk_SSL_CIPHER_find(srvrsk, c) < 0) + continue; + n = strlen(c->name); - if (n + 1 > len) { + if (n + 1 > size) { if (p != buf) --p; *p = '\0'; @@ -2579,7 +2593,7 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len) strcpy(p, c->name); p += n; *(p++) = ':'; - len -= n + 1; + size -= n + 1; } p[-1] = '\0'; return buf; @@ -2804,6 +2818,18 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, contextlen, use_context); } +int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, + size_t contextlen) +{ + if (s->version != TLS1_3_VERSION) + return 0; + + return tls13_export_keying_material_early(s, out, olen, label, llen, + context, contextlen); +} + static unsigned long ssl_session_hash(const SSL_SESSION *a) { const unsigned char *session_id = a->session_id; @@ -2897,7 +2923,12 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) if (ret->ctlog_store == NULL) goto err; #endif + + if (!SSL_CTX_set_ciphersuites(ret, TLS_DEFAULT_CIPHERSUITES)) + goto err; + if (!ssl_create_cipher_list(ret->method, + ret->tls13_ciphersuites, &ret->cipher_list, &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST, ret->cert) || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { @@ -2924,6 +2955,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data)) goto err; + if ((ret->ext.secure = OPENSSL_secure_zalloc(sizeof(*ret->ext.secure))) == NULL) + goto err; + /* No compression for DTLS */ if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)) ret->comp_methods = SSL_COMP_get_compression_methods(); @@ -2934,13 +2968,13 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) /* Setup RFC5077 ticket keys */ if ((RAND_bytes(ret->ext.tick_key_name, sizeof(ret->ext.tick_key_name)) <= 0) - || (RAND_bytes(ret->ext.tick_hmac_key, - sizeof(ret->ext.tick_hmac_key)) <= 0) - || (RAND_bytes(ret->ext.tick_aes_key, - sizeof(ret->ext.tick_aes_key)) <= 0)) + || (RAND_priv_bytes(ret->ext.secure->tick_hmac_key, + sizeof(ret->ext.secure->tick_hmac_key)) <= 0) + || (RAND_priv_bytes(ret->ext.secure->tick_aes_key, + sizeof(ret->ext.secure->tick_aes_key)) <= 0)) ret->options |= SSL_OP_NO_TICKET; - if (RAND_bytes(ret->ext.cookie_hmac_key, + if (RAND_priv_bytes(ret->ext.cookie_hmac_key, sizeof(ret->ext.cookie_hmac_key)) <= 0) goto err; @@ -2984,10 +3018,27 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->ext.status_type = TLSEXT_STATUSTYPE_nothing; /* - * Default max early data is a fully loaded single record. Could be split - * across multiple records in practice + * We cannot usefully set a default max_early_data here (which gets + * propagated in SSL_new(), for the following reason: setting the + * SSL field causes tls_construct_stoc_early_data() to tell the + * client that early data will be accepted when constructing a TLS 1.3 + * session ticket, and the client will accordingly send us early data + * when using that ticket (if the client has early data to send). + * However, in order for the early data to actually be consumed by + * the application, the application must also have calls to + * SSL_read_early_data(); otherwise we'll just skip past the early data + * and ignore it. So, since the application must add calls to + * SSL_read_early_data(), we also require them to add + * calls to SSL_CTX_set_max_early_data() in order to use early data, + * eliminating the bandwidth-wasting early data in the case described + * above. */ - ret->max_early_data = SSL3_RT_MAX_PLAIN_LENGTH; + ret->max_early_data = 0; + + /* By default we send two session tickets automatically in TLSv1.3 */ + ret->num_tickets = 2; + + ssl_ctx_system_config(ret); return ret; err: @@ -3045,6 +3096,7 @@ void SSL_CTX_free(SSL_CTX *a) #endif sk_SSL_CIPHER_free(a->cipher_list); sk_SSL_CIPHER_free(a->cipher_list_by_id); + sk_SSL_CIPHER_free(a->tls13_ciphersuites); ssl_cert_free(a->cert); sk_X509_NAME_pop_free(a->ca_names, X509_NAME_free); sk_X509_pop_free(a->extra_certs, X509_free); @@ -3064,6 +3116,7 @@ void SSL_CTX_free(SSL_CTX *a) OPENSSL_free(a->ext.supportedgroups); #endif OPENSSL_free(a->ext.alpn); + OPENSSL_secure_free(a->ext.secure); CRYPTO_THREAD_lock_free(a->lock); @@ -3228,6 +3281,12 @@ void ssl_set_masks(SSL *s) && pvalid[SSL_PKEY_ED25519] & CERT_PKEY_EXPLICIT_SIGN && TLS1_get_version(s) == TLS1_2_VERSION) mask_a |= SSL_aECDSA; + + /* Allow Ed448 for TLS 1.2 if peer supports it */ + if (!(mask_a & SSL_aECDSA) && ssl_has_cert(s, SSL_PKEY_ED448) + && pvalid[SSL_PKEY_ED448] & CERT_PKEY_EXPLICIT_SIGN + && TLS1_get_version(s) == TLS1_2_VERSION) + mask_a |= SSL_aECDSA; #endif #ifndef OPENSSL_NO_EC @@ -3291,15 +3350,48 @@ void ssl_update_cache(SSL *s, int mode) if (s->session->session_id_length == 0) return; + /* + * If sid_ctx_length is 0 there is no specific application context + * associated with this session, so when we try to resume it and + * SSL_VERIFY_PEER is requested to verify the client identity, we have no + * indication that this is actually a session for the proper application + * context, and the *handshake* will fail, not just the resumption attempt. + * Do not cache (on the server) these sessions that are not resumable + * (clients can set SSL_VERIFY_PEER without needing a sid_ctx set). + */ + if (s->server && s->session->sid_ctx_length == 0 + && (s->verify_mode & SSL_VERIFY_PEER) != 0) + return; + i = s->session_ctx->session_cache_mode; 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) { - SSL_SESSION_up_ref(s->session); - if (!s->session_ctx->new_session_cb(s, s->session)) - SSL_SESSION_free(s->session); + && (!s->hit || SSL_IS_TLS13(s))) { + /* + * Add the session to the internal cache. In server side TLSv1.3 we + * normally don't do this because its a full stateless ticket with only + * a dummy session id so there is no reason to cache it, unless: + * - we are doing early_data, in which case we cache so that we can + * detect replays + * - the application has set a remove_session_cb so needs to know about + * session timeout events + */ + if ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0 + && (!SSL_IS_TLS13(s) + || !s->server + || s->max_early_data > 0 + || s->session_ctx->remove_session_cb != NULL)) + SSL_CTX_add_session(s->session_ctx, s->session); + + /* + * Add the session to the external cache. We do this even in server side + * TLSv1.3 without early data because some applications just want to + * know about the creation of a session and aren't doing a full cache. + */ + if (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); + } } /* auto flush every 255 connections */ @@ -3790,8 +3882,6 @@ int ssl_free_wbio_buffer(SSL *s) return 1; s->wbio = BIO_pop(s->wbio); - if (!ossl_assert(s->wbio != NULL)) - return 0; BIO_free(s->bbio); s->bbio = NULL; @@ -4249,6 +4339,30 @@ int SSL_set_block_padding(SSL *ssl, size_t block_size) return 1; } +int SSL_set_num_tickets(SSL *s, size_t num_tickets) +{ + s->num_tickets = num_tickets; + + return 1; +} + +size_t SSL_get_num_tickets(SSL *s) +{ + return s->num_tickets; +} + +int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets) +{ + ctx->num_tickets = num_tickets; + + return 1; +} + +size_t SSL_CTX_get_num_tickets(SSL_CTX *ctx) +{ + return ctx->num_tickets; +} + /* * Allocates new EVP_MD_CTX and sets pointer to it into given pointer * variable, freeing EVP_MD_CTX previously stored in that variable, if any. @@ -4901,9 +5015,11 @@ int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen) if (ext->present) num++; } - present = OPENSSL_malloc(sizeof(*present) * num); - if (present == NULL) + if ((present = OPENSSL_malloc(sizeof(*present) * num)) == NULL) { + SSLerr(SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT, + ERR_R_MALLOC_FAILURE); return 0; + } for (i = 0; i < s->clienthello->pre_proc_exts_len; i++) { ext = s->clienthello->pre_proc_exts + i; if (ext->present) { @@ -5252,26 +5368,6 @@ uint32_t SSL_get_max_early_data(const SSL *s) return s->max_early_data; } -int ssl_randbytes(SSL *s, unsigned char *rnd, size_t size) -{ - if (s->drbg != NULL) { - /* - * Currently, it's the duty of the caller to serialize the generate - * requests to the DRBG. So formally we have to check whether - * s->drbg->lock != NULL and take the lock if this is the case. - * However, this DRBG is unique to a given SSL object, and we already - * require that SSL objects are only accessed by a single thread at - * a given time. Also, SSL DRBGs have no child DRBG, so there is - * no risk that this DRBG is accessed by a child DRBG in parallel - * for reseeding. As such, we can rely on the application's - * serialization of SSL accesses for the needed concurrency protection - * here. - */ - return RAND_DRBG_generate(s->drbg, rnd, size, 0, NULL, 0); - } - return RAND_bytes(rnd, (int)size); -} - __owur unsigned int ssl_get_max_send_fragment(const SSL *ssl) { /* Return any active Max Fragment Len extension */ @@ -5314,5 +5410,71 @@ int SSL_stateless(SSL *s) if (ret > 0 && s->ext.cookieok) return 1; - return 0; + if (s->hello_retry_request == SSL_HRR_PENDING && !ossl_statem_in_error(s)) + return 0; + + return -1; +} + +void SSL_force_post_handshake_auth(SSL *ssl) +{ + ssl->pha_forced = 1; +} + +int SSL_verify_client_post_handshake(SSL *ssl) +{ + if (!SSL_IS_TLS13(ssl)) { + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_WRONG_SSL_VERSION); + return 0; + } + if (!ssl->server) { + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_NOT_SERVER); + return 0; + } + + if (!SSL_is_init_finished(ssl)) { + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_STILL_IN_INIT); + return 0; + } + + switch (ssl->post_handshake_auth) { + case SSL_PHA_NONE: + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_EXTENSION_NOT_RECEIVED); + return 0; + default: + case SSL_PHA_EXT_SENT: + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, ERR_R_INTERNAL_ERROR); + return 0; + case SSL_PHA_EXT_RECEIVED: + break; + case SSL_PHA_REQUEST_PENDING: + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_REQUEST_PENDING); + return 0; + case SSL_PHA_REQUESTED: + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_REQUEST_SENT); + return 0; + } + + ssl->post_handshake_auth = SSL_PHA_REQUEST_PENDING; + + /* checks verify_mode and algorithm_auth */ + if (!send_certificate_request(ssl)) { + ssl->post_handshake_auth = SSL_PHA_EXT_RECEIVED; /* restore on error */ + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_INVALID_CONFIG); + return 0; + } + + ossl_statem_set_in_init(ssl, 1); + return 1; +} + +int SSL_CTX_set_session_ticket_cb(SSL_CTX *ctx, + SSL_CTX_generate_session_ticket_fn gen_cb, + SSL_CTX_decrypt_session_ticket_fn dec_cb, + void *arg) +{ + ctx->generate_ticket_cb = gen_cb; + ctx->decrypt_ticket_cb = dec_cb; + ctx->ticket_cb_data = arg; + return 1; }