diff options
Diffstat (limited to 'crypto/openssl/ssl')
-rw-r--r-- | crypto/openssl/ssl/d1_lib.c | 2 | ||||
-rw-r--r-- | crypto/openssl/ssl/quic/quic_ackm.c | 33 | ||||
-rw-r--r-- | crypto/openssl/ssl/quic/quic_channel.c | 18 | ||||
-rw-r--r-- | crypto/openssl/ssl/quic/quic_impl.c | 8 | ||||
-rw-r--r-- | crypto/openssl/ssl/quic/quic_port.c | 3 | ||||
-rw-r--r-- | crypto/openssl/ssl/quic/quic_record_rx.c | 10 | ||||
-rw-r--r-- | crypto/openssl/ssl/quic/quic_record_tx.c | 4 | ||||
-rw-r--r-- | crypto/openssl/ssl/quic/quic_rx_depack.c | 28 | ||||
-rw-r--r-- | crypto/openssl/ssl/record/methods/tls_common.c | 11 | ||||
-rw-r--r-- | crypto/openssl/ssl/ssl_rsa.c | 5 | ||||
-rw-r--r-- | crypto/openssl/ssl/statem/extensions_clnt.c | 10 | ||||
-rw-r--r-- | crypto/openssl/ssl/t1_trce.c | 4 |
12 files changed, 90 insertions, 46 deletions
diff --git a/crypto/openssl/ssl/d1_lib.c b/crypto/openssl/ssl/d1_lib.c index 9e1fbb0b2945..a5a52a7ee80e 100644 --- a/crypto/openssl/ssl/d1_lib.c +++ b/crypto/openssl/ssl/d1_lib.c @@ -863,7 +863,7 @@ int dtls1_shutdown(SSL *s) BIO *wbio; SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); - if (s == NULL) + if (sc == NULL) return -1; wbio = SSL_get_wbio(s); diff --git a/crypto/openssl/ssl/quic/quic_ackm.c b/crypto/openssl/ssl/quic/quic_ackm.c index 75a1e5741a03..93c83a36d8fe 100644 --- a/crypto/openssl/ssl/quic/quic_ackm.c +++ b/crypto/openssl/ssl/quic/quic_ackm.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -536,6 +536,9 @@ struct ossl_ackm_st { /* Set to 1 when the handshake is confirmed. */ char handshake_confirmed; + /* Set to 1 when attached to server channel */ + char is_server; + /* Set to 1 when the peer has completed address validation. */ char peer_completed_addr_validation; @@ -855,7 +858,13 @@ static OSSL_TIME ackm_get_pto_time_and_space(OSSL_ACKM *ackm, int *space) } for (i = QUIC_PN_SPACE_INITIAL; i < QUIC_PN_SPACE_NUM; ++i) { - if (ackm->ack_eliciting_bytes_in_flight[i] == 0) + /* + * RFC 9002 section 6.2.2.1 keep probe timeout armed until + * handshake is confirmed (client sees HANDSHAKE_DONE message + * from server). + */ + if (ackm->ack_eliciting_bytes_in_flight[i] == 0 && + (ackm->handshake_confirmed == 1 || ackm->is_server == 1)) continue; if (i == QUIC_PN_SPACE_APP) { @@ -875,10 +884,18 @@ static OSSL_TIME ackm_get_pto_time_and_space(OSSL_ACKM *ackm, int *space) } } - t = ossl_time_add(ackm->time_of_last_ack_eliciting_pkt[i], duration); - if (ossl_time_compare(t, pto_timeout) < 0) { - pto_timeout = t; - pto_space = i; + /* + * Only re-arm timer if stack has sent at least one ACK eliciting frame. + * If stack has sent no ACK eliciting frame at given encryption level then + * particular timer is zero and we must not attempt to set it. Timer keeps + * time since epoch (Jan 1 1970) and we must not set timer to past. + */ + if (!ossl_time_is_zero(ackm->time_of_last_ack_eliciting_pkt[i])) { + t = ossl_time_add(ackm->time_of_last_ack_eliciting_pkt[i], duration); + if (ossl_time_compare(t, pto_timeout) < 0) { + pto_timeout = t; + pto_space = i; + } } } @@ -1021,7 +1038,8 @@ OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg), void *now_arg, OSSL_STATM *statm, const OSSL_CC_METHOD *cc_method, - OSSL_CC_DATA *cc_data) + OSSL_CC_DATA *cc_data, + int is_server) { OSSL_ACKM *ackm; int i; @@ -1045,6 +1063,7 @@ OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg), ackm->statm = statm; ackm->cc_method = cc_method; ackm->cc_data = cc_data; + ackm->is_server = (char)is_server; ackm->rx_max_ack_delay = ossl_ms2time(QUIC_DEFAULT_MAX_ACK_DELAY); ackm->tx_max_ack_delay = DEFAULT_TX_MAX_ACK_DELAY; diff --git a/crypto/openssl/ssl/quic/quic_channel.c b/crypto/openssl/ssl/quic/quic_channel.c index 8fb651d9ceb6..652c653b9120 100644 --- a/crypto/openssl/ssl/quic/quic_channel.c +++ b/crypto/openssl/ssl/quic/quic_channel.c @@ -242,7 +242,8 @@ static int ch_init(QUIC_CHANNEL *ch) goto err; if ((ch->ackm = ossl_ackm_new(get_time, ch, &ch->statm, - ch->cc_method, ch->cc_data)) == NULL) + ch->cc_method, ch->cc_data, + ch->is_server)) == NULL) goto err; if (!ossl_quic_stream_map_init(&ch->qsm, get_stream_limit, ch, @@ -1330,8 +1331,20 @@ static int ch_on_transport_params(const unsigned char *params, ossl_unused uint64_t rx_max_idle_timeout = 0; ossl_unused const void *stateless_reset_token_p = NULL; QUIC_PREFERRED_ADDR pfa; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ch->tls); - if (ch->got_remote_transport_params) { + /* + * When HRR happens the client sends the transport params in the new client + * hello again. Reset the transport params here and load them again. + */ + if (ch->is_server && sc->hello_retry_request != SSL_HRR_NONE + && ch->got_remote_transport_params) { + ch->max_local_streams_bidi = 0; + ch->max_local_streams_uni = 0; + ch->got_local_transport_params = 0; + OPENSSL_free(ch->local_transport_params); + ch->local_transport_params = NULL; + } else if (ch->got_remote_transport_params) { reason = "multiple transport parameter extensions"; goto malformed; } @@ -2422,7 +2435,6 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only) if (!PACKET_get_net_4(&vpkt, &supported_ver)) return; - supported_ver = ntohl(supported_ver); if (supported_ver == QUIC_VERSION_1) { /* * If the server supports version 1, set it as diff --git a/crypto/openssl/ssl/quic/quic_impl.c b/crypto/openssl/ssl/quic/quic_impl.c index 5ad5a79157f4..cec05d5bd37b 100644 --- a/crypto/openssl/ssl/quic/quic_impl.c +++ b/crypto/openssl/ssl/quic/quic_impl.c @@ -3197,6 +3197,7 @@ int ossl_quic_conn_stream_conclude(SSL *s) QCTX ctx; QUIC_STREAM *qs; int err; + int ret; if (!expect_quic_with_stream_lock(s, /*remote_init=*/0, /*io=*/0, &ctx)) return 0; @@ -3204,13 +3205,15 @@ int ossl_quic_conn_stream_conclude(SSL *s) qs = ctx.xso->stream; if (!quic_mutation_allowed(ctx.qc, /*req_active=*/1)) { + ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); qctx_unlock(&ctx); - return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + return ret; } if (!quic_validate_for_write(ctx.xso, &err)) { + ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL); qctx_unlock(&ctx); - return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL); + return ret; } if (ossl_quic_sstream_get_final_size(qs->sstream, NULL)) { @@ -4769,6 +4772,7 @@ void ossl_quic_free_token_store(SSL_TOKEN_STORE *hdl) ossl_crypto_mutex_free(&hdl->mutex); lh_QUIC_TOKEN_doall(hdl->cache, free_this_token); lh_QUIC_TOKEN_free(hdl->cache); + CRYPTO_FREE_REF(&hdl->references); OPENSSL_free(hdl); return; } diff --git a/crypto/openssl/ssl/quic/quic_port.c b/crypto/openssl/ssl/quic/quic_port.c index 684c088c08c0..d6e6d4d25cb5 100644 --- a/crypto/openssl/ssl/quic/quic_port.c +++ b/crypto/openssl/ssl/quic/quic_port.c @@ -1267,7 +1267,7 @@ static void port_send_version_negotiation(QUIC_PORT *port, BIO_ADDR *peer, * Add the array of supported versions to the end of the packet */ for (i = 0; i < OSSL_NELEM(supported_versions); i++) { - if (!WPACKET_put_bytes_u32(&wpkt, htonl(supported_versions[i]))) + if (!WPACKET_put_bytes_u32(&wpkt, supported_versions[i])) return; } @@ -1691,6 +1691,7 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg, */ while (ossl_qrx_read_pkt(qrx_src, &qrx_pkt) == 1) ossl_quic_channel_inject_pkt(new_ch, qrx_pkt); + ossl_qrx_update_pn_space(qrx_src, new_ch->qrx); } /* diff --git a/crypto/openssl/ssl/quic/quic_record_rx.c b/crypto/openssl/ssl/quic/quic_record_rx.c index e01cc5253457..1a8194b396d7 100644 --- a/crypto/openssl/ssl/quic/quic_record_rx.c +++ b/crypto/openssl/ssl/quic/quic_record_rx.c @@ -237,6 +237,16 @@ static void qrx_cleanup_urxl(OSSL_QRX *qrx, QUIC_URXE_LIST *l) } } +void ossl_qrx_update_pn_space(OSSL_QRX *src, OSSL_QRX *dst) +{ + size_t i; + + for (i = 0; i < QUIC_PN_SPACE_NUM; i++) + dst->largest_pn[i] = src->largest_pn[i]; + + return; +} + void ossl_qrx_free(OSSL_QRX *qrx) { uint32_t i; diff --git a/crypto/openssl/ssl/quic/quic_record_tx.c b/crypto/openssl/ssl/quic/quic_record_tx.c index ef93a14f94a8..ae37353a9b26 100644 --- a/crypto/openssl/ssl/quic/quic_record_tx.c +++ b/crypto/openssl/ssl/quic/quic_record_tx.c @@ -279,12 +279,12 @@ static TXE *qtx_resize_txe(OSSL_QTX *qtx, TXE_LIST *txl, TXE *txe, size_t n) * data. */ txe2 = OPENSSL_realloc(txe, sizeof(TXE) + n); - if (txe2 == NULL || txe == txe2) { + if (txe2 == NULL) { if (p == NULL) ossl_list_txe_insert_head(txl, txe); else ossl_list_txe_insert_after(txl, p, txe); - return txe2; + return NULL; } if (p == NULL) diff --git a/crypto/openssl/ssl/quic/quic_rx_depack.c b/crypto/openssl/ssl/quic/quic_rx_depack.c index a36b02d5dcb4..f800d8984193 100644 --- a/crypto/openssl/ssl/quic/quic_rx_depack.c +++ b/crypto/openssl/ssl/quic/quic_rx_depack.c @@ -1429,16 +1429,8 @@ int ossl_quic_handle_frames(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpacket) uint32_t enc_level; size_t dgram_len = qpacket->datagram_len; - /* - * ok has three states: - * -1 error with ackm_data uninitialized - * 0 error with ackm_data initialized - * 1 success (ackm_data initialized) - */ - int ok = -1; /* Assume the worst */ - if (ch == NULL) - goto end; + return 0; ch->did_crypto_frame = 0; @@ -1456,9 +1448,8 @@ int ossl_quic_handle_frames(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpacket) * Retry and Version Negotiation packets should not be passed to this * function. */ - goto end; + return 0; - ok = 0; /* Still assume the worst */ ackm_data.pkt_space = ossl_quic_enc_level_to_pn_space(enc_level); /* @@ -1480,18 +1471,9 @@ int ossl_quic_handle_frames(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpacket) enc_level, qpacket->time, &ackm_data)) - goto end; + return 0; - ok = 1; - end: - /* - * ASSUMPTION: If this function is called at all, |qpacket| is - * a legitimate packet, even if its contents aren't. - * Therefore, we call ossl_ackm_on_rx_packet() unconditionally, as long as - * |ackm_data| has at least been initialized. - */ - if (ok >= 0) - ossl_ackm_on_rx_packet(ch->ackm, &ackm_data); + ossl_ackm_on_rx_packet(ch->ackm, &ackm_data); - return ok > 0; + return 1; } diff --git a/crypto/openssl/ssl/record/methods/tls_common.c b/crypto/openssl/ssl/record/methods/tls_common.c index 80d4477bd0c0..b9c79099462d 100644 --- a/crypto/openssl/ssl/record/methods/tls_common.c +++ b/crypto/openssl/ssl/record/methods/tls_common.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1093,9 +1093,12 @@ int tls13_common_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) return 0; } - if (rl->msg_callback != NULL) - rl->msg_callback(0, rl->version, SSL3_RT_INNER_CONTENT_TYPE, &rec->type, - 1, rl->cbarg); + if (rl->msg_callback != NULL) { + unsigned char ctype = (unsigned char)rec->type; + + rl->msg_callback(0, rl->version, SSL3_RT_INNER_CONTENT_TYPE, &ctype, + 1, rl->cbarg); + } /* * TLSv1.3 alert and handshake records are required to be non-zero in diff --git a/crypto/openssl/ssl/ssl_rsa.c b/crypto/openssl/ssl/ssl_rsa.c index e833bcdbc377..f4731a87af90 100644 --- a/crypto/openssl/ssl/ssl_rsa.c +++ b/crypto/openssl/ssl/ssl_rsa.c @@ -1056,10 +1056,13 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr } } - if (!X509_up_ref(x509)) + if (!X509_up_ref(x509)) { + OSSL_STACK_OF_X509_free(dup_chain); goto out; + } if (!EVP_PKEY_up_ref(privatekey)) { + OSSL_STACK_OF_X509_free(dup_chain); X509_free(x509); goto out; } diff --git a/crypto/openssl/ssl/statem/extensions_clnt.c b/crypto/openssl/ssl/statem/extensions_clnt.c index baa7c47b3cd9..d958373875a3 100644 --- a/crypto/openssl/ssl/statem/extensions_clnt.c +++ b/crypto/openssl/ssl/statem/extensions_clnt.c @@ -745,6 +745,7 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt, /* SSLfatal() already called */ return EXT_RETURN_FAIL; } + valid_keyshare++; } else { if (s->ext.supportedgroups == NULL) /* use default */ add_only_one = 1; @@ -766,13 +767,18 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt, /* SSLfatal() already called */ return EXT_RETURN_FAIL; } + valid_keyshare++; if (add_only_one) break; - - valid_keyshare++; } } + if (valid_keyshare == 0) { + /* No key shares were allowed */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_KEY_SHARE); + return EXT_RETURN_FAIL; + } + if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; diff --git a/crypto/openssl/ssl/t1_trce.c b/crypto/openssl/ssl/t1_trce.c index 35c60feb4371..73fd4ebaa4b0 100644 --- a/crypto/openssl/ssl/t1_trce.c +++ b/crypto/openssl/ssl/t1_trce.c @@ -549,8 +549,12 @@ static const ssl_trace_tbl ssl_groups_tbl[] = { {258, "ffdhe4096"}, {259, "ffdhe6144"}, {260, "ffdhe8192"}, + {512, "MLKEM512"}, + {513, "MLKEM768"}, + {514, "MLKEM1024"}, {4587, "SecP256r1MLKEM768"}, {4588, "X25519MLKEM768"}, + {4589, "SecP384r1MLKEM1024"}, {25497, "X25519Kyber768Draft00"}, {25498, "SecP256r1Kyber768Draft00"}, {0xFF01, "arbitrary_explicit_prime_curves"}, |