import CS gnutls-3.8.3-9.el9

This commit is contained in:
eabdullin 2025-09-15 12:01:55 +00:00
parent 002415d47a
commit 522f359629
6 changed files with 2756 additions and 1 deletions

View File

@ -0,0 +1,40 @@
From f1fe8d2a7669c4cdcdaaabd8969d358040c142ad Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Mon, 7 Jul 2025 10:44:12 +0900
Subject: [PATCH] x509: avoid double free when exporting othernames in SAN
Previously, the _gnutls_write_new_othername function, called by
gnutls_x509_ext_export_subject_alt_names to export "otherName" in a
certificate's SAN extension, freed the caller allocated ASN.1
structure upon error, resulting in a potential double-free.
Reported by OpenAI Security Research Team.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/x509/extensions.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/lib/x509/extensions.c b/lib/x509/extensions.c
index 6c2da8fd10..e8be12eaf5 100644
--- a/lib/x509/extensions.c
+++ b/lib/x509/extensions.c
@@ -754,7 +754,6 @@ int _gnutls_write_new_othername(asn1_node ext, const char *ext_name,
result = asn1_write_value(ext, name2, oid, 1);
if (result != ASN1_SUCCESS) {
gnutls_assert();
- asn1_delete_structure(&ext);
return _gnutls_asn2err(result);
}
@@ -763,7 +762,6 @@ int _gnutls_write_new_othername(asn1_node ext, const char *ext_name,
result = asn1_write_value(ext, name2, data, data_size);
if (result != ASN1_SUCCESS) {
gnutls_assert();
- asn1_delete_structure(&ext);
return _gnutls_asn2err(result);
}
--
2.50.0

View File

@ -0,0 +1,32 @@
From 639a551c6d4707c7fb880412d695dbdd31f60cf3 Mon Sep 17 00:00:00 2001
From: Andrew Hamilton <adhamilt@gmail.com>
Date: Mon, 7 Jul 2025 10:23:59 +0900
Subject: [PATCH] x509: fix read buffer overrun in SCT timestamps
Prevent reading beyond heap buffer in call to _gnutls_parse_ct_sct
when processing x509 Signed Certificate Timestamps with certain
malformed data. Spotted by oss-fuzz at:
https://issues.oss-fuzz.com/issues/42530513
Signed-off-by: Andrew Hamilton <adhamilt@gmail.com>
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/x509/x509_ext.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/x509/x509_ext.c b/lib/x509/x509_ext.c
index ad3af1430a..9a36f3536b 100644
--- a/lib/x509/x509_ext.c
+++ b/lib/x509/x509_ext.c
@@ -3759,7 +3759,7 @@ int gnutls_x509_ext_ct_import_scts(const gnutls_datum_t *ext,
}
length = _gnutls_read_uint16(scts_content.data);
- if (length < 4) {
+ if (length < 4 || length > scts_content.size) {
gnutls_free(scts_content.data);
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
}
--
2.50.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,282 @@
From 853a64f5e92bedd2ebf97baadba39f2d2bfa95ef Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Mon, 7 Jul 2025 11:15:45 +0900
Subject: [PATCH] handshake: clear HSK_PSK_SELECTED is when resetting binders
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When a TLS 1.3 handshake involves HRR and resumption or PSK, and the
second Client Hello omits PSK, the server would result in a NULL
pointer dereference as the PSK binder information is cleared while the
HSK_PSK_SELECTED flag is still set. This makes sure that
HSK_PSK_SELECTED flag is always cleared when the PSK binders are
reset. This also makes it clear the HSK_PSK_SELECTED flag is valid
only during a handshake; after that, whether PSK is used can be
checked with gnutls_auth_client_get_type.
Reported by Stefan Bühler.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
.gitignore | 1 +
lib/handshake.c | 25 +++-
lib/state.c | 4 +-
tests/Makefile.am | 2 +
tests/tls13/hello_retry_request_psk.c | 173 ++++++++++++++++++++++++++
5 files changed, 201 insertions(+), 4 deletions(-)
create mode 100644 tests/tls13/hello_retry_request_psk.c
diff --git a/lib/handshake.c b/lib/handshake.c
index 722307be7c..489d021945 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -589,9 +589,28 @@ static int set_auth_types(gnutls_session_t session)
/* Under TLS1.3 this returns a KX which matches the negotiated
* groups from the key shares; if we are resuming then the KX seen
* here doesn't match the original session. */
- if (!session->internals.resumed)
- kx = gnutls_kx_get(session);
- else
+ if (!session->internals.resumed) {
+ const gnutls_group_entry_st *group = get_group(session);
+
+ if (session->internals.hsk_flags & HSK_PSK_SELECTED) {
+ if (group) {
+ kx = group->pk == GNUTLS_PK_DH ?
+ GNUTLS_KX_DHE_PSK :
+ GNUTLS_KX_ECDHE_PSK;
+ } else {
+ kx = GNUTLS_KX_PSK;
+ }
+ } else if (group) {
+ /* Not necessarily be RSA, but just to
+ * make _gnutls_map_kx_get_cred below
+ * work.
+ */
+ kx = group->pk == GNUTLS_PK_DH ?
+ GNUTLS_KX_DHE_RSA :
+ GNUTLS_KX_ECDHE_RSA;
+ } else
+ kx = GNUTLS_KX_UNKNOWN;
+ } else
kx = GNUTLS_KX_UNKNOWN;
} else {
/* TLS1.2 or earlier, kx is associated with ciphersuite */
diff --git a/lib/state.c b/lib/state.c
index ec514c0cd2..10ec0eadb6 100644
--- a/lib/state.c
+++ b/lib/state.c
@@ -202,7 +202,8 @@ gnutls_kx_algorithm_t gnutls_kx_get(gnutls_session_t session)
const gnutls_group_entry_st *group = get_group(session);
if (ver->tls13_sem) {
- if (session->internals.hsk_flags & HSK_PSK_SELECTED) {
+ if (gnutls_auth_client_get_type(session) ==
+ GNUTLS_CRD_PSK) {
if (group) {
if (group->pk == GNUTLS_PK_DH)
return GNUTLS_KX_DHE_PSK;
@@ -349,6 +350,7 @@ void reset_binders(gnutls_session_t session)
_gnutls_free_temp_key_datum(&session->key.binders[0].psk);
_gnutls_free_temp_key_datum(&session->key.binders[1].psk);
memset(session->key.binders, 0, sizeof(session->key.binders));
+ session->internals.hsk_flags &= ~HSK_PSK_SELECTED;
}
/* Check whether certificate credentials of type @cert_type are set
diff --git a/tests/Makefile.am b/tests/Makefile.am
index babf3be108..f6a16552d1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -128,6 +128,8 @@ ctests += tls13/hello_retry_request
ctests += tls13/hello_retry_request_resume
+ctests += tls13/hello_retry_request_psk
+
ctests += tls13/psk-ext
ctests += tls13/key_update
diff --git a/tests/tls13/hello_retry_request_psk.c b/tests/tls13/hello_retry_request_psk.c
new file mode 100644
index 0000000000..a20cb0d965
--- /dev/null
+++ b/tests/tls13/hello_retry_request_psk.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2017-2025 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos, Daiki Ueno
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <string.h>
+#include <gnutls/gnutls.h>
+#include <assert.h>
+
+#include "cert-common.h"
+#include "utils.h"
+#include "tls13/ext-parse.h"
+#include "eagain-common.h"
+
+/* This program exercises the case where a TLS 1.3 handshake ends up
+ * with HRR, and the first CH includes PSK while the 2nd CH omits
+ * it */
+
+const char *testname = "hello entry request";
+
+const char *side = "";
+
+#define myfail(fmt, ...) fail("%s: " fmt, testname, ##__VA_ARGS__)
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "%s|<%d>| %s", side, level, str);
+}
+
+struct ctx_st {
+ unsigned hrr_seen;
+ unsigned hello_counter;
+};
+
+static int pskfunc(gnutls_session_t session, const char *username,
+ gnutls_datum_t *key)
+{
+ if (debug)
+ printf("psk: username %s\n", username);
+ key->data = gnutls_malloc(4);
+ key->data[0] = 0xDE;
+ key->data[1] = 0xAD;
+ key->data[2] = 0xBE;
+ key->data[3] = 0xEF;
+ key->size = 4;
+ return 0;
+}
+
+static int hello_callback(gnutls_session_t session, unsigned int htype,
+ unsigned post, unsigned int incoming,
+ const gnutls_datum_t *msg)
+{
+ struct ctx_st *ctx = gnutls_session_get_ptr(session);
+ assert(ctx != NULL);
+
+ if (htype == GNUTLS_HANDSHAKE_HELLO_RETRY_REQUEST)
+ ctx->hrr_seen = 1;
+
+ if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO) {
+ if (post == GNUTLS_HOOK_POST)
+ ctx->hello_counter++;
+ else {
+ /* Unset the PSK credential to omit the extension */
+ gnutls_credentials_set(session, GNUTLS_CRD_PSK, NULL);
+ }
+ }
+
+ return 0;
+}
+
+void doit(void)
+{
+ int sret, cret;
+ gnutls_psk_server_credentials_t scred;
+ gnutls_psk_client_credentials_t ccred;
+ gnutls_certificate_credentials_t ccred2;
+ gnutls_session_t server, client;
+ /* Need to enable anonymous KX specifically. */
+ const gnutls_datum_t key = { (void *)"DEADBEEF", 8 };
+
+ struct ctx_st ctx;
+ memset(&ctx, 0, sizeof(ctx));
+
+ global_init();
+
+ gnutls_global_set_log_function(tls_log_func);
+ if (debug)
+ gnutls_global_set_log_level(9);
+
+ /* Init server */
+ assert(gnutls_psk_allocate_server_credentials(&scred) >= 0);
+ gnutls_psk_set_server_credentials_function(scred, pskfunc);
+
+ gnutls_init(&server, GNUTLS_SERVER);
+
+ assert(gnutls_priority_set_direct(
+ server,
+ "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:+DHE-PSK",
+ NULL) >= 0);
+
+ gnutls_credentials_set(server, GNUTLS_CRD_PSK, scred);
+ gnutls_transport_set_push_function(server, server_push);
+ gnutls_transport_set_pull_function(server, server_pull);
+ gnutls_transport_set_ptr(server, server);
+
+ /* Init client */
+ assert(gnutls_psk_allocate_client_credentials(&ccred) >= 0);
+ gnutls_psk_set_client_credentials(ccred, "test", &key,
+ GNUTLS_PSK_KEY_HEX);
+ assert(gnutls_certificate_allocate_credentials(&ccred2) >= 0);
+
+ assert(gnutls_init(&client, GNUTLS_CLIENT | GNUTLS_KEY_SHARE_TOP) >= 0);
+
+ gnutls_session_set_ptr(client, &ctx);
+
+ cret = gnutls_priority_set_direct(
+ client,
+ "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-X25519:+DHE-PSK",
+ NULL);
+ if (cret < 0)
+ myfail("cannot set TLS 1.3 priorities\n");
+
+ gnutls_credentials_set(client, GNUTLS_CRD_PSK, ccred);
+ gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, ccred2);
+ gnutls_transport_set_push_function(client, client_push);
+ gnutls_transport_set_pull_function(client, client_pull);
+ gnutls_transport_set_ptr(client, client);
+
+ gnutls_handshake_set_hook_function(client, GNUTLS_HANDSHAKE_ANY,
+ GNUTLS_HOOK_BOTH, hello_callback);
+
+ HANDSHAKE_EXPECT(client, server, GNUTLS_E_AGAIN,
+ GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+
+ assert(ctx.hrr_seen != 0);
+
+ gnutls_bye(client, GNUTLS_SHUT_WR);
+ gnutls_bye(server, GNUTLS_SHUT_WR);
+
+ gnutls_deinit(client);
+ gnutls_deinit(server);
+
+ gnutls_psk_free_server_credentials(scred);
+ gnutls_psk_free_client_credentials(ccred);
+ gnutls_certificate_free_credentials(ccred2);
+
+ gnutls_global_deinit();
+ reset_buffers();
+}
--
2.50.0

View File

@ -0,0 +1,295 @@
From 3f5dd79d8abd40193ab3ce9b3ee9a30bf77b34ba Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 22 Jul 2025 10:49:33 +0900
Subject: [PATCH 1/3] key_update: fix state transition in KTLS code path
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/record.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/record.c b/lib/record.c
index d37f79a550..ebc75addec 100644
--- a/lib/record.c
+++ b/lib/record.c
@@ -2045,7 +2045,7 @@ ssize_t gnutls_record_send2(gnutls_session_t session, const void *data,
FALLTHROUGH;
case RECORD_SEND_KEY_UPDATE_3:
if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND)) {
- return _gnutls_ktls_send(
+ ret = _gnutls_ktls_send(
session,
session->internals.record_key_update_buffer.data,
session->internals.record_key_update_buffer
--
2.50.1
From fee06c4ac19129e0f5f4b639919a4ff244bf174c Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Thu, 31 Jul 2025 15:34:48 +0900
Subject: [PATCH 2/3] constate: switch epoch lookup to linear search
The previous logic of epoch lookup was utilizing the fact that epoch
numbers are monotonically increasing and there are no gaps in between
after garbarge collection. That is, however, no longer true when a TLS
1.3 key update is happening in only one direction.
This patch switches to using linear search instead, at the cost of
approx MAX_EPOCH_INDEX * 2 (= 8) comparison.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/constate.c | 47 ++++++++++++++++-------------------------------
lib/gnutls_int.h | 3 ---
2 files changed, 16 insertions(+), 34 deletions(-)
diff --git a/lib/constate.c b/lib/constate.c
index ca253a2bea..b091d891ff 100644
--- a/lib/constate.c
+++ b/lib/constate.c
@@ -932,17 +932,23 @@ static inline int epoch_resolve(gnutls_session_t session,
static inline record_parameters_st **epoch_get_slot(gnutls_session_t session,
uint16_t epoch)
{
- uint16_t epoch_index = epoch - session->security_parameters.epoch_min;
+ /* First look for a non-empty slot */
+ for (size_t i = 0; i < MAX_EPOCH_INDEX; i++) {
+ record_parameters_st **slot = &session->record_parameters[i];
+ if (*slot != NULL && (*slot)->epoch == epoch)
+ return slot;
+ }
- if (epoch_index >= MAX_EPOCH_INDEX) {
- _gnutls_handshake_log(
- "Epoch %d out of range (idx: %d, max: %d)\n",
- (int)epoch, (int)epoch_index, MAX_EPOCH_INDEX);
- gnutls_assert();
- return NULL;
+ /* Then look for an empty slot */
+ for (size_t i = 0; i < MAX_EPOCH_INDEX; i++) {
+ record_parameters_st **slot = &session->record_parameters[i];
+ if (*slot == NULL)
+ return slot;
}
- /* The slot may still be empty (NULL) */
- return &session->record_parameters[epoch_index];
+
+ gnutls_assert();
+ _gnutls_handshake_log("No slot available for epoch %u\n", epoch);
+ return NULL;
}
int _gnutls_epoch_get(gnutls_session_t session, unsigned int epoch_rel,
@@ -1063,8 +1069,7 @@ static inline int epoch_alive(gnutls_session_t session,
void _gnutls_epoch_gc(gnutls_session_t session)
{
- int i, j;
- unsigned int min_index = 0;
+ int i;
_gnutls_record_log("REC[%p]: Start of epoch cleanup\n", session);
@@ -1091,26 +1096,6 @@ void _gnutls_epoch_gc(gnutls_session_t session)
}
}
- /* Look for contiguous NULLs at the start of the array */
- for (i = 0;
- i < MAX_EPOCH_INDEX && session->record_parameters[i] == NULL; i++)
- ;
- min_index = i;
-
- /* Pick up the slack in the epoch window. */
- if (min_index != 0) {
- for (i = 0, j = min_index; j < MAX_EPOCH_INDEX; i++, j++) {
- session->record_parameters[i] =
- session->record_parameters[j];
- session->record_parameters[j] = NULL;
- }
- }
-
- /* Set the new epoch_min */
- if (session->record_parameters[0] != NULL)
- session->security_parameters.epoch_min =
- session->record_parameters[0]->epoch;
-
gnutls_mutex_unlock(&session->internals.epoch_lock);
_gnutls_record_log("REC[%p]: End of epoch cleanup\n", session);
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index e9ec36d585..cc5d965593 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -860,9 +860,6 @@ typedef struct {
/* The epoch that the next handshake will initialize. */
uint16_t epoch_next;
- /* The epoch at index 0 of record_parameters. */
- uint16_t epoch_min;
-
/* this is the ciphersuite we are going to use
* moved here from internals in order to be restored
* on resume;
--
2.50.1
From 0d25525656d3bcf2d8ca9d17d5ebe7cb738ed4c2 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Sat, 19 Jul 2025 07:08:24 +0900
Subject: [PATCH 3/3] key_update: rework the rekeying logic
While RFC 8446 4.6.3 says that the sender of a KeyUpdate message
should only update its sending key, the previous implementation
updated both the sending and receiving keys, preventing that any
application data interleaved being decrypted.
This splits the key update logic into 2 phases: when sending a
KeyUpdate, only update the sending key, and when receiving a
KeyUpdate, only update the receiving key. In both cases, KeyUpdate
messages are encrypted/decrypted with the old keys.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/gnutls_int.h | 2 +-
lib/tls13/key_update.c | 72 +++++++++++++++++++++++++++---------------
2 files changed, 47 insertions(+), 27 deletions(-)
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index cc5d965593..a7684f75c1 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -1652,7 +1652,7 @@ typedef struct {
} internals_st;
/* Maximum number of epochs we keep around. */
-#define MAX_EPOCH_INDEX 4
+#define MAX_EPOCH_INDEX 16
#define reset_cand_groups(session) \
session->internals.cand_ec_group = session->internals.cand_dh_group = \
diff --git a/lib/tls13/key_update.c b/lib/tls13/key_update.c
index 41243651b5..beee1dc41a 100644
--- a/lib/tls13/key_update.c
+++ b/lib/tls13/key_update.c
@@ -52,45 +52,47 @@ static inline int set_ktls_keys(gnutls_session_t session,
return 0;
}
-static int update_keys(gnutls_session_t session, hs_stage_t stage)
+static int update_sending_key(gnutls_session_t session, hs_stage_t stage)
{
int ret;
- ret = _tls13_update_secret(session,
- session->key.proto.tls13.temp_secret,
- session->key.proto.tls13.temp_secret_size);
+ _gnutls_epoch_bump(session);
+ ret = _gnutls_epoch_dup(session, EPOCH_WRITE_CURRENT);
if (ret < 0)
return gnutls_assert_val(ret);
- _gnutls_epoch_bump(session);
- ret = _gnutls_epoch_dup(session, EPOCH_READ_CURRENT);
+ ret = _tls13_write_connection_state_init(session, stage);
if (ret < 0)
return gnutls_assert_val(ret);
- /* If we send a key update during early start, only update our
- * write keys */
- if (session->internals.recv_state == RECV_STATE_EARLY_START) {
- ret = _tls13_write_connection_state_init(session, stage);
+ if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND)) {
+ ret = set_ktls_keys(session, GNUTLS_KTLS_SEND);
if (ret < 0)
return gnutls_assert_val(ret);
+ }
- if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND))
- ret = set_ktls_keys(session, GNUTLS_KTLS_SEND);
- } else {
- ret = _tls13_connection_state_init(session, stage);
- if (ret < 0)
- return gnutls_assert_val(ret);
+ return 0;
+}
- if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND) &&
- stage == STAGE_UPD_OURS)
- ret = set_ktls_keys(session, GNUTLS_KTLS_SEND);
- else if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_RECV) &&
- stage == STAGE_UPD_PEERS)
- ret = set_ktls_keys(session, GNUTLS_KTLS_RECV);
- }
+static int update_receiving_key(gnutls_session_t session, hs_stage_t stage)
+{
+ int ret;
+
+ _gnutls_epoch_bump(session);
+ ret = _gnutls_epoch_dup(session, EPOCH_READ_CURRENT);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = _tls13_read_connection_state_init(session, stage);
if (ret < 0)
return gnutls_assert_val(ret);
+ if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_RECV)) {
+ ret = set_ktls_keys(session, GNUTLS_KTLS_RECV);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ }
+
return 0;
}
@@ -128,7 +130,13 @@ int _gnutls13_recv_key_update(gnutls_session_t session, gnutls_buffer_st *buf)
switch (buf->data[0]) {
case 0:
/* peer updated its key, not requested our key update */
- ret = update_keys(session, STAGE_UPD_PEERS);
+ ret = _tls13_update_secret(
+ session, session->key.proto.tls13.temp_secret,
+ session->key.proto.tls13.temp_secret_size);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = update_receiving_key(session, STAGE_UPD_PEERS);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -141,7 +149,13 @@ int _gnutls13_recv_key_update(gnutls_session_t session, gnutls_buffer_st *buf)
}
/* peer updated its key, requested our key update */
- ret = update_keys(session, STAGE_UPD_PEERS);
+ ret = _tls13_update_secret(
+ session, session->key.proto.tls13.temp_secret,
+ session->key.proto.tls13.temp_secret_size);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = update_receiving_key(session, STAGE_UPD_PEERS);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -248,7 +262,13 @@ int gnutls_session_key_update(gnutls_session_t session, unsigned flags)
_gnutls_epoch_gc(session);
/* it was completely sent, update the keys */
- ret = update_keys(session, STAGE_UPD_OURS);
+ ret = _tls13_update_secret(session,
+ session->key.proto.tls13.temp_secret,
+ session->key.proto.tls13.temp_secret_size);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = update_sending_key(session, STAGE_UPD_OURS);
if (ret < 0)
return gnutls_assert_val(ret);
--
2.50.1

