From f2c9f9383bd5704402523b1daa89c32bee26491b Mon Sep 17 00:00:00 2001 From: Lindsay Stewart Date: Thu, 22 Aug 2024 13:44:49 -0700 Subject: [PATCH] fix: correct JA4 alpn parsing (#4721) --- tests/unit/s2n_fingerprint_ja4_test.c | 129 +++++++++++++++++++++----- tls/s2n_fingerprint_ja4.c | 10 +- 2 files changed, 109 insertions(+), 30 deletions(-) diff --git a/tests/unit/s2n_fingerprint_ja4_test.c b/tests/unit/s2n_fingerprint_ja4_test.c index 784964efb8d..ce7b064f333 100644 --- a/tests/unit/s2n_fingerprint_ja4_test.c +++ b/tests/unit/s2n_fingerprint_ja4_test.c @@ -658,12 +658,12 @@ int main(int argc, char **argv) S2N_TEST_CLIENT_HELLO_CIPHERS, S2N_TEST_CLIENT_HELLO_AFTER_CIPHERS, /* extensions size */ - 0x00, 16, + 0x00, 12, /* extension: alpn */ - 0x00, TLS_EXTENSION_ALPN, 0x00, 12, - 0x00, 10, - 0, 0x00, 2, 'h', '2', - 0, 0x00, 2, 'h', '3'); + 0x00, TLS_EXTENSION_ALPN, 0x00, 8, + 0x00, 6, + 2, 'h', '2', + 2, 'h', '3'); uint8_t output[S2N_TEST_OUTPUT_SIZE] = { 0 }; uint32_t output_size = 0; @@ -690,12 +690,12 @@ int main(int argc, char **argv) S2N_TEST_CLIENT_HELLO_CIPHERS, S2N_TEST_CLIENT_HELLO_AFTER_CIPHERS, /* extensions size */ - 0x00, 24, + 0x00, 20, /* extension: alpn */ - 0x00, TLS_EXTENSION_ALPN, 0x00, 20, - 0x00, 18, - 0, 0x00, 8, 'h', 't', 't', 'p', '/', '1', '.', '1', - 0, 0x00, 4, 'q', 'u', 'i', 'c'); + 0x00, TLS_EXTENSION_ALPN, 0x00, 16, + 0x00, 14, + 8, 'h', 't', 't', 'p', '/', '1', '.', '1', + 4, 'q', 'u', 'i', 'c'); uint8_t output[S2N_TEST_OUTPUT_SIZE] = { 0 }; uint32_t output_size = 0; @@ -717,11 +717,11 @@ int main(int argc, char **argv) S2N_TEST_CLIENT_HELLO_CIPHERS, S2N_TEST_CLIENT_HELLO_AFTER_CIPHERS, /* extensions size */ - 0x00, 10, + 0x00, 8, /* extension: alpn */ - 0x00, TLS_EXTENSION_ALPN, 0x00, 6, - 0x00, 4, - 0, 0x00, 1, 'q'); + 0x00, TLS_EXTENSION_ALPN, 0x00, 4, + 0x00, 2, + 1, 'q'); uint8_t output[S2N_TEST_OUTPUT_SIZE] = { 0 }; uint32_t output_size = 0; @@ -742,11 +742,11 @@ int main(int argc, char **argv) S2N_TEST_CLIENT_HELLO_CIPHERS, S2N_TEST_CLIENT_HELLO_AFTER_CIPHERS, /* extensions size */ - 0x00, 11, + 0x00, 9, /* extension: alpn */ - 0x00, TLS_EXTENSION_ALPN, 0x00, 7, - 0x00, 5, - 0, 0x00, 2, UINT8_MAX, 128); + 0x00, TLS_EXTENSION_ALPN, 0x00, 5, + 0x00, 3, + 2, UINT8_MAX, 128); uint8_t output[S2N_TEST_OUTPUT_SIZE] = { 0 }; uint32_t output_size = 0; @@ -812,11 +812,11 @@ int main(int argc, char **argv) S2N_TEST_CLIENT_HELLO_CIPHERS, S2N_TEST_CLIENT_HELLO_AFTER_CIPHERS, /* extensions size */ - 0x00, 9, + 0x00, 7, /* extension: alpn */ - 0x00, TLS_EXTENSION_ALPN, 0x00, 5, - 0x00, 3, - 0, 0x00, 0); + 0x00, TLS_EXTENSION_ALPN, 0x00, 3, + 0x00, 1, + 0); uint8_t output[S2N_TEST_OUTPUT_SIZE] = { 0 }; uint32_t output_size = 0; @@ -1302,5 +1302,90 @@ int main(int argc, char **argv) sizeof(output), output, &output_size)); } + /* Known value tests */ + { + /* Known value from Wireshark parsing + * https://github.com/FoxIO-LLC/ja4/blob/259739593049478dc68c84a436eca75b9f404e6e/pcap/tls12.pcap + */ + { + uint8_t packet_bytes[] = { + 0x01, 0x00, 0x01, 0xfc, 0x03, 0x03, 0xec, 0xb2, + 0x69, 0x1a, 0xdd, 0xb2, 0xbf, 0x6c, 0x59, 0x9c, + 0x7a, 0xaa, 0xe2, 0x3d, 0xe5, 0xf4, 0x25, 0x61, + 0xcc, 0x04, 0xeb, 0x41, 0x02, 0x9a, 0xcc, 0x6f, + 0xc0, 0x50, 0xa1, 0x6a, 0xc1, 0xd2, 0x20, 0x46, + 0xf8, 0x61, 0x7b, 0x58, 0x0a, 0xc9, 0x35, 0x8e, + 0x2a, 0xa4, 0x4e, 0x30, 0x6d, 0x52, 0x46, 0x6b, + 0xcc, 0x98, 0x9c, 0x87, 0xc8, 0xca, 0x64, 0x30, + 0x9f, 0x5f, 0xaf, 0x50, 0xba, 0x7b, 0x4d, 0x00, + 0x22, 0x13, 0x01, 0x13, 0x03, 0x13, 0x02, 0xc0, + 0x2b, 0xc0, 0x2f, 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, + 0x2c, 0xc0, 0x30, 0xc0, 0x0a, 0xc0, 0x09, 0xc0, + 0x13, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, + 0x2f, 0x00, 0x35, 0x01, 0x00, 0x01, 0x91, 0x00, + 0x00, 0x00, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x1c, + 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, + 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x17, 0x00, 0x00, + 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, + 0x0e, 0x00, 0x0c, 0x00, 0x1d, 0x00, 0x17, 0x00, + 0x18, 0x00, 0x19, 0x01, 0x00, 0x01, 0x01, 0x00, + 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0c, 0x02, + 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, + 0x31, 0x2e, 0x31, 0x00, 0x05, 0x00, 0x05, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x0a, + 0x00, 0x08, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, + 0x02, 0x03, 0x00, 0x33, 0x00, 0x6b, 0x00, 0x69, + 0x00, 0x1d, 0x00, 0x20, 0x89, 0x09, 0x85, 0x8f, + 0xbe, 0xb6, 0xed, 0x2f, 0x12, 0x48, 0xba, 0x5b, + 0x9e, 0x29, 0x78, 0xbe, 0xad, 0x0e, 0x84, 0x01, + 0x10, 0x19, 0x2c, 0x61, 0xda, 0xed, 0x00, 0x96, + 0x79, 0x8b, 0x18, 0x44, 0x00, 0x17, 0x00, 0x41, + 0x04, 0x4d, 0x18, 0x3d, 0x91, 0xf5, 0xee, 0xd3, + 0x57, 0x91, 0xfa, 0x98, 0x24, 0x64, 0xe3, 0xb0, + 0x21, 0x4a, 0xaa, 0x5f, 0x5d, 0x1b, 0x78, 0x61, + 0x6d, 0x9b, 0x9f, 0xbe, 0xbc, 0x22, 0xd1, 0x1f, + 0x53, 0x5b, 0x2f, 0x94, 0xc6, 0x86, 0x14, 0x31, + 0x36, 0xaa, 0x79, 0x5e, 0x6e, 0x5a, 0x87, 0x5d, + 0x6c, 0x08, 0x06, 0x4a, 0xd5, 0xb7, 0x6d, 0x44, + 0xca, 0xad, 0x76, 0x6e, 0x24, 0x83, 0x01, 0x27, + 0x48, 0x00, 0x2b, 0x00, 0x05, 0x04, 0x03, 0x04, + 0x03, 0x03, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, + 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x08, 0x04, + 0x08, 0x05, 0x08, 0x06, 0x04, 0x01, 0x05, 0x01, + 0x06, 0x01, 0x02, 0x03, 0x02, 0x01, 0x00, 0x2d, + 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c, 0x00, 0x02, + 0x40, 0x01, 0x00, 0x15, 0x00, 0x7a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + uint8_t output[S2N_TEST_OUTPUT_SIZE] = { 0 }; + uint32_t output_size = 0; + EXPECT_OK(s2n_test_ja4_hash_from_bytes( + packet_bytes, sizeof(packet_bytes), + sizeof(output), output, &output_size)); + + const char expected[] = "t13d1715h2_5b57614c22b0_3d5424432f57"; + EXPECT_EQUAL(strlen(expected), output_size); + EXPECT_BYTEARRAY_EQUAL(expected, output, output_size); + }; + }; + END_TEST(); } diff --git a/tls/s2n_fingerprint_ja4.c b/tls/s2n_fingerprint_ja4.c index fe73f1d07d4..c4e59c03a11 100644 --- a/tls/s2n_fingerprint_ja4.c +++ b/tls/s2n_fingerprint_ja4.c @@ -217,16 +217,10 @@ static S2N_RESULT s2n_client_hello_get_first_alpn(struct s2n_client_hello *ch, s struct s2n_stuffer protocols = { 0 }; RESULT_GUARD_POSIX(s2n_stuffer_init_written(&protocols, &extension->extension)); - uint16_t list_size = 0, name_size = 0; - uint8_t name_type = 0; + uint16_t list_size = 0; RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(&protocols, &list_size)); - RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(&protocols, &name_type)); - RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(&protocols, &name_size)); - - uint8_t *name = s2n_stuffer_raw_read(&protocols, name_size); - RESULT_ENSURE_REF(name); - RESULT_GUARD_POSIX(s2n_blob_init(first, name, name_size)); + RESULT_GUARD(s2n_protocol_preferences_read(&protocols, first)); return S2N_RESULT_OK; }