forked from osmocom/wireshark
QUIC: fix 0-RTT decryption for ciphers using SHA-256
Do not limit the digest function for 0-RTT ciphers to SHA-384, add support for digest algorithms with smaller output sizes such as SHA-256. Fixes 0-RTT decryption of quic_0-rtt_cannot_decrypt-dsb.pcapng (draft -23). Change-Id: I3b49d17497fbfa52773a989dc530d04b37b20c3a Ping-Bug: 13881 Reviewed-on: https://code.wireshark.org/review/35144 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
This commit is contained in:
parent
309bf5b547
commit
dc2b424e0a
|
@ -1606,7 +1606,7 @@ quic_create_decoders(packet_info *pinfo, quic_info_data_t *quic_info, quic_ciphe
|
|||
guint hash_len = gcry_md_get_algo_dlen(quic_info->hash_algo);
|
||||
char *secret = (char *)wmem_alloc0(wmem_packet_scope(), hash_len);
|
||||
|
||||
if (!tls13_get_quic_secret(pinfo, from_server, type, hash_len, secret)) {
|
||||
if (!tls13_get_quic_secret(pinfo, from_server, type, hash_len, hash_len, secret)) {
|
||||
*error = "Secrets are not available";
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1627,7 +1627,7 @@ quic_get_traffic_secret(packet_info *pinfo, int hash_algo, quic_pp_state_t *pp_s
|
|||
{
|
||||
guint hash_len = gcry_md_get_algo_dlen(hash_algo);
|
||||
char *secret = (char *)wmem_alloc0(wmem_packet_scope(), hash_len);
|
||||
if (!tls13_get_quic_secret(pinfo, !from_client, TLS_SECRET_APP, hash_len, secret)) {
|
||||
if (!tls13_get_quic_secret(pinfo, !from_client, TLS_SECRET_APP, hash_len, hash_len, secret)) {
|
||||
return FALSE;
|
||||
}
|
||||
pp_state->next_secret = (guint8 *)wmem_memdup(wmem_file_scope(), secret, hash_len);
|
||||
|
@ -1970,6 +1970,7 @@ dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tre
|
|||
}
|
||||
/* Prepare the Initial/Handshake cipher for header/payload decryption. */
|
||||
if (!PINFO_FD_VISITED(pinfo) && conn && cipher) {
|
||||
#define DIGEST_MIN_SIZE 32 /* SHA256 */
|
||||
#define DIGEST_MAX_SIZE 48 /* SHA384 */
|
||||
const gchar *error = NULL;
|
||||
gchar early_data_secret[DIGEST_MAX_SIZE];
|
||||
|
@ -1980,7 +1981,7 @@ dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tre
|
|||
* ID from the *very first* Client Initial packet. */
|
||||
quic_create_initial_decoders(&dcid, &error, conn);
|
||||
} else if (long_packet_type == QUIC_LPT_0RTT) {
|
||||
early_data_secret_len = tls13_get_quic_secret(pinfo, FALSE, TLS_SECRET_0RTT_APP, DIGEST_MAX_SIZE, early_data_secret);
|
||||
early_data_secret_len = tls13_get_quic_secret(pinfo, FALSE, TLS_SECRET_0RTT_APP, DIGEST_MIN_SIZE, DIGEST_MAX_SIZE, early_data_secret);
|
||||
if (early_data_secret_len == 0) {
|
||||
error = "Secrets are not available";
|
||||
}
|
||||
|
|
|
@ -3806,11 +3806,11 @@ tls_get_cipher_info(packet_info *pinfo, guint16 cipher_suite, int *cipher_algo,
|
|||
|
||||
/**
|
||||
* Load the QUIC traffic secret from the keylog file.
|
||||
* Returns the secret length (at most 'secret_size') and the secret into
|
||||
* Returns the secret length (at most 'secret_max_len') and the secret into
|
||||
* 'secret' if a secret was found, or zero otherwise.
|
||||
*/
|
||||
gint
|
||||
tls13_get_quic_secret(packet_info *pinfo, gboolean is_from_server, int type, guint secret_len, guint8 *secret_out)
|
||||
tls13_get_quic_secret(packet_info *pinfo, gboolean is_from_server, int type, guint secret_min_len, guint secret_max_len, guint8 *secret_out)
|
||||
{
|
||||
GHashTable *key_map;
|
||||
const char *label;
|
||||
|
@ -3869,19 +3869,15 @@ tls13_get_quic_secret(packet_info *pinfo, gboolean is_from_server, int type, gui
|
|||
}
|
||||
|
||||
StringInfo *secret = (StringInfo *)g_hash_table_lookup(key_map, &ssl->client_random);
|
||||
if (!secret || secret->data_len != secret_len) {
|
||||
ssl_debug_printf("%s Cannot find QUIC %s of size %d, found bad size %d!\n",
|
||||
G_STRFUNC, label, secret_len, secret ? secret->data_len : 0);
|
||||
if (!secret || secret->data_len < secret_min_len || secret->data_len > secret_max_len) {
|
||||
ssl_debug_printf("%s Cannot find QUIC %s of size %d..%d, found bad size %d!\n",
|
||||
G_STRFUNC, label, secret_min_len, secret_max_len, secret ? secret->data_len : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssl_debug_printf("%s Retrieved QUIC traffic secret.\n", G_STRFUNC);
|
||||
ssl_print_string("Client Random", &ssl->client_random);
|
||||
ssl_print_string(label, secret);
|
||||
if (secret->data_len > secret_len) {
|
||||
ssl_debug_printf("%s Output buffer size is too small!\n", G_STRFUNC);
|
||||
return 0;
|
||||
}
|
||||
memcpy(secret_out, secret->data, secret->data_len);
|
||||
return secret->data_len;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ tls13_exporter(packet_info *pinfo, gboolean is_early,
|
|||
guint context_length, guint key_length, guchar **out);
|
||||
|
||||
gint
|
||||
tls13_get_quic_secret(packet_info *pinfo, gboolean is_from_server, int type, guint secret_len, guint8 *secret_out);
|
||||
tls13_get_quic_secret(packet_info *pinfo, gboolean is_from_server, int type, guint secret_min_len, guint secret_max_len, guint8 *secret_out);
|
||||
|
||||
/**
|
||||
* Returns the application-layer protocol name (ALPN) for the current TLS
|
||||
|
|
Loading…
Reference in New Issue