Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 32 additions & 22 deletions scapy/layers/tls/handshake.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ def tls_session_update(self, msg_str):
if self.ext:
for e in self.ext:
if isinstance(e, TLS_Ext_SupportedVersion_CH):
for ver in e.versions:
for ver in sorted(e.versions, reverse=True):
# RFC 8701: GREASE of TLS will send unknown versions
# here. We have to ignore them
if ver in _tls_version:
Expand Down Expand Up @@ -455,7 +455,7 @@ def tls_session_update(self, msg_str):
if self.ext:
for e in self.ext:
if isinstance(e, TLS_Ext_SupportedVersion_CH):
for ver in e.versions:
for ver in sorted(e.versions, reverse=True):
# RFC 8701: GREASE of TLS will send unknown versions
# here. We have to ignore them
if ver in _tls_version:
Expand Down Expand Up @@ -530,12 +530,15 @@ def tls_session_update(self, msg_str):
"""
super(TLSServerHello, self).tls_session_update(msg_str)

self.tls_session.tls_version = self.version
self.random_bytes = msg_str[10:38]
self.tls_session.server_random = (struct.pack('!I',
self.gmt_unix_time) +
self.random_bytes)
self.tls_session.sid = self.sid
s = self.tls_session
s.tls_version = self.version
if hasattr(self, 'gmt_unix_time'):
self.random_bytes = msg_str[10:38]
s.server_random = (struct.pack('!I', self.gmt_unix_time) +
self.random_bytes)
else:
s.server_random = self.random_bytes
s.sid = self.sid

cs_cls = None
if self.cipher:
Expand All @@ -555,15 +558,15 @@ def tls_session_update(self, msg_str):
comp_val = 0
comp_cls = _tls_compression_algs_cls[comp_val]

connection_end = self.tls_session.connection_end
self.tls_session.pwcs = writeConnState(ciphersuite=cs_cls,
compression_alg=comp_cls,
connection_end=connection_end,
tls_version=self.version)
self.tls_session.prcs = readConnState(ciphersuite=cs_cls,
compression_alg=comp_cls,
connection_end=connection_end,
tls_version=self.version)
connection_end = s.connection_end
s.pwcs = writeConnState(ciphersuite=cs_cls,
compression_alg=comp_cls,
connection_end=connection_end,
tls_version=self.version)
s.prcs = readConnState(ciphersuite=cs_cls,
compression_alg=comp_cls,
connection_end=connection_end,
tls_version=self.version)


_tls_13_server_hello_fields = [
Expand All @@ -586,7 +589,7 @@ def tls_session_update(self, msg_str):
]


class TLS13ServerHello(_TLSHandshake):
class TLS13ServerHello(TLSServerHello):
""" TLS 1.3 ServerHello """
name = "TLS 1.3 Handshake - Server Hello"
fields_desc = _tls_13_server_hello_fields
Expand Down Expand Up @@ -615,16 +618,23 @@ def tls_session_update(self, msg_str):
cipher suite (if recognized), and finally we instantiate the write and
read connection states.
"""
super(TLS13ServerHello, self).tls_session_update(msg_str)

s = self.tls_session
s.server_random = self.random_bytes
s.ciphersuite = self.cipher
s.tls_version = self.version
# Check extensions
if self.ext:
for e in self.ext:
if isinstance(e, TLS_Ext_SupportedVersion_SH):
s.tls_version = e.version
break
s.server_random = self.random_bytes
s.ciphersuite = self.cipher

if s.tls_version < 0x304:
# This means that the server does not support TLS 1.3 and ignored
# the initial TLS 1.3 ClientHello. tls_version has been updated
return TLSServerHello.tls_session_update(self, msg_str)
else:
_TLSHandshake.tls_session_update(self, msg_str)

