Merge branch 'lord8266-tls1.3'

Ok: Minimal tests to ensure the previous features still worked.
This commit is contained in:
Alexandre Dulaunoy 2023-04-09 10:23:54 +02:00
commit c29e9fad89
Signed by: adulau
GPG key ID: 09E2CD4944E6CBCD
19 changed files with 677 additions and 95 deletions

41
samples/log.txt Normal file
View 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

Binary file not shown.

BIN
samples/tls1.3_aes128.pcap Normal file

Binary file not shown.

Binary file not shown.

BIN
samples/tls1.3_ccm.pcap Normal file

Binary file not shown.

BIN
samples/tls1.3_ccm8.pcap Normal file

Binary file not shown.

BIN
samples/tls1.3_chacha.pcap Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -154,6 +154,11 @@ static SSL_CipherSuite CipherSuites[]={
{195,KEX_DH,SIG_DSS,ENC_CAMELLIA256,16,256,256,DIG_SHA256,32,0}, {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}, {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}, {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}, {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}, {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}, {49155,KEX_DH,SIG_DSS,ENC_3DES,8,192,192,DIG_SHA,20,0},

View file

@ -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); 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); print_data(ssl,&d);
} } else {
else {
LF; LF;
} }
return(0); return(0);
@ -425,8 +426,6 @@ static int decode_HandshakeType_ServerHello(ssl,dir,seg,data)
ja3s_c_str = calloc(6, 1); ja3s_c_str = calloc(6, 1);
snprintf(ja3s_c_str, 6, "%u", ssl->cipher_suite); 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; P_(P_HL) LF;
SSL_DECODE_ENUM(ssl,"compressionMethod",1,compression_method_decoder,P_HL,data,0); 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'; 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) { if(!ja3s_ver_str) {
ja3s_ver_str = calloc(1, 1); ja3s_ver_str = calloc(1, 1);
*ja3s_ver_str = '\0'; *ja3s_ver_str = '\0';
@ -519,18 +526,20 @@ static int decode_HandshakeType_Certificate(ssl,dir,seg,data)
segment *seg; segment *seg;
Data *data; Data *data;
{ {
UINT4 len,exlen,ex;
UINT4 len;
Data cert; Data cert;
int r; int r;
struct json_object *jobj; struct json_object *jobj;
jobj = ssl->cur_json_st; jobj = ssl->cur_json_st;
json_object_object_add(jobj, "handshake_type", json_object_new_string("Certificate")); json_object_object_add(jobj, "handshake_type", json_object_new_string("Certificate"));
extern decoder extension_decoder[];
LF; LF;
ssl_update_handshake_messages(ssl,data); 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); SSL_DECODE_UINT24(ssl,"certificates len",0,data,&len);
json_object_object_add(jobj, "cert_chain", json_object_new_array()); 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); 0,data,&cert);
sslx_print_certificate(ssl,&cert,P_ND); sslx_print_certificate(ssl,&cert,P_ND);
len-=(cert.len + 3); 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); 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) static int decode_HandshakeType_ServerKeyExchange(ssl,dir,seg,data)
ssl_obj *ssl; ssl_obj *ssl;
int dir; int dir;
@ -650,6 +731,7 @@ static int decode_HandshakeType_CertificateVerify(ssl,dir,seg,data)
int r; int r;
UINT4 signature_type;
struct json_object *jobj; struct json_object *jobj;
jobj = ssl->cur_json_st; jobj = ssl->cur_json_st;
@ -657,6 +739,9 @@ static int decode_HandshakeType_CertificateVerify(ssl,dir,seg,data)
LF; LF;
ssl_update_handshake_messages(ssl,data); 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); SSL_DECODE_OPAQUE_ARRAY(ssl,"Signature",-((1<<15)-1),P_HL,data,0);
return(0); return(0);
@ -732,9 +817,22 @@ static int decode_HandshakeType_Finished(ssl,dir,seg,data)
break; break;
} }
ssl_process_handshake_finished(ssl,ssl->decoder,data);
return (0); 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[]={ decoder HandshakeType_decoder[]={
{ {
0, 0,
@ -751,6 +849,16 @@ decoder HandshakeType_decoder[]={
"ServerHello", "ServerHello",
decode_HandshakeType_ServerHello decode_HandshakeType_ServerHello
}, },
{
4,
"SessionTicket",
decode_HandshakeType_SessionTicket
},
{
8,
"EncryptedExtensions",
decode_HandshakeType_EncryptedExtensions
},
{ {
11, 11,
"Certificate", "Certificate",
@ -786,6 +894,11 @@ decoder HandshakeType_decoder[]={
"Finished", "Finished",
decode_HandshakeType_Finished decode_HandshakeType_Finished
}, },
{
24,
"KeyUpdate",
decode_HandshakeType_KeyUpdate
},
{-1} {-1}
}; };
@ -2839,6 +2952,18 @@ static int decode_extension(ssl,dir,seg,data)
return(0); 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") // Extension #10 supported_groups (renamed from "elliptic_curves")
static int decode_extension_supported_groups(ssl,dir,seg,data) static int decode_extension_supported_groups(ssl,dir,seg,data)
ssl_obj *ssl; ssl_obj *ssl;
@ -2856,7 +2981,8 @@ static int decode_extension_supported_groups(ssl,dir,seg,data)
LF; LF;
while(l) { while(l) {
p=data->len; 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) if(!ja3_ec_str)
ja3_ec_str = calloc(7, 1); ja3_ec_str = calloc(7, 1);
else else
@ -2875,6 +3001,11 @@ static int decode_extension_supported_groups(ssl,dir,seg,data)
return(0); 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 // Extension #11 ec_point_formats
static int decode_extension_ec_point_formats(ssl,dir,seg,data) static int decode_extension_ec_point_formats(ssl,dir,seg,data)
ssl_obj *ssl; ssl_obj *ssl;
@ -2892,7 +3023,8 @@ static int decode_extension_ec_point_formats(ssl,dir,seg,data)
LF; LF;
while(l) { while(l) {
p=data->len; 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) if(!ja3_ecp_str)
ja3_ecp_str = calloc(5, 1); ja3_ecp_str = calloc(5, 1);
else else
@ -2912,6 +3044,72 @@ static int decode_extension_ec_point_formats(ssl,dir,seg,data)
return(0); 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[] = { decoder extension_decoder[] = {
{ {
0, 0,
@ -3011,12 +3209,12 @@ decoder extension_decoder[] = {
{ {
19, 19,
"client_certificate_type", "client_certificate_type",
decode_extension decode_extension_client_certificate_type
}, },
{ {
20, 20,
"server_certificate_type", "server_certificate_type",
decode_extension decode_extension_server_certificate_type
}, },
{ {
21, 21,
@ -3126,7 +3324,7 @@ decoder extension_decoder[] = {
{ {
43, 43,
"supported_versions", "supported_versions",
decode_extension decode_extension_supported_versions
}, },
{ {
44, 44,
@ -3193,7 +3391,6 @@ decoder extension_decoder[] = {
"renegotiation_info", "renegotiation_info",
decode_extension decode_extension
}, },
{-1} {-1}
}; };

View file

@ -70,6 +70,8 @@ typedef struct d_queue_ {
typedef struct ssl_extensions_ { typedef struct ssl_extensions_ {
int encrypt_then_mac; int encrypt_then_mac;
int extended_master_secret; int extended_master_secret;
int client_certificate_type;
int server_certificate_type;
} ssl_extensions; } ssl_extensions;
typedef struct ssl_obj_ { typedef struct ssl_obj_ {
@ -135,6 +137,7 @@ typedef struct decoder_ {
#define TLSV1_VERSION 0x301 #define TLSV1_VERSION 0x301
#define TLSV11_VERSION 0x302 #define TLSV11_VERSION 0x302
#define TLSV12_VERSION 0x303 #define TLSV12_VERSION 0x303
#define TLSV13_VERSION 0x304
/*State defines*/ /*State defines*/
#define SSL_ST_SENT_NOTHING 0 #define SSL_ST_SENT_NOTHING 0

View file

@ -53,10 +53,12 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/hmac.h> #include <openssl/hmac.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/err.h>
#endif #endif
#include "ssldecode.h" #include "ssldecode.h"
#include "ssl_rec.h" #include "ssl_rec.h"
struct ssl_rec_decoder_ { struct ssl_rec_decoder_ {
SSL_CipherSuite *cs; SSL_CipherSuite *cs;
Data *mac_key; Data *mac_key;
@ -65,10 +67,9 @@ struct ssl_rec_decoder_ {
#ifdef OPENSSL #ifdef OPENSSL
EVP_CIPHER_CTX *evp; EVP_CIPHER_CTX *evp;
#endif #endif
UINT4 seq; UINT8 seq;
}; };
char *digests[]={ char *digests[]={
"MD5", "MD5",
"SHA1", "SHA1",
@ -92,7 +93,10 @@ char *ciphers[]={
"SEED", "SEED",
NULL, NULL,
"aes-128-gcm", "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)); int ver,UCHAR *data,UINT4 datalen,UCHAR *iv,UINT4 ivlen,UCHAR *mac));
static int fmt_seq PROTO_LIST((UINT4 num,UCHAR *buf)); 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_rec_decoder **dp;
SSL_CipherSuite *cs; ssl_obj *ssl;
UCHAR *mk; UCHAR *mk;
UCHAR *sk; UCHAR *sk;
UCHAR *iv; UCHAR *iv;
@ -111,10 +115,11 @@ int ssl_create_rec_decoder(dp,cs,mk,sk,iv)
ssl_rec_decoder *dec=0; ssl_rec_decoder *dec=0;
#ifdef OPENSSL #ifdef OPENSSL
const EVP_CIPHER *ciph=0; const EVP_CIPHER *ciph=0;
int iv_len = ssl->version == TLSV13_VERSION?12:ssl->cs->block;
/* Find the SSLeay cipher */ /* Find the SSLeay cipher */
if(cs->enc!=ENC_NULL){ if(ssl->cs->enc!=ENC_NULL){
ciph=(EVP_CIPHER *)EVP_get_cipherbyname(ciphers[cs->enc-0x30]); ciph=(EVP_CIPHER *)EVP_get_cipherbyname(ciphers[ssl->cs->enc-0x30]);
if(!ciph) if(!ciph)
ABORT(R_INTERNAL); 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)))) if(!(dec=(ssl_rec_decoder *)calloc(1,sizeof(ssl_rec_decoder))))
ABORT(R_NO_MEMORY); 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); ABORT(r);
if((r=r_data_alloc(&dec->implicit_iv,cs->block))) if((r=r_data_alloc(&dec->implicit_iv,iv_len)))
ABORT(r); 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); ABORT(r);
/* /*
This is necessary for AEAD ciphers, because we must wait to fully initialize the cipher This is necessary for AEAD ciphers, because we must wait to fully initialize the cipher
in order to include the implicit IV in order to include the implicit IV
*/ */
if(IS_AEAD_CIPHER(cs)){ if(IS_AEAD_CIPHER(ssl->cs)){
sk=NULL; sk=NULL;
iv=NULL; iv=NULL;
} }
else 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())) if(!(dec->evp=EVP_CIPHER_CTX_new()))
ABORT(R_NO_MEMORY); ABORT(R_NO_MEMORY);
@ -190,6 +195,95 @@ int ssl_destroy_rec_decoder(dp)
#define MSB(a) ((a>>8)&0xff) #define MSB(a) ((a>>8)&0xff)
#define LSB(a) (a&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) int ssl_decode_rec_data(ssl,d,ct,version,in,inl,out,outl)
ssl_obj *ssl; ssl_obj *ssl;
ssl_rec_decoder *d; ssl_rec_decoder *d;

View file

@ -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_destroy_rec_decoder PROTO_LIST((ssl_rec_decoder **dp));
int ssl_create_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 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 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, int ssl3_check_mac(ssl_rec_decoder *d, int ct, int ver, UCHAR *data,
UINT4 datalen, UCHAR *mac); 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 #endif

View file

@ -79,6 +79,9 @@ typedef struct SSL_CipherSuite_ {
#define ENC_NULL 0x3a #define ENC_NULL 0x3a
#define ENC_AES128_GCM 0x3b #define ENC_AES128_GCM 0x3b
#define ENC_AES256_GCM 0x3c #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_MD5 0x40
#define DIG_SHA 0x41 #define DIG_SHA 0x41

View file

@ -48,6 +48,8 @@
#include "sslprint.h" #include "sslprint.h"
#include "ssl.enums.h" #include "ssl.enums.h"
#ifdef OPENSSL #ifdef OPENSSL
#include <openssl/err.h>
#include <openssl/kdf.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/hmac.h> #include <openssl/hmac.h>
#include <openssl/evp.h> #include <openssl/evp.h>
@ -91,6 +93,10 @@ struct ssl_decoder_ {
int ephemeral_rsa; int ephemeral_rsa;
Data *PMS; Data *PMS;
Data *MS; 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 *handshake_messages;
Data *session_hash; Data *session_hash;
ssl_rec_decoder *c_to_s; ssl_rec_decoder *c_to_s;
@ -115,7 +121,7 @@ static int ssl_generate_keying_material PROTO_LIST((ssl_obj *ssl,
ssl_decoder *d)); ssl_decoder *d));
static int ssl_generate_session_hash PROTO_LIST((ssl_obj *ssl, static int ssl_generate_session_hash PROTO_LIST((ssl_obj *ssl,
ssl_decoder *d)); 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 #endif
static int ssl_create_session_lookup_key PROTO_LIST((ssl_obj *ssl, static int ssl_create_session_lookup_key PROTO_LIST((ssl_obj *ssl,
@ -196,6 +202,7 @@ int ssl_decode_ctx_destroy(dp)
{ {
#ifdef OPENSSL #ifdef OPENSSL
ssl_decode_ctx *d = *dp; ssl_decode_ctx *d = *dp;
if (!d) return 0;
if(d->ssl_key_log_file) { if(d->ssl_key_log_file) {
fclose(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); INIT_DATA(idd,msg,len);
/* First check to see if the client tried to restore */ if (ssl->version==TLSV13_VERSION){
if(d->session_id){ // No need to save/restore session in tls1.3 since the only way of decrypting is through log file
/* Now check to see if we restored */ } else {
if((r=r_data_compare(&idd,d->session_id))) /* First check to see if the client tried to restore */
ABORT(r); 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 /* Now try to look up the session. We may not be able
to find it if, for instance, the original session to find it if, for instance, the original session
was initiated with something other than static RSA */ was initiated with something other than static RSA */
if((r=ssl_restore_session(ssl,d))) if((r=ssl_restore_session(ssl,d)))
ABORT(r); ABORT(r);
restored=1; restored=1;
}
} }
_status=0; _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 //todo: better save and destroy only when successfully read key log
r_data_destroy(&d->MS); 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 //we found master secret for session in keylog
//try to save session //try to save session
@ -387,23 +398,36 @@ int ssl_process_client_session_id(ssl,d,msg,len)
#endif #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) int ssl_process_change_cipher_spec(ssl,d,direction)
ssl_obj *ssl; ssl_obj *ssl;
ssl_decoder *d; ssl_decoder *d;
int direction; int direction;
{ {
#ifdef OPENSSL #ifdef OPENSSL
if(direction==DIR_I2R){ if (ssl->version!=TLSV13_VERSION){
d->c_to_s=d->c_to_s_n; if(direction==DIR_I2R){
d->c_to_s_n=0; d->c_to_s=d->c_to_s_n;
if(d->c_to_s) ssl->process_ciphertext |= direction; 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); return(0);
} }
@ -427,7 +451,10 @@ int ssl_decode_record(ssl,dec,direction,ct,version,d)
rd=0; rd=0;
state=(direction==DIR_I2R)?ssl->i_state:ssl->r_state; 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){ if(state & SSL_ST_SENT_CHANGE_CIPHER_SPEC){
ssl->record_encryption=REC_CIPHERTEXT; ssl->record_encryption=REC_CIPHERTEXT;
return(SSL_NO_DECRYPT); return(SSL_NO_DECRYPT);
@ -443,7 +470,12 @@ int ssl_decode_record(ssl,dec,direction,ct,version,d)
if(!(out=(UCHAR *)malloc(d->len))) if(!(out=(UCHAR *)malloc(d->len)))
ABORT(R_NO_MEMORY); 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); ABORT(r);
} }
@ -620,7 +652,7 @@ int ssl_process_client_key_exchange(ssl,d,msg,len)
r_data_destroy(&d->MS); r_data_destroy(&d->MS);
if(!d->ctx->ssl_key_log_file || if(!d->ctx->ssl_key_log_file ||
ssl_read_key_log_file(d) || ssl_read_key_log_file(ssl,d) ||
!d->MS){ !d->MS){
if(ssl->cs->kex!=KEX_RSA) if(ssl->cs->kex!=KEX_RSA)
return(-1); 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, 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); ABORT(r);
if((r=ssl_create_rec_decoder(&d->s_to_c_n, 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); ABORT(r);
@ -1086,6 +1118,175 @@ static int ssl_generate_keying_material(ssl,d)
return(_status); 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) static int ssl_generate_session_hash(ssl,d)
ssl_obj *ssl; ssl_obj *ssl;
ssl_decoder *d; ssl_decoder *d;
@ -1134,36 +1335,64 @@ static int ssl_generate_session_hash(ssl,d)
return(_status); 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; ssl_decoder *d;
{ {
int r,_status,n,i; int r,_status,n,i;
unsigned int t; unsigned int t;
size_t l=0; size_t l=0;
char *line,*label_data; 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
while ((n=getline(&line,&l,d->ctx->ssl_key_log_file))!=-1) { ABORT(r);
if(n==(d->client_random->len*2)+112 && if (!(d_client_random = malloc((d->client_random->len * 2) + 1)))
!strncmp(line,"CLIENT_RANDOM",13)) { ABORT(r);
for (i = 0; i < d->client_random->len; i++)
if(!(label_data=malloc((d->client_random->len*2)+1))) if (snprintf(d_client_random + (i * 2), 3, "%02x", d->client_random->data[i]) != 2)
ABORT(r); ABORT(r);
while ((n = getline(&line, &l, d->ctx->ssl_key_log_file)) != -1) {
for(i=0;i<d->client_random->len;i++) if (line[n-1] =='\n') line[n-1] = '\0';
if(snprintf(label_data+(i*2),3,"%02x",d->client_random->data[i])!=2) if (!(label=strtok(line, " "))) continue;
ABORT(r); if (!(client_random=strtok(NULL, " ")) || strlen(client_random)!=64 || STRNICMP(client_random, d_client_random, 64)) continue;
secret=strtok(NULL, " ");
if(STRNICMP(line+14,label_data,64)) if (!(secret) || strlen(secret)!=(ssl->version==TLSV13_VERSION?ssl->cs->dig_len*2:96)) continue;
continue; if (!strncmp(label, "CLIENT_RANDOM", 13)) {
if ((r=r_data_alloc(&d->MS, 48)))
if((r=r_data_alloc(&d->MS,48))) ABORT(r);
ABORT(r); if (read_hex_string(secret, d->MS->data, 48))
ABORT(r);
for(i=0; i < d->MS->len; i++) { }
if(sscanf(line+14+65+(i*2),"%2x",&t)!=1) if (ssl->version!=TLSV13_VERSION) continue;
ABORT(r); if (!strncmp(label, "SERVER_HANDSHAKE_TRAFFIC_SECRET", 31)){
*(d->MS->data+i)=(char)t; 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: Eventually add support for other labels defined here:

View file

@ -73,6 +73,9 @@ int ssl_update_handshake_messages PROTO_LIST((ssl_obj *ssl,
Data *data)); Data *data));
int ssl_decode_record PROTO_LIST((ssl_obj *ssl,ssl_decoder *dec,int direction, int ssl_decode_record PROTO_LIST((ssl_obj *ssl,ssl_decoder *dec,int direction,
int ct,int version,Data *d)); 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 #endif

View file

@ -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); explain(ssl," Short record: %u bytes available (expecting: %u)\n",length,d.len);
return(0); return(0);
} }
version = ssl->version ? ssl->version : (vermaj*256+vermin);
P_(P_RH){ 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)); 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)); 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){ if(r==SSL_BAD_MAC){
explain(ssl," bad MAC\n"); explain(ssl," bad MAC\n");
return(0); return(0);
@ -303,9 +301,15 @@ int ssl_expand_record(ssl,q,direction,data,len)
else{ else{
//try to save unencrypted data to logger //try to save unencrypted data to logger
//we must save record with type "application_data" (this is unencrypted data) //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 (ct==23){
if (logger) {
if((r=ssl_decode_switch(ssl,ContentType_decoder,data[0],direction,q, &d))) { 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)) if(!(SSL_print_flags & SSL_PRINT_JSON))
printf(" unknown record type: %d\n", ct); printf(" unknown record type: %d\n", ct);
ERETURN(r); ERETURN(r);