diff --git a/scapy/layers/tls/extensions.py b/scapy/layers/tls/extensions.py index b488d06f48c..82da8a09dbf 100644 --- a/scapy/layers/tls/extensions.py +++ b/scapy/layers/tls/extensions.py @@ -20,6 +20,7 @@ SigAndHashAlgsField, _tls_hash_sig) from scapy.layers.tls.session import _GenericTLSSessionInheritance from scapy.layers.tls.crypto.groups import _tls_named_groups +from scapy.layers.tls.crypto.suites import _tls_cipher_suites from scapy.themes import AnsiColorTheme from scapy.compat import raw from scapy.config import conf @@ -61,7 +62,8 @@ 0x33: "key_share", 0x3374: "next_protocol_negotiation", # RFC-draft-agl-tls-nextprotoneg-03 - 0xff01: "renegotiation_info" # RFC 5746 + 0xff01: "renegotiation_info", # RFC 5746 + 0xffce: "encrypted_server_name" } @@ -182,6 +184,27 @@ class TLS_Ext_ServerName(TLS_Ext_PrettyPacketList): # RFC 4366 length_from=lambda pkt: pkt.servernameslen)] +class TLS_Ext_EncryptedServerName(TLS_Ext_PrettyPacketList): + name = "TLS Extension - Encrypted Server Name" + fields_desc = [ShortEnumField("type", 0xffce, _tls_ext), + ShortField("len", None), + EnumField("cipher", None, _tls_cipher_suites), + ShortEnumField("key_exchange_group", None, + _tls_named_groups), + FieldLenField("key_exchange_len", None, + length_of="key_exchange", fmt="H"), + XStrLenField("key_exchange", "", + length_from=lambda pkt: pkt.key_exchange_len), + FieldLenField("record_digest_len", + None, length_of="record_digest"), + XStrLenField("record_digest", "", + length_from=lambda pkt: pkt.record_digest_len), + FieldLenField("encrypted_sni_len", None, + length_of="encrypted_sni", fmt="H"), + XStrLenField("encrypted_sni", "", + length_from=lambda pkt: pkt.encrypted_sni_len)] + + class TLS_Ext_MaxFragLen(TLS_Ext_Unknown): # RFC 4366 name = "TLS Extension - Max Fragment Length" fields_desc = [ShortEnumField("type", 1, _tls_ext), @@ -669,7 +692,8 @@ class TLS_Ext_RecordSizeLimit(TLS_Ext_Unknown): # RFC 8449 # 0x2f: TLS_Ext_CertificateAuthorities, #XXX # 0x30: TLS_Ext_OIDFilters, #XXX 0x3374: TLS_Ext_NPN, - 0xff01: TLS_Ext_RenegotiationInfo + 0xff01: TLS_Ext_RenegotiationInfo, + 0xffce: TLS_Ext_EncryptedServerName } diff --git a/test/tls13.uts b/test/tls13.uts index 9dc7ea540e4..d439db83ad4 100644 --- a/test/tls13.uts +++ b/test/tls13.uts @@ -619,6 +619,54 @@ m = t.inner.msg[0] assert(isinstance(m, TLSApplicationData)) assert(m.data == payload) += TLS_Ext_EncryptedServerName(), dissect +~ crypto_advanced + +clientHello3 = clean(""" +16030102c4010002c003034b1 40e7d15fc8db422cec056fbaf 0285d306df4eedad1bc6ea57d 5114e6bd52a20a5b9c7445955 e296b886469c974648cda0a68 +5d3c06d884e388f6475c32e03 2d0024130113031302c02bc02 fcca9cca8c02cc030c00ac009 c013c01400330039002f00350 00a0100025300170000ff0100 +0100000a000e000c001d00170 018001901000101000b000201 00002300000010000b0009086 87474702f312e310005000501 000000000033006b0069001d0 +02037adee0aacc37b08d47222 caf6a5097a800fcf8406ae118 38f6348294d2dde1200170041 048b127c905d6d487a40b8b19 c99c56aa1a8c208218c178dae +02568547b2ce8f538a530b858 a7a2f608d66e148baa5693d03 c519b45017c63f48c5a4c1238 707bc002b0009080304030303 020301000d001800160403050 +3060308040805080604010501 060102030201002d00020101f fce016e1301001d0020912e86 b776ee552a6bb1e2c70d7b467 770b190432237cc743a93091d +ce24623500208bc16fdcbbc7c 8756808c94f70464d68297975 f33be90e1a200633f5eb2d4c6 101249e073bff833782e57e88 2519a53ef8bde4c94a7878a2f +8461aec57802440007c7b2dab 986d9bc79257ce00ca6a998b1 fadb0114161069d364ccebae8 dab6c88151f297daeaecfd2e1 a598a486e2efc9561298f8dd5 +f35d184f0e87768777d253e68 952b730a24b342fde10df4f8e 82afdc2f10c2481634d92015d 9d5e6a9566494735d9c079115 bdeb0cd019098d1cf847c53ef +4aac41560cacdc7ce166399df 5b0c0af91d5be3f7d8224755a aa6046de52875f9ef9ac15372 7ce08019bc2648beb4b1418cb 4979ff7eaeedaec2b15695508 +4d5a480cb939fdc7f00e6cc6f c0f9675276a9d607686c4d779 d4bb7544fb60c7f3079afbc74 61ed67fd55a78c44d6f8d4eaf 386acc17dea11e37a09f63da3 +d059243b35f449e891255ac7b 4f631509d7060f001c0002400 1 +""") +t = TLS(clientHello3) +clientESNI = t.msg[0].ext[11] +assert isinstance(clientESNI, TLS_Ext_EncryptedServerName) and clientESNI.cipher == 4865 + + += TLS_Ext_EncryptedServerName(), basic instantiation +~ crypto_advanced + +esni = TLS_Ext_EncryptedServerName(key_exchange_group=29,encrypted_sni=clean(""" +ffce016e1301001d00209 12e86b776ee552a6bb1e2 c70d7b467770b19043223 7cc743a93091dce246235 +00208bc16fdcbbc7c8756 808c94f70464d68297975 f33be90e1a200633f5eb2 d4c6101249e073bff8337 +82e57e882519a53ef8bde 4c94a7878a2f8461aec57 802440007c7b2dab986d9 bc79257ce00ca6a998b1f +adb0114161069d364cceb ae8dab6c88151f297daea ecfd2e1a598a486e2efc9 561298f8dd5f35d184f0e +87768777d253e68952b73 0a24b342fde10df4f8e82 afdc2f10c2481634d9201 5d9d5e6a9566494735d9c +079115bdeb0cd019098d1 cf847c53ef4aac41560ca cdc7ce166399df5b0c0af 91d5be3f7d8224755aaa6 +046de52875f9ef9ac1537 27ce08019bc2648beb4b1 418cb4979ff7eaeedaec2 b156955084d5a480cb939 +fdc7f00e6cc6fc0f96752 76a9d607686c4d779d4bb 7544fb60c7f3079afbc74 61ed67fd55a78c44d6f8d +4eaf386acc17dea11e37a 09f63da3d059243b35f44 9e891255ac7b4f631509d 7060f +""")) +assert esni.key_exchange_group == 29 and esni.encrypted_sni==clean(""" +ffce016e1301001d00209 12e86b776ee552a6bb1e2 c70d7b467770b19043223 7cc743a93091dce246235 +00208bc16fdcbbc7c8756 808c94f70464d68297975 f33be90e1a200633f5eb2 d4c6101249e073bff8337 +82e57e882519a53ef8bde 4c94a7878a2f8461aec57 802440007c7b2dab986d9 bc79257ce00ca6a998b1f +adb0114161069d364cceb ae8dab6c88151f297daea ecfd2e1a598a486e2efc9 561298f8dd5f35d184f0e +87768777d253e68952b73 0a24b342fde10df4f8e82 afdc2f10c2481634d9201 5d9d5e6a9566494735d9c +079115bdeb0cd019098d1 cf847c53ef4aac41560ca cdc7ce166399df5b0c0af 91d5be3f7d8224755aaa6 +046de52875f9ef9ac1537 27ce08019bc2648beb4b1 418cb4979ff7eaeedaec2 b156955084d5a480cb939 +fdc7f00e6cc6fc0f96752 76a9d607686c4d779d4bb 7544fb60c7f3079afbc74 61ed67fd55a78c44d6f8d +4eaf386acc17dea11e37a 09f63da3d059243b35f44 9e891255ac7b4f631509d 7060f +""") + = Decrypt a TLS 1.3 session - Decrypt and parse server Application Data ~ crypto_advanced # Values from RFC8448, section 3