cs_cls = None
if self.cipher:
Expand Down
13 changes: 10 additions & 3 deletions scapy/layers/tls/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,16 @@ def m2i(self, pkt, m):
if pkt.type == 22:
if len(m) >= 1:
msgtype = orb(m[0])
if ((pkt.tls_session.advertised_tls_version == 0x0304) or
(pkt.tls_session.tls_version and
pkt.tls_session.tls_version == 0x0304)):
# If a version was agreed on by both client and server,
# we use it (tls_session.tls_version)
# Otherwise, if the client advertised for TLS 1.3, we try to
# dissect the following packets (most likely, server hello)
# using TLS 1.3. The serverhello is able to fallback on
# TLS 1.2 if necessary. In any case, this will set the agreed
# version so that all future packets are correct.
if ((pkt.tls_session.advertised_tls_version == 0x0304 and
pkt.tls_session.tls_version is None) or
pkt.tls_session.tls_version == 0x0304):
cls = _tls13_handshake_cls.get(msgtype, Raw)
else:
cls = _tls_handshake_cls.get(msgtype, Raw)
Expand Down
11 changes: 6 additions & 5 deletions test/run_tests
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
DIR=$(dirname "$0")/..
if [ -z "$PYTHON" ]
then
ARGS=$(getopt 23 "$*" 2> /dev/null)
for arg in $ARGS
ARGS=""
for arg in "$@"
do
case $arg
in
-2) PYTHON=python2; shift;;
-3) PYTHON=python3; shift;;
--) PYTHON=python3; break;;
-2) PYTHON=python2;;
-3) PYTHON=python3;;
*) ARGS="$ARGS $arg";;
esac
done
PYTHON=${PYTHON:-python3}
fi
$PYTHON --version > /dev/null 2>&1
if [ ! $? -eq 0 ]
Expand Down
7 changes: 7 additions & 0 deletions test/tls.uts
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,7 @@ conf.debug_dissector = old_debug_dissector
= Test x25519 dissection in ServerKeyExchange

import binascii
from scapy.layers.tls.session import tlsSession

session = tlsSession(connection_end="client")
# Raw hex data of a TLS Handshake - Server Key Exchange with x25519 elliptic curve
Expand Down Expand Up @@ -1413,6 +1414,12 @@ assert p.msg[0].extlen is None
assert p.msg[0].ext == []
assert [type(x) for x in a.msg] == [TLSServerHello, TLSCertificate, TLSServerKeyExchange, TLSServerHelloDone]

= Issue 2778

