1
2
3
4
5
6
7
8
9 """Classes representing TLS messages."""
10
11 from .utils.compat import *
12 from .utils.cryptomath import *
13 from .errors import *
14 from .utils.codec import *
15 from .constants import *
16 from .x509 import X509
17 from .x509certchain import X509CertChain
18 from .utils.tackwrapper import *
19
22 self.type = 0
23 self.version = (0,0)
24 self.length = 0
25 self.ssl2 = False
26
28 self.type = type
29 self.version = version
30 self.length = length
31 return self
32
34 w = Writer()
35 w.add(self.type, 1)
36 w.add(self.version[0], 1)
37 w.add(self.version[1], 1)
38 w.add(self.length, 2)
39 return w.bytes
40
42 self.type = p.get(1)
43 self.version = (p.get(1), p.get(1))
44 self.length = p.get(2)
45 self.ssl2 = False
46 return self
47
50 self.type = 0
51 self.version = (0,0)
52 self.length = 0
53 self.ssl2 = True
54
63
64
67 self.contentType = ContentType.alert
68 self.level = 0
69 self.description = 0
70
72 self.level = level
73 self.description = description
74 return self
75
82
84 w = Writer()
85 w.add(self.level, 1)
86 w.add(self.description, 1)
87 return w.bytes
88
89
94
95 - def postWrite(self, w):
96 headerWriter = Writer()
97 headerWriter.add(self.handshakeType, 1)
98 headerWriter.add(len(w.bytes), 3)
99 return headerWriter.bytes + w.bytes
100
115
116 - def create(self, version, random, session_id, cipher_suites,
117 certificate_types=None, srp_username=None,
118 tack=False, supports_npn=False, server_name=""):
119 self.client_version = version
120 self.random = random
121 self.session_id = session_id
122 self.cipher_suites = cipher_suites
123 self.certificate_types = certificate_types
124 self.compression_methods = [0]
125 self.srp_username = srp_username
126 self.tack = tack
127 self.supports_npn = supports_npn
128 self.server_name = server_name
129 return self
130
188
190 w = Writer()
191 w.add(self.client_version[0], 1)
192 w.add(self.client_version[1], 1)
193 w.addFixSeq(self.random, 1)
194 w.addVarSeq(self.session_id, 1, 1)
195 w.addVarSeq(self.cipher_suites, 2, 2)
196 w.addVarSeq(self.compression_methods, 1, 1)
197
198 w2 = Writer()
199 if self.certificate_types and self.certificate_types != \
200 [CertificateType.x509]:
201 w2.add(ExtensionType.cert_type, 2)
202 w2.add(len(self.certificate_types)+1, 2)
203 w2.addVarSeq(self.certificate_types, 1, 1)
204 if self.srp_username:
205 w2.add(ExtensionType.srp, 2)
206 w2.add(len(self.srp_username)+1, 2)
207 w2.addVarSeq(stringToBytes(self.srp_username), 1, 1)
208 if self.server_name:
209 w2.add(ExtensionType.server_name, 2)
210 w2.add(len(self.server_name)+5, 2)
211 w2.add(len(self.server_name)+3, 2)
212 w2.add(NameType.host_name, 1)
213 w2.addVarSeq(stringToBytes(self.server_name), 1, 2)
214 if self.tack:
215 w2.add(ExtensionType.tack, 2)
216 w2.add(0, 2)
217 if len(w2.bytes):
218 w.add(len(w2.bytes), 2)
219 w.bytes += w2.bytes
220 return self.postWrite(w)
221
225
227 return 'Cannot encode a list of next protocols because it contains an element with invalid length %d. Element lengths must be 0 < x < 256' % self.length
228
240
241 - def create(self, version, random, session_id, cipher_suite,
242 certificate_type, tackExt, next_protos_advertised):
243 self.server_version = version
244 self.random = random
245 self.session_id = session_id
246 self.cipher_suite = cipher_suite
247 self.certificate_type = certificate_type
248 self.compression_method = 0
249 self.tackExt = tackExt
250 self.next_protos_advertised = next_protos_advertised
251 return self
252
277
279 a = []
280 for e in self.next_protos_advertised:
281 if len(e) > 255 or len(e) == 0:
282 raise BadNextProtos(len(e))
283 a.append(chr(len(e)))
284 a.append(e)
285
286 return [ord(x) for x in ''.join(a)]
287
289 w = Writer()
290 w.add(self.server_version[0], 1)
291 w.add(self.server_version[1], 1)
292 w.addFixSeq(self.random, 1)
293 w.addVarSeq(self.session_id, 1, 1)
294 w.add(self.cipher_suite, 2)
295 w.add(self.compression_method, 1)
296
297 w2 = Writer()
298 if self.certificate_type and self.certificate_type != \
299 CertificateType.x509:
300 w2.add(ExtensionType.cert_type, 2)
301 w2.add(1, 2)
302 w2.add(self.certificate_type, 1)
303 if self.tackExt:
304 b = self.tackExt.serialize()
305 w2.add(ExtensionType.tack, 2)
306 w2.add(len(b), 2)
307 w2.bytes += b
308 if self.next_protos_advertised is not None:
309 encoded_next_protos_advertised = self.__next_protos_encoded()
310 w2.add(ExtensionType.supports_npn, 2)
311 w2.add(len(encoded_next_protos_advertised), 2)
312 w2.addFixSeq(encoded_next_protos_advertised, 1)
313 if len(w2.bytes):
314 w.add(len(w2.bytes), 2)
315 w.bytes += w2.bytes
316 return self.postWrite(w)
317
318
324
326 self.certChain = certChain
327 return self
328
348
350 w = Writer()
351 if self.certificateType == CertificateType.x509:
352 chainLength = 0
353 if self.certChain:
354 certificate_list = self.certChain.x509List
355 else:
356 certificate_list = []
357
358 for cert in certificate_list:
359 bytes = cert.writeBytes()
360 chainLength += len(bytes)+3
361
362 w.add(chainLength, 3)
363 for cert in certificate_list:
364 bytes = cert.writeBytes()
365 w.addVarSeq(bytes, 1, 3)
366 else:
367 raise AssertionError()
368 return self.postWrite(w)
369
377
378 - def create(self, certificate_types, certificate_authorities):
379 self.certificate_types = certificate_types
380 self.certificate_authorities = certificate_authorities
381 return self
382
384 p.startLengthCheck(3)
385 self.certificate_types = p.getVarList(1, 1)
386 ca_list_length = p.get(2)
387 index = 0
388 self.certificate_authorities = []
389 while index != ca_list_length:
390 ca_bytes = p.getVarBytes(2)
391 self.certificate_authorities.append(ca_bytes)
392 index += len(ca_bytes)+2
393 p.stopLengthCheck()
394 return self
395
397 w = Writer()
398 w.addVarSeq(self.certificate_types, 1, 1)
399 caLength = 0
400
401 for ca_dn in self.certificate_authorities:
402 caLength += len(ca_dn)+2
403 w.add(caLength, 2)
404
405 for ca_dn in self.certificate_authorities:
406 w.addVarSeq(ca_dn, 1, 2)
407 return self.postWrite(w)
408
422
423 - def createSRP(self, srp_N, srp_g, srp_s, srp_B):
424 self.srp_N = srp_N
425 self.srp_g = srp_g
426 self.srp_s = srp_s
427 self.srp_B = srp_B
428 return self
429
431 self.dh_p = dh_p
432 self.dh_g = dh_g
433 self.dh_Ys = dh_Ys
434 return self
435
451
453 w = Writer()
454 if self.cipherSuite in CipherSuite.srpAllSuites:
455 w.addVarSeq(numberToBytes(self.srp_N), 1, 2)
456 w.addVarSeq(numberToBytes(self.srp_g), 1, 2)
457 w.addVarSeq(self.srp_s, 1, 1)
458 w.addVarSeq(numberToBytes(self.srp_B), 1, 2)
459 if self.cipherSuite in CipherSuite.srpCertSuites:
460 w.addVarSeq(self.signature, 1, 2)
461 elif self.cipherSuite in CipherSuite.anonSuites:
462 w.addVarSeq(numberToBytes(self.dh_p), 1, 2)
463 w.addVarSeq(numberToBytes(self.dh_g), 1, 2)
464 w.addVarSeq(numberToBytes(self.dh_Ys), 1, 2)
465 if self.cipherSuite in []:
466 w.addVarSeq(self.signature, 1, 2)
467 return self.postWrite(w)
468
469 - def hash(self, clientRandom, serverRandom):
470 oldCipherSuite = self.cipherSuite
471 self.cipherSuite = None
472 try:
473 bytes = clientRandom + serverRandom + self.write()[4:]
474 s = bytesToString(bytes)
475 return stringToBytes(md5(s).digest() + sha1(s).digest())
476 finally:
477 self.cipherSuite = oldCipherSuite
478
494
496 - def __init__(self, cipherSuite, version=None):
502
504 self.srp_A = srp_A
505 return self
506
507 - def createRSA(self, encryptedPreMasterSecret):
508 self.encryptedPreMasterSecret = encryptedPreMasterSecret
509 return self
510
512 self.dh_Yc = dh_Yc
513 return self
514
533
535 w = Writer()
536 if self.cipherSuite in CipherSuite.srpAllSuites:
537 w.addVarSeq(numberToBytes(self.srp_A), 1, 2)
538 elif self.cipherSuite in CipherSuite.certSuites:
539 if self.version in ((3,1), (3,2)):
540 w.addVarSeq(self.encryptedPreMasterSecret, 1, 2)
541 elif self.version == (3,0):
542 w.addFixSeq(self.encryptedPreMasterSecret, 1)
543 else:
544 raise AssertionError()
545 elif self.cipherSuite in CipherSuite.anonSuites:
546 w.addVarSeq(numberToBytes(self.dh_Yc), 1, 2)
547 else:
548 raise AssertionError()
549 return self.postWrite(w)
550
555
557 self.signature = signature
558 return self
559
565
570
575
577 self.type = 1
578 return self
579
585
587 w = Writer()
588 w.add(self.type,1)
589 return w.bytes
590
591
596
597 - def create(self, next_proto):
598 self.next_proto = next_proto
599
606
612
618
619 - def create(self, verify_data):
620 self.verify_data = verify_data
621 return self
622
633
638
643
645 self.bytes = bytes
646 return self
647
652
654 self.bytes = p.bytes
655 return self
656
659