% Tests for TLS 1.3
#
# Try me with :
# bash test/run_tests -t test/tls13.uts -F


+ Read a protected TLS 1.3 session
# /!\ These tests will not catch our 'INTEGRITY CHECK FAILED's. /!\
# We deem the knowledge of the plaintext sufficient for passing...


#~ crypto



= Reading test session - Loading unparsed TLS 1.3 records
import binascii
def clean(s):
    return binascii.unhexlify(''.join(c for c in s if c.isalnum()))

clientHello = clean("""
         16 03 01 00 c4 01 00 00 c0 03 03 cb
         34 ec b1 e7 81 63 ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12
         ec 18 a2 ef 62 83 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00
         00 91 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
         00 00 0a 00 14 00 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02
         01 03 01 04 00 23 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d
         e5 60 e4 bd 43 d2 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d
         54 13 69 1e 52 9a af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e
         04 03 05 03 06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02
         01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
      """)


serverHello = clean("""
         16 03 03 00 5a 02 00 00 56 03 03 a6
         af 06 a4 12 18 60 dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14
         34 da c1 55 77 2e d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00
         1d 00 20 c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6
         cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04
      """)

serverEncHS = clean("""
         17 03 03 02 a2 d1 ff 33 4a 56 f5 bf
         f6 59 4a 07 cc 87 b5 80 23 3f 50 0f 45 e4 89 e7 f3 3a f3 5e df
         78 69 fc f4 0a a4 0a a2 b8 ea 73 f8 48 a7 ca 07 61 2e f9 f9 45
         cb 96 0b 40 68 90 51 23 ea 78 b1 11 b4 29 ba 91 91 cd 05 d2 a3
         89 28 0f 52 61 34 aa dc 7f c7 8c 4b 72 9d f8 28 b5 ec f7 b1 3b
         d9 ae fb 0e 57 f2 71 58 5b 8e a9 bb 35 5c 7c 79 02 07 16 cf b9
         b1 18 3e f3 ab 20 e3 7d 57 a6 b9 d7 47 76 09 ae e6 e1 22 a4 cf
         51 42 73 25 25 0c 7d 0e 50 92 89 44 4c 9b 3a 64 8f 1d 71 03 5d
         2e d6 5b 0e 3c dd 0c ba e8 bf 2d 0b 22 78 12 cb b3 60 98 72 55
         cc 74 41 10 c4 53 ba a4 fc d6 10 92 8d 80 98 10 e4 b7 ed 1a 8f
         d9 91 f0 6a a6 24 82 04 79 7e 36 a6 a7 3b 70 a2 55 9c 09 ea d6
         86 94 5b a2 46 ab 66 e5 ed d8 04 4b 4c 6d e3 fc f2 a8 94 41 ac
         66 27 2f d8 fb 33 0e f8 19 05 79 b3 68 45 96 c9 60 bd 59 6e ea
         52 0a 56 a8 d6 50 f5 63 aa d2 74 09 96 0d ca 63 d3 e6 88 61 1e
         a5 e2 2f 44 15 cf 95 38 d5 1a 20 0c 27 03 42 72 96 8a 26 4e d6
         54 0c 84 83 8d 89 f7 2c 24 46 1a ad 6d 26 f5 9e ca ba 9a cb bb
         31 7b 66 d9 02 f4 f2 92 a3 6a c1 b6 39 c6 37 ce 34 31 17 b6 59
         62 22 45 31 7b 49 ee da 0c 62 58 f1 00 d7 d9 61 ff b1 38 64 7e
         92 ea 33 0f ae ea 6d fa 31 c7 a8 4d c3 bd 7e 1b 7a 6c 71 78 af
         36 87 90 18 e3 f2 52 10 7f 24 3d 24 3d c7 33 9d 56 84 c8 b0 37
         8b f3 02 44 da 8c 87 c8 43 f5 e5 6e b4 c5 e8 28 0a 2b 48 05 2c
         f9 3b 16 49 9a 66 db 7c ca 71 e4 59 94 26 f7 d4 61 e6 6f 99 88
         2b d8 9f c5 08 00 be cc a6 2d 6c 74 11 6d bd 29 72 fd a1 fa 80
         f8 5d f8 81 ed be 5a 37 66 89 36 b3 35 58 3b 59 91 86 dc 5c 69
         18 a3 96 fa 48 a1 81 d6 b6 fa 4f 9d 62 d5 13 af bb 99 2f 2b 99
         2f 67 f8 af e6 7f 76 91 3f a3 88 cb 56 30 c8 ca 01 e0 c6 5d 11
         c6 6a 1e 2a c4 c8 59 77 b7 c7 a6 99 9b bf 10 dc 35 ae 69 f5 51
         56 14 63 6c 0b 9b 68 c1 9e d2 e3 1c 0b 3b 66 76 30 38 eb ba 42
         f3 b3 8e dc 03 99 f3 a9 f2 3f aa 63 97 8c 31 7f c9 fa 66 a7 3f
         60 f0 50 4d e9 3b 5b 84 5e 27 55 92 c1 23 35 ee 34 0b bc 4f dd
         d5 02 78 40 16 e4 b3 be 7e f0 4d da 49 f4 b4 40 a3 0c b5 d2 af
         93 98 28 fd 4a e3 79 4e 44 f9 4d f5 a6 31 ed e4 2c 17 19 bf da
         bf 02 53 fe 51 75 be 89 8e 75 0e dc 53 37 0d 2b
      """)

clientEncHS = clean("""
         17 03 03 00 35 75 ec 4d c2 38 cc e6
         0b 29 80 44 a7 1e 21 9c 56 cc 77 b0 51 7f e9 b9 3c 7a 4b fc 44
         d8 7f 38 f8 03 38 ac 98 fc 46 de b3 84 bd 1c ae ac ab 68 67 d7
         26 c4 05 46
   """)


= Reading TLS 1.3 session - TLS parsing (no encryption) does not throw any error
# We will need to distinguish between connection ends. See next XXX below.
from scapy.layers.tls.record import TLS
t1 = TLS(clientHello)
t2 = TLS(serverHello, tls_session=t1.tls_session.mirror())

= Reading TLS 1.3 session - TLS Record header
# We leave the possibility for some attributes to be either '' or None.
assert(t1.type == 0x16)
assert(t1.version == 0x0301)
assert(t1.len == 196)
assert(not t1.iv)
assert(not t1.mac)
assert(not t1.pad and not t1.padlen)
len(t1.msg) == 1


= Reading TLS 1.3 session - TLS Record __getitem__
from scapy.layers.tls.handshake import TLSClientHello
TLSClientHello in t1


= Reading TLS 1.3 session - ClientHello
ch = t1.msg[0]
assert(isinstance(ch, TLSClientHello))
assert(ch.msgtype == 1)
assert(ch.msglen == 192)
assert(ch.version == 0x0303)
assert(ch.gmt_unix_time == 0xcb34ecb1)
assert(ch.random_bytes == b'\xe7\x81c\xba\x1c8\xc6\xda\xcb\x19jm\xff\xa2\x1a\x8d\x99\x12\xec\x18\xa2\xefb\x83\x02M\xec\xe7')
assert(ch.sidlen == 0)
assert(not ch.sid)
assert(ch.cipherslen == 6)
assert(ch.ciphers == [4865, 4867, 4866])
assert(ch.complen == 1)
assert(ch.comp == [0])


= Reading TLS 1.3 session - ClientHello extensions
from scapy.layers.tls.extensions import (TLS_Ext_ServerName,
TLS_Ext_RenegotiationInfo, TLS_Ext_SupportedGroups, 
TLS_Ext_SessionTicket, TLS_Ext_SupportedVersion_CH,
TLS_Ext_SignatureAlgorithms, TLS_Ext_PSKKeyExchangeModes, 
TLS_Ext_RecordSizeLimit) 

from scapy.layers.tls.keyexchange_tls13 import TLS_Ext_KeyShare_CH

