Skip to content
Snippets Groups Projects
Commit db280e36 authored by Pierre Lalet's avatar Pierre Lalet Committed by GitHub
Browse files

Merge pull request #767 from mtury/tls_notebooks

Add JCSA17 TLS notebooks
parents 408094ea e398df05
No related branches found
No related tags found
No related merge requests found
Showing
with 890 additions and 0 deletions
doc/notebooks/tls/images/handshake_tls12.png

63.5 KiB

doc/notebooks/tls/images/handshake_tls13.png

53.2 KiB

%% Cell type:markdown id: tags:
# Notebook 1: X.509 certificates
%% Cell type:markdown id: tags:
## Jupyter notebook cheat sheet
%% Cell type:code id: tags:
``` python
# Use Shift+Enter to run the current cell
print 'Hello!'
```
%% Cell type:code id: tags:
``` python
# You may also use Alt+Enter to run the current cell, then create a new cell right below
from datetime import datetime
print 'This is the time right now: %s' % datetime.now()
```
%% Cell type:code id: tags:
``` python
# If needed, pause the cell edition with Ctrl-M.
# Then you can delete the current cell with D+D. You can also undo cell deletion with Z.
# Finally, should Jupyter become stuck in execution, use Kernel/Interrupt from the menu bar.
print 'Got it!'
```
%% Cell type:markdown id: tags:
## Data manipulation with Scapy
%% Cell type:code id: tags:
``` python
from scapy.all import *
```
%% Cell type:code id: tags:
``` python
keystr = open('raw_data/pki/ca_key.der', 'r').read()
print repr(keystr)
# (btw, you can hide the output of a cell by double-clicking on the left of the output)
```
%% Cell type:code id: tags:
``` python
privkey = RSAPrivateKey(keystr)
privkey.show()
```
%% Cell type:code id: tags:
``` python
v = privkey.version
print 'The \'version\' stripped from any ASN.1 encoding is 0x%02x.' % v.val
print 'The \'version\' field correspond to bytes %r.' % str(v)
```
%% Cell type:code id: tags:
``` python
privkey.version = ASN1_INTEGER(1)
privkey.modulus.val *= 2
privkey.show()
```
%% Cell type:code id: tags:
``` python
print 'Original data: %r...' % keystr[:13]
print 'New version bytes: %r' % str(privkey.version)
print 'New modulus bytes: %r...' % str(privkey.modulus)[:6]
print 'Rebuilt data: %r...' % str(privkey)[:13]
```
%% Cell type:markdown id: tags:
## X.509 certificate features
%% Cell type:code id: tags:
``` python
# Let's reload the original key, then let's load a certificate associated with it
privkey = RSAPrivateKey(keystr)
cert = X509_Cert(open('raw_data/pki/ca_cert.der', 'r').read())
cert.show()
```
%% Cell type:code id: tags:
``` python
cert.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.show()
cert.tbsCertificate.subject[-1].rdn[0].show()
```
%% Cell type:code id: tags:
``` python
cert.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.modulus == privkey.modulus
```
%% Cell type:code id: tags:
``` python
cert.tbsCertificate.extensions[2].show()
```
%% Cell type:code id: tags:
``` python
cert.signatureAlgorithm.algorithm
```
%% Cell type:markdown id: tags:
## Scapy crypto tools
%% Cell type:code id: tags:
``` python
# Let's reload the key with Scapy's crypto-enhanced wrapper
privkey = PrivKey('raw_data/pki/ca_key.der')
```
%% Cell type:code id: tags:
``` python
privkey.der == keystr
```
%% Cell type:code id: tags:
``` python
print privkey.key
print privkey.pubkey
```
%% Cell type:code id: tags:
``` python
# We can compute the RSA signature over the part of the certificate which is to be signed
privkey.sign(str(cert.tbsCertificate))
```
%% Cell type:code id: tags:
``` python
cert.signatureValue
```
%% Cell type:code id: tags:
``` python
# We can quickly modify a certificate field and update the signature accordingly
cert.tbsCertificate.serialNumber.val = 0xdeadcafe
cert.tbsCertificate.subject[-1].rdn[0].value.val = 'my new deadcafe CA'
cert2 = privkey.resignCert(cert)
cert2.show()
```
%% Cell type:markdown id: tags:
# TLS handshake overview
This is the standard, modern TLS 1.2 handshake:
<img src="images/handshake_tls12.png" alt="Handshake TLS 1.2" width="400"/>
%% Cell type:code id: tags:
``` python
# We're going to parse several successive records from the passive listening of a standard TLS handshake
from scapy.all import *
```
%% Cell type:markdown id: tags:
## (C) ---> (S) ClientHello
%% Cell type:code id: tags:
``` python
record1 = TLS(open('raw_data/tls_session_protected/01_cli.raw').read())
record1.show()
```
%% Cell type:code id: tags:
``` python
for extension in record1.msg[0].ext:
print ''
extension.show()
```
%% Cell type:markdown id: tags:
## (C) <--- (S) ServerHello
%% Cell type:code id: tags:
``` python
record2 = TLS(open('raw_data/tls_session_protected/02_srv.raw').read())
record2.show()
```
%% Cell type:markdown id: tags:
## (C) <--- (S) Certificate
%% Cell type:code id: tags:
``` python
record3 = TLS(open('raw_data/tls_session_protected/03_srv.raw').read())
record3.show()
```
%% Cell type:code id: tags:
``` python
# The Certificate message actually contains a *chain* of certificates
for cert in record3.msg[0].certs:
print type(cert[1])
cert[1].show()
print ''
```
%% Cell type:code id: tags:
``` python
# Let's recall the domain that the client wants to access
record1.msg[0].ext[0].show()
# Indeed the certificate may be used with other domains than its CN 'www.github.com'
x509c = record3.msg[0].certs[0][1].x509Cert
print type(x509c)
x509c.tbsCertificate.extensions[2].show()
```
%% Cell type:markdown id: tags:
## (C) <--- (S) CertificateStatus, ServerKeyExchange, ServerHelloDone
%% Cell type:code id: tags:
``` python
# Here the server sent three TLS records in the same TCP segment
record4 = TLS(open('raw_data/tls_session_protected/04_srv.raw').read())
record4.show()
```
%% Cell type:code id: tags:
``` python
# Let's verify the signature in the ServerKeyExchange
# First, we need to assemble the whole data being signed
cli_random = pkcs_i2osp(record1.msg[0].gmt_unix_time, 4) + record1.msg[0].random_bytes
srv_random = pkcs_i2osp(record2.msg[0].gmt_unix_time, 4) + record2.msg[0].random_bytes
ecdh_params = str(record4[TLSServerKeyExchange].params)
# Then we retrieve the server's Cert and verify the signature
cert_srv = record3.msg[0].certs[0][1]
cert_srv.verify(cli_random + srv_random + ecdh_params, record4[TLSServerKeyExchange].sig.sig_val, h='sha512')
```
%% Cell type:markdown id: tags:
## (C) ---> (S) ClientKeyExchange, ChangeCipherSpec, Finished
%% Cell type:code id: tags:
``` python
record5_str = open('raw_data/tls_session_protected/05_cli.raw').read()
record5 = TLS(record5_str)
record5.show()
```
%% Cell type:code id: tags:
``` python
# Every record has a 'tls_session' context which may enhance the parsing of later records
record5 = TLS(record5_str, tls_session=record2.tls_session.mirror())
record5.show()
```
%% Cell type:markdown id: tags:
## (C) <--- (S) NewSessionTicket, ChangeCipherSpec, Finished
%% Cell type:code id: tags:
``` python
record6_str = open('raw_data/tls_session_protected/06_srv.raw').read()
record6 = TLS(record6_str, tls_session=record5.tls_session.mirror())
record6.show()
```
%% Cell type:markdown id: tags:
## (C) ---> (S) ApplicationData
%% Cell type:code id: tags:
``` python
record7_str = open('raw_data/tls_session_protected/07_cli.raw').read()
record7 = TLS(record7_str, tls_session=record6.tls_session.mirror())
record7.show()
```
%% Cell type:markdown id: tags:
# The lack of PFS: a danger to privacy
%% Cell type:code id: tags:
``` python
from scapy.all import *
```
%% Cell type:code id: tags:
``` python
record1_str = open('raw_data/tls_session_compromised/01_cli.raw').read()
record1 = TLS(record1_str)
record1.msg[0].show()
```
%% Cell type:code id: tags:
``` python
record2_str = open('raw_data/tls_session_compromised/02_srv.raw').read()
record2 = TLS(record2_str, tls_session=record1.tls_session.mirror())
record2.msg[0].show()
```
%% Cell type:code id: tags:
``` python
# Suppose we possess the private key of the server
# Try registering it to the session
#key = PrivKey('raw_data/pki/srv_key.pem')
#record2.tls_session.server_rsa_key = key
```
%% Cell type:code id: tags:
``` python
record3_str = open('raw_data/tls_session_compromised/03_cli.raw').read()
record3 = TLS(record3_str, tls_session=record2.tls_session.mirror())
record3.show()
```
%% Cell type:code id: tags:
``` python
record4_str = open('raw_data/tls_session_compromised/04_srv.raw').read()
record4 = TLS(record4_str, tls_session=record3.tls_session.mirror())
record4.show()
```
%% Cell type:code id: tags:
``` python
record5_str = open('raw_data/tls_session_compromised/05_cli.raw').read()
record5 = TLS(record5_str, tls_session=record4.tls_session.mirror())
record5.show()
```
%% Cell type:markdown id: tags:
# TLS 1.3 handshake overview
This is the basic TLS 1.3 handshake:
<img src="images/handshake_tls13.png" alt="Handshake TLS 1.3" width="400"/>
%% Cell type:code id: tags:
``` python
from scapy.all import *
```
%% Cell type:code id: tags:
``` python
record1_str = open('raw_data/tls_session_13/01_cli.raw').read()
record1 = TLS(record1_str)
sess = record1.tls_session
record1.show()
```
%% Cell type:code id: tags:
``` python
record2_str = open('raw_data/tls_session_13/02_srv.raw').read()
record2 = TLS(record2_str, tls_session=sess.mirror())
record2.show()
```
%% Cell type:code id: tags:
``` python
record3_str = open('raw_data/tls_session_13/03_cli.raw').read()
record3 = TLS(record3_str, tls_session=sess.mirror())
record3.show()
```
%% Cell type:code id: tags:
``` python
# The PFS relies on the ECDH secret below being kept from observers, and deleted right after the key exchange
#from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateNumbers
#from cryptography.hazmat.backends import default_backend
#secp256r1_client_privkey = open('raw_data/tls_session_13/cli_key.raw').read()
#pubnum = sess.tls13_client_pubshares["secp256r1"].public_numbers()
#privnum = EllipticCurvePrivateNumbers(pkcs_os2ip(secp256r1_client_privkey), pubnum)
#privkey = privnum.private_key(default_backend())
#sess.tls13_client_privshares["secp256r1"] = privkey
```
%% Cell type:code id: tags:
``` python
record4_str = open('raw_data/tls_session_13/04_srv.raw').read()
record4 = TLS(record4_str, tls_session=sess.mirror())
record4.show()
```
%% Cell type:code id: tags:
``` python
record5_str = open('raw_data/tls_session_13/05_srv.raw').read()
record5 = TLS(record5_str, tls_session=sess)
record5.show()
```
%% Cell type:code id: tags:
``` python
record6_str = open('raw_data/tls_session_13/06_cli.raw').read()
record6 = TLS(record6_str, tls_session=sess.mirror())
record6.show()
```
%% Cell type:markdown id: tags:
## Observations sur TLS 1.3
* Certificat désormais chiffré...
* ...mais pas le Server Name dans le ClientHello
* Risques du mode 0-RTT
File added
File added
-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIJAP4EVw3HJ+n2MA0GCSqGSIb3DQEBCwUAMFQxCzAJBgNV
BAYTAk1OMRQwEgYDVQQHDAtVbGFhbmJhYXRhcjEXMBUGA1UECwwOU2NhcHkgVGVz
dCBQS0kxFjAUBgNVBAMMDVNjYXB5IFRlc3QgQ0EwHhcNMTYwOTE2MTAyODExWhcN
MjYwOTE1MTAyODExWjBYMQswCQYDVQQGEwJNTjEUMBIGA1UEBwwLVWxhYW5iYWF0
YXIxFzAVBgNVBAsMDlNjYXB5IFRlc3QgUEtJMRowGAYDVQQDDBFTY2FweSBUZXN0
IFNlcnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMzx8ZtgLWCu
8pgNJynZwAlZTA9KMKhS3+WxIZ9Pwz1Wk91fxvez9lWL55Li3vKFSbShLPT9dqhn
ygQgYBEYpvKptqYd2arl2duv5q9VV5//Uoll5oBigCGUvM+BG8tnwp21BXcEpseI
GIB4aJU23pcbtmGHQhp1mEWC6z4yEcibhkI5jU0St1gbGfOdK6GYgsrXOyT7CTmw
vMKVz4IpdRYpP0IgFytNQIxWbK26DzSFsX9AeXF4t6UEu5T3tUGV7nzrjQx5aFnv
y7P6Pnge7mdMet3gme/a5++yCV2+gCAhBYMsRNtdKnYppbAjiHQHVCLWKXqS9W8t
nuf4JiucWGUCAwEAAaNvMG0wCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0O
BBYEFKErIHDSa4DlZbzrAw+In3St3fYTMB8GA1UdIwQYMBaAFGZTlPQV0b1naLBR
NzI14aSq3gd8MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IB
AQCBiJJza5PnldbdQe6OHr2jSFinQTU/e33QN5gOuCyUd8hRNkCtWQkoyFbW6lus
tNg/aLdmyuFWN6kAZepRyeyyaUld+ePA7WFUyRKfxrAKc1XoVTVg7xw28NrRkHdW
BLirOO73CcWlmJAj6h/bFX8yKIGrm4UCS5XnN1F7G0gu+z5Sow20RqmSOhwf1woe
WEr6LlGPKcYeuA4xDnPxJ4gXyshpDPqDzbN5DhSwuJsvOi0J4/wG8Dpu/TY7KxoJ
KuirX4xA5IGyvPeDZxFuTpPqIq//o5p3V3bQCzis+IqUNY7X1GHMAf8ktI9hI7qI
11nk6boqTrUVD5zQ6gaR2d6r
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDM8fGbYC1grvKY
DScp2cAJWUwPSjCoUt/lsSGfT8M9VpPdX8b3s/ZVi+eS4t7yhUm0oSz0/XaoZ8oE
IGARGKbyqbamHdmq5dnbr+avVVef/1KJZeaAYoAhlLzPgRvLZ8KdtQV3BKbHiBiA
eGiVNt6XG7Zhh0IadZhFgus+MhHIm4ZCOY1NErdYGxnznSuhmILK1zsk+wk5sLzC
lc+CKXUWKT9CIBcrTUCMVmytug80hbF/QHlxeLelBLuU97VBle58640MeWhZ78uz
+j54Hu5nTHrd4Jnv2ufvsgldvoAgIQWDLETbXSp2KaWwI4h0B1Qi1il6kvVvLZ7n
+CYrnFhlAgMBAAECggEAIPA9uZAimuhjOwbaJYLGt3nvnIF7AoKXU449biJeqawR
hcHP852r2KHsrRHjbSz45JwG4rUd7gEIWdNuPTEuG9Ak99vSUQIyGnnR5JodxCw/
8q869aVfHIaQNfV1JyLdB4XBhBhuSaFY9sTjYh/4dGbS0Cfx+titiXZ6InvfmdMD
eLd/ZO35/BwtWN3J2ntRziTTREKLeEYFEe7FtXKGwDGIsvVn7egckefKMnflhMFA
SuoPn2VvTqmhiwSuATdx1TP4XOVdVzuL2wT7brS7qHvabRDBKdVOfrNGOoMdnnua
ursIQjQindNT8kVK8EGxws9eFr/dooYYFR72IusTfQKBgQDuQBzzKEtt86uRCbZX
Y3lu0MJnR5OOodfGBBYF9Ue+W3OJTd9EvXLSgLBLvwirB7lsNXgXf8LHCTQOtF3H
lnB8jE5OFSDGeSKWmUwZS+KVzq8vy7Qylp9i6x4pElwGUeba6AqeZZ+jUUn/HzdB
s2pO8YWqyOp/Zo/m8P+vPZN4fwKBgQDcNqJ4Dutt/i60E9kaktGQVQODRNMhYCEq
E5fhwJiZ0E9FBeuKPKjo7dGIux3KPQPBv3T0zjmB+M5QERVe5/ID8iytgbHGlnsg
916iTN9rvi1Gk518vyFPsYjX9pPiQIayRBQKOXSYIkY+6rj2384XPRlZrN8D9n3Q
+An1JXfdGwKBgDs3YjqpnD3i35S4BkMoLUl2x6rl5m4AGeJUp6ipc0CD+G57FXA/
aieZ5rec7qmbzOFxVLz6e03/Ipo5CEoQQTsjoF7V74SFHSyzQ2/SJao4aeCGT+52
83yhlah9sLO9bZShMep2tbvg+3RWrOQ+lMC0VRXCxE4QDtpGsjY7Jsk/AoGAPstV
iOa4O6U/rBn8zpcPKxkS51u42MuQqW7s4HMLENFVyVjm0YR6pfEqztKMrB6584Wk
1Cn6PBW2vx4f+fAqEvX7x340M2y1r7DaS22gSBjy0C1Hu0rFNPRrESo/AUVlI3BG
RqQbm0YqwcYs+DjZi8bgc7HX5kljlzMjo8QLagECgYA1DHAWv4WVrHt4I8V4ZCth
9DZEtEOFpYjuoFh/xSIMZLsnvWRuyYVWcQwAqmK0Ew4m5opHFsQzABeGLVsK5aHX
zmbYiRUuZGVpyc7c5XXomw50X8ajfQ+P21OPPc33h96cdHi2qbJIejZPia6A6ThU
u13D93hAM6bzH6Ds5FPUQw==
-----END PRIVATE KEY-----
File added
File added
File added
File added
File added
File added
File added
File added
HS؝`6&]9-vmBN
\ No newline at end of file
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment