mirror of
https://github.com/adulau/ssldump.git
synced 2024-12-22 16:05:58 +00:00
Merge branch 'lord8266-tls1.3'
Ok: Minimal tests to ensure the previous features still worked.
This commit is contained in:
commit
c29e9fad89
19 changed files with 677 additions and 95 deletions
41
samples/log.txt
Normal file
41
samples/log.txt
Normal file
|
@ -0,0 +1,41 @@
|
|||
SERVER_HANDSHAKE_TRAFFIC_SECRET 1ba4a034638a63221f55e3e684fa4e6a5bbbb9f9711c035e23441810b82667c8 aa87c1bd965ea9e1361d15e7fd671792980da373f34e4eefe1fd21effbd65a80
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET 1ba4a034638a63221f55e3e684fa4e6a5bbbb9f9711c035e23441810b82667c8 533b0dcc030ecac8feace33031a405f5e05ecd0d7c7e64a6e30fa7bbee9bb813
|
||||
EXPORTER_SECRET 1ba4a034638a63221f55e3e684fa4e6a5bbbb9f9711c035e23441810b82667c8 027a31d81dfa560205e25a50740b13dc7ce6f5c18004dac45e2b68517c0a75e1
|
||||
SERVER_TRAFFIC_SECRET_0 1ba4a034638a63221f55e3e684fa4e6a5bbbb9f9711c035e23441810b82667c8 15f1d79f92d5b5cc15a1ebb67c39bfc4cce4934aac2722fb89a0e055c81c562e
|
||||
CLIENT_TRAFFIC_SECRET_0 1ba4a034638a63221f55e3e684fa4e6a5bbbb9f9711c035e23441810b82667c8 e7cd79a7d0bd712d966261ddc5a7eec31b1e9d5cff667843eafa7e01348d1dcc
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET 1ca51d8032bbf6e0748bc3852de83b111463295f913ea8a0695ee384a4503848 53f1bfdfbc44559025a6562937995d9406033304bf59a457e1b1eb817f530e16
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET 1ca51d8032bbf6e0748bc3852de83b111463295f913ea8a0695ee384a4503848 b8412c25f615a5674f51817604e28b8bf70b269007c05cd408b1a24cfaa9a936
|
||||
EXPORTER_SECRET 1ca51d8032bbf6e0748bc3852de83b111463295f913ea8a0695ee384a4503848 fb2e70cca12d1e15534b3c2b6b67b85a2a148ee4318922451bc2d7cc768a4c91
|
||||
SERVER_TRAFFIC_SECRET_0 1ca51d8032bbf6e0748bc3852de83b111463295f913ea8a0695ee384a4503848 17e8205e0f334bd5c34c9b73e7f791386f3c8e3316d3bdf133d8227380555109
|
||||
CLIENT_TRAFFIC_SECRET_0 1ca51d8032bbf6e0748bc3852de83b111463295f913ea8a0695ee384a4503848 eaedfbfff17ffe92267845cda264104c3ba8da6d6d10a1233ef388bfb8bbbf2d
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET 2e78ab0ab702be305ae81cf0886bc93d09967eb60d9a1d837677c0af52b88c89 91e7f391b276856033a47e458e1d64bf81d08a3292ff30aa582bcbd140d764cc8626c16742ebd6d9a7f500a68aeb5ebb
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET 2e78ab0ab702be305ae81cf0886bc93d09967eb60d9a1d837677c0af52b88c89 ef2ac5e176b3e5713a6c205790e3b58b12b64cc4628fbb6ac0b12273a73be6e6913a0556f823eebe12c4e42199bfbcc6
|
||||
EXPORTER_SECRET 2e78ab0ab702be305ae81cf0886bc93d09967eb60d9a1d837677c0af52b88c89 ad46dd23b08dd4135c63f3291953254977a7526630d3cc9455d8da59eb5cf712cf671d9970dad31f1c793617a60c6f99
|
||||
SERVER_TRAFFIC_SECRET_0 2e78ab0ab702be305ae81cf0886bc93d09967eb60d9a1d837677c0af52b88c89 3f4de0cda8b51bf7533e12279bebd1062459700be861c1a951e4224652872aec2162bd2b8ae16a3a16fe580aa941e6ff
|
||||
CLIENT_TRAFFIC_SECRET_0 2e78ab0ab702be305ae81cf0886bc93d09967eb60d9a1d837677c0af52b88c89 7ea195809a87dc2b3af3f1a1f0317a4f5d51d0e26012e59bc2aeba8c867c0ab735140853234354feb6adc49ea24714b8
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET 172f0e36bede6f9f78157e8e338ee8b5d501a0c264a7c248d4d2092283badd19 574e234b9ed1fe38053194bd7641126bde6e0e005ce33162d5743ab34a99327fce670b1fa134caf943dfbc0a5d686ecc
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET 172f0e36bede6f9f78157e8e338ee8b5d501a0c264a7c248d4d2092283badd19 838049b240d1ae3a80ff4ff0268e248588ec6913f4caae68dfeaf4ea03f330bcab4606d1bee74d299be6c800b2671595
|
||||
EXPORTER_SECRET 172f0e36bede6f9f78157e8e338ee8b5d501a0c264a7c248d4d2092283badd19 13965d7ae6d230cee91ebe990c07e7d5ca46ed40a6924a91bf60901618226a88d606fb5467827cd1d3765fa827476a50
|
||||
SERVER_TRAFFIC_SECRET_0 172f0e36bede6f9f78157e8e338ee8b5d501a0c264a7c248d4d2092283badd19 da4c9bb2d82ce66a35ec5899a9f7bf67e2f24e2b190f9cabc94dd56bfdbf39f54d001da93120554293f711972f03fb16
|
||||
CLIENT_TRAFFIC_SECRET_0 172f0e36bede6f9f78157e8e338ee8b5d501a0c264a7c248d4d2092283badd19 f7f968b5b7eee2b521cda8575822bfdb2887913764a08e35648a26ab4ff98aad230b192ae6b376701395575a372c1c3e
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET 4b038c23f532ba8c893ead81d1f07f1681e4d18987b65333408e20957fde7e71 9eb2c91bcc6e0864c364858e0864d041c52f41ca3ce396d128d4fb5dc386ac00
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET 4b038c23f532ba8c893ead81d1f07f1681e4d18987b65333408e20957fde7e71 8577431055b2a50669270c3bf08aaf32dc7dd66a7e9a5efbeb93677db231fd72
|
||||
EXPORTER_SECRET 4b038c23f532ba8c893ead81d1f07f1681e4d18987b65333408e20957fde7e71 6a58ac33631d88787f62a919a8f0d2b6c0f8d03075aeb04b880ce2330cb9b2fc
|
||||
SERVER_TRAFFIC_SECRET_0 4b038c23f532ba8c893ead81d1f07f1681e4d18987b65333408e20957fde7e71 243d0b750befa5d25af82ea4d5eaacf7f52c5343dc260f75344dcaadc69544b3
|
||||
CLIENT_TRAFFIC_SECRET_0 4b038c23f532ba8c893ead81d1f07f1681e4d18987b65333408e20957fde7e71 0a921480912454ce03a14c5eeb75ae44c7c9a82a883eb632e7279cbdab3d1188
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET 169637b581d83e615cee48ae69fd0d810f24e8855dac989600b48fac970c36d9 182ed636bf590c245fea0ad4b04d9b2304bb30279e1a2f7bfef16861d13e2462
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET 169637b581d83e615cee48ae69fd0d810f24e8855dac989600b48fac970c36d9 1e4ad1aaddf8a4f64f35859461df54d193d1cd081845a422ef44d71f5ca71f71
|
||||
EXPORTER_SECRET 169637b581d83e615cee48ae69fd0d810f24e8855dac989600b48fac970c36d9 23136badd3a8975b1ceea1b4d9523055cbe296dfe75596b1e90ab6f0b7100350
|
||||
SERVER_TRAFFIC_SECRET_0 169637b581d83e615cee48ae69fd0d810f24e8855dac989600b48fac970c36d9 e15200b68d7f703abe7b04165c8885566d90c4dd509c7d174dc4c2cf130cf4d2
|
||||
CLIENT_TRAFFIC_SECRET_0 169637b581d83e615cee48ae69fd0d810f24e8855dac989600b48fac970c36d9 c5fef93efea3e4a24499a408af7e3de26411738cf25063c9efaad9b8d045487d
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET 86c98dd9032df8ef2e6f74b4396c2c2acd8da6f35406412400f9da8d2b48ffbc 783799f80f8d03250acd957dac465e0cb95a5c3b5a1adf4b928a8bceda57246c9d722d02675504a512d7800ebd21f7c0
|
||||
EXPORTER_SECRET 86c98dd9032df8ef2e6f74b4396c2c2acd8da6f35406412400f9da8d2b48ffbc 363ac8e9af29c6063792ca3e2bc7301b6cbbbfbe646f82254a843528ff708846ea934d55b4e37d8b22797f842c4b5aad
|
||||
SERVER_TRAFFIC_SECRET_0 86c98dd9032df8ef2e6f74b4396c2c2acd8da6f35406412400f9da8d2b48ffbc f5402ccfccbf4a46844be1f356931700bb5881ad4dfd07fe57e7330afdfeac08a753035684ffb2b48f504ae836fca1c5
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET 86c98dd9032df8ef2e6f74b4396c2c2acd8da6f35406412400f9da8d2b48ffbc d5f5c7ac89b41eb782181a5d230c8ddf51233f6d3989b4944a95dc95924ee200fe4b1fa02b3e6cf07908c334905a8961
|
||||
CLIENT_TRAFFIC_SECRET_0 86c98dd9032df8ef2e6f74b4396c2c2acd8da6f35406412400f9da8d2b48ffbc 6b37aa85b4698e4d6abfb66933e3fd4283f9fe08faee2a314ce8e1b95a245ceead2f64f4024c27e0cb4fc3c7b20f7ad5
|
||||
CLIENT_RANDOM ff71dd83376f0a35a8b86e8b9f516d9938a36ec3803e48b5a256fc7cd597528d 6bf5b5d1515d70facf6f2a76c997add2a9464b5712b17ee0273dbfeaa3c1ddc7daf5ff21e552cc1ab09ad45fe815d616
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET 3c5b65efb7b4424f2f1bb4d263befa34af2fbb14058f16428ba0187586ee6973 fcb2538d16f80d242d51c0a35395169944182eb5710fb984d03c7b8df864b181642af07af807a75bc133382641ed8bd3
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET 3c5b65efb7b4424f2f1bb4d263befa34af2fbb14058f16428ba0187586ee6973 551c476c45b74d91062991523ff7374b211575d497a41eb0902c3d8329382b51c00df6ebc461da6f2bead0a637352c09
|
||||
EXPORTER_SECRET 3c5b65efb7b4424f2f1bb4d263befa34af2fbb14058f16428ba0187586ee6973 e4c4e35876208551f3f3db9916db2841e2c81b730e9815e52c319ca82e718cad579e351fee75b7a94181419f83d705a2
|
||||
SERVER_TRAFFIC_SECRET_0 3c5b65efb7b4424f2f1bb4d263befa34af2fbb14058f16428ba0187586ee6973 035eed62f0d1ff88326220347fbb3e60e4ee76c99b3a73415f55af9d5cb0d7a2e73e0faa29097acd718fea92c811558e
|
||||
CLIENT_TRAFFIC_SECRET_0 3c5b65efb7b4424f2f1bb4d263befa34af2fbb14058f16428ba0187586ee6973 869488a30d316752c049f2704315bd505f2aa59c608f20867bc9adce929aa25a774500214a0bc06c34dc6774add3b82a
|
BIN
samples/tls1.2_aes256.pcap
Normal file
BIN
samples/tls1.2_aes256.pcap
Normal file
Binary file not shown.
BIN
samples/tls1.3_aes128.pcap
Normal file
BIN
samples/tls1.3_aes128.pcap
Normal file
Binary file not shown.
BIN
samples/tls1.3_aes256gcm.pcap
Normal file
BIN
samples/tls1.3_aes256gcm.pcap
Normal file
Binary file not shown.
BIN
samples/tls1.3_ccm.pcap
Normal file
BIN
samples/tls1.3_ccm.pcap
Normal file
Binary file not shown.
BIN
samples/tls1.3_ccm8.pcap
Normal file
BIN
samples/tls1.3_ccm8.pcap
Normal file
Binary file not shown.
BIN
samples/tls1.3_chacha.pcap
Normal file
BIN
samples/tls1.3_chacha.pcap
Normal file
Binary file not shown.
BIN
samples/tls1.3_curl_google.pcap
Normal file
BIN
samples/tls1.3_curl_google.pcap
Normal file
Binary file not shown.
BIN
samples/tls1.3_keyupdates_aes256.pcap
Normal file
BIN
samples/tls1.3_keyupdates_aes256.pcap
Normal file
Binary file not shown.
BIN
samples/tls1.3_session_resumption.pcap
Normal file
BIN
samples/tls1.3_session_resumption.pcap
Normal file
Binary file not shown.
|
@ -154,6 +154,11 @@ static SSL_CipherSuite CipherSuites[]={
|
|||
{195,KEX_DH,SIG_DSS,ENC_CAMELLIA256,16,256,256,DIG_SHA256,32,0},
|
||||
{196,KEX_DH,SIG_RSA,ENC_CAMELLIA256,16,256,256,DIG_SHA256,32,0},
|
||||
{197,KEX_DH,SIG_NONE,ENC_CAMELLIA256,16,256,256,DIG_SHA256,32,0},
|
||||
{4865,KEX_DH,SIG_NONE,ENC_AES128_GCM,16,128,128,DIG_SHA256,32,0},
|
||||
{4866,KEX_DH,SIG_NONE,ENC_AES256_GCM,16,256,256,DIG_SHA384,48,0},
|
||||
{4867,KEX_DH,SIG_NONE,ENC_CHACHA20_POLY1305,64,256,256,DIG_SHA256,32,0},
|
||||
{4868,KEX_DH,SIG_NONE,ENC_AES128_CCM,16,128,128,DIG_SHA256,32,0},
|
||||
{4869,KEX_DH,SIG_NONE,ENC_AES128_CCM_8,16,128,128,DIG_SHA256,32,0},
|
||||
{49153,KEX_DH,SIG_DSS,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
||||
{49154,KEX_DH,SIG_DSS,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
||||
{49155,KEX_DH,SIG_DSS,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
||||
|
|
225
ssl/ssl.enums.c
225
ssl/ssl.enums.c
|
@ -138,10 +138,11 @@ static int decode_ContentType_application_data(ssl,dir,seg,data)
|
|||
|
||||
SSL_DECODE_OPAQUE_ARRAY(ssl,"data",data->len,0,data,&d);
|
||||
|
||||
P_(P_AD){
|
||||
if(NET_print_flags & NET_PRINT_JSON) {
|
||||
json_object_object_add(jobj, "msg_data", json_object_new_string_len(d.data, d.len));
|
||||
} else P_(P_AD) {
|
||||
print_data(ssl,&d);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
LF;
|
||||
}
|
||||
return(0);
|
||||
|
@ -425,8 +426,6 @@ static int decode_HandshakeType_ServerHello(ssl,dir,seg,data)
|
|||
ja3s_c_str = calloc(6, 1);
|
||||
snprintf(ja3s_c_str, 6, "%u", ssl->cipher_suite);
|
||||
|
||||
ssl_process_server_session_id(ssl,ssl->decoder,session_id.data,
|
||||
session_id.len);
|
||||
|
||||
P_(P_HL) LF;
|
||||
SSL_DECODE_ENUM(ssl,"compressionMethod",1,compression_method_decoder,P_HL,data,0);
|
||||
|
@ -457,6 +456,14 @@ static int decode_HandshakeType_ServerHello(ssl,dir,seg,data)
|
|||
ja3s_ex_str[strlen(ja3s_ex_str) - 1] = '\0';
|
||||
}
|
||||
|
||||
if (ssl->version==TLSV13_VERSION){
|
||||
// tls version is known in server hello for tls1.3 hence generate keying material here
|
||||
ssl_tls13_generate_keying_material(ssl,ssl->decoder);
|
||||
}
|
||||
|
||||
ssl_process_server_session_id(ssl,ssl->decoder,session_id.data,
|
||||
session_id.len);
|
||||
|
||||
if(!ja3s_ver_str) {
|
||||
ja3s_ver_str = calloc(1, 1);
|
||||
*ja3s_ver_str = '\0';
|
||||
|
@ -519,18 +526,20 @@ static int decode_HandshakeType_Certificate(ssl,dir,seg,data)
|
|||
segment *seg;
|
||||
Data *data;
|
||||
{
|
||||
|
||||
|
||||
UINT4 len;
|
||||
UINT4 len,exlen,ex;
|
||||
Data cert;
|
||||
int r;
|
||||
|
||||
struct json_object *jobj;
|
||||
jobj = ssl->cur_json_st;
|
||||
json_object_object_add(jobj, "handshake_type", json_object_new_string("Certificate"));
|
||||
extern decoder extension_decoder[];
|
||||
|
||||
LF;
|
||||
ssl_update_handshake_messages(ssl,data);
|
||||
if (ssl->version==TLSV13_VERSION){
|
||||
SSL_DECODE_OPAQUE_ARRAY(ssl,"certificate request context",-((1<<7)-1),0, data, NULL);
|
||||
}
|
||||
SSL_DECODE_UINT24(ssl,"certificates len",0,data,&len);
|
||||
|
||||
json_object_object_add(jobj, "cert_chain", json_object_new_array());
|
||||
|
@ -540,11 +549,83 @@ static int decode_HandshakeType_Certificate(ssl,dir,seg,data)
|
|||
0,data,&cert);
|
||||
sslx_print_certificate(ssl,&cert,P_ND);
|
||||
len-=(cert.len + 3);
|
||||
if (ssl->version==TLSV13_VERSION) { // TLS 1.3 has certificate extensions
|
||||
SSL_DECODE_UINT16(ssl,"certificate extensions len",0,data,&exlen);
|
||||
len-=2;
|
||||
while (exlen) {
|
||||
SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex);
|
||||
len -= (2+ex);
|
||||
if (ssl_decode_switch(ssl, extension_decoder, ex, dir, seg, data) == R_NOT_FOUND) {
|
||||
decode_extension(ssl, dir, seg, data);
|
||||
P_(P_RH) { explain(ssl, "Extension type: %u not yet implemented in ssldump\n", ex); }
|
||||
continue;
|
||||
}
|
||||
LF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
static int decode_HandshakeType_SessionTicket(ssl,dir,seg,data)
|
||||
ssl_obj *ssl;
|
||||
int dir;
|
||||
segment *seg;
|
||||
Data *data;
|
||||
{
|
||||
int r;
|
||||
UINT4 exlen, ex, val;
|
||||
extern decoder extension_decoder[];
|
||||
|
||||
SSL_DECODE_UINT32(ssl, "ticket_lifetime",P_HL, data, &val);
|
||||
if (ssl->version == TLSV13_VERSION) {
|
||||
SSL_DECODE_UINT32(ssl, "ticket_age_add", P_HL, data, &val);
|
||||
SSL_DECODE_OPAQUE_ARRAY(ssl,"ticket_nonce",-((1<<7)-1), P_ND, data, NULL);
|
||||
}
|
||||
SSL_DECODE_OPAQUE_ARRAY(ssl,"ticket",-((1<<15)-1), P_ND, data, NULL);
|
||||
if (ssl->version == TLSV13_VERSION) {
|
||||
SSL_DECODE_UINT16(ssl, "exlen", 0, data, &exlen);
|
||||
if (exlen) {
|
||||
while (data->len) {
|
||||
SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex);
|
||||
if (ssl_decode_switch(ssl, extension_decoder, ex, dir, seg, data) == R_NOT_FOUND) {
|
||||
if ((r=decode_extension(ssl, dir, seg, data))) ERETURN(r);
|
||||
P_(P_RH) { explain(ssl, "Extension type: %u not yet implemented in ssldump\n", ex); }
|
||||
continue;
|
||||
}
|
||||
LF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_HandshakeType_EncryptedExtensions(ssl,dir,seg,data)
|
||||
ssl_obj *ssl;
|
||||
int dir;
|
||||
segment *seg;
|
||||
Data *data;
|
||||
{
|
||||
int r;
|
||||
UINT4 exlen, ex;
|
||||
extern decoder extension_decoder[];
|
||||
|
||||
SSL_DECODE_UINT16(ssl, 0, 0, data, &exlen);
|
||||
LF;
|
||||
if (exlen) {
|
||||
while (data->len) {
|
||||
SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex);
|
||||
if (ssl_decode_switch(ssl, extension_decoder, ex, dir, seg, data) == R_NOT_FOUND) {
|
||||
decode_extension(ssl, dir, seg, data);
|
||||
P_(P_RH) { explain(ssl, "Extension type: %u not yet implemented in ssldump\n", ex); }
|
||||
continue;
|
||||
}
|
||||
LF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_HandshakeType_ServerKeyExchange(ssl,dir,seg,data)
|
||||
ssl_obj *ssl;
|
||||
int dir;
|
||||
|
@ -650,6 +731,7 @@ static int decode_HandshakeType_CertificateVerify(ssl,dir,seg,data)
|
|||
|
||||
|
||||
int r;
|
||||
UINT4 signature_type;
|
||||
|
||||
struct json_object *jobj;
|
||||
jobj = ssl->cur_json_st;
|
||||
|
@ -657,6 +739,9 @@ static int decode_HandshakeType_CertificateVerify(ssl,dir,seg,data)
|
|||
|
||||
LF;
|
||||
ssl_update_handshake_messages(ssl,data);
|
||||
if (ssl->version == TLSV13_VERSION) {
|
||||
SSL_DECODE_UINT16(ssl,"signature_type",P_HL,data,&signature_type);
|
||||
}
|
||||
SSL_DECODE_OPAQUE_ARRAY(ssl,"Signature",-((1<<15)-1),P_HL,data,0);
|
||||
return(0);
|
||||
|
||||
|
@ -732,9 +817,22 @@ static int decode_HandshakeType_Finished(ssl,dir,seg,data)
|
|||
break;
|
||||
}
|
||||
|
||||
ssl_process_handshake_finished(ssl,ssl->decoder,data);
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
static int decode_HandshakeType_KeyUpdate(ssl,dir,seg,data)
|
||||
ssl_obj *ssl;
|
||||
int dir;
|
||||
segment *seg;
|
||||
Data *data;
|
||||
{
|
||||
LF;
|
||||
ssl_tls13_update_keying_material(ssl, ssl->decoder, dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
decoder HandshakeType_decoder[]={
|
||||
{
|
||||
0,
|
||||
|
@ -751,6 +849,16 @@ decoder HandshakeType_decoder[]={
|
|||
"ServerHello",
|
||||
decode_HandshakeType_ServerHello
|
||||
},
|
||||
{
|
||||
4,
|
||||
"SessionTicket",
|
||||
decode_HandshakeType_SessionTicket
|
||||
},
|
||||
{
|
||||
8,
|
||||
"EncryptedExtensions",
|
||||
decode_HandshakeType_EncryptedExtensions
|
||||
},
|
||||
{
|
||||
11,
|
||||
"Certificate",
|
||||
|
@ -786,6 +894,11 @@ decoder HandshakeType_decoder[]={
|
|||
"Finished",
|
||||
decode_HandshakeType_Finished
|
||||
},
|
||||
{
|
||||
24,
|
||||
"KeyUpdate",
|
||||
decode_HandshakeType_KeyUpdate
|
||||
},
|
||||
{-1}
|
||||
};
|
||||
|
||||
|
@ -2839,6 +2952,18 @@ static int decode_extension(ssl,dir,seg,data)
|
|||
return(0);
|
||||
}
|
||||
|
||||
decoder supported_groups_decoder[] = {
|
||||
{0x0017,"secp256r1",0},
|
||||
{0x0018,"secp384r1",0},
|
||||
{0x0019,"secp521r1",0},
|
||||
{0x001d,"x25519",0},
|
||||
{0x001e,"x448",0},
|
||||
{0x0100,"ffdhe2048",0},
|
||||
{0x0101,"ffdhe3072",0},
|
||||
{0x0102,"ffdhe4096",0},
|
||||
{0x0103,"ffdhe6144",0},
|
||||
{0x0104,"ffdhe8192",0},
|
||||
};
|
||||
// Extension #10 supported_groups (renamed from "elliptic_curves")
|
||||
static int decode_extension_supported_groups(ssl,dir,seg,data)
|
||||
ssl_obj *ssl;
|
||||
|
@ -2856,7 +2981,8 @@ static int decode_extension_supported_groups(ssl,dir,seg,data)
|
|||
LF;
|
||||
while(l) {
|
||||
p=data->len;
|
||||
SSL_DECODE_UINT16(ssl, "supported group", 0, data, &g);
|
||||
SSL_DECODE_ENUM(ssl,"supported group",2,supported_groups_decoder,SSL_PRINT_ALL,data,&g);
|
||||
LF;
|
||||
if(!ja3_ec_str)
|
||||
ja3_ec_str = calloc(7, 1);
|
||||
else
|
||||
|
@ -2875,6 +3001,11 @@ static int decode_extension_supported_groups(ssl,dir,seg,data)
|
|||
return(0);
|
||||
}
|
||||
|
||||
decoder ec_point_formats_decoder[] = {
|
||||
{0,"uncompressed",0,},
|
||||
{1,"ansiX962_compressed_prime",0,},
|
||||
{2,"ansiX962_compressed_char2",0,}
|
||||
};
|
||||
// Extension #11 ec_point_formats
|
||||
static int decode_extension_ec_point_formats(ssl,dir,seg,data)
|
||||
ssl_obj *ssl;
|
||||
|
@ -2892,7 +3023,8 @@ static int decode_extension_ec_point_formats(ssl,dir,seg,data)
|
|||
LF;
|
||||
while(l) {
|
||||
p=data->len;
|
||||
SSL_DECODE_UINT8(ssl, "ec point format", 0, data, &f);
|
||||
SSL_DECODE_ENUM(ssl,"ec point format",1,ec_point_formats_decoder,SSL_PRINT_ALL,data, &f);
|
||||
LF;
|
||||
if(!ja3_ecp_str)
|
||||
ja3_ecp_str = calloc(5, 1);
|
||||
else
|
||||
|
@ -2912,6 +3044,72 @@ static int decode_extension_ec_point_formats(ssl,dir,seg,data)
|
|||
return(0);
|
||||
}
|
||||
|
||||
static int decode_extension_supported_versions(ssl,dir,seg,data)
|
||||
ssl_obj *ssl;
|
||||
int dir;
|
||||
segment *seg;
|
||||
Data *data;
|
||||
{
|
||||
int r;
|
||||
UINT4 len, version;
|
||||
SSL_DECODE_UINT16(ssl, "extensions length", 0, data, &len);
|
||||
LF;
|
||||
if (dir == DIR_I2R) SSL_DECODE_UINT8(ssl, "supported versions length", 0, data, &len);//client sends extension<..>
|
||||
while (len) {
|
||||
SSL_DECODE_UINT16(ssl, "supported version", 0, data, &version);
|
||||
explain(ssl, "version: %u.%u", (version>>8)&0xff, version&0xff);
|
||||
len -= 2;
|
||||
if (len) printf("\n");
|
||||
}
|
||||
if (dir == DIR_R2I) ssl->version = version; // Server sets the tls version
|
||||
}
|
||||
|
||||
decoder tls13_certificate_types[] = {
|
||||
{0,"x509",0},
|
||||
{1,"openpgp",0},
|
||||
{2,"raw public key",0},
|
||||
{3,"1609 dot 2",0}
|
||||
};
|
||||
static int decode_extension_client_certificate_type(ssl,dir,seg,data)
|
||||
ssl_obj *ssl;
|
||||
int dir;
|
||||
segment *seg;
|
||||
Data *data;
|
||||
{
|
||||
int r;
|
||||
UINT4 len, certificate_type;
|
||||
SSL_DECODE_UINT16(ssl, "extensions length", 0, data, &len);
|
||||
LF;
|
||||
if (dir == DIR_I2R) SSL_DECODE_UINT8(ssl, "client certificates length", 0, data, &len);//client sends certificates<..>
|
||||
while (len) {
|
||||
SSL_DECODE_ENUM(ssl,"certificate type",1,tls13_certificate_types,SSL_PRINT_ALL,data, &certificate_type);
|
||||
len -= 1;
|
||||
data += 1;
|
||||
if (len) printf("\n");
|
||||
}
|
||||
if (dir == DIR_R2I) ssl->extensions->client_certificate_type = certificate_type; // Server sets the client_certificate_type
|
||||
}
|
||||
|
||||
static int decode_extension_server_certificate_type(ssl,dir,seg,data)
|
||||
ssl_obj *ssl;
|
||||
int dir;
|
||||
segment *seg;
|
||||
Data *data;
|
||||
{
|
||||
int r;
|
||||
UINT4 len, certificate_type;
|
||||
SSL_DECODE_UINT16(ssl, "extensions length", 0, data, &len);
|
||||
LF;
|
||||
if (dir == DIR_I2R) SSL_DECODE_UINT8(ssl, "server certificates length", 0, data, &len);//client sends certificates<..>
|
||||
while (len) {
|
||||
SSL_DECODE_ENUM(ssl,"certificate type",1,tls13_certificate_types,SSL_PRINT_ALL,data, &certificate_type);
|
||||
len -= 1;
|
||||
data += 1;
|
||||
if (len) printf("\n");
|
||||
}
|
||||
if (dir == DIR_R2I) ssl->extensions->server_certificate_type = certificate_type; // Server sets the server_certificate_type
|
||||
}
|
||||
|
||||
decoder extension_decoder[] = {
|
||||
{
|
||||
0,
|
||||
|
@ -3011,12 +3209,12 @@ decoder extension_decoder[] = {
|
|||
{
|
||||
19,
|
||||
"client_certificate_type",
|
||||
decode_extension
|
||||
decode_extension_client_certificate_type
|
||||
},
|
||||
{
|
||||
20,
|
||||
"server_certificate_type",
|
||||
decode_extension
|
||||
decode_extension_server_certificate_type
|
||||
},
|
||||
{
|
||||
21,
|
||||
|
@ -3126,7 +3324,7 @@ decoder extension_decoder[] = {
|
|||
{
|
||||
43,
|
||||
"supported_versions",
|
||||
decode_extension
|
||||
decode_extension_supported_versions
|
||||
},
|
||||
{
|
||||
44,
|
||||
|
@ -3193,7 +3391,6 @@ decoder extension_decoder[] = {
|
|||
"renegotiation_info",
|
||||
decode_extension
|
||||
},
|
||||
|
||||
{-1}
|
||||
};
|
||||
|
||||
|
|
|
@ -70,6 +70,8 @@ typedef struct d_queue_ {
|
|||
typedef struct ssl_extensions_ {
|
||||
int encrypt_then_mac;
|
||||
int extended_master_secret;
|
||||
int client_certificate_type;
|
||||
int server_certificate_type;
|
||||
} ssl_extensions;
|
||||
|
||||
typedef struct ssl_obj_ {
|
||||
|
@ -135,6 +137,7 @@ typedef struct decoder_ {
|
|||
#define TLSV1_VERSION 0x301
|
||||
#define TLSV11_VERSION 0x302
|
||||
#define TLSV12_VERSION 0x303
|
||||
#define TLSV13_VERSION 0x304
|
||||
|
||||
/*State defines*/
|
||||
#define SSL_ST_SENT_NOTHING 0
|
||||
|
|
122
ssl/ssl_rec.c
122
ssl/ssl_rec.c
|
@ -53,10 +53,12 @@
|
|||
#include <openssl/ssl.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
#include "ssldecode.h"
|
||||
#include "ssl_rec.h"
|
||||
|
||||
|
||||
struct ssl_rec_decoder_ {
|
||||
SSL_CipherSuite *cs;
|
||||
Data *mac_key;
|
||||
|
@ -65,10 +67,9 @@ struct ssl_rec_decoder_ {
|
|||
#ifdef OPENSSL
|
||||
EVP_CIPHER_CTX *evp;
|
||||
#endif
|
||||
UINT4 seq;
|
||||
UINT8 seq;
|
||||
};
|
||||
|
||||
|
||||
char *digests[]={
|
||||
"MD5",
|
||||
"SHA1",
|
||||
|
@ -92,7 +93,10 @@ char *ciphers[]={
|
|||
"SEED",
|
||||
NULL,
|
||||
"aes-128-gcm",
|
||||
"aes-256-gcm"
|
||||
"aes-256-gcm",
|
||||
"ChaCha20-Poly1305",
|
||||
"aes-128-ccm",
|
||||
"aes-128-ccm", // for ccm 8, uses the same cipher
|
||||
};
|
||||
|
||||
|
||||
|
@ -100,9 +104,9 @@ static int tls_check_mac PROTO_LIST((ssl_rec_decoder *d,int ct,
|
|||
int ver,UCHAR *data,UINT4 datalen,UCHAR *iv,UINT4 ivlen,UCHAR *mac));
|
||||
static int fmt_seq PROTO_LIST((UINT4 num,UCHAR *buf));
|
||||
|
||||
int ssl_create_rec_decoder(dp,cs,mk,sk,iv)
|
||||
int ssl_create_rec_decoder(dp,ssl,mk,sk,iv)
|
||||
ssl_rec_decoder **dp;
|
||||
SSL_CipherSuite *cs;
|
||||
ssl_obj *ssl;
|
||||
UCHAR *mk;
|
||||
UCHAR *sk;
|
||||
UCHAR *iv;
|
||||
|
@ -111,10 +115,11 @@ int ssl_create_rec_decoder(dp,cs,mk,sk,iv)
|
|||
ssl_rec_decoder *dec=0;
|
||||
#ifdef OPENSSL
|
||||
const EVP_CIPHER *ciph=0;
|
||||
int iv_len = ssl->version == TLSV13_VERSION?12:ssl->cs->block;
|
||||
|
||||
/* Find the SSLeay cipher */
|
||||
if(cs->enc!=ENC_NULL){
|
||||
ciph=(EVP_CIPHER *)EVP_get_cipherbyname(ciphers[cs->enc-0x30]);
|
||||
if(ssl->cs->enc!=ENC_NULL){
|
||||
ciph=(EVP_CIPHER *)EVP_get_cipherbyname(ciphers[ssl->cs->enc-0x30]);
|
||||
if(!ciph)
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
@ -125,28 +130,28 @@ int ssl_create_rec_decoder(dp,cs,mk,sk,iv)
|
|||
if(!(dec=(ssl_rec_decoder *)calloc(1,sizeof(ssl_rec_decoder))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
dec->cs=cs;
|
||||
dec->cs=ssl->cs;
|
||||
|
||||
if((r=r_data_alloc(&dec->mac_key,cs->dig_len)))
|
||||
if((r=r_data_alloc(&dec->mac_key,ssl->cs->dig_len)))
|
||||
ABORT(r);
|
||||
|
||||
if((r=r_data_alloc(&dec->implicit_iv,cs->block)))
|
||||
if((r=r_data_alloc(&dec->implicit_iv,iv_len)))
|
||||
ABORT(r);
|
||||
memcpy(dec->implicit_iv->data,iv,cs->block);
|
||||
memcpy(dec->implicit_iv->data,iv, iv_len);
|
||||
|
||||
if((r=r_data_create(&dec->write_key,sk,cs->eff_bits/8)))
|
||||
if((r=r_data_create(&dec->write_key,sk,ssl->cs->eff_bits/8)))
|
||||
ABORT(r);
|
||||
|
||||
/*
|
||||
This is necessary for AEAD ciphers, because we must wait to fully initialize the cipher
|
||||
in order to include the implicit IV
|
||||
*/
|
||||
if(IS_AEAD_CIPHER(cs)){
|
||||
if(IS_AEAD_CIPHER(ssl->cs)){
|
||||
sk=NULL;
|
||||
iv=NULL;
|
||||
}
|
||||
else
|
||||
memcpy(dec->mac_key->data,mk,cs->dig_len);
|
||||
memcpy(dec->mac_key->data,mk,ssl->cs->dig_len);
|
||||
|
||||
if(!(dec->evp=EVP_CIPHER_CTX_new()))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
@ -190,6 +195,95 @@ int ssl_destroy_rec_decoder(dp)
|
|||
#define MSB(a) ((a>>8)&0xff)
|
||||
#define LSB(a) (a&0xff)
|
||||
|
||||
int tls13_update_rec_key(d,newkey,newiv)
|
||||
ssl_rec_decoder *d;
|
||||
UCHAR *newkey;
|
||||
UCHAR *newiv;
|
||||
{
|
||||
d->write_key->data = newkey;
|
||||
d->implicit_iv->data = newiv;
|
||||
d->seq = 0;
|
||||
}
|
||||
|
||||
int tls13_decode_rec_data(ssl,d,ct,version,in,inl,out,outl)
|
||||
ssl_obj *ssl;
|
||||
ssl_rec_decoder *d;
|
||||
int ct;
|
||||
int version;
|
||||
UCHAR *in;
|
||||
int inl;
|
||||
UCHAR *out;
|
||||
int *outl;
|
||||
{
|
||||
int pad,i;
|
||||
int r,encpadl,x,_status=0;
|
||||
UCHAR aad[5],aead_nonce[12], *tag;
|
||||
int taglen = d->cs->enc==ENC_AES128_CCM_8?8:16;
|
||||
CRDUMP("CipherText",in,inl);
|
||||
CRDUMPD("KEY",d->write_key);
|
||||
CRDUMPD("IV",d->implicit_iv);
|
||||
if (!IS_AEAD_CIPHER(d->cs)){
|
||||
fprintf(stderr, "Non aead cipher in tls13\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
memcpy(aead_nonce, d->implicit_iv->data, 12);
|
||||
for (i = 0; i < 8; i++) { // AEAD NONCE according to RFC TLS1.3
|
||||
aead_nonce[12 - 1 - i] ^= ((d->seq >> (i * 8)) & 0xFF);
|
||||
}
|
||||
d->seq++;
|
||||
CRDUMP("NONCE",aead_nonce,12);
|
||||
tag = in+(inl-taglen);
|
||||
CRDUMP("Tag", tag, taglen);
|
||||
|
||||
aad[0] = ct;
|
||||
aad[1] = 0x03;
|
||||
aad[2] = 0x03;
|
||||
aad[3] = MSB(inl);
|
||||
aad[4] = LSB(inl);
|
||||
CRDUMP("AAD",aad,5);
|
||||
inl-=taglen;
|
||||
|
||||
if (!EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL)) {
|
||||
fprintf(stderr, "Unable to set ivlen\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
if (IS_CCM_CIPHER(d->cs) && !EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_AEAD_SET_TAG, taglen, tag)) {
|
||||
fprintf(stderr, "Unable to set tag for ccm cipher\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
if(!EVP_DecryptInit_ex(d->evp,NULL,NULL,d->write_key->data,aead_nonce)){
|
||||
fprintf(stderr,"Unable to init evp1\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
if (IS_CCM_CIPHER(d->cs) && !EVP_DecryptUpdate(d->evp,NULL,outl,NULL,inl)){
|
||||
fprintf(stderr,"Unable to update data length\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
if (!EVP_DecryptUpdate(d->evp,NULL,outl,aad,5)){
|
||||
fprintf(stderr,"Unable to update aad\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
CRDUMP("Real CipherText", in, inl);
|
||||
if (!EVP_DecryptUpdate(d->evp,out,outl,in,inl)){
|
||||
fprintf(stderr,"Unable to update with CipherText\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
if (!IS_CCM_CIPHER(d->cs) && (!EVP_CIPHER_CTX_ctrl(d->evp,EVP_CTRL_GCM_SET_TAG,taglen,tag) || !EVP_DecryptFinal(d->evp,NULL,&x))) {
|
||||
fprintf(stderr,"BAD MAC\n");
|
||||
ABORT(SSL_BAD_MAC);
|
||||
}
|
||||
|
||||
abort:
|
||||
ERR_print_errors_fp(stderr);
|
||||
return _status;
|
||||
}
|
||||
|
||||
int ssl_decode_rec_data(ssl,d,ct,version,in,inl,out,outl)
|
||||
ssl_obj *ssl;
|
||||
ssl_rec_decoder *d;
|
||||
|
|
|
@ -51,13 +51,16 @@ typedef struct ssl_rec_decoder_ ssl_rec_decoder;
|
|||
|
||||
int ssl_destroy_rec_decoder PROTO_LIST((ssl_rec_decoder **dp));
|
||||
int ssl_create_rec_decoder PROTO_LIST((ssl_rec_decoder **dp,
|
||||
SSL_CipherSuite *cs,UCHAR *mk,UCHAR *sk,UCHAR *iv));
|
||||
ssl_obj *ssl,UCHAR *mk,UCHAR *sk,UCHAR *iv));
|
||||
int ssl_decode_rec_data PROTO_LIST((ssl_obj *ssl,ssl_rec_decoder *d,
|
||||
int ct,int version,UCHAR *in,int inl,UCHAR *out,int *outl));
|
||||
int tls13_decode_rec_data PROTO_LIST((ssl_obj *ssl,ssl_rec_decoder *d,int ct,int version,UCHAR *in,int inl,UCHAR *out,int *outl));
|
||||
int tls13_update_rec_key PROTO_LIST((ssl_rec_decoder *d,UCHAR *newkey, UCHAR *newiv));
|
||||
|
||||
int ssl3_check_mac(ssl_rec_decoder *d, int ct, int ver, UCHAR *data,
|
||||
UINT4 datalen, UCHAR *mac);
|
||||
|
||||
#define IS_AEAD_CIPHER(cs) (cs->enc==0x3b||cs->enc==0x3c)
|
||||
#define IS_AEAD_CIPHER(cs) (cs->enc==0x3b||cs->enc==0x3c||cs->enc==0x3d||cs->enc==0x3e||cs->enc==0x3f)
|
||||
#define IS_CCM_CIPHER(cs) (cs->enc==0x3e||cs->enc==0x3f)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -79,6 +79,9 @@ typedef struct SSL_CipherSuite_ {
|
|||
#define ENC_NULL 0x3a
|
||||
#define ENC_AES128_GCM 0x3b
|
||||
#define ENC_AES256_GCM 0x3c
|
||||
#define ENC_CHACHA20_POLY1305 0x3d
|
||||
#define ENC_AES128_CCM 0x3e
|
||||
#define ENC_AES128_CCM_8 0x3f
|
||||
|
||||
#define DIG_MD5 0x40
|
||||
#define DIG_SHA 0x41
|
||||
|
|
341
ssl/ssldecode.c
341
ssl/ssldecode.c
|
@ -48,6 +48,8 @@
|
|||
#include "sslprint.h"
|
||||
#include "ssl.enums.h"
|
||||
#ifdef OPENSSL
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/evp.h>
|
||||
|
@ -91,6 +93,10 @@ struct ssl_decoder_ {
|
|||
int ephemeral_rsa;
|
||||
Data *PMS;
|
||||
Data *MS;
|
||||
Data *SHTS;//Server Handshake traffic secret
|
||||
Data *CHTS;//Client Handshake traffic secret
|
||||
Data *STS;//Server traffic Secret
|
||||
Data *CTS;//Client traffic secret
|
||||
Data *handshake_messages;
|
||||
Data *session_hash;
|
||||
ssl_rec_decoder *c_to_s;
|
||||
|
@ -115,7 +121,7 @@ static int ssl_generate_keying_material PROTO_LIST((ssl_obj *ssl,
|
|||
ssl_decoder *d));
|
||||
static int ssl_generate_session_hash PROTO_LIST((ssl_obj *ssl,
|
||||
ssl_decoder *d));
|
||||
static int ssl_read_key_log_file PROTO_LIST((ssl_decoder *d));
|
||||
static int ssl_read_key_log_file PROTO_LIST((ssl_obj* obj,ssl_decoder *d));
|
||||
#endif
|
||||
|
||||
static int ssl_create_session_lookup_key PROTO_LIST((ssl_obj *ssl,
|
||||
|
@ -196,6 +202,7 @@ int ssl_decode_ctx_destroy(dp)
|
|||
{
|
||||
#ifdef OPENSSL
|
||||
ssl_decode_ctx *d = *dp;
|
||||
if (!d) return 0;
|
||||
if(d->ssl_key_log_file) {
|
||||
fclose(d->ssl_key_log_file);
|
||||
}
|
||||
|
@ -320,19 +327,23 @@ int ssl_process_server_session_id(ssl,d,msg,len)
|
|||
|
||||
INIT_DATA(idd,msg,len);
|
||||
|
||||
/* First check to see if the client tried to restore */
|
||||
if(d->session_id){
|
||||
/* Now check to see if we restored */
|
||||
if((r=r_data_compare(&idd,d->session_id)))
|
||||
ABORT(r);
|
||||
if (ssl->version==TLSV13_VERSION){
|
||||
// No need to save/restore session in tls1.3 since the only way of decrypting is through log file
|
||||
} else {
|
||||
/* First check to see if the client tried to restore */
|
||||
if(d->session_id){
|
||||
/* Now check to see if we restored */
|
||||
if((r=r_data_compare(&idd,d->session_id)))
|
||||
ABORT(r);
|
||||
|
||||
/* Now try to look up the session. We may not be able
|
||||
to find it if, for instance, the original session
|
||||
was initiated with something other than static RSA */
|
||||
if((r=ssl_restore_session(ssl,d)))
|
||||
ABORT(r);
|
||||
/* Now try to look up the session. We may not be able
|
||||
to find it if, for instance, the original session
|
||||
was initiated with something other than static RSA */
|
||||
if((r=ssl_restore_session(ssl,d)))
|
||||
ABORT(r);
|
||||
|
||||
restored=1;
|
||||
restored=1;
|
||||
}
|
||||
}
|
||||
|
||||
_status=0;
|
||||
|
@ -365,7 +376,7 @@ int ssl_process_client_session_id(ssl,d,msg,len)
|
|||
//todo: better save and destroy only when successfully read key log
|
||||
r_data_destroy(&d->MS);
|
||||
|
||||
if(d->ctx->ssl_key_log_file && (ssl_read_key_log_file(d)==0) && d->MS)
|
||||
if(d->ctx->ssl_key_log_file && (ssl_read_key_log_file(ssl, d)==0) && d->MS)
|
||||
{
|
||||
//we found master secret for session in keylog
|
||||
//try to save session
|
||||
|
@ -387,24 +398,37 @@ int ssl_process_client_session_id(ssl,d,msg,len)
|
|||
#endif
|
||||
}
|
||||
|
||||
int ssl_process_handshake_finished(ssl_obj* ssl,ssl_decoder *dec, Data *data){
|
||||
if (ssl->version==TLSV13_VERSION){
|
||||
if (ssl->direction==DIR_I2R){ // Change from handshake decoder to data traffic decoder
|
||||
dec->c_to_s = dec->c_to_s_n;
|
||||
dec->c_to_s_n = 0;
|
||||
} else {
|
||||
dec->s_to_c = dec->s_to_c_n;
|
||||
dec->s_to_c_n = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ssl_process_change_cipher_spec(ssl,d,direction)
|
||||
ssl_obj *ssl;
|
||||
ssl_decoder *d;
|
||||
int direction;
|
||||
{
|
||||
#ifdef OPENSSL
|
||||
if(direction==DIR_I2R){
|
||||
d->c_to_s=d->c_to_s_n;
|
||||
d->c_to_s_n=0;
|
||||
if(d->c_to_s) ssl->process_ciphertext |= direction;
|
||||
#ifdef OPENSSL
|
||||
if (ssl->version!=TLSV13_VERSION){
|
||||
if(direction==DIR_I2R){
|
||||
d->c_to_s=d->c_to_s_n;
|
||||
d->c_to_s_n=0;
|
||||
if(d->c_to_s) ssl->process_ciphertext |= direction;
|
||||
}
|
||||
else {
|
||||
d->s_to_c=d->s_to_c_n;
|
||||
d->s_to_c_n=0;
|
||||
if(d->s_to_c) ssl->process_ciphertext |= direction;
|
||||
}
|
||||
}
|
||||
else{
|
||||
d->s_to_c=d->s_to_c_n;
|
||||
d->s_to_c_n=0;
|
||||
if(d->s_to_c) ssl->process_ciphertext |= direction;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
int ssl_decode_record(ssl,dec,direction,ct,version,d)
|
||||
|
@ -426,8 +450,11 @@ int ssl_decode_record(ssl,dec,direction,ct,version,d)
|
|||
else
|
||||
rd=0;
|
||||
state=(direction==DIR_I2R)?ssl->i_state:ssl->r_state;
|
||||
|
||||
if(!rd){
|
||||
|
||||
if (ssl->version == TLSV13_VERSION && ct != 23) { // Only type 23 is encrypted in tls1.3
|
||||
ssl->record_encryption = REC_PLAINTEXT;
|
||||
return 0;
|
||||
} else if(!rd){
|
||||
if(state & SSL_ST_SENT_CHANGE_CIPHER_SPEC){
|
||||
ssl->record_encryption=REC_CIPHERTEXT;
|
||||
return(SSL_NO_DECRYPT);
|
||||
|
@ -443,7 +470,12 @@ int ssl_decode_record(ssl,dec,direction,ct,version,d)
|
|||
if(!(out=(UCHAR *)malloc(d->len)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
if((r=ssl_decode_rec_data(ssl,rd,ct,version,d->data,d->len,out,&outl))){
|
||||
if (ssl->version==TLSV13_VERSION){
|
||||
r=tls13_decode_rec_data(ssl,rd,ct,version,d->data,d->len,out,&outl);
|
||||
} else {
|
||||
r=ssl_decode_rec_data(ssl,rd,ct,version,d->data,d->len,out,&outl);
|
||||
}
|
||||
if(r) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
|
@ -620,7 +652,7 @@ int ssl_process_client_key_exchange(ssl,d,msg,len)
|
|||
r_data_destroy(&d->MS);
|
||||
|
||||
if(!d->ctx->ssl_key_log_file ||
|
||||
ssl_read_key_log_file(d) ||
|
||||
ssl_read_key_log_file(ssl,d) ||
|
||||
!d->MS){
|
||||
if(ssl->cs->kex!=KEX_RSA)
|
||||
return(-1);
|
||||
|
@ -1070,10 +1102,10 @@ static int ssl_generate_keying_material(ssl,d)
|
|||
}
|
||||
|
||||
if((r=ssl_create_rec_decoder(&d->c_to_s_n,
|
||||
ssl->cs,c_mk,c_wk,c_iv)))
|
||||
ssl,c_mk,c_wk,c_iv)))
|
||||
ABORT(r);
|
||||
if((r=ssl_create_rec_decoder(&d->s_to_c_n,
|
||||
ssl->cs,s_mk,s_wk,s_iv)))
|
||||
ssl,s_mk,s_wk,s_iv)))
|
||||
ABORT(r);
|
||||
|
||||
|
||||
|
@ -1086,6 +1118,175 @@ static int ssl_generate_keying_material(ssl,d)
|
|||
return(_status);
|
||||
}
|
||||
|
||||
static int hkdf_expand_label(ssl,d,secret,label,context,length,out)
|
||||
ssl_obj *ssl;
|
||||
ssl_decoder *d;
|
||||
Data *secret;
|
||||
char *label;
|
||||
Data *context;
|
||||
uint16_t length;
|
||||
UCHAR **out;
|
||||
{
|
||||
int r;
|
||||
size_t outlen = length;
|
||||
EVP_PKEY_CTX *pctx;
|
||||
|
||||
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
|
||||
|
||||
Data hkdf_label;
|
||||
UCHAR *ptr;
|
||||
|
||||
//Construct HkdfLabel
|
||||
hkdf_label.data = ptr = malloc(512);
|
||||
*(uint16_t*)ptr = ntohs(length);
|
||||
ptr+=2;
|
||||
*(uint8_t*)ptr++ = 6+(label?strlen(label):0);
|
||||
memcpy(ptr, "tls13 ", 6);
|
||||
ptr+=6;
|
||||
if (label) {
|
||||
memcpy(ptr, label, strlen(label));
|
||||
ptr+=strlen(label);
|
||||
}
|
||||
*(uint8_t*)ptr++ = context?context->len:0;
|
||||
if (context) {
|
||||
memcpy(ptr, context->data, context->len);
|
||||
ptr+=context->len;
|
||||
}
|
||||
hkdf_label.len = ptr - hkdf_label.data;
|
||||
CRDUMPD("hkdf_label", &hkdf_label);
|
||||
// Load parameters
|
||||
*out = malloc(length);
|
||||
if (EVP_PKEY_derive_init(pctx) <= 0) {
|
||||
fprintf(stderr, "EVP_PKEY_derive_init failed\n");
|
||||
}
|
||||
/* Error */
|
||||
if (EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY)<=0) {
|
||||
fprintf(stderr, "EVP_PKEY_CTX_hkdf_mode failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_get_digestbyname(digests[ssl->cs->dig-0x40])) <= 0) {
|
||||
fprintf(stderr, "EVP_PKEY_CTX_set_hkdf_md failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (EVP_PKEY_CTX_set1_hkdf_key(pctx, secret->data, secret->len) <= 0) {
|
||||
fprintf(stderr, "EVP_PKEY_CTX_set_hkdf_md failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (EVP_PKEY_CTX_add1_hkdf_info(pctx, hkdf_label.data, hkdf_label.len) <= 0) {
|
||||
fprintf(stderr, "EVP_PKEY_CTX_add1_hkdf_info failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (EVP_PKEY_derive(pctx, *out, &outlen) <= 0) {
|
||||
fprintf(stderr, "EVP_PKEY_derive failed\n");
|
||||
goto abort;
|
||||
}
|
||||
|
||||
CRDUMP("out_hkdf", *out, outlen);
|
||||
return 0;
|
||||
abort:
|
||||
ERR_print_errors_fp(stderr);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Will update the keys for the particular direction
|
||||
int ssl_tls13_update_keying_material(ssl,d,direction)
|
||||
ssl_obj *ssl;
|
||||
ssl_decoder *d;
|
||||
int direction;
|
||||
{
|
||||
Data *secret;
|
||||
ssl_rec_decoder *decoder;
|
||||
UCHAR *newsecret;
|
||||
UCHAR *newkey;
|
||||
UCHAR *newiv;
|
||||
|
||||
if (direction == DIR_I2R) {
|
||||
secret = d->CTS;
|
||||
decoder = d->c_to_s;
|
||||
} else {
|
||||
secret = d->STS;
|
||||
decoder = d->s_to_c;
|
||||
}
|
||||
hkdf_expand_label(ssl, d, secret, "traffic upd", NULL, ssl->cs->dig_len, &newsecret);
|
||||
secret->data = newsecret;
|
||||
hkdf_expand_label(ssl, d, secret, "key", NULL, ssl->cs->eff_bits/8, &newkey);
|
||||
hkdf_expand_label(ssl, d, secret, "iv", NULL, 12, &newiv);
|
||||
tls13_update_rec_key(decoder,newkey,newiv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssl_tls13_generate_keying_material(ssl,d)
|
||||
ssl_obj* ssl;
|
||||
ssl_decoder *d;
|
||||
{
|
||||
int r,_status;
|
||||
Data out;
|
||||
UCHAR *s_wk_h,*s_iv_h,*c_wk_h,*c_iv_h,
|
||||
*s_wk,*s_iv,*c_wk,*c_iv;
|
||||
if (!(d->ctx->ssl_key_log_file && ssl_read_key_log_file(ssl, d)==0 &&
|
||||
d->SHTS && d->CHTS && d->STS && d->CTS)){
|
||||
ABORT(-1);
|
||||
}
|
||||
// It is 12 for all ciphers
|
||||
if (hkdf_expand_label(ssl, d, d->SHTS, "key", NULL, ssl->cs->eff_bits/8, &s_wk_h)) {
|
||||
fprintf(stderr, "s_wk_h hkdf_expand_label failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (hkdf_expand_label(ssl, d, d->SHTS, "iv", NULL, 12, &s_iv_h)) {
|
||||
fprintf(stderr, "s_iv_h hkdf_expand_label failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (hkdf_expand_label(ssl, d, d->CHTS, "key", NULL, ssl->cs->eff_bits/8, &c_wk_h)) {
|
||||
fprintf(stderr, "c_wk_h hkdf_expand_label failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (hkdf_expand_label(ssl, d, d->CHTS, "iv", NULL, 12, &c_iv_h)) {
|
||||
fprintf(stderr, "c_iv_h hkdf_expand_label failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (hkdf_expand_label(ssl, d, d->STS, "key", NULL, ssl->cs->eff_bits/8, &s_wk)) {
|
||||
fprintf(stderr, "s_wk hkdf_expand_label failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (hkdf_expand_label(ssl, d, d->STS, "iv", NULL, 12, &s_iv)) {
|
||||
fprintf(stderr, "s_iv hkdf_expand_label failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (hkdf_expand_label(ssl, d, d->CTS, "key", NULL, ssl->cs->eff_bits/8, &c_wk)) {
|
||||
fprintf(stderr, "c_wk hkdf_expand_label failed\n");
|
||||
goto abort;
|
||||
}
|
||||
if (hkdf_expand_label(ssl, d, d->CTS, "iv", NULL, 12, &c_iv)) {
|
||||
fprintf(stderr, "c_iv hkdf_expand_label failed\n");
|
||||
goto abort;
|
||||
}
|
||||
CRDUMP("Server Handshake Write key", s_wk_h,ssl->cs->eff_bits/8 );
|
||||
CRDUMP("Server Handshake IV", s_iv_h, 12);
|
||||
CRDUMP("Client Handshake Write key", c_wk_h, ssl->cs->eff_bits/8);
|
||||
CRDUMP("Client Handshake IV", c_iv_h,12);
|
||||
CRDUMP("Server Write key", s_wk,ssl->cs->eff_bits/8);
|
||||
CRDUMP("Server IV", s_iv,12);
|
||||
CRDUMP("Client Write key",c_wk, ssl->cs->eff_bits/8);
|
||||
CRDUMP("Client IV", c_iv,12);
|
||||
|
||||
if((r=ssl_create_rec_decoder(&d->c_to_s_n,
|
||||
ssl,NULL,c_wk,c_iv)))
|
||||
ABORT(r);
|
||||
if((r=ssl_create_rec_decoder(&d->s_to_c_n,
|
||||
ssl,NULL,s_wk,s_iv)))
|
||||
ABORT(r);
|
||||
if((r=ssl_create_rec_decoder(&d->c_to_s,
|
||||
ssl,NULL,c_wk_h,c_iv_h)))
|
||||
ABORT(r);
|
||||
if((r=ssl_create_rec_decoder(&d->s_to_c,
|
||||
ssl,NULL,s_wk_h,s_iv_h)))
|
||||
ABORT(r);
|
||||
return 0;
|
||||
abort:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int ssl_generate_session_hash(ssl,d)
|
||||
ssl_obj *ssl;
|
||||
ssl_decoder *d;
|
||||
|
@ -1134,36 +1335,64 @@ static int ssl_generate_session_hash(ssl,d)
|
|||
return(_status);
|
||||
}
|
||||
|
||||
static int ssl_read_key_log_file(d)
|
||||
static int read_hex_string(char *str, UCHAR *buf, int n) {
|
||||
unsigned int t;
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (sscanf(str + i * 2, "%02x", &t) != 1)
|
||||
return -1;
|
||||
buf[i] = (char)t;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int ssl_read_key_log_file(ssl,d)
|
||||
ssl_obj *ssl;
|
||||
ssl_decoder *d;
|
||||
{
|
||||
int r,_status,n,i;
|
||||
unsigned int t;
|
||||
size_t l=0;
|
||||
char *line,*label_data;
|
||||
|
||||
while ((n=getline(&line,&l,d->ctx->ssl_key_log_file))!=-1) {
|
||||
if(n==(d->client_random->len*2)+112 &&
|
||||
!strncmp(line,"CLIENT_RANDOM",13)) {
|
||||
|
||||
if(!(label_data=malloc((d->client_random->len*2)+1)))
|
||||
ABORT(r);
|
||||
|
||||
for(i=0;i<d->client_random->len;i++)
|
||||
if(snprintf(label_data+(i*2),3,"%02x",d->client_random->data[i])!=2)
|
||||
ABORT(r);
|
||||
|
||||
if(STRNICMP(line+14,label_data,64))
|
||||
continue;
|
||||
|
||||
if((r=r_data_alloc(&d->MS,48)))
|
||||
ABORT(r);
|
||||
|
||||
for(i=0; i < d->MS->len; i++) {
|
||||
if(sscanf(line+14+65+(i*2),"%2x",&t)!=1)
|
||||
ABORT(r);
|
||||
*(d->MS->data+i)=(char)t;
|
||||
}
|
||||
char *line, *d_client_random, *label, *client_random, *secret;
|
||||
if (ssl->version==TLSV13_VERSION && !ssl->cs)// ssl->cs is not set when called from ssl_process_client_session_id
|
||||
ABORT(r);
|
||||
if (!(d_client_random = malloc((d->client_random->len * 2) + 1)))
|
||||
ABORT(r);
|
||||
for (i = 0; i < d->client_random->len; i++)
|
||||
if (snprintf(d_client_random + (i * 2), 3, "%02x", d->client_random->data[i]) != 2)
|
||||
ABORT(r);
|
||||
while ((n = getline(&line, &l, d->ctx->ssl_key_log_file)) != -1) {
|
||||
if (line[n-1] =='\n') line[n-1] = '\0';
|
||||
if (!(label=strtok(line, " "))) continue;
|
||||
if (!(client_random=strtok(NULL, " ")) || strlen(client_random)!=64 || STRNICMP(client_random, d_client_random, 64)) continue;
|
||||
secret=strtok(NULL, " ");
|
||||
if (!(secret) || strlen(secret)!=(ssl->version==TLSV13_VERSION?ssl->cs->dig_len*2:96)) continue;
|
||||
if (!strncmp(label, "CLIENT_RANDOM", 13)) {
|
||||
if ((r=r_data_alloc(&d->MS, 48)))
|
||||
ABORT(r);
|
||||
if (read_hex_string(secret, d->MS->data, 48))
|
||||
ABORT(r);
|
||||
}
|
||||
if (ssl->version!=TLSV13_VERSION) continue;
|
||||
if (!strncmp(label, "SERVER_HANDSHAKE_TRAFFIC_SECRET", 31)){
|
||||
if ((r=r_data_alloc(&d->SHTS, ssl->cs->dig_len)))
|
||||
ABORT(r);
|
||||
if (read_hex_string(secret, d->SHTS->data, ssl->cs->dig_len))
|
||||
ABORT(r);
|
||||
} else if (!strncmp(label, "CLIENT_HANDSHAKE_TRAFFIC_SECRET", 31)){
|
||||
if ((r=r_data_alloc(&d->CHTS, ssl->cs->dig_len)))
|
||||
ABORT(r);
|
||||
if (read_hex_string(secret, d->CHTS->data, ssl->cs->dig_len))
|
||||
ABORT(r);
|
||||
} else if (!strncmp(label, "SERVER_TRAFFIC_SECRET_0", 23)){
|
||||
if ((r=r_data_alloc(&d->STS, ssl->cs->dig_len)))
|
||||
ABORT(r);
|
||||
if (read_hex_string(secret, d->STS->data, ssl->cs->dig_len))
|
||||
ABORT(r);
|
||||
} else if (!strncmp(label, "CLIENT_TRAFFIC_SECRET_0", 23)){
|
||||
if ((r=r_data_alloc(&d->CTS, ssl->cs->dig_len)))
|
||||
ABORT(r);
|
||||
if (read_hex_string(secret, d->CTS->data, ssl->cs->dig_len))
|
||||
ABORT(r);
|
||||
}
|
||||
/*
|
||||
Eventually add support for other labels defined here:
|
||||
|
|
|
@ -73,6 +73,9 @@ int ssl_update_handshake_messages PROTO_LIST((ssl_obj *ssl,
|
|||
Data *data));
|
||||
int ssl_decode_record PROTO_LIST((ssl_obj *ssl,ssl_decoder *dec,int direction,
|
||||
int ct,int version,Data *d));
|
||||
int ssl_tls13_generate_keying_material PROTO_LIST((ssl_obj *obj,ssl_decoder *dec));
|
||||
int ssl_process_handshake_finished PROTO_LIST((ssl_obj* ssl,ssl_decoder *dec, Data *data));
|
||||
int ssl_tls13_update_keying_material PROTO_LIST((ssl_obj *ssl,ssl_decoder *dec,int dir));
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -268,18 +268,16 @@ int ssl_expand_record(ssl,q,direction,data,len)
|
|||
explain(ssl," Short record: %u bytes available (expecting: %u)\n",length,d.len);
|
||||
return(0);
|
||||
}
|
||||
version = ssl->version ? ssl->version : (vermaj*256+vermin);
|
||||
|
||||
P_(P_RH){
|
||||
explain(ssl," V%d.%d(%d)",vermaj,vermin,length);
|
||||
explain(ssl," V%d.%d(%d)",(version>>8)&0xff,version&0xff,length);
|
||||
json_object_object_add(jobj, "record_len", json_object_new_int(length));
|
||||
snprintf(verstr,8,"%d.%d",vermaj,vermin);
|
||||
snprintf(verstr,8,"%d.%d",(version>>8)&0xff,version&0xff);
|
||||
json_object_object_add(jobj, "record_ver", json_object_new_string(verstr));
|
||||
}
|
||||
|
||||
version=vermaj*256+vermin;
|
||||
|
||||
r=ssl_decode_record(ssl,ssl->decoder,direction,ct,version,&d);
|
||||
|
||||
r = ssl_decode_record(ssl, ssl->decoder, direction, ct, version, &d);
|
||||
if(r==SSL_BAD_MAC){
|
||||
explain(ssl," bad MAC\n");
|
||||
return(0);
|
||||
|
@ -303,9 +301,15 @@ int ssl_expand_record(ssl,q,direction,data,len)
|
|||
else{
|
||||
//try to save unencrypted data to logger
|
||||
//we must save record with type "application_data" (this is unencrypted data)
|
||||
if ((ct == 23) && (logger)) logger->vtbl->data(ssl->logger_obj,d.data,d.len,direction);
|
||||
|
||||
if((r=ssl_decode_switch(ssl,ContentType_decoder,data[0],direction,q, &d))) {
|
||||
if (ct==23){
|
||||
if (logger) {
|
||||
logger->vtbl->data(ssl->logger_obj,d.data,d.len,direction);
|
||||
}
|
||||
if (ssl->version==TLSV13_VERSION){
|
||||
ct = d.data[--d.len]; // In TLS 1.3 ct is stored in the end for encrypted records
|
||||
}
|
||||
}
|
||||
if((r=ssl_decode_switch(ssl,ContentType_decoder,ct,direction,q, &d))) {
|
||||
if(!(SSL_print_flags & SSL_PRINT_JSON))
|
||||
printf(" unknown record type: %d\n", ct);
|
||||
ERETURN(r);
|
||||
|
|
Loading…
Reference in a new issue