forked from osmocom/wireshark
TLS: fix RSA decryption with EMS and renegotiation
The handshake hash is used to derive TLS decryption keys when the Extended Master Secret (EMS) extension is in use. ssl_calculate_handshake_hash updates this hash only when the master secret has not been determined yet. During TLS renegotiation, there are two master secrets: one before, and one after. Before this fix, the second calculated master secret is wrong because the second Client Hello is missing in the handshake hash. It was missing because the handshake hash was not being updated since the master secret for the first handshake was still present, and the decryption state was only reset after that hash update. To fix this, make sure to clear the SSL_MASTER_SECRET flag before updating the handshake hash when needed. Additionally, clear the handshake hash when processing the Client Hello just to make sure that any previous state is gone. Fixes #18059
This commit is contained in:
parent
b1ba667acc
commit
62100da7f4
|
@ -1400,6 +1400,11 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo,
|
|||
sub_tvb = tvb_new_subset_length(tvb, offset, fragment_length);
|
||||
}
|
||||
|
||||
if ((msg_type == SSL_HND_CLIENT_HELLO || msg_type == SSL_HND_SERVER_HELLO)) {
|
||||
/* Prepare for renegotiation by resetting the state. */
|
||||
ssl_reset_session(session, ssl, msg_type == SSL_HND_CLIENT_HELLO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add handshake message (including type, length, etc.) to hash (for
|
||||
* Extended Master Secret). The computation must however happen as if
|
||||
|
|
|
@ -5308,8 +5308,7 @@ ssl_get_session(conversation_t *conversation, dissector_handle_t tls_handle)
|
|||
return ssl_session;
|
||||
}
|
||||
|
||||
/* Resets the decryption parameters for the next decoder. */
|
||||
static void ssl_reset_session(SslSession *session, SslDecryptSession *ssl, gboolean is_client)
|
||||
void ssl_reset_session(SslSession *session, SslDecryptSession *ssl, gboolean is_client)
|
||||
{
|
||||
if (ssl) {
|
||||
/* Ensure that secrets are not restored using stale identifiers. Split
|
||||
|
@ -5323,6 +5322,13 @@ static void ssl_reset_session(SslSession *session, SslDecryptSession *ssl, gbool
|
|||
ssl->master_secret.data_len = 0;
|
||||
ssl->client_random.data_len = 0;
|
||||
ssl->has_early_data = FALSE;
|
||||
if (ssl->handshake_data.data_len > 0) {
|
||||
// The EMS handshake hash starts with at the Client Hello,
|
||||
// ensure that any messages before it are forgotten.
|
||||
wmem_free(wmem_file_scope(), ssl->handshake_data.data);
|
||||
ssl->handshake_data.data = NULL;
|
||||
ssl->handshake_data.data_len = 0;
|
||||
}
|
||||
} else {
|
||||
clear_flags |= SSL_SERVER_EXTENDED_MASTER_SECRET | SSL_NEW_SESSION_TICKET;
|
||||
ssl->server_random.data_len = 0;
|
||||
|
@ -8000,9 +8006,6 @@ ssl_dissect_hnd_hello_common(ssl_common_dissect_t *hf, tvbuff_t *tvb,
|
|||
proto_tree *ti_rnd;
|
||||
guint8 draft_version = session->tls13_draft_version;
|
||||
|
||||
/* Prepare for renegotiation by resetting the state. */
|
||||
ssl_reset_session(session, ssl, !from_server);
|
||||
|
||||
if (ssl) {
|
||||
StringInfo *rnd;
|
||||
if (from_server)
|
||||
|
|
|
@ -592,6 +592,10 @@ SslDecryptSession *ssl_get_session_by_cid(tvbuff_t *tvb, guint32 offset);
|
|||
extern SslDecryptSession *
|
||||
ssl_get_session(conversation_t *conversation, dissector_handle_t tls_handle);
|
||||
|
||||
/** Resets the decryption parameters for the next decoder. */
|
||||
extern void
|
||||
ssl_reset_session(SslSession *session, SslDecryptSession *ssl, gboolean is_client);
|
||||
|
||||
/** Set server address and port */
|
||||
extern void
|
||||
ssl_set_server(SslSession *session, address *addr, port_type ptype, guint32 port);
|
||||
|
|
|
@ -2600,6 +2600,11 @@ dissect_tls_handshake_full(tvbuff_t *tvb, packet_info *pinfo,
|
|||
tvb, offset, 3, length);
|
||||
offset += 3;
|
||||
|
||||
if ((msg_type == SSL_HND_CLIENT_HELLO || msg_type == SSL_HND_SERVER_HELLO)) {
|
||||
/* Prepare for renegotiation by resetting the state. */
|
||||
ssl_reset_session(session, ssl, msg_type == SSL_HND_CLIENT_HELLO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add handshake message (including type, length, etc.) to hash (for
|
||||
* Extended Master Secret).
|
||||
|
|
Loading…
Reference in New Issue