71 lines
2.9 KiB
Python
71 lines
2.9 KiB
Python
|
import io
|
||
|
|
||
|
import pyshark
|
||
|
from kaitaistruct import KaitaiStream
|
||
|
from scapy.all import PcapReader, Raw
|
||
|
|
||
|
import tls_client_hello
|
||
|
|
||
|
packets = pyshark.FileCapture("tls-handshake-dump.pcap")
|
||
|
with PcapReader('tls-handshake-dump.pcap') as pcap_reader:
|
||
|
for pkt_pcap, pkt in zip(pcap_reader, packets):
|
||
|
try:
|
||
|
ssl = pkt.ssl
|
||
|
except AttributeError: # TCP Retransmission packet
|
||
|
continue
|
||
|
|
||
|
ch_bytes = bytes(pkt_pcap.getlayer(Raw))[9:] # Remove headers
|
||
|
client_hello = tls_client_hello.TlsClientHello(KaitaiStream(io.BytesIO(bytes(ch_bytes))))
|
||
|
|
||
|
# Version
|
||
|
assert(int(ssl.handshake_version.raw_value[:2]) == client_hello.version.major)
|
||
|
assert(int(ssl.handshake_version.raw_value[2:]) == client_hello.version.minor)
|
||
|
|
||
|
# Random
|
||
|
assert(ssl.handshake_random_time.hex_value == client_hello.random.gmt_unix_time)
|
||
|
assert(bytes.fromhex(ssl.handshake_random.raw_value) == client_hello.random.random)
|
||
|
|
||
|
# Session Id
|
||
|
assert(int(ssl.handshake_session_id_length) == client_hello.session_id.len)
|
||
|
try:
|
||
|
assert(bytes.fromhex(ssl.handshake_session_id.raw_value) == client_hello.session_id.sid)
|
||
|
except AttributeError:
|
||
|
if not int(ssl.handshake_session_id_length):
|
||
|
pass
|
||
|
else:
|
||
|
raise Exception
|
||
|
|
||
|
# Cipher Suites
|
||
|
assert(int(ssl.handshake_cipher_suites_length) == client_hello.cipher_suites.len)
|
||
|
for cs1, cs2 in zip(ssl.handshake_ciphersuite.fields, client_hello.cipher_suites.cipher_suites):
|
||
|
assert(cs1.hex_value == cs2.cipher_suite)
|
||
|
|
||
|
# Compression methods
|
||
|
assert(int(ssl.handshake_comp_methods_length) == client_hello.compression_methods.len)
|
||
|
assert(bytes.fromhex(ssl.handshake_comp_method.raw_value) == client_hello.compression_methods.compression_methods)
|
||
|
|
||
|
# Extensions
|
||
|
assert(int(ssl.handshake_extensions_length) == client_hello.extensions.len)
|
||
|
|
||
|
for ext_len1, ext_len2 in zip(ssl.handshake_extension_len.fields, client_hello.extensions.extensions):
|
||
|
assert(ext_len1.hex_value == ext_len2.len)
|
||
|
|
||
|
for ext1, ext2 in zip(ssl.handshake_extension_type.fields, client_hello.extensions.extensions):
|
||
|
assert(ext1.hex_value == ext2.type)
|
||
|
if ext2.type == 0:
|
||
|
sni = ext2
|
||
|
elif ext2.type == 16:
|
||
|
alpn = ext2
|
||
|
|
||
|
# SNI
|
||
|
assert(int(ssl.handshake_extensions_server_name_list_len) == sni.body.list_length)
|
||
|
|
||
|
assert(int(ssl.handshake_extensions_server_name_type) == sni.body.server_names[0].name_type)
|
||
|
assert(ssl.handshake_extensions_server_name == str(sni.body.server_names[0].host_name, 'idna'))
|
||
|
|
||
|
# ALPN
|
||
|
assert(int(ssl.handshake_extensions_alpn_len) == alpn.body.ext_len)
|
||
|
|
||
|
for pname1, pname2 in zip(ssl.handshake_extensions_alpn_str.all_fields, alpn.body.alpn_protocols):
|
||
|
assert(pname1.show == pname2.name.decode())
|