Skip to content
Closed
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
4 changes: 3 additions & 1 deletion scapy/layers/inet.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,9 @@ class IP(Packet, IPTools):
# IPField("src", "127.0.0.1"),
Emph(SourceIPField("src", "dst")),
Emph(DestIPField("dst", "127.0.0.1")),
PacketListField("options", [], IPOption, length_from=lambda p:p.ihl * 4 - 20)] # noqa: E501
PacketListField("options", [], IPOption, length_from=(
lambda p: max(0, p.ihl * 4 - 20)))
]

def post_build(self, p, pay):
ihl = self.ihl
Expand Down
4 changes: 2 additions & 2 deletions scapy/layers/tls/automaton_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from scapy.layers.tls.handshake import TLSCertificate, TLSCertificateRequest, \
TLSCertificateVerify, TLSClientHello, TLSClientKeyExchange, \
TLSEncryptedExtensions, TLSFinished, TLSServerHello, TLSServerHelloDone, \
TLSServerKeyExchange, TLS13Certificate, TLS13ServerHello
TLSServerKeyExchange, TLS13Certificate
from scapy.layers.tls.handshake_sslv2 import SSLv2ClientHello, \
SSLv2ServerHello, SSLv2ClientMasterKey, SSLv2ServerVerify, \
SSLv2ClientFinished, SSLv2ServerFinished, SSLv2ClientCertificate, \
Expand Down Expand Up @@ -856,7 +856,7 @@ def TLS13_WAITING_SERVERHELLO(self):