assert(ch.extlen == 145)
ext = ch.ext
assert(len(ext) == 9)
assert(isinstance(ext[0], TLS_Ext_ServerName))
assert(ext[0].type == 0)
assert(ext[0].len == 11)
assert(ext[0].servernameslen == 9)
assert(len(ext[0].servernames) == 1)
assert(ext[0].servernames[0].nametype == 0)
assert(ext[0].servernames[0].namelen == 6)
assert(ext[0].servernames[0].servername == b"server")
assert(isinstance(ext[1], TLS_Ext_RenegotiationInfo))
assert(not ext[1].renegotiated_connection)
assert(isinstance(ext[2], TLS_Ext_SupportedGroups))
assert(ext[2].groups == [29, 23, 24, 25, 256, 257, 258, 259, 260])
assert(isinstance(ext[3], TLS_Ext_SessionTicket))
assert(not ext[3].ticket)
assert(isinstance(ext[4], TLS_Ext_KeyShare_CH))
assert(ext[4].client_shares_len == 36)
assert(len(ext[4].client_shares) == 1)
assert(ext[4].client_shares[0].group == 29)
assert(ext[4].client_shares[0].kxlen == 32)
assert(ext[4].client_shares[0].key_exchange == b'\x998\x1d\xe5`\xe4\xbdC\xd2=\x8eCZ}\xba\xfe\xb3\xc0nQ\xc1<\xaeMT\x13i\x1eR\x9a\xaf,')
assert(isinstance(ext[5],TLS_Ext_SupportedVersion_CH))
assert(ext[5].len == 3)
assert(ext[5].versionslen == 2)
assert(ext[5].versions == [772])
assert(isinstance(ext[6], TLS_Ext_SignatureAlgorithms))
assert(ext[6].sig_algs_len == 30)
assert(len(ext[6].sig_algs) == 15)
assert(ext[6].sig_algs[0] == 1027)
assert(ext[6].sig_algs[-1] == 514)
assert(isinstance(ext[7], TLS_Ext_PSKKeyExchangeModes))
assert(ext[7].kxmodeslen == 1)
assert(ext[7].kxmodes[0] == 1)
assert(isinstance(ext[8], TLS_Ext_RecordSizeLimit))
assert(ext[8].record_size_limit == 16385)


= Reading TLS 1.3 session - ServerHello
from scapy.layers.tls.handshake import TLS13ServerHello
from scapy.layers.tls.extensions import TLS_Ext_SupportedVersion_SH
from scapy.layers.tls.keyexchange_tls13 import TLS_Ext_KeyShare_SH

assert(TLS13ServerHello in t2)
sh = t2.msg[0]
ext = sh.ext
assert(isinstance(sh, TLS13ServerHello))
assert(sh.random_bytes == b'\xa6\xaf\x06\xa4\x12\x18`\xdc^n`$\x9c\xd3L\x95\x93\x0c\x8a\xc5\xcb\x144\xda\xc1Uw.\xd3\xe2i(')
assert(sh.cipher == 0x1301)
assert(len(sh.ext) == 2)
assert(isinstance(ext[0], TLS_Ext_KeyShare_SH))
assert(ext[0].len == 36)
assert(ext[0].server_share.group == 29)
assert(ext[0].server_share.key_exchange == b'\xc9\x82\x88v\x11 \x95\xfefv+\xdb\xf7\xc6r\xe1V\xd6\xcc%;\x83=\xf1\xddi\xb1\xb0Nu\x1f\x0f')
assert(isinstance(ext[1], TLS_Ext_SupportedVersion_SH))
assert(ext[1].version == 0x0304)


= Reading TLS 1.3 session - TLS parsing (with encryption) does not throw any error
from scapy.layers.tls.record_tls13 import TLS13
t3 = TLS13(serverEncHS, tls_session=t2.tls_session)


= Reading TLS 1.3 session - TLS13 Record header
assert(t3.type == 0x17)
assert(t3.version == 0x0303)
assert(t3.len == 674)


= Reading TLS 1.3 session - TLS13 Record __getitem__
TLS13 in t3

= Reading TLS 1.3 session - TLS13 ApplicationData
from scapy.layers.tls.record_tls13 import TLSInnerPlaintext
TLSInnerPlaintext in t3
assert(len(t3.auth_tag) == 16)
assert(t3.auth_tag == b'\xbf\x02S\xfeQu\xbe\x89\x8eu\x0e\xdcS7\r+')


+ Decrypt a TLS 1.3 session


= Decrypt a TLS 1.3 session - Parse client Hello
~ crypto_advanced

from scapy.layers.tls.extensions import TLS_Ext_SessionTicket
# Values from RFC8448, section 3
x25519_clt_priv = clean("""
         49 af 42 ba 7f 79 94 85 2d 71 3e f2 78
         4b cb ca a7 91 1d e2 6a dc 56 42 cb 63 45 40 e7 ea 50 05
      """)

x25519_clt_pub = clean("""
      99 38 1d e5 60 e4 bd 43 d2 3d 8e 43 5a 7d
      ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af 2c
   """)

t = TLS(clientHello)
assert(len(t.msg) == 1)
assert(t.msg[0].msgtype == 1)
assert(t.msg[0].extlen == 145)
assert(len(t.msg[0].ext) == 9)
e = t.msg[0].ext
assert(isinstance(e[0], TLS_Ext_ServerName))
assert(isinstance(e[1], TLS_Ext_RenegotiationInfo))
assert(isinstance(e[2], TLS_Ext_SupportedGroups))
assert(isinstance(e[3],TLS_Ext_SessionTicket))
assert(e[3].len == 0)
assert(isinstance(e[4], TLS_Ext_KeyShare_CH))
assert(len(e[4].client_shares) == 1)
assert(e[4].client_shares[0].group == 29)
assert(e[4].client_shares[0].key_exchange == x25519_clt_pub)
assert(isinstance(e[5], TLS_Ext_SupportedVersion_CH))
assert(isinstance(e[6], TLS_Ext_SignatureAlgorithms))
assert(isinstance(e[7], TLS_Ext_PSKKeyExchangeModes))
assert(e[7].kxmodeslen == 1)
assert(len(e[7].kxmodes) == 1)
assert(e[7].kxmodes[0] == 1)
assert(isinstance(e[8], TLS_Ext_RecordSizeLimit))


= Decrypt a TLS 1.3 session - Parse server Hello
~ crypto_advanced

from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
from scapy.layers.tls.crypto.pkcs1 import pkcs_os2ip

# Values from RFC8448, section 3
x25519_srv_priv = clean("""
        b1 58 0e ea df 6d d5 89 b8 ef 4f 2d 56
        52 57 8c c8 10 e9 98 01 91 ec 8d 05 83 08 ce a2 16 a2 1e
""")

x25519_srv_pub = clean("""
        c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6
        72 e1 56 d6 cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f     
""") 

privkey = X25519PrivateKey.from_private_bytes(x25519_clt_priv)
t.tls_session.tls13_client_privshares["x25519"] = privkey

t = TLS(serverHello, tls_session=t.tls_session.mirror())

assert(len(t.msg) == 1)
assert(isinstance(t.msg[0], TLS13ServerHello))
assert(len(t.msg[0].ext) == 2)
e = t.msg[0].ext
assert(isinstance(e[0], TLS_Ext_KeyShare_SH))
assert(e[0].server_share.group == 29)
assert(e[0].server_share.key_exchange == x25519_srv_pub)
assert(isinstance(e[1], TLS_Ext_SupportedVersion_SH))


= Decrypt a TLS 1.3 session - Handshake traffic secret derivation 
~ crypto_advanced

# Values from RFC8448, section 3
early_secret = clean("""
    33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c
    e2 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a
""")

ecdhe_secret = clean("""
    8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d
    35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d
""")

handshake_secret = clean("""
        1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b
        01 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
""")

client_handshake_traffic_secret = clean("""
        b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e
        2d 8f 3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21
""")

server_handshake_traffic_secret = clean("""
        b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d
        37 b4 e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
""")

assert(len(t.tls_session.tls13_derived_secrets) == 5)
assert(t.tls_session.tls13_early_secret is not None)
assert(t.tls_session.tls13_early_secret == early_secret)
assert(t.tls_session.tls13_dhe_secret == ecdhe_secret)
assert(t.tls_session.tls13_handshake_secret is not None)
assert(t.tls_session.tls13_handshake_secret == handshake_secret)
assert( 'client_handshake_traffic_secret' in t.tls_session.tls13_derived_secrets)
assert( t.tls_session.tls13_derived_secrets['client_handshake_traffic_secret'] == client_handshake_traffic_secret)
assert( 'server_handshake_traffic_secret' in t.tls_session.tls13_derived_secrets)
assert(t.tls_session.tls13_derived_secrets['server_handshake_traffic_secret'] == server_handshake_traffic_secret)


= Decrypt a TLS 1.3 session - Server handshake traffic key calculation 
~ crypto_advanced

# Values from RFC8448, section 3
server_hs_traffic_key = clean("""
             3f ce 51 60 09 c2 17 27 d0 f2 e4 e8 6e
             e4 03 bc
""")

