Skip to content

Commit

Permalink
fix: correct JA4 alpn parsing (aws#4721)
Browse files Browse the repository at this point in the history
  • Loading branch information
lrstewart authored Aug 22, 2024
1 parent b5dba3b commit f2c9f93
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 30 deletions.
129 changes: 107 additions & 22 deletions tests/unit/s2n_fingerprint_ja4_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
10 changes: 2 additions & 8 deletions tls/s2n_fingerprint_ja4.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down

0 comments on commit f2c9f93

Please sign in to comment.