1
2
3
4
5
6
7 """Classes representing TLS messages."""
8
9 from .utils.compat import *
10 from .utils.cryptomath import *
11 from .errors import *
12 from .utils.codec import *
13 from .constants import *
14 from .x509 import X509
15 from .x509certchain import X509CertChain
16 from .utils.tackwrapper import *
17
20 self.type = 0
21 self.version = (0,0)
22 self.length = 0
23 self.ssl2 = False
24
26 self.type = type
27 self.version = version
28 self.length = length
29 return self
30
32 w = Writer()
33 w.add(self.type, 1)
34 w.add(self.version[0], 1)
35 w.add(self.version[1], 1)
36 w.add(self.length, 2)
37 return w.bytes
38
40 self.type = p.get(1)
41 self.version = (p.get(1), p.get(1))
42 self.length = p.get(2)
43 self.ssl2 = False
44 return self
45
48 self.type = 0
49 self.version = (0,0)
50 self.length = 0
51 self.ssl2 = True
52
61
62
65 self.contentType = ContentType.alert
66 self.level = 0
67 self.description = 0
68
70 self.level = level
71 self.description = description
72 return self
73
80
82 w = Writer()
83 w.add(self.level, 1)
84 w.add(self.description, 1)
85 return w.bytes
86
87
92
93 - def postWrite(self, w):
94 headerWriter = Writer()
95 headerWriter.add(self.handshakeType, 1)
96 headerWriter.add(len(w.bytes), 3)
97 return headerWriter.bytes + w.bytes
98
111
112 - def create(self, version, random, session_id, cipher_suites,
113 certificate_types=None, srp_username=None,
114 tack=False):
115 self.client_version = version
116 self.random = random
117 self.session_id = session_id
118 self.cipher_suites = cipher_suites
119 self.certificate_types = certificate_types
120 self.compression_methods = [0]
121 self.srp_username = srp_username
122 self.tack = tack
123 return self
124
126 if self.ssl2:
127 self.client_version = (p.get(1), p.get(1))
128 cipherSpecsLength = p.get(2)
129 sessionIDLength = p.get(2)
130 randomLength = p.get(2)
131 self.cipher_suites = p.getFixList(3, cipherSpecsLength//3)
132 self.session_id = p.getFixBytes(sessionIDLength)
133 self.random = p.getFixBytes(randomLength)
134 if len(self.random) < 32:
135 zeroBytes = 32-len(self.random)
136 self.random = createByteArrayZeros(zeroBytes) + self.random
137 self.compression_methods = [0]
138
139
140 else:
141 p.startLengthCheck(3)
142 self.client_version = (p.get(1), p.get(1))
143 self.random = p.getFixBytes(32)
144 self.session_id = p.getVarBytes(1)
145 self.cipher_suites = p.getVarList(2, 2)
146 self.compression_methods = p.getVarList(1, 1)
147 if not p.atLengthCheck():
148 totalExtLength = p.get(2)
149 soFar = 0
150 while soFar != totalExtLength:
151 extType = p.get(2)
152 extLength = p.get(2)
153 index1 = p.index
154 if extType == ExtensionType.srp:
155 self.srp_username = bytesToString(p.getVarBytes(1))
156 elif extType == ExtensionType.cert_type:
157 self.certificate_types = p.getVarList(1, 1)
158 elif extType == ExtensionType.tack:
159 self.tack = True
160 else:
161 p.getFixBytes(extLength)
162 index2 = p.index
163 if index2 - index1 != extLength:
164 raise SyntaxError("Bad length for extension_data")
165 soFar += 4 + extLength
166 p.stopLengthCheck()
167 return self
168
170 w = Writer()
171 w.add(self.client_version[0], 1)
172 w.add(self.client_version[1], 1)
173 w.addFixSeq(self.random, 1)
174 w.addVarSeq(self.session_id, 1, 1)
175 w.addVarSeq(self.cipher_suites, 2, 2)
176 w.addVarSeq(self.compression_methods, 1, 1)
177
178 w2 = Writer()
179 if self.certificate_types and self.certificate_types != \
180 [CertificateType.x509]:
181 w2.add(ExtensionType.cert_type, 2)
182 w2.add(len(self.certificate_types)+1, 2)
183 w2.addVarSeq(self.certificate_types, 1, 1)
184 if self.srp_username:
185 w2.add(ExtensionType.srp, 2)
186 w2.add(len(self.srp_username)+1, 2)
187 w2.addVarSeq(stringToBytes(self.srp_username), 1, 1)
188 if self.tack:
189 w2.add(ExtensionType.tack, 2)
190 w2.add(0, 2)
191 if len(w2.bytes):
192 w.add(len(w2.bytes), 2)
193 w.bytes += w2.bytes
194 return self.postWrite(w)
195
206
207 - def create(self, version, random, session_id, cipher_suite,
208 certificate_type, tackExt):
209 self.server_version = version
210 self.random = random
211 self.session_id = session_id
212 self.cipher_suite = cipher_suite
213 self.certificate_type = certificate_type
214 self.compression_method = 0
215 self.tackExt = tackExt
216 return self
217
243
245 w = Writer()
246 w.add(self.server_version[0], 1)
247 w.add(self.server_version[1], 1)
248 w.addFixSeq(self.random, 1)
249 w.addVarSeq(self.session_id, 1, 1)
250 w.add(self.cipher_suite, 2)
251 w.add(self.compression_method, 1)
252
253 w2 = Writer()
254 if self.certificate_type and self.certificate_type != \
255 CertificateType.x509:
256 w2.add(ExtensionType.cert_type, 2)
257 w2.add(1, 2)
258 w2.add(self.certificate_type, 1)
259 if self.tackExt:
260 b = self.tackExt.write()
261 w2.add(ExtensionType.tack, 2)
262 w2.add(len(b), 2)
263 w2.bytes += b
264 if len(w2.bytes):
265 w.add(len(w2.bytes), 2)
266 w.bytes += w2.bytes
267 return self.postWrite(w)
268
269
275
277 self.certChain = certChain
278 return self
279
299
301 w = Writer()
302 if self.certificateType == CertificateType.x509:
303 chainLength = 0
304 if self.certChain:
305 certificate_list = self.certChain.x509List
306 else:
307 certificate_list = []
308
309 for cert in certificate_list:
310 bytes = cert.writeBytes()
311 chainLength += len(bytes)+3
312
313 w.add(chainLength, 3)
314 for cert in certificate_list:
315 bytes = cert.writeBytes()
316 w.addVarSeq(bytes, 1, 3)
317 else:
318 raise AssertionError()
319 return self.postWrite(w)
320
328
329 - def create(self, certificate_types, certificate_authorities):
330 self.certificate_types = certificate_types
331 self.certificate_authorities = certificate_authorities
332 return self
333
335 p.startLengthCheck(3)
336 self.certificate_types = p.getVarList(1, 1)
337 ca_list_length = p.get(2)
338 index = 0
339 self.certificate_authorities = []
340 while index != ca_list_length:
341 ca_bytes = p.getVarBytes(2)
342 self.certificate_authorities.append(ca_bytes)
343 index += len(ca_bytes)+2
344 p.stopLengthCheck()
345 return self
346
348 w = Writer()
349 w.addVarSeq(self.certificate_types, 1, 1)
350 caLength = 0
351
352 for ca_dn in self.certificate_authorities:
353 caLength += len(ca_dn)+2
354 w.add(caLength, 2)
355
356 for ca_dn in self.certificate_authorities:
357 w.addVarSeq(ca_dn, 1, 2)
358 return self.postWrite(w)
359
369
370 - def createSRP(self, srp_N, srp_g, srp_s, srp_B):
371 self.srp_N = srp_N
372 self.srp_g = srp_g
373 self.srp_s = srp_s
374 self.srp_B = srp_B
375 return self
376
387
389 w = Writer()
390 w.addVarSeq(numberToBytes(self.srp_N), 1, 2)
391 w.addVarSeq(numberToBytes(self.srp_g), 1, 2)
392 w.addVarSeq(self.srp_s, 1, 1)
393 w.addVarSeq(numberToBytes(self.srp_B), 1, 2)
394 if self.cipherSuite in CipherSuite.srpCertSuites:
395 w.addVarSeq(self.signature, 1, 2)
396 return self.postWrite(w)
397
398 - def hash(self, clientRandom, serverRandom):
399 oldCipherSuite = self.cipherSuite
400 self.cipherSuite = None
401 try:
402 bytes = clientRandom + serverRandom + self.write()[4:]
403 s = bytesToString(bytes)
404 return stringToBytes(md5(s).digest() + sha1(s).digest())
405 finally:
406 self.cipherSuite = oldCipherSuite
407
423
425 - def __init__(self, cipherSuite, version=None):
431
433 self.srp_A = srp_A
434 return self
435
436 - def createRSA(self, encryptedPreMasterSecret):
437 self.encryptedPreMasterSecret = encryptedPreMasterSecret
438 return self
439
456
471
476
478 self.signature = signature
479 return self
480
486
491
496
498 self.type = 1
499 return self
500
506
508 w = Writer()
509 w.add(self.type,1)
510 return w.bytes
511
512
518
519 - def create(self, verify_data):
520 self.verify_data = verify_data
521 return self
522
533
538
543
545 self.bytes = bytes
546 return self
547
552
554 self.bytes = p.bytes
555 return self
556
559