server_hs_traffic_iv = clean("""
             5d 31 3e b2 67 12 76 ee 13 00 0b 30
""")

assert(t.tls_session.prcs.cipher.key == server_hs_traffic_key)
assert(t.tls_session.prcs.cipher.fixed_iv == server_hs_traffic_iv)

= Decrypt a TLS 1.3 session - Decrypt and parse server encrypted handshake
~ crypto_advanced

# Values from RFC8448, section 3
server_finished = clean("""
         88 63 e6 bf b0 42 0a 92 7f a2 7f 34 33 6a
         70 ae 42 6e 96 8e 3e b8 84 94 5b 96 85 6d ba 39 76 d1
   """)

t = TLS13(serverEncHS, tls_session=t.tls_session)
assert(t.deciphered_len == 658)
assert(t.inner.type == 22)
assert(len(t.inner.msg) == 4)
assert(t.auth_tag == b'\xbf\x02S\xfeQu\xbe\x89\x8eu\x0e\xdcS7\r+')

m = t.inner.msg

= Decrypt a TLS 1.3 session - Parse decrypted EncryptedExtension
~ crypto_advanced

from scapy.layers.tls.handshake import TLSEncryptedExtensions
assert(isinstance(m[0], TLSEncryptedExtensions))
assert(m[0].msgtype == 8)
assert(m[0].msglen == 36)
assert(m[0].extlen == 34)
assert(len(m[0].ext) == 3)
assert(isinstance(m[0].ext[0], TLS_Ext_SupportedGroups))
assert(m[0].ext[0].groupslen == 18)
assert(m[0].ext[0].groups == [29, 23, 24, 25, 256, 257, 258, 259, 260])
assert(isinstance(m[0].ext[1], TLS_Ext_RecordSizeLimit))
assert(m[0].ext[1].record_size_limit == 16385)
assert(isinstance(m[0].ext[2], TLS_Ext_ServerName))
assert(m[0].ext[2].len == 0)

= Decrypt a TLS 1.3 session - Parse decrypted TLS13Certificate
~ crypto_advanced

from scapy.layers.tls.cert import Cert
from scapy.layers.tls.handshake import (_ASN1CertAndExt, TLS13Certificate)

assert(isinstance(m[1], TLS13Certificate))
assert(m[1].msgtype == 11)
assert(m[1].msglen == 441)
assert(m[1].cert_req_ctxt_len == 0)
assert(m[1].cert_req_ctxt == b'')
assert(m[1].certslen == 437)
assert(len(m[1].certs) == 1)
assert(isinstance(m[1].certs[0], _ASN1CertAndExt))
assert(m[1].certs[0].cert[0] == 432)
assert(isinstance(m[1].certs[0].cert[1], Cert))
assert(m[1].certs[0].cert[1].cA == False)
assert(m[1].certs[0].cert[1].isSelfSigned() == True)
assert(m[1].certs[0].cert[1].issuer['commonName'] == 'rsa')
assert(m[1].certs[0].cert[1].keyUsage == ['digitalSignature', 'keyEncipherment'])
assert(m[1].certs[0].cert[1].notAfter_str == 'Jul 30 01:23:59 2026 GMT')
assert(m[1].certs[0].cert[1].notBefore_str == 'Jul 30 01:23:59 2016 GMT')
assert(m[1].certs[0].cert[1].serial == 2)
assert(m[1].certs[0].cert[1].sigAlg == 'sha256WithRSAEncryption')
assert(m[1].certs[0].cert[1].signatureLen == 128)
assert(m[1].certs[0].cert[1].subject['commonName'] == 'rsa')
assert(m[1].certs[0].cert[1].version == 3)


= Decrypt a TLS 1.3 session - Parse decrypted TLSCertificateVerify
~ crypto_advanced

from scapy.layers.tls.handshake import TLSCertificateVerify
from scapy.layers.tls.keyexchange import _TLSSignature
assert(isinstance(m[2], TLSCertificateVerify))
assert(isinstance(m[2], TLSCertificateVerify))
assert(m[2].msgtype == 15)
assert(m[2].msglen == 132)
assert(isinstance(m[2].sig, _TLSSignature))
assert(m[2].sig.sig_alg == 2052)
assert(m[2].sig.sig_len == 128)
assert(m[2].sig.sig_val == b"Zt|]\x88\xfa\x9b\xd2\xe5Z\xb0\x85\xa6\x10\x15\xb7!\x1f\x82L\xd4\x84\x14Z\xb3\xffR\xf1\xfd\xa8G{\x0bz\xbc\x90\xdbx\xe2\xd3:\\\x14\x1a\x07\x86S\xfak\xefx\x0c^\xa2H\xee\xaa\xa7\x85\xc4\xf3\x94\xca\xb6\xd3\x0b\xbe\x8dHY\xeeQ\x1f`)W\xb1T\x11\xac\x02vqE\x9eFD\\\x9e\xa5\x8c\x18\x1e\x81\x8e\x95\xb8\xc3\xfb\x0b\xf3'\x84\t\xd3\xbe\x15*=\xa5\x04>\x06=\xdae\xcd\xf5\xae\xa2\rS\xdf\xac\xd4/t\xf3")

= Decrypt a TLS 1.3 session - Parse decrypted TLSFinished
~ crypto_advanced
from scapy.layers.tls.handshake import TLSFinished
# Values from RFC8448, section 3
server_finished = clean("""
         9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4
         de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07 18
   """)
assert(isinstance(m[3], TLSFinished))
assert(m[3].msgtype == 20)
assert(m[3].msglen == 32)
assert(m[3].vdata == server_finished)


= Decrypt a TLS 1.3 session - Client handshake traffic key calculation
~ crypto_advanced
# Values from RFC8448, section 3
client_hs_traffic_key = clean("""
         db fa a6 93 d1 76 2c 5b 66 6a f5 d9 50
         25 8d 01
   """)
client_hs_traffic_iv = clean("""
          5b d3 c7 1b 83 6e 0b 76 bb 73 26 5f
   """)

assert(t.tls_session.pwcs.cipher.key == client_hs_traffic_key)
assert(t.tls_session.pwcs.cipher.fixed_iv == client_hs_traffic_iv)

= Decrypt a TLS 1.3 session - Decrypt and parse client encrypted handshake 
~ crypto_advanced
# Values from RFC8448, section 3
client_finished = clean("""
         a8 ec 43 6d 67 76 34 ae 52 5a c1 fc eb e1
         1a 03 9e c1 76 94 fa c6 e9 85 27 b6 42 f2 ed d5 ce 61
   """)

t = TLS13(clientEncHS, tls_session=t.tls_session.mirror())
assert(t.deciphered_len == 37)
assert(t.inner.type == 22)
assert(len(t.inner.msg) == 1)
m = t.inner.msg
assert(isinstance(m[0], TLSFinished))
assert(m[0].vdata == client_finished)

= Decrypt a TLS 1.3 session - Application traffic secret derivation
~ crypto_advanced
# Values from RFC8448, section 3
master_secret = clean("""
         18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a
         47 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
   """)

client_application_traffic_secret_0 = clean("""
         9e 40 64 6c e7 9a 7f 9d c0 5a f8 88 9b ce
         65 52 87 5a fa 0b 06 df 00 87 f7 92 eb b7 c1 75 04 a5
   """)

server_application_traffic_secret_0 = clean("""
         a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9
         50 32 82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43
   """)


exporter_master_secret = clean("""
         fe 22 f8 81 17 6e da 18 eb 8f 44 52 9e 67
         92 c5 0c 9a 3f 89 45 2f 68 d8 ae 31 1b 43 09 d3 cf 50
   """)

resumption_master_secret = clean("""
         7d f2 35 f2 03 1d 2a 05 12 87 d0 2b 02 41
         b0 bf da f8 6c c8 56 23 1f 2d 5a ba 46 c4 34 ec 19 6c
   """)


assert(t.tls_session.tls13_master_secret is not None)
assert(t.tls_session.tls13_master_secret == master_secret)

assert(len(t.tls_session.tls13_derived_secrets) == 9)
assert('client_traffic_secrets' in  t.tls_session.tls13_derived_secrets)
assert(len(t.tls_session.tls13_derived_secrets['client_traffic_secrets']) == 1)
assert(t.tls_session.tls13_derived_secrets['client_traffic_secrets'][0] == client_application_traffic_secret_0)