View File

@ -13,7 +13,7 @@ print(string.sub(hash, 0, 16))
}
Version: 3.8.3
Release: 6%{?dist}
Release: 9%{?dist}
# not upstreamed
Patch: gnutls-3.2.7-rpath.patch
Patch: gnutls-3.7.2-enable-intel-cet.patch
@ -30,6 +30,11 @@ Patch: gnutls-3.8.3-ktls-utsname.patch
Patch: gnutls-3.8.3-deterministic-ecdsa-fixes.patch
Patch: gnutls-3.8.3-verify-chain.patch
Patch: gnutls-3.8.9-CVE-2024-12243.patch
Patch: gnutls-3.8.3-cve-2025-32988.patch
Patch: gnutls-3.8.3-cve-2025-32989.patch
Patch: gnutls-3.8.3-cve-2025-32990.patch
Patch: gnutls-3.8.3-cve-2025-6395.patch
Patch: gnutls-3.8.3-keyupdate.patch
%bcond_without bootstrap
%bcond_without dane
@ -416,6 +421,15 @@ make check %{?_smp_mflags} GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null XFAIL_TESTS="$x
%endif
%changelog
* Tue Aug 5 2025 Daiki Ueno <dueno@redhat.com> - 3.8.3-9
- key_update: rework the rekeying logic (RHEL-107499)
* Fri Jul 18 2025 Daiki Ueno <dueno@redhat.com> - 3.8.3-8
- Add missing changelog entry
* Fri Jul 18 2025 Daiki Ueno <dueno@redhat.com> - 3.8.3-7
- Fix CVE-2025-32988, CVE-2025-32989, CVE-2025-32990, and CVE-2025-6395
* Mon Feb 17 2025 Daiki Ueno <dueno@redhat.com> - 3.8.3-6
- Bump nettle dependency to 3.10.1 (RHEL-52740)