xref: /aosp_15_r20/external/scapy/scapy/layers/tls/extensions.py (revision 7dc08ffc4802948ccbc861daaf1e81c405c2c4bd)
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