assert('server_traffic_secrets' in  t.tls_session.tls13_derived_secrets)
assert(len(t.tls_session.tls13_derived_secrets['server_traffic_secrets']) == 1)
assert(t.tls_session.tls13_derived_secrets['server_traffic_secrets'][0] == server_application_traffic_secret_0)

assert('exporter_secret' in t.tls_session.tls13_derived_secrets)
assert(t.tls_session.tls13_derived_secrets['exporter_secret'] == exporter_master_secret)

assert('resumption_secret' in t.tls_session.tls13_derived_secrets)
assert(t.tls_session.tls13_derived_secrets['resumption_secret'] == resumption_master_secret)

= Decrypt a TLS 1.3 session - Application traffic keys calculation 
~ crypto_advanced
# Values from RFC8448, section 3
client_ap_traffic_key = clean("""
         17 42 2d da 59 6e d5 d9 ac d8 90 e3 c6
         3f 50 51
   """)

client_ap_traffic_iv = clean("""
          5b 78 92 3d ee 08 57 90 33 e5 23 d9
   """)

server_ap_traffic_key = clean("""
         9f 02 28 3b 6c 9c 07 ef c2 6b b9 f2 ac
         92 e3 56
   """)

server_ap_traffic_iv = clean("""
        cf 78 2b 88 dd 83 54 9a ad f1 e9 84
   """)

assert(t.tls_session.rcs.cipher.key == client_ap_traffic_key)
assert(t.tls_session.rcs.cipher.fixed_iv == client_ap_traffic_iv)
assert(t.tls_session.wcs.cipher.key == server_ap_traffic_key)
assert(t.tls_session.wcs.cipher.fixed_iv == server_ap_traffic_iv)

= Decrypt a TLS 1.3 session - Decrypt and parse server NewSessionTicket
~ crypto_advanced
from scapy.layers.tls.extensions import TLS_Ext_EarlyDataIndicationTicket
# Value from RFC8448, section 3
serverEncTicket = clean("""
         17 03 03 00 de 3a 6b 8f 90 41 4a 97
         d6 95 9c 34 87 68 0d e5 13 4a 2b 24 0e 6c ff ac 11 6e 95 d4 1d
         6a f8 f6 b5 80 dc f3 d1 1d 63 c7 58 db 28 9a 01 59 40 25 2f 55
         71 3e 06 1d c1 3e 07 88 91 a3 8e fb cf 57 53 ad 8e f1 70 ad 3c
         73 53 d1 6d 9d a7 73 b9 ca 7f 2b 9f a1 b6 c0 d4 a3 d0 3f 75 e0
         9c 30 ba 1e 62 97 2a c4 6f 75 f7 b9 81 be 63 43 9b 29 99 ce 13
         06 46 15 13 98 91 d5 e4 c5 b4 06 f1 6e 3f c1 81 a7 7c a4 75 84
         00 25 db 2f 0a 77 f8 1b 5a b0 5b 94 c0 13 46 75 5f 69 23 2c 86
         51 9d 86 cb ee ac 87 aa c3 47 d1 43 f9 60 5d 64 f6 50 db 4d 02
         3e 70 e9 52 ca 49 fe 51 37 12 1c 74 bc 26 97 68 7e 24 87 46 d6
         df 35 30 05 f3 bc e1 86 96 12 9c 81 53 55 6b 3b 6c 67 79 b3 7b
         f1 59 85 68 4f
         """)
t = TLS13(serverEncTicket, tls_session=t.tls_session.mirror())

assert(t.deciphered_len == 206)
assert(t.inner.type == 22)
assert(t.auth_tag == b'\x9c\x81SUk;lgy\xb3{\xf1Y\x85hO')
assert(len(t.inner.msg) == 1)
m = t.inner.msg[0]
assert(m.msgtype == 4)
assert(m.ticket_lifetime == 30)
assert(m.ticket_age_add == 4208372421)
assert(m.noncelen == 2)
assert(len(m.ticket_nonce) == 2)
assert(m.ticket_nonce == b'\x00\x00')
assert(m.ticket == b',\x03]\x82\x93Y\xee_\xf7\xafN\xc9\x00\x00\x00\x00&*d\x94\xdcHm,\x8a4\xcb3\xfa\x90\xbf\x1b\x00p\xad<I\x88\x83\xc96|\t\xa2\xbexZ\xbcU\xcd"`\x97\xa3\xa9\x82\x11r\x83\xf8*\x03\xa1C\xef\xd3\xff]\xd3md\xe8a\xbe\x7f\xd6\x1d(\'\xdb\'\x9c\xce\x14Pw\xd4T\xa3fMNm\xa4\xd2\x9e\xe07%\xa6\xa4\xda\xfc\xd0\xfcg\xd2\xae\xa7\x05)Q>=\xa2g\x7f\xa5\x90l[?}\x8f\x92\xf2(\xbd\xa4\r\xdar\x14p\xf9\xfb\xf2\x97\xb5\xae\xa6\x17do\xac\\\x03\'.\x97\x07\'\xc6!\xa7\x91A\xef_}\xe6P^[\xfb\xc3\x88\xe93Ci@\x93\x93J\xe4\xd3W')
assert(len(m.ext) == 1)
assert(isinstance(m.ext[0], TLS_Ext_EarlyDataIndicationTicket))
assert(m.ext[0].max_early_data_size == 1024)


= Decrypt a TLS 1.3 session - Compute the PSK associated with the ticket
~ crypto_advanced
from scapy.layers.tls.crypto.hkdf import TLS13_HKDF
hash_len = t.tls_session.rcs.ciphersuite.hash_alg.hash_len
hkdf = TLS13_HKDF(t.tls_session.rcs.ciphersuite.hash_alg.name.lower())
tls13_psk_secret = hkdf.expand_label(t.tls_session.tls13_derived_secrets['resumption_secret'],
                                     b"resumption",
                                     m.ticket_nonce,
                                     hash_len)

# Value from RFC8448, section 3
psk_resumption = clean("""
         4e cd 0e b6 ec 3b 4d 87 f5 d6 02 8f 92 2c
         a4 c5 85 1a 27 7f d4 13 11 c9 e6 2d 2c 94 92 e1 c4 f3
      """)

assert(hash_len == 32) 
assert(tls13_psk_secret == psk_resumption)

= Decrypt a TLS 1.3 session - Decrypt and parse client Application Data
~ crypto_advanced
from scapy.layers.tls.record import TLSApplicationData
# Values from RFC8448, section 3
payload = clean("""
         00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e
         0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
         24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31
   """)


clientEncAppData = clean("""
         17 03 03 00 43 a2 3f 70 54 b6 2c 94
         d0 af fa fe 82 28 ba 55 cb ef ac ea 42 f9 14 aa 66 bc ab 3f 2b
         98 19 a8 a5 b4 6b 39 5b d5 4a 9a 20 44 1e 2b 62 97 4e 1f 5a 62
         92 a2 97 70 14 bd 1e 3d ea e6 3a ee bb 21 69 49 15 e4
      """)
t = TLS13(clientEncAppData, tls_session=t.tls_session.mirror())

assert(t.deciphered_len == 51)
assert(len(t.inner.msg) == 1)
assert(t.inner.type == 23)
m = t.inner.msg[0]
assert(isinstance(m, TLSApplicationData))
assert(m.data == payload)

= TLS_Ext_EncryptedServerName(), dissect
~ crypto_advanced

from scapy.layers.tls.extensions import TLS_Ext_EncryptedServerName

