-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathTLSConstructs.py
executable file
·96 lines (82 loc) · 4.22 KB
/
TLSConstructs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
from construct import *
"Contructs for parsing TLS"
"A hacky class to represent a unsigned, 24 bit big-endian integer. Needed " +\
"for TLS's funny certificate lengths."
class UInt24(StaticField):
def __init__(self, name):
self.length = 3
StaticField.__init__(self, name, self.length)
def _parse(self, stream, context):
try:
d = core._read_stream(stream, self.length)
return (ord(d[0]) * 65536) + (ord(d[1]) * 256) + ord(d[2])
except Exception, ex:
raise FieldError(ex)
def _build(self, obj, stream, context):
try:
b= chr(obj / 65536) + chr((obj% 65536)/256) + chr((obj%256))
core._write_stream(stream, self.length, b)
except Exception, ex:
raise FieldError(ex)
HandshakeType = Enum(UBInt8("msg_type"), hello_request=0, client_hello=1,
server_hello=2, certificate=11, server_key_exchange=12,
certificate_request=13, server_hello_done=14,
certificate_verify=15, client_key_exchange=16,
finished=20)
CompressionMethod = Enum(Byte("compression_method"), null=0)
ProtocolVersion = Struct('ProtocolVersion', UBInt8('major'), UBInt8('minor'))
Random = Struct("random", UBInt32("gmt_unix_time"), String("random_bytes", 28))
HelloRequest = Struct("HelloRequest")
ClientHello = Struct("ClientHello", ProtocolVersion, Random,
PascalString("session_id",
length_field=UBInt8("session_id_length")),
# hacky
PascalString("cipher_suites",
length_field=UBInt16("cipher_suites_length")),
PascalString("compression_methods",
length_field=UBInt8("compression_length")),
PascalString("extensions",
length_field=UBInt16("extensions_length"))
)
ServerHello = Struct("ServerHello", ProtocolVersion, Random,
PascalString("session_id",
length_field=UBInt8("session_id_length")),
# hacky
PascalString("cipher_suites",
length_field=UBInt16("cipher_suites_length")),
PascalString("compression_methods",
length_field=UBInt8("compression_length")),
)
Certificate = Struct("Certificate", UInt24('list_length'), MetaField('list_data', lambda ctx: ctx.list_length))
ASNCert = Struct("ASNCert", UInt24('cert_length'), MetaField('cert', lambda ctx: ctx.cert_length))
Handshake = GreedyRepeater(Struct("Handshake",
HandshakeType,
UInt24("length"), # 24-bit length akward,
# Probe("handshake message decode before body"),
MetaField('body', lambda ctx: ctx.length)
# Switch("body", lambda ctx: ctx["msg_type"],
# {
# "hello_request" : Embed(HelloRequest),
# "client_hello" : Embed(ClientHello),
# "server_hello" : Embed(ServerHello)#,
# "certificate" : Embed(Certificate),
# "server_key_exchange" : Embed(ServerKeyExchange),
# "certificate_request" : Embed(CertificatRequest),
# "server_hello_done" : Embed(ServerHelloDone),
# "certificate_verify" : Embed(CertificateVerify),
# "client_key_exchange" : Embed(ClientKeyExchange),
# "finished" : Embed(Finished)
# }
# )
))
ContentType = Enum(UBInt8('ContentType'),
change_cipher_spec = 20,
alert=21,
handshake=22,
application_data=23)
TLSRecord = GreedyRepeater(Struct("TLSRecord",
ContentType,
ProtocolVersion,
UBInt16("length"),
MetaField('data', lambda ctx: ctx.length)
) )