From 03b7495bbe55154fe36430cab67bcf9e3280c0f1 Mon Sep 17 00:00:00 2001 From: Damir Zainullin Date: Sun, 17 Nov 2024 19:08:55 +0100 Subject: [PATCH] Refactor QUIC Parser to use refactored TLS Parser --- process/quic_parser.cpp | 128 +++++++++++++++------------------------- process/quic_parser.hpp | 2 +- 2 files changed, 50 insertions(+), 80 deletions(-) diff --git a/process/quic_parser.cpp b/process/quic_parser.cpp index 2bc8554ce..fbd0b75fb 100644 --- a/process/quic_parser.cpp +++ b/process/quic_parser.cpp @@ -248,95 +248,65 @@ uint64_t QUICParser::quic_get_variable_length(const uint8_t* start, uint64_t& of } } // QUICParser::quic_get_variable_length -bool QUICParser::quic_obtain_tls_data(TLSData& payload) +bool QUICParser::quic_parse_tls_extensions() { - quic_tls_extension_lengths_pos = 0; - quic_tls_ext_type_pos = 0; - quic_tls_ext_pos = 0; - while (payload.start + sizeof(tls_ext) <= payload.end) { - tls_ext* ext = (tls_ext*) payload.start; - uint16_t type = ntohs(ext->type); - uint16_t length = ntohs(ext->length); - - // Store extension type - if (quic_tls_ext_type_pos < MAX_QUIC_TLS_EXT_LEN) { - quic_tls_ext_type[quic_tls_ext_type_pos] = type; - quic_tls_ext_type_pos += 1; - } - - // Store extension type length - if (quic_tls_extension_lengths_pos < MAX_QUIC_TLS_EXT_LEN) { - quic_tls_extension_lengths[quic_tls_extension_lengths_pos] = length; - quic_tls_extension_lengths_pos += 1; - } - - // - payload.start += sizeof(tls_ext); - - if (payload.start + length > payload.end) { - break; - } - - // Save value payload except for length - if (quic_tls_ext_pos + length < CURRENT_BUFFER_SIZE) { + const bool extensions_parsed = tls_parser.parse_extensions([this]( + uint16_t extension_type, + const uint8_t* extension_payload, + uint16_t extension_length) { + if (extension_type == TLS_EXT_SERVER_NAME && extension_length != 0) { + tls_parser.parse_server_names(extension_payload, extension_length); + } else if ( + (extension_type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS_V1 + || extension_type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS + || extension_type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS_V2) + && extension_length != 0) { + tls_parser.parse_quic_user_agent(extension_payload, extension_length); + } + if (quic_tls_ext_pos + extension_length < CURRENT_BUFFER_SIZE) { #ifndef QUIC_CH_FULL_TLS_EXT - if (type == TLS_EXT_ALPN || type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS_V1 - || type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS - || type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS_V2) { + if (extension_type == TLS_EXT_ALPN || extension_type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS_V1 + || extension_type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS + || extension_type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS_V2) { #endif - memcpy(quic_tls_ext + quic_tls_ext_pos, payload.start, length); - quic_tls_ext_pos += length; + memcpy(quic_tls_ext + quic_tls_ext_pos, extension_payload, extension_length); + quic_tls_ext_pos += extension_length; #ifndef QUIC_CH_FULL_TLS_EXT - } + } #endif - } - - // Legacy extract specific fields - if (type == TLS_EXT_SERVER_NAME && length != 0) { - tls_parser.tls_get_server_name(payload, sni, BUFF_SIZE); - } else if ( - (type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS_V1 - || type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS - || type == TLS_EXT_QUIC_TRANSPORT_PARAMETERS_V2) - && length != 0) { - tls_parser.tls_get_quic_user_agent(payload, user_agent, BUFF_SIZE); - } - payload.start += length; - } - return payload.obejcts_parsed != 0; + } + tls_parser.add_extension(extension_type, extension_length); + }); + if (!extensions_parsed){ + return false; + } + tls_parser.save_server_names(sni, BUFF_SIZE); + tls_parser.save_quic_user_agent(user_agent, BUFF_SIZE); + + const size_t copy_count = std::min(tls_parser.get_extensions().size(), MAX_QUIC_TLS_EXT_LEN); + std::transform(tls_parser.get_extensions().begin(), + tls_parser.get_extensions().begin() + static_cast(copy_count), + std::begin(quic_tls_ext_type), + [](const TLSExtension& typeLength) { + return typeLength.type; + }); + std::transform(tls_parser.get_extensions().begin(), + tls_parser.get_extensions().begin() + static_cast(copy_count), + std::begin(quic_tls_extension_lengths), + [](const TLSExtension& typeLength) { + return typeLength.length; + }); + quic_tls_ext_type_pos = quic_tls_extension_lengths_pos = copy_count; + return true; } bool QUICParser::quic_parse_tls() { - TLSData payload = { - payload.start = final_payload + quic_crypto_start, - payload.end = final_payload + quic_crypto_start + quic_crypto_len, - payload.obejcts_parsed = 0, - }; - - if (!tls_parser.tls_check_handshake(payload)) { - return false; - } - if (!tls_parser.tls_skip_random(payload)) { - return false; - } - if (!tls_parser.tls_skip_sessid(payload)) { + if (!tls_parser.parse_quic_tls(final_payload + quic_crypto_start, quic_crypto_len)){ return false; } - if (!tls_parser.tls_skip_cipher_suites(payload)) { - return false; - } - if (!tls_parser.tls_skip_compression_met(payload)) { - return false; - } - if (!tls_parser.tls_check_ext_len(payload)) { - return false; - } - // If no parameters were extracted. We also accept the QUIC connection. (no error check here) - quic_obtain_tls_data(payload); - - return true; -} // QUICPlugin::quic_parse_tls + return quic_parse_tls_extensions(); +} uint8_t QUICParser::quic_draft_version(uint32_t version) { @@ -1394,7 +1364,7 @@ bool QUICParser::quic_parse_headers(const Packet& pkt, bool forceInitialParsing) bool QUICParser::quic_set_server_port(const Packet& pkt) { - tls_handshake hs = tls_parser.tls_get_handshake(); + TLSHandshake hs = tls_parser.get_handshake(); switch (packet_type) { case INITIAL: diff --git a/process/quic_parser.hpp b/process/quic_parser.hpp index 629e9d489..27c522e2f 100644 --- a/process/quic_parser.hpp +++ b/process/quic_parser.hpp @@ -119,7 +119,7 @@ class QUICParser { uint64_t quic_get_variable_length(const uint8_t*, uint64_t&); bool quic_check_version(uint32_t, uint8_t); bool quic_check_pointer_pos(const uint8_t*, const uint8_t*); - bool quic_obtain_tls_data(TLSData&); + bool quic_parse_tls_extensions(); bool quic_set_server_port(const Packet& pkt); bool quic_check_min_initial_size(const Packet& pkt); bool quic_check_supported_version(const uint32_t version);