clientHello3 = clean("""
16030102c4010002c003034b1 40e7d15fc8db422cec056fbaf 0285d306df4eedad1bc6ea57d 5114e6bd52a20a5b9c7445955 e296b886469c974648cda0a68
5d3c06d884e388f6475c32e03 2d0024130113031302c02bc02 fcca9cca8c02cc030c00ac009 c013c01400330039002f00350 00a0100025300170000ff0100
0100000a000e000c001d00170 018001901000101000b000201 00002300000010000b0009086 87474702f312e310005000501 000000000033006b0069001d0
02037adee0aacc37b08d47222 caf6a5097a800fcf8406ae118 38f6348294d2dde1200170041 048b127c905d6d487a40b8b19 c99c56aa1a8c208218c178dae
02568547b2ce8f538a530b858 a7a2f608d66e148baa5693d03 c519b45017c63f48c5a4c1238 707bc002b0009080304030303 020301000d001800160403050
3060308040805080604010501 060102030201002d00020101f fce016e1301001d0020912e86 b776ee552a6bb1e2c70d7b467 770b190432237cc743a93091d
ce24623500208bc16fdcbbc7c 8756808c94f70464d68297975 f33be90e1a200633f5eb2d4c6 101249e073bff833782e57e88 2519a53ef8bde4c94a7878a2f
8461aec57802440007c7b2dab 986d9bc79257ce00ca6a998b1 fadb0114161069d364ccebae8 dab6c88151f297daeaecfd2e1 a598a486e2efc9561298f8dd5
f35d184f0e87768777d253e68 952b730a24b342fde10df4f8e 82afdc2f10c2481634d92015d 9d5e6a9566494735d9c079115 bdeb0cd019098d1cf847c53ef
4aac41560cacdc7ce166399df 5b0c0af91d5be3f7d8224755a aa6046de52875f9ef9ac15372 7ce08019bc2648beb4b1418cb 4979ff7eaeedaec2b15695508
4d5a480cb939fdc7f00e6cc6f c0f9675276a9d607686c4d779 d4bb7544fb60c7f3079afbc74 61ed67fd55a78c44d6f8d4eaf 386acc17dea11e37a09f63da3
d059243b35f449e891255ac7b 4f631509d7060f001c0002400 1
""")
t = TLS(clientHello3)
clientESNI = t.msg[0].ext[11]
assert isinstance(clientESNI, TLS_Ext_EncryptedServerName) and clientESNI.cipher == 4865


= TLS_Ext_EncryptedServerName(),  basic instantiation
~ crypto_advanced

esni = TLS_Ext_EncryptedServerName(key_exchange_group=29,encrypted_sni=clean("""
ffce016e1301001d00209 12e86b776ee552a6bb1e2 c70d7b467770b19043223 7cc743a93091dce246235
00208bc16fdcbbc7c8756 808c94f70464d68297975 f33be90e1a200633f5eb2 d4c6101249e073bff8337
82e57e882519a53ef8bde 4c94a7878a2f8461aec57 802440007c7b2dab986d9 bc79257ce00ca6a998b1f
adb0114161069d364cceb ae8dab6c88151f297daea ecfd2e1a598a486e2efc9 561298f8dd5f35d184f0e
87768777d253e68952b73 0a24b342fde10df4f8e82 afdc2f10c2481634d9201 5d9d5e6a9566494735d9c
079115bdeb0cd019098d1 cf847c53ef4aac41560ca cdc7ce166399df5b0c0af 91d5be3f7d8224755aaa6
046de52875f9ef9ac1537 27ce08019bc2648beb4b1 418cb4979ff7eaeedaec2 b156955084d5a480cb939
fdc7f00e6cc6fc0f96752 76a9d607686c4d779d4bb 7544fb60c7f3079afbc74 61ed67fd55a78c44d6f8d
4eaf386acc17dea11e37a 09f63da3d059243b35f44 9e891255ac7b4f631509d 7060f
"""))
assert esni.key_exchange_group == 29 and esni.encrypted_sni==clean("""
ffce016e1301001d00209 12e86b776ee552a6bb1e2 c70d7b467770b19043223 7cc743a93091dce246235
00208bc16fdcbbc7c8756 808c94f70464d68297975 f33be90e1a200633f5eb2 d4c6101249e073bff8337
82e57e882519a53ef8bde 4c94a7878a2f8461aec57 802440007c7b2dab986d9 bc79257ce00ca6a998b1f
adb0114161069d364cceb ae8dab6c88151f297daea ecfd2e1a598a486e2efc9 561298f8dd5f35d184f0e
87768777d253e68952b73 0a24b342fde10df4f8e82 afdc2f10c2481634d9201 5d9d5e6a9566494735d9c
079115bdeb0cd019098d1 cf847c53ef4aac41560ca cdc7ce166399df5b0c0af 91d5be3f7d8224755aaa6
046de52875f9ef9ac1537 27ce08019bc2648beb4b1 418cb4979ff7eaeedaec2 b156955084d5a480cb939
fdc7f00e6cc6fc0f96752 76a9d607686c4d779d4bb 7544fb60c7f3079afbc74 61ed67fd55a78c44d6f8d
4eaf386acc17dea11e37a 09f63da3d059243b35f44 9e891255ac7b4f631509d 7060f
""")

= Decrypt a TLS 1.3 session - Decrypt and parse server Application Data
~ crypto_advanced
# Values from RFC8448, section 3
payload = clean("""
         00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e
         0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
         24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31
   """)

serverEncAppData = clean("""
         17 03 03 00 43 2e 93 7e 11 ef 4a c7
         40 e5 38 ad 36 00 5f c4 a4 69 32 fc 32 25 d0 5f 82 aa 1b 36 e3
         0e fa f9 7d 90 e6 df fc 60 2d cb 50 1a 59 a8 fc c4 9c 4b f2 e5
         f0 a2 1c 00 47 c2 ab f3 32 54 0d d0 32 e1 67 c2 95 5d
      """)

t = TLS13(serverEncAppData, tls_session=t.tls_session.mirror())
assert(t.deciphered_len == 51)
assert(len(t.inner.msg) == 1)
assert(t.inner.type == 23)
m = t.inner.msg[0]
assert(isinstance(m, TLSApplicationData))
assert(m.data == payload)

= Decrypt a TLS 1.3 session - Decrypt client Alert
~ crypto_advanced
from scapy.layers.tls.record import TLSAlert
# Value from RFC8448, section 3
clientEncAlert = clean("""
         17 03 03 00 13 c9 87 27 60 65 56 66
         b7 4d 7f f1 15 3e fd 6d b6 d0 b0 e3
   """)

t = TLS13(clientEncAlert, tls_session=t.tls_session.mirror())
assert(t.deciphered_len == 3)
assert(len(t.inner.msg) == 1)
assert(t.inner.type == 21)
m = t.inner.msg[0]
assert(isinstance(m, TLSAlert))
assert(m.level == 1)
assert(m.descr == 0)

= Decrypt a TLS 1.3 session - Decrypt server Alert
~ crypto_advanced
# Value from RFC8448, section 3
serverEncAlert = clean("""
         17 03 03 00 13 b5 8f d6 71 66 eb f5
         99 d2 47 20 cf be 7e fa 7a 88 64 a9
   """)
t = TLS13(serverEncAlert, tls_session=t.tls_session.mirror())
assert(t.deciphered_len == 3)
assert(len(t.inner.msg) == 1)
assert(t.inner.type == 21)
m = t.inner.msg[0]
assert(isinstance(m, TLSAlert))
assert(m.level == 1)
assert(m.descr == 0)


########### HelloRetryRequest ###############################################
+ Decrypt a TLS 1.3 session with a retry

= Decrypt a TLS 1.3 session with a retry - Parse first ClientHello
# Values from RFC8448, section 5
x25519_clt_priv = clean("""
         0e d0 2f 8e 81 17 ef c7 5c a7 ac 32 aa
         7e 34 ed a6 4c dc 0d da d1 54 a5 e8 52 89 f9 59 f6 32 04
   """)

x25519_clt_pub = clean("""
         e8 e8 e3 f3 b9 3a 25 ed 97 a1 4a 7d ca cb
         8a 27 2c 62 88 e5 85 c6 48 4d 05 26 2f ca d0 62 ad 1f
   """)

clientHello1 = clean("""
         16 03 01 00 b4 01 00 00 b0 03 03 b0
         b1 c5 a5 aa 37 c5 91 9f 2e d1 d5 c6 ff f7 fc b7 84 97 16 94 5a
         2b 8c ee 92 58 a3 46 67 7b 6f 00 00 06 13 01 13 03 13 02 01 00
         00 81 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
         00 00 0a 00 08 00 06 00 1d 00 17 00 18 00 33 00 26 00 24 00 1d
         00 20 e8 e8 e3 f3 b9 3a 25 ed 97 a1 4a 7d ca cb 8a 27 2c 62 88
         e5 85 c6 48 4d 05 26 2f ca d0 62 ad 1f 00 2b 00 03 02 03 04 00
         0d 00 20 00 1e 04 03 05 03 06 03 02 03 08 04 08 05 08 06 04 01
         05 01 06 01 02 01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00
         1c 00 02 40 01
   """)