@ATMT.condition(TLS13_WAITING_SERVERHELLO)
def tls13_should_handle_ServerHello(self):
self.raise_on_packet(TLS13ServerHello,
self.raise_on_packet(TLSServerHello,
self.TLS13_WAITING_ENCRYPTEDEXTENSIONS)

@ATMT.state()
Expand Down
10 changes: 5 additions & 5 deletions scapy/layers/tls/basefields.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,27 +72,27 @@ def i2m(self, pkt, x):
class _TLSVersionField(ShortEnumField):
"""
We use the tls_version if it has been defined, else the advertised version.
Also, the legacy 0x0301 is used for TLS 1.3 packets.
Also, the legacy 0x0303 is used for TLS 1.3 packets.
"""

def i2h(self, pkt, x):
if x is None:
v = pkt.tls_session.tls_version
if v:
return _tls13_version_filter(v, 0x0301)
return _tls13_version_filter(v, 0x0303)
else:
adv_v = pkt.tls_session.advertised_tls_version
return _tls13_version_filter(adv_v, 0x0301)
return _tls13_version_filter(adv_v, 0x0303)
return x

def i2m(self, pkt, x):
if x is None:
v = pkt.tls_session.tls_version
if v:
return _tls13_version_filter(v, 0x0301)
return _tls13_version_filter(v, 0x0303)
else:
adv_v = pkt.tls_session.advertised_tls_version
return _tls13_version_filter(adv_v, 0x0301)
return _tls13_version_filter(adv_v, 0x0303)
return x


Expand Down
13 changes: 7 additions & 6 deletions scapy/layers/tls/crypto/cipher_aead.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def auth_decrypt(self, A, C, seq_num=None, add_length=True):
P = self._cipher.decrypt(self._get_nonce(), C + mac, A)
except InvalidTag:
raise AEADTagError(nonce_explicit_str,
"<unauthenticated data>",
b"<unauthenticated data>",
mac)
return nonce_explicit_str, P, mac

Expand Down Expand Up @@ -340,9 +340,10 @@ def auth_decrypt(self, A, C, seq_num):
responsibility to catch it if deemed useful. If we lack the key, we
raise a CipherError which contains the encrypted input.
"""

C, mac = C[:-self.tag_len], C[-self.tag_len:]
if False in six.itervalues(self.ready):
raise CipherError(C, mac)
raise CipherError(b"", C, mac)

if hasattr(self, "pc_cls"):
self._cipher.mode._initialization_vector = self._get_nonce(seq_num)
Expand All @@ -353,7 +354,7 @@ def auth_decrypt(self, A, C, seq_num):
try:
decryptor.finalize()
except InvalidTag:
raise AEADTagError(P, mac)
raise AEADTagError(b"", P, mac)
else:
try:
if (conf.crypto_valid_advanced and
Expand All @@ -366,8 +367,8 @@ def auth_decrypt(self, A, C, seq_num):
A += struct.pack("!H", len(C))
P = self._cipher.decrypt(self._get_nonce(seq_num), C + mac, A) # noqa: E501
except InvalidTag:
raise AEADTagError("<unauthenticated data>", mac)
return P, mac
raise AEADTagError(b"", b"<unauthenticated data>", mac)
return b"", P, mac

def snapshot(self):
c = self.__class__(self.key, self.fixed_iv)
Expand Down Expand Up @@ -400,8 +401,8 @@ class Cipher_AES_128_GCM_TLS13(_AEADCipher_TLS13):
pc_cls = algorithms.AES
pc_cls_mode = modes.GCM
key_len = 16
fixed_iv_len = 12
tag_len = 16
fixed_iv_len = 12

class Cipher_AES_256_GCM_TLS13(Cipher_AES_128_GCM_TLS13):
key_len = 32
Expand Down
12 changes: 10 additions & 2 deletions scapy/layers/tls/crypto/prf.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,18 +208,26 @@ def __init__(self, hash_name="SHA256", tls_version=0x0303):
warning("Unknown TLS version")

def compute_master_secret(self, pre_master_secret,
client_random, server_random):
client_random, server_random,
extms=False, handshake_hash=None):
"""
Return the 48-byte master_secret, computed from pre_master_secret,
client_random and server_random. See RFC 5246, section 6.3.
Supports Extended Master Secret Derivation, see RFC 7627
"""
seed = client_random + server_random
label = b'master secret'

if extms is True and handshake_hash is not None:
seed = handshake_hash
label = b'extended master secret'

if self.tls_version < 0x0300:
return None
elif self.tls_version == 0x0300:
return self.prf(pre_master_secret, seed, 48)
else:
return self.prf(pre_master_secret, b"master secret", seed, 48)
return self.prf(pre_master_secret, label, seed, 48)

def derive_key_block(self, master_secret, server_random,
client_random, req_len):
Expand Down
37 changes: 26 additions & 11 deletions scapy/layers/tls/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from scapy.fields import ByteEnumField, ByteField, EnumField, FieldLenField, \
FieldListField, IntField, PacketField, PacketListField, ShortEnumField, \
ShortField, StrFixedLenField, StrLenField, XStrLenField
ShortField, StrFixedLenField, StrLenField, XStrLenField, ConditionalField
from scapy.packet import Packet, Raw, Padding
from scapy.layers.x509 import X509_Extensions
from scapy.layers.tls.basefields import _tls_version
Expand Down Expand Up @@ -46,7 +46,6 @@
0x16: "encrypt_then_mac", # RFC 7366
0x17: "extended_master_secret", # RFC 7627
0x23: "session_ticket", # RFC 5077
0x28: "key_share",
0x29: "pre_shared_key",
0x2a: "early_data",
0x2b: "supported_versions",
Expand All @@ -55,6 +54,8 @@
0x2e: "ticket_early_data_info",
0x2f: "certificate_authorities",
0x30: "oid_filters",
0x32: "signature_algorithms_cert",
0x33: "key_share",
0x3374: "next_protocol_negotiation",
# RFC-draft-agl-tls-nextprotoneg-03
0xff01: "renegotiation_info" # RFC 5746
Expand Down Expand Up @@ -496,13 +497,13 @@ class TLS_Ext_SessionTicket(TLS_Ext_Unknown): # RFC 5077


class TLS_Ext_KeyShare(TLS_Ext_Unknown):
name = "TLS Extension - Key Share (dummy class)"
fields_desc = [ShortEnumField("type", 0x28, _tls_ext),
name = "TLS Extension - Key Share (Unknown)"
fields_desc = [ShortEnumField("type", 0x33, _tls_ext),
ShortField("len", None)]


class TLS_Ext_PreSharedKey(TLS_Ext_Unknown):
name = "TLS Extension - Pre Shared Key (dummy class)"
name = "TLS Extension - Pre Shared Key (Unknown)"
fields_desc = [ShortEnumField("type", 0x29, _tls_ext),
ShortField("len", None)]

Expand All @@ -517,12 +518,20 @@ class TLS_Ext_SupportedVersions(TLS_Ext_Unknown):
name = "TLS Extension - Supported Versions"
fields_desc = [ShortEnumField("type", 0x2b, _tls_ext),
ShortField("len", None),
FieldLenField("versionslen", None, fmt='B',
length_of="versions"),
# Depending on whether the extension is from
# ServerHello or ClientHello, versionslen may
# or may not exist.
ConditionalField(
FieldLenField("versionslen", None, fmt='B',
length_of="versions"),
lambda x: x.len % 2),
FieldListField("versions", [],
ShortEnumField("version", None,
_tls_version),
length_from=lambda pkt: pkt.versionslen)]
length_from=(
lambda pkt: pkt.versionslen if
pkt.len % 2 else pkt.len - (pkt.len % 2))
)]


class TLS_Ext_Cookie(TLS_Ext_Unknown):
Expand Down Expand Up @@ -597,14 +606,15 @@ class TLS_Ext_RenegotiationInfo(TLS_Ext_Unknown): # RFC 5746
0x16: TLS_Ext_EncryptThenMAC,
0x17: TLS_Ext_ExtendedMasterSecret,
0x23: TLS_Ext_SessionTicket,
0x28: TLS_Ext_KeyShare,
0x29: TLS_Ext_PreSharedKey,
0x2a: TLS_Ext_EarlyData,
0x2b: TLS_Ext_SupportedVersions,
0x2c: TLS_Ext_Cookie,
0x2d: TLS_Ext_PSKKeyExchangeModes,
0x2e: TLS_Ext_TicketEarlyDataInfo,
# 0x2f: TLS_Ext_CertificateAuthorities, #XXX
# 0x32: TLS_Ext_SignatureAlgorithmsCert, #XXX
0x33: TLS_Ext_KeyShare,
# 0x30: TLS_Ext_OIDFilters, #XXX
0x3374: TLS_Ext_NPN,
0xff01: TLS_Ext_RenegotiationInfo
Expand Down Expand Up @@ -653,9 +663,14 @@ def addfield(self, pkt, s, i):


class _ExtensionsField(StrLenField):
__slots__ = ["msg_type"]
islist = 1
holds_packets = 1

def __init__(self, name, default, **kargs):
self.msg_type = kargs.pop("msg_type", lambda pkt: pkt.msgtype)
StrLenField.__init__(self, name, default, **kargs)

def i2len(self, pkt, i):
if i is None:
return 0
Expand Down Expand Up @@ -690,10 +705,10 @@ def m2i(self, pkt, m):
cls = _tls_ext_cls.get(t, TLS_Ext_Unknown)
if cls is TLS_Ext_KeyShare:
from scapy.layers.tls.keyexchange_tls13 import _tls_ext_keyshare_cls # noqa: E501
cls = _tls_ext_keyshare_cls.get(pkt.msgtype, TLS_Ext_Unknown)
cls = _tls_ext_keyshare_cls.get(self.msg_type(pkt), TLS_Ext_KeyShare)
elif cls is TLS_Ext_PreSharedKey:
from scapy.layers.tls.keyexchange_tls13 import _tls_ext_presharedkey_cls # noqa: E501
cls = _tls_ext_presharedkey_cls.get(pkt.msgtype, TLS_Ext_Unknown) # noqa: E501
cls = _tls_ext_presharedkey_cls.get(self.msg_type(pkt), TLS_Ext_PreSharedKey) # noqa: E501
res.append(cls(m[:tmp_len + 4], tls_session=pkt.tls_session))
m = m[tmp_len + 4:]
return res
Loading