A new function gnutls_record_get_max_send_size() has been added to
determine the maximum size of a TLS record to be sent to the peer.
+** libgnutls: Expose a new function to update keys without sending a KeyUpdate
+ to the peer. A new function gnutls_handshake_update_receiving_key()
+ has been added to allow updating the local receiving key without
+ sending any KeyUpdate messages.
+
** libgnutls: PKCS#11 cryptographic provider configuration takes a token URI
instead of a module path. To allow using a PKCS#11 module exposing
multiple tokens, the "path" configuration keyword was replaced with
gnutls_psk_allocate_client_credentials2: New function
gnutls_psk_allocate_server_credentials2: New function
gnutls_record_get_max_send_size: New function
+gnutls_handshake_update_receiving_key: New function
* Version 3.8.10 (released 2025-07-08)
GNUTLS_3_8_2@GNUTLS_3_8_2
GNUTLS_3_8_4@GNUTLS_3_8_4
GNUTLS_3_8_6@GNUTLS_3_8_6
+GNUTLS_3_8_10@GNUTLS_3_8_10
_gnutls_global_init_skip@GNUTLS_3_4
gnutls_aead_cipher_decrypt@GNUTLS_3_4
gnutls_aead_cipher_decryptv2@GNUTLS_3_6_10
gnutls_session_ticket_enable_server@GNUTLS_3_4
gnutls_session_ticket_key_generate@GNUTLS_3_4
gnutls_session_ticket_send@GNUTLS_3_6_3
+gnutls_handshake_update_receiving_key@GNUTLS_3_8_6
gnutls_set_default_priority@GNUTLS_3_4
gnutls_set_default_priority_append@GNUTLS_3_6_3
gnutls_sign_algorithm_get@GNUTLS_3_4
FUNCS += functions/gnutls_handshake_set_secret_function.short
FUNCS += functions/gnutls_handshake_set_timeout
FUNCS += functions/gnutls_handshake_set_timeout.short
+FUNCS += functions/gnutls_handshake_update_receiving_key
+FUNCS += functions/gnutls_handshake_update_receiving_key.short
FUNCS += functions/gnutls_handshake_write
FUNCS += functions/gnutls_handshake_write.short
FUNCS += functions/gnutls_hash
APIMANS += gnutls_handshake_set_read_function.3
APIMANS += gnutls_handshake_set_secret_function.3
APIMANS += gnutls_handshake_set_timeout.3
+APIMANS += gnutls_handshake_update_receiving_key.3
APIMANS += gnutls_handshake_write.3
APIMANS += gnutls_hash.3
APIMANS += gnutls_hash_copy.3
#define GNUTLS_KU_PEER 1
int gnutls_session_key_update(gnutls_session_t session, unsigned flags);
+int gnutls_handshake_update_receiving_key(gnutls_session_t session);
+
gnutls_alert_description_t gnutls_alert_get(gnutls_session_t session);
int gnutls_alert_send(gnutls_session_t session, gnutls_alert_level_t level,
gnutls_alert_description_t desc);
gnutls_psk_allocate_client_credentials2;
gnutls_psk_allocate_server_credentials2;
gnutls_record_get_max_send_size;
+ gnutls_handshake_update_receiving_key;
local:
*;
} GNUTLS_3_8_6;
return 0;
}
+
+/**
+ * gnutls_handshake_update_receiving_key:
+ * @session: is a #gnutls_session_t type.
+ *
+ * This function will update/refresh the session receiving keys when
+ * the TLS protocol is 1.3 or better. Unlike gnutls_session_key_update()
+ * this function does not notify the peer, it will only update
+ * the local keys.
+ *
+ * If the negotiated version is not TLS 1.3 or better this
+ * function will return %GNUTLS_E_INVALID_REQUEST.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
+ *
+ * Since: 3.8.11
+ **/
+int gnutls_handshake_update_receiving_key(gnutls_session_t session)
+{
+ int ret;
+ const version_entry_st *vers = get_version(session);
+
+ if (!vers->tls13_sem)
+ return GNUTLS_E_INVALID_REQUEST;
+
+ _gnutls_epoch_gc(session);
+
+ 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);
+
+ return 0;
+}
#ifndef GNUTLS_LIB_TLS13_KEY_UPDATE_H
#define GNUTLS_LIB_TLS13_KEY_UPDATE_H
+int gnutls_handshake_update_receiving_key(gnutls_session_t session);
+
int _gnutls13_recv_key_update(gnutls_session_t session, gnutls_buffer_st *buf);
int _gnutls13_send_key_update(gnutls_session_t session, unsigned again,
unsigned flags);
if (htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC)
return 0;
+ if (htype == GNUTLS_HANDSHAKE_KEY_UPDATE)
+ return 0;
+
return gnutls_handshake_write(peer, level, data, data_size);
}
TRANSFER(client, server, MSG, strlen(MSG), buffer, MAX_BUF);
TRANSFER(server, client, MSG, strlen(MSG), buffer, MAX_BUF);
+ /* Trigger a KeyUpdate that won't actually be sent to the client,
+ * as handshake_read_func() will drop the message.
+ */
+ gnutls_session_key_update(server, GNUTLS_KU_PEER);
+
+ /* Manually update the client keys */
+ gnutls_handshake_update_receiving_key(client);
+
+ TRANSFER(client, server, MSG, strlen(MSG), buffer, MAX_BUF);
+ TRANSFER(server, client, MSG, strlen(MSG), buffer, MAX_BUF);
+
gnutls_bye(client, GNUTLS_SHUT_WR);
gnutls_bye(server, GNUTLS_SHUT_WR);