secdev / secdev/scapy

TLS in Scapy should have more doc

Open
#4,377 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

discussion tls
Dominant language
Python
Stars
12.6k
Forks
2.2k
Avg merge
1d 4h
Merged PRs (30d)
56

Description

Brief description

When connecting to a TLS server using TLS1.3 that negotiates TLS_CHACHA20_POLY1305, using tlsSessions fails with ValueError: not enough values to unpack (expected 3, got 2)

Scapy version

2.5.0

Python version

3.12.3

Operating system

Linux Kernel 6.8.8

Additional environment information

No response

How to reproduce

Send a client record such as

client_hello = TLSClientHello(
    ciphers=[
        tls.TLS_CHACHA20_POLY1305_SHA256,
    ],
    ext=[
        tls.TLS_Ext_ServerName(servernames=[tls.ServerName(servername=b"localhost")]),
        tls.TLS_Ext_ExtendedMasterSecret(),
        tls.TLS_Ext_EncryptThenMAC(),
        tls.TLS_Ext_SupportedGroups(groups=["x25519", "secp256r1", "x448"]),
        tls.TLS_Ext_SupportedVersion_CH(versions=["TLS 1.3"]),
        tls.TLS_Ext_SignatureAlgorithms(sig_algs=["ed25519", "sha256+rsaepss", "sha256+ecdsa"]),
        tls.TLS_Ext_KeyShare_CH(client_shares=[tls.KeyShareEntry(group="x25519")]),
    ],
)
ch_record = TLS(type=22, version=0x0303, len=len(client_hello.build())) / client_hello

to a server like openssl s_server and try to decrypt the response through the tlsSession.

Actual result

No response

Expected result

No response

Related resources

The error occurs at

File .venv/lib/python3.12/site-packages/scapy/layers/tls/record.py:537, in TLS.pre_dissect(self, s)
    535         cfrag, mac = self._tls_auth_decrypt(hdr, efrag)
    536     else:
--> 537         iv, cfrag, mac = self._tls_auth_decrypt(hdr, efrag)
    538     decryption_success = True       # see XXX above
    540 frag = self._tls_decompress(cfrag)

ValueError: not enough values to unpack (expected 3, got 2)

Quick debugging showed that

type(tls_session.rcs.cipher) = scapy.layers.tls.crypto.cipher_aead.Cipher_CHACHA20_POLY1305_TLS13
isinstance(tls_session.rcs.cipher, tls.Cipher_CHACHA20_POLY1305) = False

as Cipher_CHACHA20_POLY1305 is a subclass of Cipher_CHACHA20_POLY1305_TLS13 and not reverse.

Thus, the check in scapy/layers/tls/record.py does not cover this case.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in scapy/layers/tls/record.py around the check at line 530 and trace TLS.pre_dissect with Cipher_CHACHA20_POLY1305_TLS13 from scapy.layers.tls.crypto.cipher_aead. Reproduce using the supplied TLSClientHello against an openssl s_server and decrypt the response through tlsSession; done means TLS 1.3 ChaCha20-Poly1305 no longer raises the unpacking error.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
networking, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.