t = TLS(clientHello1)
assert(len(t.msg) == 1)
assert(t.msg[0].msgtype == 1)
assert(t.msg[0].extlen == 129)
assert(len(t.msg[0].ext) == 8)
e = t.msg[0].ext
assert(isinstance(e[0], TLS_Ext_ServerName))
assert(isinstance(e[1], TLS_Ext_RenegotiationInfo))
assert(isinstance(e[2], TLS_Ext_SupportedGroups))
assert(isinstance(e[3],TLS_Ext_KeyShare_CH))
assert(len(e[3].client_shares) == 1)
assert(e[3].client_shares[0].group == 29)
assert(e[3].client_shares[0].key_exchange == x25519_clt_pub)
assert(isinstance(e[4], TLS_Ext_SupportedVersion_CH))
assert(isinstance(e[5], TLS_Ext_SignatureAlgorithms))
assert(isinstance(e[6], TLS_Ext_PSKKeyExchangeModes))
assert(e[6].kxmodeslen == 1)
assert(len(e[6].kxmodes) == 1)
assert(e[6].kxmodes[0] == 1)
assert(isinstance(e[7], TLS_Ext_RecordSizeLimit))



secp256_srv_pub = clean("""
         8c 51 06 01 f9 76 5b fb 8e d6 93 44 9a
         48 98 98 59 b5 cf a8 79 cb 9f 54 43 c4 1c 5f f1 06 34 ed
   """)

secp256_srv_pub = clean("""
         04 58 3e 05 4b 7a 66 67 2a e0 20 ad 9d 26
         86 fc c8 5b 5a d4 1a 13 4a 0f 03 ee 72 b8 93 05 2b d8 5b 4c 8d
         e6 77 6f 5b 04 ac 07 d8 35 40 ea b3 e3 d9 c5 47 bc 65 28 c4 31
         7d 29 46 86 09 3a 6c ad 7d
   """)



= Decrypt a TLS 1.3 session with a retry - Parse ServerHelloRetryRequest
from scapy.layers.tls.keyexchange_tls13 import TLS_Ext_KeyShare_HRR
from scapy.layers.tls.extensions import TLS_Ext_Cookie
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
# Value from RFC8448, section 5
helloRetryRequest = clean("""
         16 03 03 00 b0 02 00 00 ac 03 03 cf
         21 ad 74 e5 9a 61 11 be 1d 8c 02 1e 65 b8 91 c2 a2 11 16 7a bb
         8c 5e 07 9e 09 e2 c8 a8 33 9c 00 13 01 00 00 84 00 33 00 02 00
         17 00 2c 00 74 00 72 71 dc d0 4b b8 8b c3 18 91 19 39 8a 00 00
         00 00 ee fa fc 76 c1 46 b8 23 b0 96 f8 aa ca d3 65 dd 00 30 95
         3f 4e df 62 56 36 e5 f2 1b b2 e2 3f cc 65 4b 1b 5b 40 31 8d 10
         d1 37 ab cb b8 75 74 e3 6e 8a 1f 02 5f 7d fa 5d 6e 50 78 1b 5e
         da 4a a1 5b 0c 8b e7 78 25 7d 16 aa 30 30 e9 e7 84 1d d9 e4 c0
         34 22 67 e8 ca 0c af 57 1f b2 b7 cf f0 f9 34 b0 00 2b 00 02 03
         04
   """)

t = TLS(helloRetryRequest, tls_session=t.tls_session.mirror())
assert(len(t.msg) == 1)
assert(t.msg[0].msgtype == 2)
digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
digest.update(b"HelloRetryRequest")
assert(t.msg[0].random_bytes == digest.finalize())
assert(t.msg[0].extlen == 132)
assert(len(t.msg[0].ext) == 3)
e = t.msg[0].ext
assert(isinstance(e[0], TLS_Ext_KeyShare_HRR))
assert(e[0].type == 51)
assert(e[0].len == 2)
assert(e[0].selected_group == 23)
assert(isinstance(e[1], TLS_Ext_Cookie))
assert(e[1].type == 44)
assert(e[1].len == 116)
assert(e[1].cookielen == 114)
assert(e[1].cookie == b'q\xdc\xd0K\xb8\x8b\xc3\x18\x91\x199\x8a\x00\x00\x00\x00\xee\xfa\xfcv\xc1F\xb8#\xb0\x96\xf8\xaa\xca\xd3e\xdd\x000\x95?N\xdfbV6\xe5\xf2\x1b\xb2\xe2?\xcceK\x1b[@1\x8d\x10\xd17\xab\xcb\xb8ut\xe3n\x8a\x1f\x02_}\xfa]nPx\x1b^\xdaJ\xa1[\x0c\x8b\xe7x%}\x16\xaa00\xe9\xe7\x84\x1d\xd9\xe4\xc04"g\xe8\xca\x0c\xafW\x1f\xb2\xb7\xcf\xf0\xf94\xb0')
assert(isinstance(e[2], TLS_Ext_SupportedVersion_SH))


= Decrypt a TLS 1.3 session with a retry - Parse second ClientHello

from scapy.layers.tls.extensions import TLS_Ext_Padding
# Values from RFC8448, section 5
secp256_clt_pub = clean("""
         04 a6 da 73 92 ec 59 1e 17 ab fd 53 59 64
         b9 98 94 d1 3b ef b2 21 b3 de f2 eb e3 83 0e ac 8f 01 51 81 26
         77 c4 d6 d2 23 7e 85 cf 01 d6 91 0c fb 83 95 4e 76 ba 73 52 83
         05 34 15 98 97 e8 06 57 80
   """)

secp256_clt_priv = clean("""
         ab 54 73 46 7e 19 34 6c eb 0a 04 14 e4
         1d a2 1d 4d 24 45 bc 30 25 af e9 7c 4e 8d c8 d5 13 da 39
   """)

clientHello2 = clean("""
         16 03 03 02 00 01 00 01 fc 03 03 b0
         b1 c5 a5 aa 37 c5 91 9f 2e d1 d5 c6 ff f7 fc b7 84 97 16 94 5a
         2b 8c ee 92 58 a3 46 67 7b 6f 00 00 06 13 01 13 03 13 02 01 00
         01 cd 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
         00 00 0a 00 08 00 06 00 1d 00 17 00 18 00 33 00 47 00 45 00 17
         00 41 04 a6 da 73 92 ec 59 1e 17 ab fd 53 59 64 b9 98 94 d1 3b
         ef b2 21 b3 de f2 eb e3 83 0e ac 8f 01 51 81 26 77 c4 d6 d2 23
         7e 85 cf 01 d6 91 0c fb 83 95 4e 76 ba 73 52 83 05 34 15 98 97
         e8 06 57 80 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03
         06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05
         02 06 02 02 02 00 2c 00 74 00 72 71 dc d0 4b b8 8b c3 18 91 19
         39 8a 00 00 00 00 ee fa fc 76 c1 46 b8 23 b0 96 f8 aa ca d3 65
         dd 00 30 95 3f 4e df 62 56 36 e5 f2 1b b2 e2 3f cc 65 4b 1b 5b
         40 31 8d 10 d1 37 ab cb b8 75 74 e3 6e 8a 1f 02 5f 7d fa 5d 6e
         50 78 1b 5e da 4a a1 5b 0c 8b e7 78 25 7d 16 aa 30 30 e9 e7 84
         1d d9 e4 c0 34 22 67 e8 ca 0c af 57 1f b2 b7 cf f0 f9 34 b0 00
         2d 00 02 01 01 00 1c 00 02 40 01 00 15 00 af 00 00 00 00 00 00
         00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         00
   """)

t = TLS(clientHello2, tls_session=t.tls_session.mirror())
assert(len(t.msg) == 1)
assert(t.msg[0].msgtype == 1)
assert(t.msg[0].extlen == 461)
assert(len(t.msg[0].ext) == 10)
e = t.msg[0].ext
assert(isinstance(e[0], TLS_Ext_ServerName))
assert(isinstance(e[1], TLS_Ext_RenegotiationInfo))
assert(isinstance(e[2], TLS_Ext_SupportedGroups))
assert(isinstance(e[3],TLS_Ext_KeyShare_CH))
assert(len(e[3].client_shares) == 1)
assert(e[3].client_shares[0].group == 23)
assert(e[3].client_shares[0].key_exchange == secp256_clt_pub)
assert(isinstance(e[4], TLS_Ext_SupportedVersion_CH))
assert(isinstance(e[5], TLS_Ext_SignatureAlgorithms))
assert(isinstance(e[6], TLS_Ext_Cookie))
assert(e[6].cookie == b'q\xdc\xd0K\xb8\x8b\xc3\x18\x91\x199\x8a\x00\x00\x00\x00\xee\xfa\xfcv\xc1F\xb8#\xb0\x96\xf8\xaa\xca\xd3e\xdd\x000\x95?N\xdfbV6\xe5\xf2\x1b\xb2\xe2?\xcceK\x1b[@1\x8d\x10\xd17\xab\xcb\xb8ut\xe3n\x8a\x1f\x02_}\xfa]nPx\x1b^\xdaJ\xa1[\x0c\x8b\xe7x%}\x16\xaa00\xe9\xe7\x84\x1d\xd9\xe4\xc04"g\xe8\xca\x0c\xafW\x1f\xb2\xb7\xcf\xf0\xf94\xb0')
assert(isinstance(e[7], TLS_Ext_PSKKeyExchangeModes))
assert(e[7].kxmodeslen == 1)
assert(len(e[7].kxmodes) == 1)
assert(e[7].kxmodes[0] == 1)
assert(isinstance(e[8], TLS_Ext_RecordSizeLimit))
assert(isinstance(e[9], TLS_Ext_Padding))
assert(e[9].len == 175)
assert(e[9].padding == 175*b'\x00')

