1*7dc08ffcSJunyu Lai## This file is part of Scapy 2*7dc08ffcSJunyu Lai## Copyright (C) 2017 Maxence Tury 3*7dc08ffcSJunyu Lai## This program is published under a GPLv2 license 4*7dc08ffcSJunyu Lai 5*7dc08ffcSJunyu Lai""" 6*7dc08ffcSJunyu LaiTLS handshake extensions. 7*7dc08ffcSJunyu Lai""" 8*7dc08ffcSJunyu Lai 9*7dc08ffcSJunyu Laifrom __future__ import print_function 10*7dc08ffcSJunyu Lai 11*7dc08ffcSJunyu Laifrom scapy.fields import * 12*7dc08ffcSJunyu Laifrom scapy.packet import Packet, Raw, Padding 13*7dc08ffcSJunyu Laifrom scapy.layers.x509 import X509_Extensions 14*7dc08ffcSJunyu Laifrom scapy.layers.tls.basefields import _tls_version 15*7dc08ffcSJunyu Laifrom scapy.layers.tls.keyexchange import (SigAndHashAlgsLenField, 16*7dc08ffcSJunyu Lai SigAndHashAlgsField, _tls_hash_sig) 17*7dc08ffcSJunyu Laifrom scapy.layers.tls.session import _GenericTLSSessionInheritance 18*7dc08ffcSJunyu Laifrom scapy.layers.tls.crypto.groups import _tls_named_groups 19*7dc08ffcSJunyu Lai 20*7dc08ffcSJunyu Lai 21*7dc08ffcSJunyu Lai_tls_ext = { 0: "server_name", # RFC 4366 22*7dc08ffcSJunyu Lai 1: "max_fragment_length", # RFC 4366 23*7dc08ffcSJunyu Lai 2: "client_certificate_url", # RFC 4366 24*7dc08ffcSJunyu Lai 3: "trusted_ca_keys", # RFC 4366 25*7dc08ffcSJunyu Lai 4: "truncated_hmac", # RFC 4366 26*7dc08ffcSJunyu Lai 5: "status_request", # RFC 4366 27*7dc08ffcSJunyu Lai 6: "user_mapping", # RFC 4681 28*7dc08ffcSJunyu Lai 7: "client_authz", # RFC 5878 29*7dc08ffcSJunyu Lai 8: "server_authz", # RFC 5878 30*7dc08ffcSJunyu Lai 9: "cert_type", # RFC 6091 31*7dc08ffcSJunyu Lai #10: "elliptic_curves", # RFC 4492 32*7dc08ffcSJunyu Lai 10: "supported_groups", 33*7dc08ffcSJunyu Lai 11: "ec_point_formats", # RFC 4492 34*7dc08ffcSJunyu Lai 13: "signature_algorithms", # RFC 5246 35*7dc08ffcSJunyu Lai 0x0f: "heartbeat", # RFC 6520 36*7dc08ffcSJunyu Lai 0x10: "alpn", # RFC 7301 37*7dc08ffcSJunyu Lai 0x12: "signed_certificate_timestamp", # RFC 6962 38*7dc08ffcSJunyu Lai 0x15: "padding", # RFC 7685 39*7dc08ffcSJunyu Lai 0x16: "encrypt_then_mac", # RFC 7366 40*7dc08ffcSJunyu Lai 0x17: "extended_master_secret",# RFC 7627 41*7dc08ffcSJunyu Lai 0x23: "session_ticket", # RFC 5077 42*7dc08ffcSJunyu Lai 0x28: "key_share", 43*7dc08ffcSJunyu Lai 0x29: "pre_shared_key", 44*7dc08ffcSJunyu Lai 0x2a: "early_data", 45*7dc08ffcSJunyu Lai 0x2b: "supported_versions", 46*7dc08ffcSJunyu Lai 0x2c: "cookie", 47*7dc08ffcSJunyu Lai 0x2d: "psk_key_exchange_modes", 48*7dc08ffcSJunyu Lai 0x2e: "ticket_early_data_info", 49*7dc08ffcSJunyu Lai 0x2f: "certificate_authorities", 50*7dc08ffcSJunyu Lai 0x30: "oid_filters", 51*7dc08ffcSJunyu Lai 0x3374: "next_protocol_negotiation", 52*7dc08ffcSJunyu Lai # RFC-draft-agl-tls-nextprotoneg-03 53*7dc08ffcSJunyu Lai 0xff01: "renegotiation_info" # RFC 5746 54*7dc08ffcSJunyu Lai } 55*7dc08ffcSJunyu Lai 56*7dc08ffcSJunyu Lai 57*7dc08ffcSJunyu Laiclass TLS_Ext_Unknown(_GenericTLSSessionInheritance): 58*7dc08ffcSJunyu Lai """ 59*7dc08ffcSJunyu Lai We put this here rather than in extensions.py in order to avoid 60*7dc08ffcSJunyu Lai circular imports... 61*7dc08ffcSJunyu Lai """ 62*7dc08ffcSJunyu Lai name = "TLS Extension - Scapy Unknown" 63*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", None, _tls_ext), 64*7dc08ffcSJunyu Lai FieldLenField("len", None, fmt="!H", length_of="val"), 65*7dc08ffcSJunyu Lai StrLenField("val", "", 66*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.len) ] 67*7dc08ffcSJunyu Lai 68*7dc08ffcSJunyu Lai def post_build(self, p, pay): 69*7dc08ffcSJunyu Lai if self.len is None: 70*7dc08ffcSJunyu Lai l = len(p) - 4 71*7dc08ffcSJunyu Lai p = p[:2] + struct.pack("!H", l) + p[4:] 72*7dc08ffcSJunyu Lai return p+pay 73*7dc08ffcSJunyu Lai 74*7dc08ffcSJunyu Lai 75*7dc08ffcSJunyu Lai############################################################################### 76*7dc08ffcSJunyu Lai### ClientHello/ServerHello extensions ### 77*7dc08ffcSJunyu Lai############################################################################### 78*7dc08ffcSJunyu Lai 79*7dc08ffcSJunyu Lai# We provide these extensions mostly for packet manipulation purposes. 80*7dc08ffcSJunyu Lai# For now, most of them are not considered by our automaton. 81*7dc08ffcSJunyu Lai 82*7dc08ffcSJunyu Laiclass TLS_Ext_PrettyPacketList(TLS_Ext_Unknown): 83*7dc08ffcSJunyu Lai """ 84*7dc08ffcSJunyu Lai Dummy extension used for server_name/ALPN/NPN for a lighter representation: 85*7dc08ffcSJunyu Lai the final field is showed as a 1-line list rather than as lots of packets. 86*7dc08ffcSJunyu Lai XXX Define a new condition for packet lists in Packet._show_or_dump? 87*7dc08ffcSJunyu Lai """ 88*7dc08ffcSJunyu Lai def _show_or_dump(self, dump=False, indent=3, 89*7dc08ffcSJunyu Lai lvl="", label_lvl="", first_call=True): 90*7dc08ffcSJunyu Lai """ Reproduced from packet.py """ 91*7dc08ffcSJunyu Lai ct = AnsiColorTheme() if dump else conf.color_theme 92*7dc08ffcSJunyu Lai s = "%s%s %s %s \n" % (label_lvl, ct.punct("###["), 93*7dc08ffcSJunyu Lai ct.layer_name(self.name), ct.punct("]###")) 94*7dc08ffcSJunyu Lai for f in self.fields_desc[:-1]: 95*7dc08ffcSJunyu Lai ncol = ct.field_name 96*7dc08ffcSJunyu Lai vcol = ct.field_value 97*7dc08ffcSJunyu Lai fvalue = self.getfieldval(f.name) 98*7dc08ffcSJunyu Lai begn = "%s %-10s%s " % (label_lvl+lvl, ncol(f.name), 99*7dc08ffcSJunyu Lai ct.punct("="),) 100*7dc08ffcSJunyu Lai reprval = f.i2repr(self,fvalue) 101*7dc08ffcSJunyu Lai if isinstance(reprval, str): 102*7dc08ffcSJunyu Lai reprval = reprval.replace("\n", "\n"+" "*(len(label_lvl) 103*7dc08ffcSJunyu Lai +len(lvl) 104*7dc08ffcSJunyu Lai +len(f.name) 105*7dc08ffcSJunyu Lai +4)) 106*7dc08ffcSJunyu Lai s += "%s%s\n" % (begn,vcol(reprval)) 107*7dc08ffcSJunyu Lai f = self.fields_desc[-1] 108*7dc08ffcSJunyu Lai ncol = ct.field_name 109*7dc08ffcSJunyu Lai vcol = ct.field_value 110*7dc08ffcSJunyu Lai fvalue = self.getfieldval(f.name) 111*7dc08ffcSJunyu Lai begn = "%s %-10s%s " % (label_lvl+lvl, ncol(f.name), ct.punct("="),) 112*7dc08ffcSJunyu Lai reprval = f.i2repr(self,fvalue) 113*7dc08ffcSJunyu Lai if isinstance(reprval, str): 114*7dc08ffcSJunyu Lai reprval = reprval.replace("\n", "\n"+" "*(len(label_lvl) 115*7dc08ffcSJunyu Lai +len(lvl) 116*7dc08ffcSJunyu Lai +len(f.name) 117*7dc08ffcSJunyu Lai +4)) 118*7dc08ffcSJunyu Lai s += "%s%s\n" % (begn,vcol(reprval)) 119*7dc08ffcSJunyu Lai if self.payload: 120*7dc08ffcSJunyu Lai s += self.payload._show_or_dump(dump=dump, indent=indent, 121*7dc08ffcSJunyu Lai lvl=lvl+(" "*indent*self.show_indent), 122*7dc08ffcSJunyu Lai label_lvl=label_lvl, first_call=False) 123*7dc08ffcSJunyu Lai 124*7dc08ffcSJunyu Lai if first_call and not dump: 125*7dc08ffcSJunyu Lai print(s) 126*7dc08ffcSJunyu Lai else: 127*7dc08ffcSJunyu Lai return s 128*7dc08ffcSJunyu Lai 129*7dc08ffcSJunyu Lai 130*7dc08ffcSJunyu Lai_tls_server_name_types = { 0: "host_name" } 131*7dc08ffcSJunyu Lai 132*7dc08ffcSJunyu Laiclass ServerName(Packet): 133*7dc08ffcSJunyu Lai name = "HostName" 134*7dc08ffcSJunyu Lai fields_desc = [ ByteEnumField("nametype", 0, _tls_server_name_types), 135*7dc08ffcSJunyu Lai FieldLenField("namelen", None, length_of="servername"), 136*7dc08ffcSJunyu Lai StrLenField("servername", "", 137*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.namelen) ] 138*7dc08ffcSJunyu Lai def guess_payload_class(self, p): 139*7dc08ffcSJunyu Lai return Padding 140*7dc08ffcSJunyu Lai 141*7dc08ffcSJunyu Laiclass ServerListField(PacketListField): 142*7dc08ffcSJunyu Lai def i2repr(self, pkt, x): 143*7dc08ffcSJunyu Lai res = [p.servername for p in x] 144*7dc08ffcSJunyu Lai return "[%s]" % b", ".join(res) 145*7dc08ffcSJunyu Lai 146*7dc08ffcSJunyu Laiclass ServerLenField(FieldLenField): 147*7dc08ffcSJunyu Lai """ 148*7dc08ffcSJunyu Lai There is no length when there are no servernames (as in a ServerHello). 149*7dc08ffcSJunyu Lai """ 150*7dc08ffcSJunyu Lai def addfield(self, pkt, s, val): 151*7dc08ffcSJunyu Lai if not val: 152*7dc08ffcSJunyu Lai if not pkt.servernames: 153*7dc08ffcSJunyu Lai return s 154*7dc08ffcSJunyu Lai return super(ServerLenField, self).addfield(pkt, s, val) 155*7dc08ffcSJunyu Lai 156*7dc08ffcSJunyu Laiclass TLS_Ext_ServerName(TLS_Ext_PrettyPacketList): # RFC 4366 157*7dc08ffcSJunyu Lai name = "TLS Extension - Server Name" 158*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0, _tls_ext), 159*7dc08ffcSJunyu Lai FieldLenField("len", None, length_of="servernames", 160*7dc08ffcSJunyu Lai adjust=lambda pkt,x: x+2), 161*7dc08ffcSJunyu Lai ServerLenField("servernameslen", None, 162*7dc08ffcSJunyu Lai length_of="servernames"), 163*7dc08ffcSJunyu Lai ServerListField("servernames", [], ServerName, 164*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.servernameslen)] 165*7dc08ffcSJunyu Lai 166*7dc08ffcSJunyu Lai 167*7dc08ffcSJunyu Laiclass TLS_Ext_MaxFragLen(TLS_Ext_Unknown): # RFC 4366 168*7dc08ffcSJunyu Lai name = "TLS Extension - Max Fragment Length" 169*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 1, _tls_ext), 170*7dc08ffcSJunyu Lai ShortField("len", None), 171*7dc08ffcSJunyu Lai ByteEnumField("maxfraglen", 4, { 1: "2^9", 172*7dc08ffcSJunyu Lai 2: "2^10", 173*7dc08ffcSJunyu Lai 3: "2^11", 174*7dc08ffcSJunyu Lai 4: "2^12" }) ] 175*7dc08ffcSJunyu Lai 176*7dc08ffcSJunyu Lai 177*7dc08ffcSJunyu Laiclass TLS_Ext_ClientCertURL(TLS_Ext_Unknown): # RFC 4366 178*7dc08ffcSJunyu Lai name = "TLS Extension - Client Certificate URL" 179*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 2, _tls_ext), 180*7dc08ffcSJunyu Lai ShortField("len", None) ] 181*7dc08ffcSJunyu Lai 182*7dc08ffcSJunyu Lai 183*7dc08ffcSJunyu Lai_tls_trusted_authority_types = {0: "pre_agreed", 184*7dc08ffcSJunyu Lai 1: "key_sha1_hash", 185*7dc08ffcSJunyu Lai 2: "x509_name", 186*7dc08ffcSJunyu Lai 3: "cert_sha1_hash" } 187*7dc08ffcSJunyu Lai 188*7dc08ffcSJunyu Laiclass TAPreAgreed(Packet): 189*7dc08ffcSJunyu Lai name = "Trusted authority - pre_agreed" 190*7dc08ffcSJunyu Lai fields_desc = [ ByteEnumField("idtype", 0, _tls_trusted_authority_types) ] 191*7dc08ffcSJunyu Lai def guess_payload_class(self, p): 192*7dc08ffcSJunyu Lai return Padding 193*7dc08ffcSJunyu Lai 194*7dc08ffcSJunyu Laiclass TAKeySHA1Hash(Packet): 195*7dc08ffcSJunyu Lai name = "Trusted authority - key_sha1_hash" 196*7dc08ffcSJunyu Lai fields_desc = [ ByteEnumField("idtype", 1, _tls_trusted_authority_types), 197*7dc08ffcSJunyu Lai StrFixedLenField("id", None, 20) ] 198*7dc08ffcSJunyu Lai def guess_payload_class(self, p): 199*7dc08ffcSJunyu Lai return Padding 200*7dc08ffcSJunyu Lai 201*7dc08ffcSJunyu Laiclass TAX509Name(Packet): 202*7dc08ffcSJunyu Lai """ 203*7dc08ffcSJunyu Lai XXX Section 3.4 of RFC 4366. Implement a more specific DNField 204*7dc08ffcSJunyu Lai rather than current StrLenField. 205*7dc08ffcSJunyu Lai """ 206*7dc08ffcSJunyu Lai name = "Trusted authority - x509_name" 207*7dc08ffcSJunyu Lai fields_desc = [ ByteEnumField("idtype", 2, _tls_trusted_authority_types), 208*7dc08ffcSJunyu Lai FieldLenField("dnlen", None, length_of="dn"), 209*7dc08ffcSJunyu Lai StrLenField("dn", "", length_from=lambda pkt: pkt.dnlen) ] 210*7dc08ffcSJunyu Lai def guess_payload_class(self, p): 211*7dc08ffcSJunyu Lai return Padding 212*7dc08ffcSJunyu Lai 213*7dc08ffcSJunyu Laiclass TACertSHA1Hash(Packet): 214*7dc08ffcSJunyu Lai name = "Trusted authority - cert_sha1_hash" 215*7dc08ffcSJunyu Lai fields_desc = [ ByteEnumField("idtype", 3, _tls_trusted_authority_types), 216*7dc08ffcSJunyu Lai StrFixedLenField("id", None, 20) ] 217*7dc08ffcSJunyu Lai def guess_payload_class(self, p): 218*7dc08ffcSJunyu Lai return Padding 219*7dc08ffcSJunyu Lai 220*7dc08ffcSJunyu Lai_tls_trusted_authority_cls = {0: TAPreAgreed, 221*7dc08ffcSJunyu Lai 1: TAKeySHA1Hash, 222*7dc08ffcSJunyu Lai 2: TAX509Name, 223*7dc08ffcSJunyu Lai 3: TACertSHA1Hash } 224*7dc08ffcSJunyu Lai 225*7dc08ffcSJunyu Laiclass _TAListField(PacketListField): 226*7dc08ffcSJunyu Lai """ 227*7dc08ffcSJunyu Lai Specific version that selects the right Trusted Authority (previous TA*) 228*7dc08ffcSJunyu Lai class to be used for dissection based on idtype. 229*7dc08ffcSJunyu Lai """ 230*7dc08ffcSJunyu Lai def m2i(self, pkt, m): 231*7dc08ffcSJunyu Lai idtype = ord(m[0]) 232*7dc08ffcSJunyu Lai cls = self.cls 233*7dc08ffcSJunyu Lai if idtype in _tls_trusted_authority_cls: 234*7dc08ffcSJunyu Lai cls = _tls_trusted_authority_cls[idtype] 235*7dc08ffcSJunyu Lai return cls(m) 236*7dc08ffcSJunyu Lai 237*7dc08ffcSJunyu Laiclass TLS_Ext_TrustedCAInd(TLS_Ext_Unknown): # RFC 4366 238*7dc08ffcSJunyu Lai name = "TLS Extension - Trusted CA Indication" 239*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 3, _tls_ext), 240*7dc08ffcSJunyu Lai ShortField("len", None), 241*7dc08ffcSJunyu Lai FieldLenField("talen", None, length_of="ta"), 242*7dc08ffcSJunyu Lai _TAListField("ta", [], Raw, 243*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.talen) ] 244*7dc08ffcSJunyu Lai 245*7dc08ffcSJunyu Lai 246*7dc08ffcSJunyu Laiclass TLS_Ext_TruncatedHMAC(TLS_Ext_Unknown): # RFC 4366 247*7dc08ffcSJunyu Lai name = "TLS Extension - Truncated HMAC" 248*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 4, _tls_ext), 249*7dc08ffcSJunyu Lai ShortField("len", None) ] 250*7dc08ffcSJunyu Lai 251*7dc08ffcSJunyu Lai 252*7dc08ffcSJunyu Laiclass ResponderID(Packet): 253*7dc08ffcSJunyu Lai name = "Responder ID structure" 254*7dc08ffcSJunyu Lai fields_desc = [ FieldLenField("respidlen", None, length_of="respid"), 255*7dc08ffcSJunyu Lai StrLenField("respid", "", 256*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.respidlen)] 257*7dc08ffcSJunyu Lai def guess_payload_class(self, p): 258*7dc08ffcSJunyu Lai return Padding 259*7dc08ffcSJunyu Lai 260*7dc08ffcSJunyu Laiclass OCSPStatusRequest(Packet): 261*7dc08ffcSJunyu Lai """ 262*7dc08ffcSJunyu Lai This is the structure defined in RFC 6066, not in RFC 6960! 263*7dc08ffcSJunyu Lai """ 264*7dc08ffcSJunyu Lai name = "OCSPStatusRequest structure" 265*7dc08ffcSJunyu Lai fields_desc = [ FieldLenField("respidlen", None, length_of="respid"), 266*7dc08ffcSJunyu Lai PacketListField("respid", [], ResponderID, 267*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.respidlen), 268*7dc08ffcSJunyu Lai FieldLenField("reqextlen", None, length_of="reqext"), 269*7dc08ffcSJunyu Lai PacketField("reqext", "", X509_Extensions) ] 270*7dc08ffcSJunyu Lai def guess_payload_class(self, p): 271*7dc08ffcSJunyu Lai return Padding 272*7dc08ffcSJunyu Lai 273*7dc08ffcSJunyu Lai_cert_status_type = { 1: "ocsp" } 274*7dc08ffcSJunyu Lai_cert_status_req_cls = { 1: OCSPStatusRequest } 275*7dc08ffcSJunyu Lai 276*7dc08ffcSJunyu Laiclass _StatusReqField(PacketListField): 277*7dc08ffcSJunyu Lai def m2i(self, pkt, m): 278*7dc08ffcSJunyu Lai idtype = pkt.stype 279*7dc08ffcSJunyu Lai cls = self.cls 280*7dc08ffcSJunyu Lai if idtype in _cert_status_req_cls: 281*7dc08ffcSJunyu Lai cls = _cert_status_req_cls[idtype] 282*7dc08ffcSJunyu Lai return cls(m) 283*7dc08ffcSJunyu Lai 284*7dc08ffcSJunyu Laiclass TLS_Ext_CSR(TLS_Ext_Unknown): # RFC 4366 285*7dc08ffcSJunyu Lai name = "TLS Extension - Certificate Status Request" 286*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 5, _tls_ext), 287*7dc08ffcSJunyu Lai ShortField("len", None), 288*7dc08ffcSJunyu Lai ByteEnumField("stype", None, _cert_status_type), 289*7dc08ffcSJunyu Lai _StatusReqField("req", [], Raw, 290*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.len - 1) ] 291*7dc08ffcSJunyu Lai 292*7dc08ffcSJunyu Lai 293*7dc08ffcSJunyu Laiclass TLS_Ext_UserMapping(TLS_Ext_Unknown): # RFC 4681 294*7dc08ffcSJunyu Lai name = "TLS Extension - User Mapping" 295*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 6, _tls_ext), 296*7dc08ffcSJunyu Lai ShortField("len", None), 297*7dc08ffcSJunyu Lai FieldLenField("umlen", None, fmt="B", length_of="um"), 298*7dc08ffcSJunyu Lai FieldListField("um", [], 299*7dc08ffcSJunyu Lai ByteField("umtype", 0), 300*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.umlen) ] 301*7dc08ffcSJunyu Lai 302*7dc08ffcSJunyu Lai 303*7dc08ffcSJunyu Laiclass TLS_Ext_ClientAuthz(TLS_Ext_Unknown): # RFC 5878 304*7dc08ffcSJunyu Lai """ XXX Unsupported """ 305*7dc08ffcSJunyu Lai name = "TLS Extension - Client Authz" 306*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 7, _tls_ext), 307*7dc08ffcSJunyu Lai ShortField("len", None), 308*7dc08ffcSJunyu Lai ] 309*7dc08ffcSJunyu Lai 310*7dc08ffcSJunyu Laiclass TLS_Ext_ServerAuthz(TLS_Ext_Unknown): # RFC 5878 311*7dc08ffcSJunyu Lai """ XXX Unsupported """ 312*7dc08ffcSJunyu Lai name = "TLS Extension - Server Authz" 313*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 8, _tls_ext), 314*7dc08ffcSJunyu Lai ShortField("len", None), 315*7dc08ffcSJunyu Lai ] 316*7dc08ffcSJunyu Lai 317*7dc08ffcSJunyu Lai 318*7dc08ffcSJunyu Lai_tls_cert_types = { 0: "X.509", 1: "OpenPGP" } 319*7dc08ffcSJunyu Lai 320*7dc08ffcSJunyu Laiclass TLS_Ext_ClientCertType(TLS_Ext_Unknown): # RFC 5081 321*7dc08ffcSJunyu Lai name = "TLS Extension - Certificate Type (client version)" 322*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 9, _tls_ext), 323*7dc08ffcSJunyu Lai ShortField("len", None), 324*7dc08ffcSJunyu Lai FieldLenField("ctypeslen", None, length_of="ctypes"), 325*7dc08ffcSJunyu Lai FieldListField("ctypes", [0, 1], 326*7dc08ffcSJunyu Lai ByteEnumField("certtypes", None, 327*7dc08ffcSJunyu Lai _tls_cert_types), 328*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.ctypeslen) ] 329*7dc08ffcSJunyu Lai 330*7dc08ffcSJunyu Laiclass TLS_Ext_ServerCertType(TLS_Ext_Unknown): # RFC 5081 331*7dc08ffcSJunyu Lai name = "TLS Extension - Certificate Type (server version)" 332*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 9, _tls_ext), 333*7dc08ffcSJunyu Lai ShortField("len", None), 334*7dc08ffcSJunyu Lai ByteEnumField("ctype", None, _tls_cert_types) ] 335*7dc08ffcSJunyu Lai 336*7dc08ffcSJunyu Laidef _TLS_Ext_CertTypeDispatcher(m, *args, **kargs): 337*7dc08ffcSJunyu Lai """ 338*7dc08ffcSJunyu Lai We need to select the correct one on dissection. We use the length for 339*7dc08ffcSJunyu Lai that, as 1 for client version would emply an empty list. 340*7dc08ffcSJunyu Lai """ 341*7dc08ffcSJunyu Lai l = struct.unpack("!H", m[2:4])[0] 342*7dc08ffcSJunyu Lai if l == 1: 343*7dc08ffcSJunyu Lai cls = TLS_Ext_ServerCertType 344*7dc08ffcSJunyu Lai else: 345*7dc08ffcSJunyu Lai cls = TLS_Ext_ClientCertType 346*7dc08ffcSJunyu Lai return cls(m, *args, **kargs) 347*7dc08ffcSJunyu Lai 348*7dc08ffcSJunyu Lai 349*7dc08ffcSJunyu Laiclass TLS_Ext_SupportedGroups(TLS_Ext_Unknown): 350*7dc08ffcSJunyu Lai """ 351*7dc08ffcSJunyu Lai This extension was known as 'Supported Elliptic Curves' before TLS 1.3 352*7dc08ffcSJunyu Lai merged both group selection mechanisms for ECDH and FFDH. 353*7dc08ffcSJunyu Lai """ 354*7dc08ffcSJunyu Lai name = "TLS Extension - Supported Groups" 355*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 10, _tls_ext), 356*7dc08ffcSJunyu Lai ShortField("len", None), 357*7dc08ffcSJunyu Lai FieldLenField("groupslen", None, length_of="groups"), 358*7dc08ffcSJunyu Lai FieldListField("groups", [], 359*7dc08ffcSJunyu Lai ShortEnumField("ng", None, 360*7dc08ffcSJunyu Lai _tls_named_groups), 361*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.groupslen) ] 362*7dc08ffcSJunyu Lai 363*7dc08ffcSJunyu Laiclass TLS_Ext_SupportedEllipticCurves(TLS_Ext_SupportedGroups): # RFC 4492 364*7dc08ffcSJunyu Lai pass 365*7dc08ffcSJunyu Lai 366*7dc08ffcSJunyu Lai 367*7dc08ffcSJunyu Lai_tls_ecpoint_format = { 0: "uncompressed", 368*7dc08ffcSJunyu Lai 1: "ansiX962_compressed_prime", 369*7dc08ffcSJunyu Lai 2: "ansiX962_compressed_char2" } 370*7dc08ffcSJunyu Lai 371*7dc08ffcSJunyu Laiclass TLS_Ext_SupportedPointFormat(TLS_Ext_Unknown): # RFC 4492 372*7dc08ffcSJunyu Lai name = "TLS Extension - Supported Point Format" 373*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 11, _tls_ext), 374*7dc08ffcSJunyu Lai ShortField("len", None), 375*7dc08ffcSJunyu Lai FieldLenField("ecpllen", None, fmt="B", length_of="ecpl"), 376*7dc08ffcSJunyu Lai FieldListField("ecpl", [0], 377*7dc08ffcSJunyu Lai ByteEnumField("nc", None, 378*7dc08ffcSJunyu Lai _tls_ecpoint_format), 379*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.ecpllen) ] 380*7dc08ffcSJunyu Lai 381*7dc08ffcSJunyu Lai 382*7dc08ffcSJunyu Laiclass TLS_Ext_SignatureAlgorithms(TLS_Ext_Unknown): # RFC 5246 383*7dc08ffcSJunyu Lai name = "TLS Extension - Signature Algorithms" 384*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 13, _tls_ext), 385*7dc08ffcSJunyu Lai ShortField("len", None), 386*7dc08ffcSJunyu Lai SigAndHashAlgsLenField("sig_algs_len", None, 387*7dc08ffcSJunyu Lai length_of="sig_algs"), 388*7dc08ffcSJunyu Lai SigAndHashAlgsField("sig_algs", [], 389*7dc08ffcSJunyu Lai EnumField("hash_sig", None, 390*7dc08ffcSJunyu Lai _tls_hash_sig), 391*7dc08ffcSJunyu Lai length_from= 392*7dc08ffcSJunyu Lai lambda pkt: pkt.sig_algs_len) ] 393*7dc08ffcSJunyu Lai 394*7dc08ffcSJunyu Lai 395*7dc08ffcSJunyu Laiclass TLS_Ext_Heartbeat(TLS_Ext_Unknown): # RFC 6520 396*7dc08ffcSJunyu Lai name = "TLS Extension - Heartbeat" 397*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x0f, _tls_ext), 398*7dc08ffcSJunyu Lai ShortField("len", None), 399*7dc08ffcSJunyu Lai ByteEnumField("heartbeat_mode", 2, 400*7dc08ffcSJunyu Lai { 1: "peer_allowed_to_send", 401*7dc08ffcSJunyu Lai 2: "peer_not_allowed_to_send" }) ] 402*7dc08ffcSJunyu Lai 403*7dc08ffcSJunyu Lai 404*7dc08ffcSJunyu Laiclass ProtocolName(Packet): 405*7dc08ffcSJunyu Lai name = "Protocol Name" 406*7dc08ffcSJunyu Lai fields_desc = [ FieldLenField("len", None, fmt='B', length_of="protocol"), 407*7dc08ffcSJunyu Lai StrLenField("protocol", "", 408*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.len)] 409*7dc08ffcSJunyu Lai def guess_payload_class(self, p): 410*7dc08ffcSJunyu Lai return Padding 411*7dc08ffcSJunyu Lai 412*7dc08ffcSJunyu Laiclass ProtocolListField(PacketListField): 413*7dc08ffcSJunyu Lai def i2repr(self, pkt, x): 414*7dc08ffcSJunyu Lai res = [p.protocol for p in x] 415*7dc08ffcSJunyu Lai return "[%s]" % b", ".join(res) 416*7dc08ffcSJunyu Lai 417*7dc08ffcSJunyu Laiclass TLS_Ext_ALPN(TLS_Ext_PrettyPacketList): # RFC 7301 418*7dc08ffcSJunyu Lai name = "TLS Extension - Application Layer Protocol Negotiation" 419*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x10, _tls_ext), 420*7dc08ffcSJunyu Lai ShortField("len", None), 421*7dc08ffcSJunyu Lai FieldLenField("protocolslen", None, length_of="protocols"), 422*7dc08ffcSJunyu Lai ProtocolListField("protocols", [], ProtocolName, 423*7dc08ffcSJunyu Lai length_from=lambda pkt:pkt.protocolslen) ] 424*7dc08ffcSJunyu Lai 425*7dc08ffcSJunyu Lai 426*7dc08ffcSJunyu Laiclass TLS_Ext_Padding(TLS_Ext_Unknown): # RFC 7685 427*7dc08ffcSJunyu Lai name = "TLS Extension - Padding" 428*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x15, _tls_ext), 429*7dc08ffcSJunyu Lai FieldLenField("len", None, length_of="padding"), 430*7dc08ffcSJunyu Lai StrLenField("padding", "", 431*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.len) ] 432*7dc08ffcSJunyu Lai 433*7dc08ffcSJunyu Lai 434*7dc08ffcSJunyu Laiclass TLS_Ext_EncryptThenMAC(TLS_Ext_Unknown): # RFC 7366 435*7dc08ffcSJunyu Lai name = "TLS Extension - Encrypt-then-MAC" 436*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x16, _tls_ext), 437*7dc08ffcSJunyu Lai ShortField("len", None) ] 438*7dc08ffcSJunyu Lai 439*7dc08ffcSJunyu Lai 440*7dc08ffcSJunyu Laiclass TLS_Ext_ExtendedMasterSecret(TLS_Ext_Unknown): # RFC 7627 441*7dc08ffcSJunyu Lai name = "TLS Extension - Extended Master Secret" 442*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x17, _tls_ext), 443*7dc08ffcSJunyu Lai ShortField("len", None) ] 444*7dc08ffcSJunyu Lai 445*7dc08ffcSJunyu Lai 446*7dc08ffcSJunyu Laiclass TLS_Ext_SessionTicket(TLS_Ext_Unknown): # RFC 5077 447*7dc08ffcSJunyu Lai """ 448*7dc08ffcSJunyu Lai RFC 5077 updates RFC 4507 according to most implementations, which do not 449*7dc08ffcSJunyu Lai use another (useless) 'ticketlen' field after the global 'len' field. 450*7dc08ffcSJunyu Lai """ 451*7dc08ffcSJunyu Lai name = "TLS Extension - Session Ticket" 452*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x23, _tls_ext), 453*7dc08ffcSJunyu Lai FieldLenField("len", None, length_of="ticket"), 454*7dc08ffcSJunyu Lai StrLenField("ticket", "", 455*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.len) ] 456*7dc08ffcSJunyu Lai 457*7dc08ffcSJunyu Lai 458*7dc08ffcSJunyu Laiclass TLS_Ext_KeyShare(TLS_Ext_Unknown): 459*7dc08ffcSJunyu Lai name = "TLS Extension - Key Share (dummy class)" 460*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x28, _tls_ext), 461*7dc08ffcSJunyu Lai ShortField("len", None) ] 462*7dc08ffcSJunyu Lai 463*7dc08ffcSJunyu Lai 464*7dc08ffcSJunyu Laiclass TLS_Ext_PreSharedKey(TLS_Ext_Unknown): 465*7dc08ffcSJunyu Lai name = "TLS Extension - Pre Shared Key (dummy class)" 466*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x29, _tls_ext), 467*7dc08ffcSJunyu Lai ShortField("len", None) ] 468*7dc08ffcSJunyu Lai 469*7dc08ffcSJunyu Lai 470*7dc08ffcSJunyu Laiclass TLS_Ext_EarlyData(TLS_Ext_Unknown): 471*7dc08ffcSJunyu Lai name = "TLS Extension - Early Data" 472*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x2a, _tls_ext), 473*7dc08ffcSJunyu Lai ShortField("len", None) ] 474*7dc08ffcSJunyu Lai 475*7dc08ffcSJunyu Lai 476*7dc08ffcSJunyu Laiclass TLS_Ext_SupportedVersions(TLS_Ext_Unknown): 477*7dc08ffcSJunyu Lai name = "TLS Extension - Supported Versions" 478*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x2b, _tls_ext), 479*7dc08ffcSJunyu Lai ShortField("len", None), 480*7dc08ffcSJunyu Lai FieldLenField("versionslen", None, fmt='B', 481*7dc08ffcSJunyu Lai length_of="versions"), 482*7dc08ffcSJunyu Lai FieldListField("versions", [], 483*7dc08ffcSJunyu Lai ShortEnumField("version", None, 484*7dc08ffcSJunyu Lai _tls_version), 485*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.versionslen) ] 486*7dc08ffcSJunyu Lai 487*7dc08ffcSJunyu Lai 488*7dc08ffcSJunyu Laiclass TLS_Ext_Cookie(TLS_Ext_Unknown): 489*7dc08ffcSJunyu Lai name = "TLS Extension - Cookie" 490*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x2c, _tls_ext), 491*7dc08ffcSJunyu Lai ShortField("len", None), 492*7dc08ffcSJunyu Lai FieldLenField("cookielen", None, length_of="cookie"), 493*7dc08ffcSJunyu Lai XStrLenField("cookie", "", 494*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.cookielen) ] 495*7dc08ffcSJunyu Lai 496*7dc08ffcSJunyu Lai 497*7dc08ffcSJunyu Lai_tls_psk_kx_modes = { 0: "psk_ke", 1: "psk_dhe_ke" } 498*7dc08ffcSJunyu Lai 499*7dc08ffcSJunyu Laiclass TLS_Ext_PSKKeyExchangeModes(TLS_Ext_Unknown): 500*7dc08ffcSJunyu Lai name = "TLS Extension - PSK Key Exchange Modes" 501*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x2d, _tls_ext), 502*7dc08ffcSJunyu Lai ShortField("len", None), 503*7dc08ffcSJunyu Lai FieldLenField("kxmodeslen", None, fmt='B', 504*7dc08ffcSJunyu Lai length_of="kxmodes"), 505*7dc08ffcSJunyu Lai FieldListField("kxmodes", [], 506*7dc08ffcSJunyu Lai ByteEnumField("kxmode", None, 507*7dc08ffcSJunyu Lai _tls_psk_kx_modes), 508*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.kxmodeslen) ] 509*7dc08ffcSJunyu Lai 510*7dc08ffcSJunyu Lai 511*7dc08ffcSJunyu Laiclass TLS_Ext_TicketEarlyDataInfo(TLS_Ext_Unknown): 512*7dc08ffcSJunyu Lai name = "TLS Extension - Ticket Early Data Info" 513*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x2e, _tls_ext), 514*7dc08ffcSJunyu Lai ShortField("len", None), 515*7dc08ffcSJunyu Lai IntField("max_early_data_size", 0) ] 516*7dc08ffcSJunyu Lai 517*7dc08ffcSJunyu Lai 518*7dc08ffcSJunyu Laiclass TLS_Ext_NPN(TLS_Ext_PrettyPacketList): 519*7dc08ffcSJunyu Lai """ 520*7dc08ffcSJunyu Lai Defined in RFC-draft-agl-tls-nextprotoneg-03. Deprecated in favour of ALPN. 521*7dc08ffcSJunyu Lai """ 522*7dc08ffcSJunyu Lai name = "TLS Extension - Next Protocol Negotiation" 523*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0x3374, _tls_ext), 524*7dc08ffcSJunyu Lai FieldLenField("len", None, length_of="protocols"), 525*7dc08ffcSJunyu Lai ProtocolListField("protocols", [], ProtocolName, 526*7dc08ffcSJunyu Lai length_from=lambda pkt:pkt.len) ] 527*7dc08ffcSJunyu Lai 528*7dc08ffcSJunyu Lai 529*7dc08ffcSJunyu Laiclass TLS_Ext_RenegotiationInfo(TLS_Ext_Unknown): # RFC 5746 530*7dc08ffcSJunyu Lai name = "TLS Extension - Renegotiation Indication" 531*7dc08ffcSJunyu Lai fields_desc = [ShortEnumField("type", 0xff01, _tls_ext), 532*7dc08ffcSJunyu Lai ShortField("len", None), 533*7dc08ffcSJunyu Lai FieldLenField("reneg_conn_len", None, fmt='B', 534*7dc08ffcSJunyu Lai length_of="renegotiated_connection"), 535*7dc08ffcSJunyu Lai StrLenField("renegotiated_connection", "", 536*7dc08ffcSJunyu Lai length_from=lambda pkt: pkt.reneg_conn_len) ] 537*7dc08ffcSJunyu Lai 538*7dc08ffcSJunyu Lai 539*7dc08ffcSJunyu Lai_tls_ext_cls = { 0: TLS_Ext_ServerName, 540*7dc08ffcSJunyu Lai 1: TLS_Ext_MaxFragLen, 541*7dc08ffcSJunyu Lai 2: TLS_Ext_ClientCertURL, 542*7dc08ffcSJunyu Lai 3: TLS_Ext_TrustedCAInd, 543*7dc08ffcSJunyu Lai 4: TLS_Ext_TruncatedHMAC, 544*7dc08ffcSJunyu Lai 5: TLS_Ext_CSR, 545*7dc08ffcSJunyu Lai 6: TLS_Ext_UserMapping, 546*7dc08ffcSJunyu Lai 7: TLS_Ext_ClientAuthz, 547*7dc08ffcSJunyu Lai 8: TLS_Ext_ServerAuthz, 548*7dc08ffcSJunyu Lai 9: _TLS_Ext_CertTypeDispatcher, 549*7dc08ffcSJunyu Lai #10: TLS_Ext_SupportedEllipticCurves, 550*7dc08ffcSJunyu Lai 10: TLS_Ext_SupportedGroups, 551*7dc08ffcSJunyu Lai 11: TLS_Ext_SupportedPointFormat, 552*7dc08ffcSJunyu Lai 13: TLS_Ext_SignatureAlgorithms, 553*7dc08ffcSJunyu Lai 0x0f: TLS_Ext_Heartbeat, 554*7dc08ffcSJunyu Lai 0x10: TLS_Ext_ALPN, 555*7dc08ffcSJunyu Lai 0x15: TLS_Ext_Padding, 556*7dc08ffcSJunyu Lai 0x16: TLS_Ext_EncryptThenMAC, 557*7dc08ffcSJunyu Lai 0x17: TLS_Ext_ExtendedMasterSecret, 558*7dc08ffcSJunyu Lai 0x23: TLS_Ext_SessionTicket, 559*7dc08ffcSJunyu Lai 0x28: TLS_Ext_KeyShare, 560*7dc08ffcSJunyu Lai 0x29: TLS_Ext_PreSharedKey, 561*7dc08ffcSJunyu Lai 0x2a: TLS_Ext_EarlyData, 562*7dc08ffcSJunyu Lai 0x2b: TLS_Ext_SupportedVersions, 563*7dc08ffcSJunyu Lai 0x2c: TLS_Ext_Cookie, 564*7dc08ffcSJunyu Lai 0x2d: TLS_Ext_PSKKeyExchangeModes, 565*7dc08ffcSJunyu Lai 0x2e: TLS_Ext_TicketEarlyDataInfo, 566*7dc08ffcSJunyu Lai #0x2f: TLS_Ext_CertificateAuthorities, #XXX 567*7dc08ffcSJunyu Lai #0x30: TLS_Ext_OIDFilters, #XXX 568*7dc08ffcSJunyu Lai 0x3374: TLS_Ext_NPN, 569*7dc08ffcSJunyu Lai 0xff01: TLS_Ext_RenegotiationInfo 570*7dc08ffcSJunyu Lai } 571*7dc08ffcSJunyu Lai 572*7dc08ffcSJunyu Lai 573*7dc08ffcSJunyu Laiclass _ExtensionsLenField(FieldLenField): 574*7dc08ffcSJunyu Lai def getfield(self, pkt, s): 575*7dc08ffcSJunyu Lai """ 576*7dc08ffcSJunyu Lai We try to compute a length, usually from a msglen parsed earlier. 577*7dc08ffcSJunyu Lai If this length is 0, we consider 'selection_present' (from RFC 5246) 578*7dc08ffcSJunyu Lai to be False. This means that there should not be any length field. 579*7dc08ffcSJunyu Lai However, with TLS 1.3, zero lengths are always explicit. 580*7dc08ffcSJunyu Lai """ 581*7dc08ffcSJunyu Lai ext = pkt.get_field(self.length_of) 582*7dc08ffcSJunyu Lai l = ext.length_from(pkt) 583*7dc08ffcSJunyu Lai if l is None or l <= 0: 584*7dc08ffcSJunyu Lai v = pkt.tls_session.tls_version 585*7dc08ffcSJunyu Lai if v is None or v < 0x0304: 586*7dc08ffcSJunyu Lai return s, None 587*7dc08ffcSJunyu Lai return super(_ExtensionsLenField, self).getfield(pkt, s) 588*7dc08ffcSJunyu Lai 589*7dc08ffcSJunyu Lai def addfield(self, pkt, s, i): 590*7dc08ffcSJunyu Lai """ 591*7dc08ffcSJunyu Lai There is a hack with the _ExtensionsField.i2len. It works only because 592*7dc08ffcSJunyu Lai we expect _ExtensionsField.i2m to return a string of the same size (if 593*7dc08ffcSJunyu Lai not of the same value) upon successive calls (e.g. through i2len here, 594*7dc08ffcSJunyu Lai then i2m when directly building the _ExtensionsField). 595*7dc08ffcSJunyu Lai 596*7dc08ffcSJunyu Lai XXX A proper way to do this would be to keep the extensions built from 597*7dc08ffcSJunyu Lai the i2len call here, instead of rebuilding them later on. 598*7dc08ffcSJunyu Lai """ 599*7dc08ffcSJunyu Lai if i is None: 600*7dc08ffcSJunyu Lai if self.length_of is not None: 601*7dc08ffcSJunyu Lai fld,fval = pkt.getfield_and_val(self.length_of) 602*7dc08ffcSJunyu Lai 603*7dc08ffcSJunyu Lai tmp = pkt.tls_session.frozen 604*7dc08ffcSJunyu Lai pkt.tls_session.frozen = True 605*7dc08ffcSJunyu Lai f = fld.i2len(pkt, fval) 606*7dc08ffcSJunyu Lai pkt.tls_session.frozen = tmp 607*7dc08ffcSJunyu Lai 608*7dc08ffcSJunyu Lai i = self.adjust(pkt, f) 609*7dc08ffcSJunyu Lai if i == 0: # for correct build if no ext and not explicitly 0 610*7dc08ffcSJunyu Lai return s 611*7dc08ffcSJunyu Lai return s + struct.pack(self.fmt, i) 612*7dc08ffcSJunyu Lai 613*7dc08ffcSJunyu Laiclass _ExtensionsField(StrLenField): 614*7dc08ffcSJunyu Lai islist=1 615*7dc08ffcSJunyu Lai holds_packets=1 616*7dc08ffcSJunyu Lai 617*7dc08ffcSJunyu Lai def i2len(self, pkt, i): 618*7dc08ffcSJunyu Lai if i is None: 619*7dc08ffcSJunyu Lai return 0 620*7dc08ffcSJunyu Lai return len(self.i2m(pkt, i)) 621*7dc08ffcSJunyu Lai 622*7dc08ffcSJunyu Lai def getfield(self, pkt, s): 623*7dc08ffcSJunyu Lai l = self.length_from(pkt) 624*7dc08ffcSJunyu Lai if l is None: 625*7dc08ffcSJunyu Lai return s, [] 626*7dc08ffcSJunyu Lai return s[l:], self.m2i(pkt, s[:l]) 627*7dc08ffcSJunyu Lai 628*7dc08ffcSJunyu Lai def i2m(self, pkt, i): 629*7dc08ffcSJunyu Lai if i is None: 630*7dc08ffcSJunyu Lai return b"" 631*7dc08ffcSJunyu Lai if isinstance(pkt, _GenericTLSSessionInheritance): 632*7dc08ffcSJunyu Lai if not pkt.tls_session.frozen: 633*7dc08ffcSJunyu Lai s = b"" 634*7dc08ffcSJunyu Lai for ext in i: 635*7dc08ffcSJunyu Lai if isinstance(ext, _GenericTLSSessionInheritance): 636*7dc08ffcSJunyu Lai ext.tls_session = pkt.tls_session 637*7dc08ffcSJunyu Lai s += ext.raw_stateful() 638*7dc08ffcSJunyu Lai else: 639*7dc08ffcSJunyu Lai s += raw(ext) 640*7dc08ffcSJunyu Lai return s 641*7dc08ffcSJunyu Lai return b"".join(map(raw, i)) 642*7dc08ffcSJunyu Lai 643*7dc08ffcSJunyu Lai def m2i(self, pkt, m): 644*7dc08ffcSJunyu Lai res = [] 645*7dc08ffcSJunyu Lai while m: 646*7dc08ffcSJunyu Lai t = struct.unpack("!H", m[:2])[0] 647*7dc08ffcSJunyu Lai l = struct.unpack("!H", m[2:4])[0] 648*7dc08ffcSJunyu Lai cls = _tls_ext_cls.get(t, TLS_Ext_Unknown) 649*7dc08ffcSJunyu Lai if cls is TLS_Ext_KeyShare: 650*7dc08ffcSJunyu Lai from scapy.layers.tls.keyexchange_tls13 import _tls_ext_keyshare_cls 651*7dc08ffcSJunyu Lai cls = _tls_ext_keyshare_cls.get(pkt.msgtype, TLS_Ext_Unknown) 652*7dc08ffcSJunyu Lai elif cls is TLS_Ext_PreSharedKey: 653*7dc08ffcSJunyu Lai from scapy.layers.tls.keyexchange_tls13 import _tls_ext_presharedkey_cls 654*7dc08ffcSJunyu Lai cls = _tls_ext_presharedkey_cls.get(pkt.msgtype, TLS_Ext_Unknown) 655*7dc08ffcSJunyu Lai res.append(cls(m[:l+4], tls_session=pkt.tls_session)) 656*7dc08ffcSJunyu Lai m = m[l+4:] 657*7dc08ffcSJunyu Lai return res 658*7dc08ffcSJunyu Lai 659*7dc08ffcSJunyu Lai 660