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
11 changes: 7 additions & 4 deletions scapy/layers/tls/crypto/cipher_aead.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,11 @@ def __init__(self, key=None, fixed_iv=None, nonce_explicit=None):
self.pc_cls_mode(fixed_iv),
backend=default_backend())
else:
self._cipher = self.cipher_cls(key)
if self.cipher_cls == ChaCha20Poly1305:
# ChaCha20Poly1305 doesn't have a tag_length argument...
self._cipher = self.cipher_cls(key)
else:
self._cipher = self.cipher_cls(key, tag_length=self.tag_len)

def __setattr__(self, name, val):
if name == "key":
Expand All @@ -308,8 +312,7 @@ def _get_nonce(self, seq_num):
def auth_encrypt(self, P, A, seq_num):
"""
Encrypt the data, and append the computed authentication code.
TLS 1.3 does not use additional data, but we leave this option to the
user nonetheless.
The additional data for TLS 1.3 is the record header.

Note that the cipher's authentication tag must be None when encrypting.
"""
Expand All @@ -335,7 +338,6 @@ def auth_encrypt(self, P, A, seq_num):
def auth_decrypt(self, A, C, seq_num):
"""
Decrypt the data and verify the authentication code (in this order).
Note that TLS 1.3 is not supposed to use any additional data A.
If the verification fails, an AEADTagError is raised. It is the user's
responsibility to catch it if deemed useful. If we lack the key, we
raise a CipherError which contains the encrypted input.
Expand Down Expand Up @@ -412,6 +414,7 @@ class Cipher_AES_128_CCM_TLS13(_AEADCipher_TLS13):
cipher_cls = AESCCM
key_len = 16
tag_len = 16
fixed_iv_len = 12

class Cipher_AES_128_CCM_8_TLS13(Cipher_AES_128_CCM_TLS13):
tag_len = 8
4 changes: 2 additions & 2 deletions scapy/layers/tls/crypto/hkdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def expand(self, prk, info, L):

def expand_label(self, secret, label, hash_value, length):
hkdf_label = struct.pack("!H", length)
hkdf_label += struct.pack("B", 9 + len(label))
hkdf_label += b"TLS 1.3, "
hkdf_label += struct.pack("B", 6 + len(label))
hkdf_label += b"tls13 "
hkdf_label += label
hkdf_label += struct.pack("B", len(hash_value))
hkdf_label += hash_value
Expand Down
91 changes: 82 additions & 9 deletions scapy/layers/tls/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,23 @@
0x0f: "heartbeat", # RFC 6520
0x10: "alpn", # RFC 7301
0x12: "signed_certificate_timestamp", # RFC 6962
0x13: "client_certificate_type", # RFC 7250
0x14: "server_certificate_type", # RFC 7250
0x15: "padding", # RFC 7685
0x16: "encrypt_then_mac", # RFC 7366
0x17: "extended_master_secret", # RFC 7627
0x1c: "record_size_limit", # RFC 8449
0x23: "session_ticket", # RFC 5077
0x28: "key_share",
0x29: "pre_shared_key",
0x2a: "early_data",
0x2a: "early_data_indication",
0x2b: "supported_versions",
0x2c: "cookie",
0x2d: "psk_key_exchange_modes",
0x2e: "ticket_early_data_info",
0x2f: "certificate_authorities",
0x30: "oid_filters",
0x31: "post_handshake_auth",
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 @@ -507,14 +511,32 @@ class TLS_Ext_PreSharedKey(TLS_Ext_Unknown):
ShortField("len", None)]


class TLS_Ext_EarlyData(TLS_Ext_Unknown):
class TLS_Ext_EarlyDataIndication(TLS_Ext_Unknown):
name = "TLS Extension - Early Data"
fields_desc = [ShortEnumField("type", 0x2a, _tls_ext),
ShortField("len", None)]


class TLS_Ext_EarlyDataIndicationTicket(TLS_Ext_Unknown):
name = "TLS Extension - Ticket Early Data Info"
fields_desc = [ShortEnumField("type", 0x2a, _tls_ext),
ShortField("len", None),
IntField("max_early_data_size", 0)]


_tls_ext_early_data_cls = {1: TLS_Ext_EarlyDataIndication,
4: TLS_Ext_EarlyDataIndicationTicket,
8: TLS_Ext_EarlyDataIndication}


class TLS_Ext_SupportedVersions(TLS_Ext_Unknown):
name = "TLS Extension - Supported Versions"
name = "TLS Extension - Supported Versions (dummy class)"
fields_desc = [ShortEnumField("type", 0x2b, _tls_ext),
ShortField("len", None)]


class TLS_Ext_SupportedVersion_CH(TLS_Ext_Unknown):
name = "TLS Extension - Supported Versions (for ClientHello)"
fields_desc = [ShortEnumField("type", 0x2b, _tls_ext),
ShortField("len", None),
FieldLenField("versionslen", None, fmt='B',
Expand All @@ -525,6 +547,17 @@ class TLS_Ext_SupportedVersions(TLS_Ext_Unknown):
length_from=lambda pkt: pkt.versionslen)]


class TLS_Ext_SupportedVersion_SH(TLS_Ext_Unknown):
name = "TLS Extension - Supported Versions (for ServerHello)"
fields_desc = [ShortEnumField("type", 0x2b, _tls_ext),
ShortField("len", None),
ShortEnumField("version", None, _tls_version)]


_tls_ext_supported_version_cls = {1: TLS_Ext_SupportedVersion_CH,
2: TLS_Ext_SupportedVersion_SH}


class TLS_Ext_Cookie(TLS_Ext_Unknown):
name = "TLS Extension - Cookie"
fields_desc = [ShortEnumField("type", 0x2c, _tls_ext),
Expand Down Expand Up @@ -567,6 +600,24 @@ class TLS_Ext_NPN(TLS_Ext_PrettyPacketList):
length_from=lambda pkt:pkt.len)]


class TLS_Ext_PostHandshakeAuth(TLS_Ext_Unknown): # RFC 8446
name = "TLS Extension - Post Handshake Auth"
fields_desc = [ShortEnumField("type", 0x31, _tls_ext),
ShortField("len", None)]


class TLS_Ext_SignatureAlgorithmsCert(TLS_Ext_Unknown): # RFC 8446
name = "TLS Extension - Signature Algorithms Cert"
fields_desc = [ShortEnumField("type", 0x31, _tls_ext),
ShortField("len", None),
SigAndHashAlgsLenField("sig_algs_len", None,
length_of="sig_algs"),
SigAndHashAlgsField("sig_algs", [],
EnumField("hash_sig", None,
_tls_hash_sig),
length_from=lambda pkt: pkt.sig_algs_len)] # noqa: E501


class TLS_Ext_RenegotiationInfo(TLS_Ext_Unknown): # RFC 5746
name = "TLS Extension - Renegotiation Indication"
fields_desc = [ShortEnumField("type", 0xff01, _tls_ext),
Expand All @@ -577,6 +628,13 @@ class TLS_Ext_RenegotiationInfo(TLS_Ext_Unknown): # RFC 5746
length_from=lambda pkt: pkt.reneg_conn_len)]


class TLS_Ext_RecordSizeLimit(TLS_Ext_Unknown): # RFC 8449
name = "TLS Extension - Record Size Limit"
fields_desc = [ShortEnumField("type", 0x1c, _tls_ext),
ShortField("len", None),
ShortField("record_size_limit", None)]


_tls_ext_cls = {0: TLS_Ext_ServerName,
1: TLS_Ext_MaxFragLen,
2: TLS_Ext_ClientCertURL,
Expand All @@ -596,14 +654,18 @@ class TLS_Ext_RenegotiationInfo(TLS_Ext_Unknown): # RFC 5746
0x15: TLS_Ext_Padding,
0x16: TLS_Ext_EncryptThenMAC,
0x17: TLS_Ext_ExtendedMasterSecret,
0x1c: TLS_Ext_RecordSizeLimit,
0x23: TLS_Ext_SessionTicket,
0x28: TLS_Ext_KeyShare,
# 0x28: TLS_Ext_KeyShare,
0x29: TLS_Ext_PreSharedKey,
0x2a: TLS_Ext_EarlyData,
0x2a: TLS_Ext_EarlyDataIndication,
0x2b: TLS_Ext_SupportedVersions,
0x2c: TLS_Ext_Cookie,
0x2d: TLS_Ext_PSKKeyExchangeModes,
0x2e: TLS_Ext_TicketEarlyDataInfo,
# 0x2e: TLS_Ext_TicketEarlyDataInfo,
0x31: TLS_Ext_PostHandshakeAuth,
0x32: TLS_Ext_SignatureAlgorithmsCert,
0x33: TLS_Ext_KeyShare,
# 0x2f: TLS_Ext_CertificateAuthorities, #XXX
# 0x30: TLS_Ext_OIDFilters, #XXX
0x3374: TLS_Ext_NPN,
Expand Down Expand Up @@ -684,16 +746,27 @@ def i2m(self, pkt, i):

def m2i(self, pkt, m):
res = []
while len(m) > 4:
while len(m) >= 4:
t = struct.unpack("!H", m[:2])[0]
tmp_len = struct.unpack("!H", m[2:4])[0]
cls = _tls_ext_cls.get(t, TLS_Ext_Unknown)
if cls is TLS_Ext_KeyShare:
# TLS_Ext_KeyShare can be :
# - TLS_Ext_KeyShare_CH if the message is a ClientHello
# - TLS_Ext_KeyShare_SH if the message is a ServerHello
# and all parameters are accepted by the serveur
# - TLS_Ext_KeyShare_HRR if message is a ServerHello and
# the client has not provided a sufficient "key_share"
# extension
from scapy.layers.tls.keyexchange_tls13 import _tls_ext_keyshare_cls # noqa: E501
cls = _tls_ext_keyshare_cls.get(pkt.msgtype, TLS_Ext_Unknown)
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
elif cls is TLS_Ext_SupportedVersions:
cls = _tls_ext_supported_version_cls.get(pkt.msgtype, TLS_Ext_Unknown) # noqa: E501
elif cls is TLS_Ext_EarlyDataIndication:
cls = _tls_ext_early_data_cls.get(pkt.msgtype, TLS_Ext_Unknown)
res.append(cls(m[:tmp_len + 4], tls_session=pkt.tls_session))
m = m[tmp_len + 4:]
return res
Loading