= Decrypt a TLS 1.3 session with a retry - Parse ServerHello
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateNumbers
pubnum = t.tls_session.tls13_client_pubshares["secp256r1"].public_numbers()
privnum = EllipticCurvePrivateNumbers(pkcs_os2ip(secp256_clt_priv), pubnum)
privkey = privnum.private_key(default_backend())
t.tls_session.tls13_client_privshares["secp256r1"] = privkey

serverHello = clean("""
         16 03 03 00 7b 02 00 00 77 03 03 bb
         34 1d 84 7f d7 89 c4 7c 38 71 72 dc 0c 9b f1 47 fc ca cb 50 43
         d8 6c a4 c5 98 d3 ff 57 1b 98 00 13 01 00 00 4f 00 33 00 45 00
         17 00 41 04 58 3e 05 4b 7a 66 67 2a e0 20 ad 9d 26 86 fc c8 5b
         5a d4 1a 13 4a 0f 03 ee 72 b8 93 05 2b d8 5b 4c 8d e6 77 6f 5b
         04 ac 07 d8 35 40 ea b3 e3 d9 c5 47 bc 65 28 c4 31 7d 29 46 86
         09 3a 6c ad 7d 00 2b 00 02 03 04
   """)

t = TLS(serverHello, tls_session=t.tls_session.mirror())
assert(len(t.msg) == 1)
assert(isinstance(t.msg[0], TLS13ServerHello))
assert(len(t.msg[0].ext) == 2)
e = t.msg[0].ext
assert(isinstance(e[0], TLS_Ext_KeyShare_SH))
assert(e[0].server_share.group == 23)
assert(e[0].server_share.key_exchange == secp256_srv_pub)
assert(isinstance(e[1], TLS_Ext_SupportedVersion_SH))

= Decrypt a TLS 1.3 session with a retry - Handshake traffic secret derivation

# Values from RFC8448, section 5
early_secret = clean("""
         33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c
         e2 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a
   """)

ecdhe_secret = clean("""
         c1 42 ce 13 ca 11 b5 c2 23 36 52 e6 3a d3 d9 78
         44 f1 62 1f bf b9 de 69 d5 47 dc 8f ed ea be b4
   """)

handshake_secret = clean("""
         ce 02 2e 5e 6e 81 e5 07 36 d7 73 f2 d3 ad fc
         e8 22 0d 04 9b f5 10 f0 db fa c9 27 ef 42 43 b1 48
   """)

client_handshake_traffic_secret = clean("""
         15 8a a7 ab 88 55 07 35 82 b4 1d 67 4b 40
         55 ca bc c5 34 72 8f 65 93 14 86 1b 4e 08 e2 01 15 66
   """)

server_handshake_traffic_secret = clean("""
         34 03 e7 81 e2 af 7b 65 08 da 28 57 4f 6e
         95 a1 ab f1 62 de 83 a9 79 27 c3 76 72 a4 a0 ce f8 a1
   """)

assert(len(t.tls_session.tls13_derived_secrets) == 5)
assert(t.tls_session.tls13_early_secret is not None)
assert(t.tls_session.tls13_early_secret == early_secret)
assert(t.tls_session.tls13_dhe_secret == ecdhe_secret)
assert(t.tls_session.tls13_handshake_secret is not None)
assert(t.tls_session.tls13_handshake_secret == handshake_secret)
assert( 'client_handshake_traffic_secret' in t.tls_session.tls13_derived_secrets)
assert( t.tls_session.tls13_derived_secrets['client_handshake_traffic_secret'] == client_handshake_traffic_secret)
assert( 'server_handshake_traffic_secret' in t.tls_session.tls13_derived_secrets)
assert(t.tls_session.tls13_derived_secrets['server_handshake_traffic_secret'] == server_handshake_traffic_secret)


= Decrypt a TLS 1.3 session with a retry - Server handshake traffic key calculation
# Values from RFC8448, section 5
server_hs_traffic_key = clean("""
         46 46 bf ac 17 12 c4 26 cd 78 d8 a2 4a
         8a 6f 6b
   """)
server_hs_traffic_iv = clean("""
         c7 d3 95 c0 8d 62 f2 97 d1 37 68 ea
   """)

assert(t.tls_session.prcs.cipher.key == server_hs_traffic_key)
assert(t.tls_session.prcs.cipher.fixed_iv == server_hs_traffic_iv)


= Decrypt a TLS 1.3 session with a retry - Decrypt and parse server handshake 
# Values from RFC8448, section 5
serverEncHS = clean("""
         17 03 03 02 96 99 be e2 0b af 5b 7f
         c7 27 bf ab 62 23 92 8a 38 1e 6d 0c f9 c4 da 65 3f 9d 2a 7b 23
         f7 de 11 cc e8 42 d5 cf 75 63 17 63 45 0f fb 8b 0c c1 d2 38 e6
         58 af 7a 12 ad c8 62 43 11 4a b1 4a 1d a2 fa e4 26 21 ce 48 3f
         b6 24 2e ab fa ad 52 56 6b 02 b3 1d 2e dd ed ef eb 80 e6 6a 99
         00 d5 f9 73 b4 0c 4f df 74 71 9e cf 1b 68 d7 f9 c3 b6 ce b9 03
         ca 13 dd 1b b8 f8 18 7a e3 34 17 e1 d1 52 52 2c 58 22 a1 a0 3a
         d5 2c 83 8c 55 95 3d 61 02 22 87 4c ce 8e 17 90 b2 29 a2 aa 0b
         53 c8 d3 77 ee 72 01 82 95 1d c6 18 1d c5 d9 0b d1 f0 10 5e d1
         e8 4a a5 f7 59 57 c6 66 18 97 07 9e 5e a5 00 74 49 e3 19 7b dc
         7c 9b ee ed dd ea fd d8 44 af a5 c3 15 ec fe 65 e5 76 af e9 09
         81 28 80 62 0e c7 04 8b 42 d7 f5 c7 8d 76 f2 99 d6 d8 25 34 bd
         d8 f5 12 fe bc 0e d3 81 4a ca 47 0c d8 00 0d 3e 1c b9 96 2b 05
         2f bb 95 0d f6 83 a5 2c 2b a7 7e d3 71 3b 12 29 37 a6 e5 17 09
         64 e2 ab 79 69 dc d9 80 b3 db 9b 45 8d a7 60 31 24 d6 dc 00 5e
         4d 6e 04 b4 d0 c4 ba f3 27 5d b8 27 db ba 0a 6d b0 96 72 17 1f
         c0 57 b3 85 1d 7e 02 68 41 e2 97 8f bd 23 46 bb ef dd 03 76 bb
         11 08 fe 9a cc 92 18 9f 56 50 aa 5e 85 d8 e8 c7 b6 7a c5 10 db
         a0 03 d3 d7 e1 63 50 bb 66 d4 50 13 ef d4 4c 9b 60 7c 0d 31 8c
         4c 7d 1a 1f 5c bc 57 e2 06 11 80 4e 37 87 d7 b4 a4 b5 f0 8e d8
         fd 70 bd ae ad e0 22 60 b1 2a b8 42 ef 69 0b 4a 3e e7 91 1e 84
         1b 37 4e cd 5e bb bc 2a 54 d0 47 b6 00 33 6d d7 d0 c8 8b 4b c1
         0e 58 ee 6c b6 56 de 72 47 fa 20 d8 e9 1d eb 84 62 86 08 cf 80
         61 5b 62 e9 6c 14 91 c7 ac 37 55 eb 69 01 40 5d 34 74 fe 1a c7
         9d 10 6a 0c ee 56 c2 57 7f c8 84 80 f9 6c b6 b8 c6 81 b7 b6 8b
         53 c1 46 09 39 08 f3 50 88 81 75 bd fb 0b 1e 31 ad 61 e3 0b a0
         ad fe 6d 22 3a a0 3c 07 83 b5 00 1a 57 58 7c 32 8a 9a fc fc fb
         97 8d 1c d4 32 8f 7d 9d 60 53 0e 63 0b ef d9 6c 0c 81 6e e2 0b
         01 00 76 8a e2 a6 df 51 fc 68 f1 72 74 0a 79 af 11 39 8e e3 be
         12 52 49 1f a9 c6 93 47 9e 87 7f 94 ab 7c 5f 8c ad 48 02 03 e6
         ab 7b 87 dd 71 e8 a0 72 91 13 df 17 f5 ee e8 6c e1 08 d1 d7 20
         07 ec 1c d1 3c 85 a6 c1 49 62 1e 77 b7 d7 8d 80 5a 30 f0 be 03
         0c 31 5e 54
   """)

