# We're going to parse several successive records from the passive listening of a standard TLS handshake
from scapy.all import *
load_layer('tls')

"""
Explanation: TLS handshake overview
This is the standard, modern TLS 1.2 handshake:
<img src="images/handshake_tls12.png" alt="Handshake TLS 1.2" width="400"/>
End of explanation
"""


record1 = TLS(open('raw_data/tls_session_protected/01_cli.raw', 'rb').read())
record1.show()

for extension in record1.msg[0].ext:
    print('')
    extension.show()

"""
Explanation: (C) ---> (S) ClientHello
End of explanation
"""


record2 = TLS(open('raw_data/tls_session_protected/02_srv.raw', 'rb').read())
record2.show()

"""
Explanation: (C) <--- (S) ServerHello
End of explanation
"""


record3 = TLS(open('raw_data/tls_session_protected/03_srv.raw', 'rb').read())
record3.show()

# The Certificate message actually contains a *chain* of certificates
for cert in record3.msg[0].certs:
    print(type(cert[1]))
    cert[1].show()
    print('')

# Let's recall the domain that the client wants to access
record1.msg[0].ext[0].show()

# Indeed the certificate may be used with other domains than its CN 'www.github.com'
x509c = record3.msg[0].certs[0][1].x509Cert
print(type(x509c))
x509c.tbsCertificate.extensions[2].show()

"""
Explanation: (C) <--- (S) Certificate
End of explanation
"""


# Here the server sent three TLS records in the same TCP segment
record4 = TLS(open('raw_data/tls_session_protected/04_srv.raw', 'rb').read())
record4.show()

# Let's verify the signature in the ServerKeyExchange
# First, we need to assemble the whole data being signed
cli_random = pkcs_i2osp(record1.msg[0].gmt_unix_time, 4) + record1.msg[0].random_bytes
srv_random = pkcs_i2osp(record2.msg[0].gmt_unix_time, 4) + record2.msg[0].random_bytes
ecdh_params = bytes(record4[TLSServerKeyExchange].params)

# Then we retrieve the server's Cert and verify the signature
cert_srv = record3.msg[0].certs[0][1]
cert_srv.verify(cli_random + srv_random + ecdh_params, record4[TLSServerKeyExchange].sig.sig_val, h='sha512')

"""
Explanation: (C) <--- (S) CertificateStatus, ServerKeyExchange, ServerHelloDone
End of explanation
"""


record5_str = open('raw_data/tls_session_protected/05_cli.raw', 'rb').read()
record5 = TLS(record5_str)
record5.show()

# Every record has a 'tls_session' context which may enhance the parsing of later records
record5 = TLS(record5_str, tls_session=record2.tls_session.mirror())
record5.show()

"""
Explanation: (C) ---> (S) ClientKeyExchange, ChangeCipherSpec, Finished
End of explanation
"""


record6_str = open('raw_data/tls_session_protected/06_srv.raw', 'rb').read()
record6 = TLS(record6_str, tls_session=record5.tls_session.mirror())
record6.show()

"""
Explanation: (C) <--- (S) NewSessionTicket, ChangeCipherSpec, Finished
End of explanation
"""


record7_str = open('raw_data/tls_session_protected/07_cli.raw', 'rb').read()
record7 = TLS(record7_str, tls_session=record6.tls_session.mirror())
record7.show()

"""
Explanation: (C) ---> (S) ApplicationData
End of explanation
"""