r1 = TLS(b"\x16\x03\x01\x02\x00\x01\x00\x01\xfc\x03\x03\xf8\xb3\xdb\xcbp\xed8\x04\x00\x9c\x15\xafJB\x98r\x06\x19\xb7\r\x1a\xd4\xf2M\x0e\x99\xde\x9e\x93\xce<; \x1c;,\xf3&k\xcb\xa1\x9b)G\x9e\xc6o\xe8\x15\xf7\xdb\nk\x97a\x11\xf7\tX9^z\xee\xba\xba\x00>\x13\x02\x13\x03\x13\x01\xc0,\xc00\x00\x9f\xcc\xa9\xcc\xa8\xcc\xaa\xc0+\xc0/\x00\x9e\xc0$\xc0(\x00k\xc0#\xc0'\x00g\xc0\n\xc0\x14\x009\xc0\t\xc0\x13\x003\x00\x9d\x00\x9c\x00=\x00<\x005\x00/\x00\xff\x01\x00\x01u\x00\x0b\x00\x04\x03\x00\x01\x02\x00\n\x00\x0c\x00\n\x00\x1d\x00\x17\x00\x1e\x00\x19\x00\x183t\x00\x00\x00\x10\x00\x0e\x00\x0c\x02h2\x08http/1.1\x00\x16\x00\x00\x00\x17\x00\x00\x001\x00\x00\x00\r\x00*\x00(\x04\x03\x05\x03\x06\x03\x08\x07\x08\x08\x08\t\x08\n\x08\x0b\x08\x04\x08\x05\x08\x06\x04\x01\x05\x01\x06\x01\x03\x03\x03\x01\x03\x02\x04\x02\x05\x02\x06\x02\x00+\x00\x05\x04\x03\x04\x03\x03\x00-\x00\x02\x01\x01\x003\x00&\x00$\x00\x1d\x00 \xe8A\x0fZ\xb0\x9d\x96\xb0_\x10\x18<\xcd\x9e\x93\xa0W\xa72\x90\xb4\xc9\xe1\xc2T\xcd\xfc)\x9f\xc0\x1dA\x00\x15\x00\xd0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
r2 = TLS(b'\x16\x03\x03\x00U\x02\x00\x00Q\x03\x03 \xa5@2G~\xa3\xa9c\xb8\xa7\x00\t\x04Y\xf1\x1f\x1fJ\xd1\x89n\x1dut[~+\xdcQ\xdd\xe0 \x06\x00\xf5R\xdblQ\xb9z0\x97\x17\xff\x84{\xb6\xe8\xfe\xf1\xce&\x01TD\x13\xfd\xa7\xb6`u\xb8\x87\x00\x9d\x00\x00\t\xff\x01\x00\x01\x00\x00\x17\x00\x00\x16\x03\x03\x03n\x0b\x00\x03j\x00\x03g\x00\x03d0\x82\x03`0\x82\x02H\xa0\x03\x02\x01\x02\x02\t\x00\xebs\xb7\x1c>/\x9f\xdc0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x000E1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd0\x1e\x17\r190215151403Z\x17\r290212151403Z0E1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd0\x82\x01"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xd2\xf7\xd3k#:V\x196\x8f\xc3\xa7\xdb\x0f#d\xdcq\x98m\xd4\xee\xbc\xbe\xe8[x>\x13\x9c\xfe\xb0\xa8\r\xe5\x01G\xc96\xaa\x84#\x0e/\xa2\xeb\x91\xef\x177A\x03\x87\xb92D\n\xc7\xcf\xda<Yf\xee\xf8\x8fh\x8b\xcb\xeej]\r\xfa\xa0u\xb7}\xfe\x83o,\xb3\x187_\xf5\xbe+5\xf6\xd6-\xd7\xc4\xb1G"Og\xd5=\x95\xc7\xfc\xc1\x1c\xda{\xc6"6\x9bMJhVU\x16\x9f\xb2\x8ff\xe5\x11rO\x0c\x9a\xf2\xf7N\xa4\xcd\xf0\x9b\x92\xf9\x17$jX/g\xfa\xde>\xff~\xca,yMq<\x13\xf8\x0c\xd5?\x84z\xa1\x96\xd0\xad\xc0D\x94y\nb\x8e2\x7fKS\xd0[\x83\x02\\>\xa5A\x19_\x95<\xe6\xfc7\xed\xcch\xa8\xfdn\xcab\x1f8\xbc\x08\xbc-\x8dr\xcf\xcd\xf8\\h\xf9\xf4\xf4H[2\x13<c)\x9f\x85\xff\xd6+\xdeZ\x9dX^Z\x89o\x081\x94H\'\x7f\x19\xe8m]hx\xbcSv\x8b.\xf9\xb3!\x02\x03\x01\x00\x01\xa3S0Q0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\x82\x97\xfb\x8c\xf3\xd9\xdd\xf2\xf6\x0e\xc9\x0f\x92\x81\\(\xe3\xf3\xff50\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14\x82\x97\xfb\x8c\xf3\xd9\xdd\xf2\xf6\x0e\xc9\x0f\x92\x81\\(\xe3\xf3\xff50\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00<\x00\x1f\x0f]\x10`r\xe0\xbe\xed\xfaG\x89S)\xd4b4"\x08\x0ef\xca\xa4\xbe\xb4\xc3\xd9\xb6\x86\x8f\xa1\x07F}a`\xe5\x12\xed\xe7\xcb\xbe\xfd\xeb\x17\xc0\x9b\x9fYO\x86\xf1\xa9\x92,\x98,\xcf\x96U\xd4\xd6~\xda\x06\x1ff~\xeb%\xfer\x03\xbe\xa0\x0e@\xf1P\xa4\x90\xa7\x8c\xa9c\xd8|\x18Z\xde\x8b|)OPR\xfb\x1e\x1e\xdb4\x03\x83\x1e3\xe4\x02l\x8eVq|\xb7{\xc3#!\x85\x8b\xe3zw\xfe\x7fU\x11\xef\x8c \x13\xc8n\'0\xc5\xb26hu\x13\x1c\xae\x0cv\x16\xfd\xc7\xc8`V\x96\x13>zh_ <\r\xb8\xe0\xff\x1d\x1aY\x91\xd2\xf0X\xf4\x8f \xb1\n_\xb0\xdf\'\xa1\xf9\x87L\xc0\xfe\x8dn\xbfw\xe9\xa7\xba8I\x0e\x9dc$\x1a\x0f\xb3\xfdw\x01\xff;\x13\x0c\x9a\xa7\xaaww\x02\x80\xb7\x00<\x1b\xb5\xe0xL4\xaa\xcbt\xce\x81\x14\x96\x0eP\xee\xe0F\x02\xa7\xab \xe5\xc8x\x02\x8eB\x92\xe9\x0e@\xfdc\x1f\xee\x16\x03\x03\x00\x04\x0e\x00\x00\x00', tls_session=r1.tls_session.mirror())
assert r2.tls_session.tls_version == 0x303

###############################################################################
############################ Automaton behaviour ##############################
###############################################################################
Expand Down