server_finished = clean("""
         88 63 e6 bf b0 42 0a 92 7f a2 7f 34 33 6a
         70 ae 42 6e 96 8e 3e b8 84 94 5b 96 85 6d ba 39 76 d1
   """)

t = TLS13(serverEncHS, tls_session=t.tls_session)
assert(t.deciphered_len == 646)
assert(len(t.inner.msg) == 4)
m = t.inner.msg
assert(isinstance(m[0], TLSEncryptedExtensions))
assert(len(m[0].ext) == 3)
assert(isinstance(m[0].ext[0], TLS_Ext_SupportedGroups))
assert(isinstance(m[0].ext[1], TLS_Ext_RecordSizeLimit))
assert(isinstance(m[0].ext[2], TLS_Ext_ServerName))
assert(isinstance(m[1], TLS13Certificate))
assert(isinstance(m[2], TLSCertificateVerify))
assert(isinstance(m[3], TLSFinished))
assert(m[3].vdata == server_finished)

= Decrypt a TLS 1.3 session with a retry - Client handshake traffic key calculation
# Values from RFC8448, section 5
client_hs_traffic_key = clean("""
         2f 1f 91 86 63 d5 90 e7 42 11 49 a2 9d
         94 b0 b6
   """)
client_hs_traffic_iv = clean("""
         41 4d 54 85 23 5e 1a 68 87 93 bd 74
   """)

assert(t.tls_session.pwcs.cipher.key == client_hs_traffic_key)
assert(t.tls_session.pwcs.cipher.fixed_iv == client_hs_traffic_iv)


= Decrypt a TLS 1.3 session with a retry - Decrypt and parse client finished
# Values from RFC8448, section 5
clientFinished = clean("""
         23 f5 2f db 07 09 a5 5b d7 f7 9b 99 1f 25
         48 40 87 bc fd 4d 43 80 b1 23 26 a5 2a 28 b2 e3 68 e1
   """)

clientEncHS = clean("""
         17 03 03 00 35 d7 4f 19 23 c6 62 fd
         34 13 7c 6f 50 2f 3d d2 b9 3d 95 1d 1b 3b c9 7e 42 af e2 3c 31
         ab ea 92 fe 91 b4 74 99 9e 85 e3 b7 91 ce 25 2f e8 c3 e9 f9 39
         a4 12 0c b2
   """)

t = TLS13(clientEncHS, tls_session=t.tls_session.mirror())
assert(t.deciphered_len == 37)
assert(len(t.inner.msg) == 1)
assert(isinstance(t.inner.msg[0], TLSFinished))
assert(t.inner.msg[0].vdata == clientFinished)
assert(t.inner.type == 22)

= Decrypt a TLS 1.3 session with a retry - Application traffic secret derivation 
# Values from RFC8448, section 5
master_secret = clean("""
         11 31 54 5d 0b af 79 dd ce 9b 87 f0 69 45 78
         1a 57 dd 18 ef 37 8d cd 20 60 f8 f9 a5 69 02 7e d8
   """)

client_application_traffic_secret_0 = clean("""
         75 ec f4 b9 72 52 5a a0 dc d0 57 c9 94 4d
         4c d5 d8 26 71 d8 84 31 41 d7 dc 2a 4f f1 5a 21 dc 51
   """)

server_application_traffic_secret_0 = clean("""
         5c 74 f8 7d f0 42 25 db 0f 82 09 c9 de 64
         29 e4 94 35 fd ef a7 ca d6 18 64 87 4d 12 f3 1c fc 8d
   """)

exporter_master_secret = clean("""
      7c 06 d3 ae 10 6a 3a 37 4a ce 48 37 b3 98
      5c ac 67 78 0a 6e 2c 5c 04 b5 83 19 d5 84 df 09 d2 23
   """)

resumption_master_secret = clean("""
      09 17 0c 6d 47 27 21 56 6f 9c f9 9b 08 69
      9d af f5 61 ec 8f b2 2d 5a 32 c3 f9 4c e0 09 b6 99 75
   """)


assert(t.tls_session.tls13_master_secret is not None)
assert(t.tls_session.tls13_master_secret == master_secret)

assert(len(t.tls_session.tls13_derived_secrets) == 9)
assert('client_traffic_secrets' in  t.tls_session.tls13_derived_secrets)
assert(len(t.tls_session.tls13_derived_secrets['client_traffic_secrets']) == 1)
assert(t.tls_session.tls13_derived_secrets['client_traffic_secrets'][0] == client_application_traffic_secret_0)

assert('server_traffic_secrets' in  t.tls_session.tls13_derived_secrets)
assert(len(t.tls_session.tls13_derived_secrets['server_traffic_secrets']) == 1)
assert(t.tls_session.tls13_derived_secrets['server_traffic_secrets'][0] == server_application_traffic_secret_0)

assert('exporter_secret' in t.tls_session.tls13_derived_secrets)
assert(t.tls_session.tls13_derived_secrets['exporter_secret'] == exporter_master_secret)

assert('resumption_secret' in t.tls_session.tls13_derived_secrets)
assert(t.tls_session.tls13_derived_secrets['resumption_secret'] == resumption_master_secret)

= Decrypt a TLS 1.3 session with a retry - Application traffic keys calculation 
# Values from RFC8448, section 5
client_ap_traffic_key = clean("""
         a7 eb 2a 05 25 eb 43 31 d5 8f cb f9 f7
         ca 2e 9c
   """)

client_ap_traffic_iv = clean("""
         86 e8 be 22 7c 1b d2 b3 e3 9c b4 44
   """)

server_ap_traffic_key = clean("""
         f2 7a 5d 97 bd 25 55 0c 48 23 b0 f3 e5
         d2 93 88
   """)

server_ap_traffic_iv = clean("""
         0d d6 31 f7 b7 1c bb c7 97 c3 5f e7
   """)

assert(t.tls_session.rcs.cipher.key == client_ap_traffic_key)
assert(t.tls_session.rcs.cipher.fixed_iv == client_ap_traffic_iv)
assert(t.tls_session.wcs.cipher.key == server_ap_traffic_key)
assert(t.tls_session.wcs.cipher.fixed_iv == server_ap_traffic_iv)

= Decrypt a TLS 1.3 session with a retry - Decrypt and parse client Alert 
# Values from RFC8448, section 5
clientEncAlert = clean("""
         17 03 03 00 13 2e a6 cd f7 49 19 60
         23 e2 b3 a4 94 91 69 55 36 42 60 47
   """)

t = TLS13(clientEncAlert, tls_session = t.tls_session)
assert(t.deciphered_len == 3)
assert(len(t.inner.msg) == 1)
assert(t.inner.type == 21)
m = t.inner.msg[0]
assert(isinstance(m, TLSAlert))
assert(m.level == 1)
assert(m.descr == 0)


= Decrypt a TLS 1.3 session with a retry - Decrypt and parse server Alert 
# Values from RFC8448, section 5
serverEncAlert = clean("""
         17 03 03 00 13 51 9f c5 07 5c b0 88
         43 49 75 9f f9 ef 6f 01 1b b4 c6 f2
   """)

t = TLS13(serverEncAlert, tls_session = t.tls_session.mirror())
assert(t.deciphered_len == 3)
assert(len(t.inner.msg) == 1)
assert(t.inner.type == 21)
m = t.inner.msg[0]
assert(isinstance(m, TLSAlert))
assert(m.level == 1)
assert(m.descr == 0)
