77TLS helpers, provided as out-of-context methods.
88"""
99
10+ from __future__ import absolute_import
11+ import struct
12+
13+ from scapy .compat import orb , chb
1014from scapy .error import warning
1115from scapy .fields import (ByteEnumField , ShortEnumField ,
1216 FieldLenField , StrLenField )
@@ -19,10 +23,9 @@ class TLSPlaintext(Packet):
1923 name = "TLS Plaintext"
2024 fields_desc = [ ByteEnumField ("type" , None , _tls_type ),
2125 ShortEnumField ("version" , None , _tls_version ),
22- FieldLenField ("len" , None , length_of = "fragment" ,
23- fmt = "!H" ),
24- StrLenField ("fragment" , "" ,
25- length_from = lambda pkt : pkt .length ) ]
26+ FieldLenField ("len" , None , length_of = "data" , fmt = "!H" ),
27+ StrLenField ("data" , "" ,
28+ length_from = lambda pkt : pkt .len ) ]
2629
2730class TLSCompressed (TLSPlaintext ):
2831 name = "TLS Compressed"
@@ -39,8 +42,8 @@ def _tls_compress(alg, p):
3942 c = TLSCompressed ()
4043 c .type = p .type
4144 c .version = p .version
42- c .fragment = alg .compress (p .fragment )
43- c .len = len (c .fragment )
45+ c .data = alg .compress (p .data )
46+ c .len = len (c .data )
4447 return c
4548
4649def _tls_decompress (alg , c ):
@@ -51,21 +54,21 @@ def _tls_decompress(alg, c):
5154 p = TLSPlaintext ()
5255 p .type = c .type
5356 p .version = c .version
54- p .fragment = alg .decompress (c .fragment )
55- p .len = len (p .fragment )
57+ p .data = alg .decompress (c .data )
58+ p .len = len (p .data )
5659 return p
5760
5861def _tls_mac_add (alg , c , write_seq_num ):
5962 """
6063 Compute the MAC using provided MAC alg instance over TLSCiphertext c using
6164 current write sequence number write_seq_num. Computed MAC is then appended
62- to c.fragment and c.length is updated to reflect that change. It is the
65+ to c.data and c.len is updated to reflect that change. It is the
6366 caller responsability to increment the sequence number after the operation.
6467 The function has no return value.
6568 """
6669 write_seq_num = struct .pack ("!Q" , write_seq_num )
67- h = alg .digest (write_seq_num + str (c ))
68- c .fragment += h
70+ h = alg .digest (write_seq_num + bytes (c ))
71+ c .data += h
6972 c .len += alg .hash_len
7073
7174def _tls_mac_verify (alg , p , read_seq_num ):
@@ -77,7 +80,7 @@ def _tls_mac_verify(alg, p, read_seq_num):
7780 If the MAC is valid:
7881 - The function returns True
7982 - The packet p is updated in the following way: trailing MAC value is
80- removed from p.fragment and length is updated accordingly.
83+ removed from p.data and length is updated accordingly.
8184
8285 In case of error, False is returned, and p may have been modified.
8386
@@ -87,52 +90,52 @@ def _tls_mac_verify(alg, p, read_seq_num):
8790 h_size = alg .hash_len
8891 if p .len < h_size :
8992 return False
90- received_h = p .fragment [- h_size :]
93+ received_h = p .data [- h_size :]
9194 p .len -= h_size
92- p .fragment = p .fragment [:- h_size ]
95+ p .data = p .data [:- h_size ]
9396
9497 read_seq_num = struct .pack ("!Q" , read_seq_num )
95- h = alg .digest (read_seq_num + str (p ))
98+ h = alg .digest (read_seq_num + bytes (p ))
9699 return h == received_h
97100
98101def _tls_add_pad (p , block_size ):
99102 """
100103 Provided with cipher block size parameter and current TLSCompressed packet
101104 p (after MAC addition), the function adds required, deterministic padding
102- to p.fragment before encryption step, as it is defined for TLS (i.e. not
105+ to p.data before encryption step, as it is defined for TLS (i.e. not
103106 SSL and its allowed random padding). The function has no return value.
104107 """
105- padlen = block_size - ((p .len + 1 ) % block_size )
106- if padlen == block_size :
107- padlen = 0
108- padding = chr (padlen ) * (padlen + 1 )
108+ padlen = - p .len % block_size
109+ padding = chb (padlen ) * (padlen + 1 )
109110 p .len += len (padding )
110- p .fragment += padding
111+ p .data += padding
111112
112113def _tls_del_pad (p ):
113114 """
114115 Provided with a just decrypted TLSCiphertext (now a TLSPlaintext instance)
115- p, the function removes the trailing padding found in p.fragment . It also
116+ p, the function removes the trailing padding found in p.data . It also
116117 performs some sanity checks on the padding (length, content, ...). False
117118 is returned if one of the check fails. Otherwise, True is returned,
118- indicating that p.fragment and p.len have been updated.
119+ indicating that p.data and p.len have been updated.
119120 """
120121
121122 if p .len < 1 :
122123 warning ("Message format is invalid (padding)" )
123124 return False
124125
125- padlen = ord (p .fragment [- 1 ]) + 1
126- if (p .len < padlen ):
126+ padlen = orb (p .data [- 1 ])
127+ padsize = padlen + 1
128+
129+ if p .len < padsize :
127130 warning ("Invalid padding length" )
128131 return False
129132
130- if ( p . fragment [ - padlen :] != p . fragment [ - 1 ] * padlen ) :
131- warning ("Padding content is invalid %s" , repr (p .fragment [ - padlen :]))
133+ if p . data [ - padsize :] != chb ( padlen ) * padsize :
134+ warning ("Padding content is invalid %s" , repr (p .data [ - padsize :]))
132135 return False
133136
134- p .fragment = p .fragment [:- padlen ]
135- p .len -= padlen
137+ p .data = p .data [:- padsize ]
138+ p .len -= padsize
136139
137140 return True
138141
@@ -146,66 +149,67 @@ def _tls_encrypt(alg, p):
146149 c = TLSCiphertext ()
147150 c .type = p .type
148151 c .version = p .version
149- c .fragment = alg .encrypt (p .fragment )
150- c .len = len (c .fragment )
152+ c .data = alg .encrypt (p .data )
153+ c .len = len (c .data )
151154 return c
152155
153156def _tls_decrypt (alg , c ):
154157 """
155158 Provided with a TLSCiphertext instance c, and a stream or block cipher alg,
156- the function decrypts c.fragment and returns a newly created TLSPlaintext.
159+ the function decrypts c.data and returns a newly created TLSPlaintext.
157160 """
158161 p = TLSPlaintext ()
159162 p .type = c .type
160163 p .version = c .version
161- p .fragment = alg .decrypt (c .fragment )
162- p .len = len (p .fragment )
164+ p .data = alg .decrypt (c .data )
165+ p .len = len (p .data )
163166 return p
164167
165168def _tls_aead_auth_encrypt (alg , p , write_seq_num ):
166169 """
167170 Provided with a TLSCompressed instance p, the function applies AEAD
168- cipher alg to p.fragment and builds a new TLSCiphertext instance. Unlike
171+ cipher alg to p.data and builds a new TLSCiphertext instance. Unlike
169172 for block and stream ciphers, for which the authentication step is done
170173 separately, AEAD alg does it simultaneously: this is the reason why
171174 write_seq_num is passed to the function, to be incorporated in
172175 authenticated data. Note that it is the caller's responsibility to increment
173176 write_seq_num afterwards.
174177 """
175- P = str (p )
178+ P = bytes (p )
176179 write_seq_num = struct .pack ("!Q" , write_seq_num )
177180 A = write_seq_num + P [:5 ]
178181
179- c = TLCCiphertext ()
182+ c = TLSCiphertext ()
180183 c .type = p .type
181184 c .version = p .version
182- c .fragment = alg .auth_encrypt (P , A )
183- c .len = len (c .fragment )
185+ c .data = alg .auth_encrypt (P , A , write_seq_num )
186+ c .len = len (c .data )
184187 return c
185188
186189def _tls_aead_auth_decrypt (alg , c , read_seq_num ):
187190 """
188191 Provided with a TLSCiphertext instance c, the function applies AEAD
189- cipher alg auth_decrypt function to c.fragment (and additional data)
190- in order to authenticate the data and decrypt c.fragment . When those
192+ cipher alg auth_decrypt function to c.data (and additional data)
193+ in order to authenticate the data and decrypt c.data . When those
191194 steps succeed, the result is a newly created TLSCompressed instance.
192195 On error, None is returned. Note that it is the caller's responsibility to
193196 increment read_seq_num afterwards.
194197 """
195198 # 'Deduce' TLSCompressed length from TLSCiphertext length
196199 # There is actually no guaranty of this equality, but this is defined as
197200 # such in TLS 1.2 specifications, and it works for GCM and CCM at least.
198- l = p .len - alg .nonce_explicit_len - alg .tag_len
201+ #
202+ plen = c .len - getattr (alg , "nonce_explicit_len" , 0 ) - alg .tag_len
199203 read_seq_num = struct .pack ("!Q" , read_seq_num )
200- A = read_seq_num + struct .pack ('!BHH' , p .type , p .version , l )
204+ A = read_seq_num + struct .pack ('!BHH' , c .type , c .version , plen )
201205
202206 p = TLSCompressed ()
203207 p .type = c .type
204208 p .version = c .version
205- p .len = l
206- p .fragment = alg .auth_decrypt (A , c .fragment )
209+ p .len = plen
210+ p .data = alg .auth_decrypt (A , c .data , read_seq_num )
207211
208- if p .fragment is None : # Verification failed.
212+ if p .data is None : # Verification failed.
209213 return None
210214 return p
211215
0 commit comments