mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2025-01-15 11:05:18 +00:00
Connect QUIC decryption to UDP processing
This commit is contained in:
parent
e5153e9186
commit
b11a183bb3
89
src/quic.c
89
src/quic.c
@ -1,4 +1,5 @@
|
||||
#include "quic.h"
|
||||
#include "tls.h"
|
||||
#include "logging.h"
|
||||
|
||||
|
||||
@ -316,6 +317,53 @@ int gen_fake_udp(struct udp_fake_type type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tls_verdict parse_quic_decrypted(
|
||||
const struct section_config_t *section,
|
||||
const uint8_t *decrypted_message, uint32_t decrypted_message_len
|
||||
) {
|
||||
const uint8_t *curptr = decrypted_message;
|
||||
ssize_t curptr_len = decrypted_message_len;
|
||||
ssize_t fret;
|
||||
int ret;
|
||||
struct tls_verdict tlsv = {0};
|
||||
struct quic_frame_crypto fr_cr;
|
||||
|
||||
while (curptr_len > 0) {
|
||||
uint8_t type = curptr[0];
|
||||
switch (type) {
|
||||
case QUIC_FRAME_PADDING:
|
||||
case QUIC_FRAME_PING:
|
||||
curptr++, curptr_len--;
|
||||
break;
|
||||
case QUIC_FRAME_CRYPTO:
|
||||
fret = quic_parse_crypto(&fr_cr, curptr, curptr_len);
|
||||
if (fret < 0)
|
||||
break;
|
||||
curptr += fret;
|
||||
curptr_len -= fret;
|
||||
|
||||
ret = analyze_tls_message(
|
||||
section, fr_cr.payload, fr_cr.payload_length, &tlsv
|
||||
);
|
||||
switch (ret) {
|
||||
case TLS_MESSAGE_ANALYZE_GOTO_NEXT:
|
||||
break;
|
||||
case TLS_MESSAGE_ANALYZE_FOUND:
|
||||
case TLS_MESSAGE_ANALYZE_INVALID:
|
||||
default:
|
||||
goto out;
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return tlsv;
|
||||
}
|
||||
|
||||
int detect_udp_filtered(const struct section_config_t *section,
|
||||
const uint8_t *payload, uint32_t plen) {
|
||||
const void *iph;
|
||||
@ -341,14 +389,14 @@ int detect_udp_filtered(const struct section_config_t *section,
|
||||
const struct quic_lhdr *qch;
|
||||
uint32_t qch_len;
|
||||
struct quic_cids qci;
|
||||
const uint8_t *quic_raw_payload;
|
||||
uint32_t quic_raw_plen;
|
||||
const uint8_t *quic_in_payload;
|
||||
uint32_t quic_in_plen;
|
||||
|
||||
lgtrace_addp("QUIC probe");
|
||||
|
||||
ret = quic_parse_data((uint8_t *)data, dlen,
|
||||
&qch, &qch_len, &qci,
|
||||
&quic_raw_payload, &quic_raw_plen);
|
||||
&quic_in_payload, &quic_in_plen);
|
||||
|
||||
if (ret < 0) {
|
||||
lgtrace_addp("QUIC undefined type");
|
||||
@ -358,10 +406,43 @@ int detect_udp_filtered(const struct section_config_t *section,
|
||||
lgtrace_addp("QUIC detected");
|
||||
|
||||
|
||||
if (quic_check_is_initial(qch)) {
|
||||
if (!quic_check_is_initial(qch)) {
|
||||
lgtrace_addp("QUIC not initial");
|
||||
goto match_port;
|
||||
}
|
||||
|
||||
uint8_t *decrypted_payload;
|
||||
uint32_t decrypted_payload_len;
|
||||
const uint8_t *decrypted_message;
|
||||
uint32_t decrypted_message_len;
|
||||
struct tls_verdict tlsv;
|
||||
|
||||
lgtrace_addp("QUIC initial message");
|
||||
ret = quic_parse_initial_message(
|
||||
data, dlen,
|
||||
&decrypted_payload, &decrypted_payload_len,
|
||||
&decrypted_message, &decrypted_message_len
|
||||
);
|
||||
|
||||
if (ret < 0) {
|
||||
goto match_port;
|
||||
}
|
||||
|
||||
tlsv = parse_quic_decrypted(section,
|
||||
decrypted_message, decrypted_message_len
|
||||
);
|
||||
|
||||
if (tlsv.sni_len != 0) {
|
||||
lgdebugmsg("QUIC SNI detected: %.*s", tlsv.sni_len, tlsv.sni_ptr);
|
||||
}
|
||||
|
||||
if (tlsv.target_sni) {
|
||||
lgdebugmsg("QUIC target SNI detected: %.*s", tlsv.sni_len, tlsv.sni_ptr);
|
||||
free(decrypted_payload);
|
||||
goto approve;
|
||||
}
|
||||
|
||||
free(decrypted_payload);
|
||||
}
|
||||
|
||||
match_port:
|
||||
|
@ -43,6 +43,7 @@
|
||||
|
||||
#define QUIC_FRAME_CRYPTO 0x06
|
||||
#define QUIC_FRAME_PADDING 0x00
|
||||
#define QUIC_FRAME_PING 0x01
|
||||
|
||||
#define QUIC_V1 1 // RFC 9000
|
||||
#define QUIC_V2 0x6b3343cf // RFC 9369
|
||||
@ -200,6 +201,14 @@ int quic_parse_initial_message(
|
||||
const uint8_t **udecrypted_message, uint32_t *udecrypted_message_len
|
||||
);
|
||||
|
||||
/**
|
||||
* Like analyze_tls_data for QUIC
|
||||
*/
|
||||
struct tls_verdict parse_quic_decrypted(
|
||||
const struct section_config_t *section,
|
||||
const uint8_t *decrypted_message, uint32_t decrypted_message_len
|
||||
);
|
||||
|
||||
// Like fail_packet for TCP
|
||||
int udp_fail_packet(struct udp_failing_strategy strategy, uint8_t *payload, uint32_t *plen, uint32_t avail_buflen);
|
||||
|
||||
|
@ -26,6 +26,9 @@ struct tls_verdict {
|
||||
#define TLS_MESSAGE_ANALYZE_FOUND 0
|
||||
#define TLS_MESSAGE_ANALYZE_GOTO_NEXT 1
|
||||
|
||||
/**
|
||||
* Analyzes each TLS Client Hello message (inside TLS Record or QUIC CRYPTO FRAME)
|
||||
*/
|
||||
int analyze_tls_message(
|
||||
const struct section_config_t *section,
|
||||
const uint8_t *message_data,
|
||||
|
30
test/quic.c
30
test/quic.c
@ -58,6 +58,10 @@ TEST(QuicTest, Test_decrypts)
|
||||
|
||||
// tag is left
|
||||
TEST_ASSERT_EQUAL(16, decrypted_payload + decrypted_payload_len - curptr);
|
||||
|
||||
#undef free
|
||||
free(decrypted_payload);
|
||||
#define free unity_free
|
||||
}
|
||||
|
||||
TEST(QuicTest, Test_crypto_parser_valid)
|
||||
@ -81,7 +85,9 @@ TEST(QuicTest, Test_crypto_parser_tls)
|
||||
struct tls_verdict tlsv;
|
||||
|
||||
fret = quic_parse_crypto(&fr_cr, (const uint8_t *)quic_decrypted_crypto, sizeof(quic_decrypted_crypto));
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(0, fret);
|
||||
ret = analyze_tls_message(&sconf, fr_cr.payload, fr_cr.payload_length, &tlsv);
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL_STRING_LEN("example.com", tlsv.sni_ptr, 11);
|
||||
}
|
||||
|
||||
@ -129,6 +135,29 @@ TEST(QuicTest, Test_varlength_parser)
|
||||
TEST_ASSERT_EQUAL(0, mlen);
|
||||
}
|
||||
|
||||
TEST(QuicTest, Test_parse_quic_decrypted)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *decrypted_payload;
|
||||
uint32_t decrypted_payload_len;
|
||||
const uint8_t *decrypted_message;
|
||||
uint32_t decrypted_message_len;
|
||||
struct tls_verdict tlsv = {0};
|
||||
|
||||
ret = quic_parse_initial_message(
|
||||
(const uint8_t *)quic_testing_payload, sizeof(quic_testing_payload) - 1,
|
||||
&decrypted_payload, &decrypted_payload_len,
|
||||
&decrypted_message, &decrypted_message_len
|
||||
);
|
||||
TEST_ASSERT_EQUAL(ret, 0);
|
||||
|
||||
tlsv = parse_quic_decrypted(&sconf, decrypted_message, decrypted_message_len);
|
||||
TEST_ASSERT_EQUAL_STRING_LEN("example.com", tlsv.sni_ptr, 11);
|
||||
#undef free
|
||||
free(decrypted_payload);
|
||||
#define free unity_free
|
||||
}
|
||||
|
||||
TEST_GROUP_RUNNER(QuicTest)
|
||||
{
|
||||
RUN_TEST_CASE(QuicTest, Test_decrypts);
|
||||
@ -136,4 +165,5 @@ TEST_GROUP_RUNNER(QuicTest)
|
||||
RUN_TEST_CASE(QuicTest, Test_crypto_parser_tls);
|
||||
RUN_TEST_CASE(QuicTest, Test_crypto_parser_invalid);
|
||||
RUN_TEST_CASE(QuicTest, Test_varlength_parser);
|
||||
RUN_TEST_CASE(QuicTest, Test_parse_quic_decrypted)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user