blob: 726581e8048cc0ebf3956dd0ccb93c0619049987 [file] [log] [blame]
mtue398df02017-08-22 11:37:07 +02001{
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "# TLS handshake overview\n",
8 "This is the standard, modern TLS 1.2 handshake:\n",
9 "\n",
10 "<img src=\"images/handshake_tls12.png\" alt=\"Handshake TLS 1.2\" width=\"400\"/>"
11 ]
12 },
13 {
14 "cell_type": "code",
15 "execution_count": null,
16 "metadata": {
17 "collapsed": true
18 },
19 "outputs": [],
20 "source": [
21 "# We're going to parse several successive records from the passive listening of a standard TLS handshake\n",
22 "from scapy.all import *"
23 ]
24 },
25 {
26 "cell_type": "markdown",
27 "metadata": {},
28 "source": [
29 "## (C) ---> (S) ClientHello"
30 ]
31 },
32 {
33 "cell_type": "code",
34 "execution_count": null,
35 "metadata": {
36 "collapsed": false
37 },
38 "outputs": [],
39 "source": [
40 "record1 = TLS(open('raw_data/tls_session_protected/01_cli.raw').read())\n",
41 "record1.show()"
42 ]
43 },
44 {
45 "cell_type": "code",
46 "execution_count": null,
47 "metadata": {
48 "collapsed": false
49 },
50 "outputs": [],
51 "source": [
52 "for extension in record1.msg[0].ext:\n",
53 " print ''\n",
54 " extension.show()"
55 ]
56 },
57 {
58 "cell_type": "markdown",
59 "metadata": {},
60 "source": [
61 "## (C) <--- (S) ServerHello"
62 ]
63 },
64 {
65 "cell_type": "code",
66 "execution_count": null,
67 "metadata": {
68 "collapsed": false
69 },
70 "outputs": [],
71 "source": [
72 "record2 = TLS(open('raw_data/tls_session_protected/02_srv.raw').read())\n",
73 "record2.show()"
74 ]
75 },
76 {
77 "cell_type": "markdown",
78 "metadata": {},
79 "source": [
80 "## (C) <--- (S) Certificate"
81 ]
82 },
83 {
84 "cell_type": "code",
85 "execution_count": null,
86 "metadata": {
87 "collapsed": false
88 },
89 "outputs": [],
90 "source": [
91 "record3 = TLS(open('raw_data/tls_session_protected/03_srv.raw').read())\n",
92 "record3.show()"
93 ]
94 },
95 {
96 "cell_type": "code",
97 "execution_count": null,
98 "metadata": {
99 "collapsed": false
100 },
101 "outputs": [],
102 "source": [
103 "# The Certificate message actually contains a *chain* of certificates\n",
104 "for cert in record3.msg[0].certs:\n",
105 " print type(cert[1])\n",
106 " cert[1].show()\n",
107 " print ''"
108 ]
109 },
110 {
111 "cell_type": "code",
112 "execution_count": null,
113 "metadata": {
114 "collapsed": false
115 },
116 "outputs": [],
117 "source": [
118 "# Let's recall the domain that the client wants to access\n",
119 "record1.msg[0].ext[0].show()\n",
120 "\n",
121 "# Indeed the certificate may be used with other domains than its CN 'www.github.com'\n",
122 "x509c = record3.msg[0].certs[0][1].x509Cert\n",
123 "print type(x509c)\n",
124 "x509c.tbsCertificate.extensions[2].show()"
125 ]
126 },
127 {
128 "cell_type": "markdown",
129 "metadata": {},
130 "source": [
131 "## (C) <--- (S) CertificateStatus, ServerKeyExchange, ServerHelloDone"
132 ]
133 },
134 {
135 "cell_type": "code",
136 "execution_count": null,
137 "metadata": {
138 "collapsed": false
139 },
140 "outputs": [],
141 "source": [
142 "# Here the server sent three TLS records in the same TCP segment\n",
143 "record4 = TLS(open('raw_data/tls_session_protected/04_srv.raw').read())\n",
144 "record4.show()"
145 ]
146 },
147 {
148 "cell_type": "code",
149 "execution_count": null,
150 "metadata": {
151 "collapsed": false
152 },
153 "outputs": [],
154 "source": [
155 "# Let's verify the signature in the ServerKeyExchange\n",
156 "# First, we need to assemble the whole data being signed\n",
157 "cli_random = pkcs_i2osp(record1.msg[0].gmt_unix_time, 4) + record1.msg[0].random_bytes\n",
158 "srv_random = pkcs_i2osp(record2.msg[0].gmt_unix_time, 4) + record2.msg[0].random_bytes\n",
159 "ecdh_params = str(record4[TLSServerKeyExchange].params)\n",
160 "\n",
161 "# Then we retrieve the server's Cert and verify the signature\n",
162 "cert_srv = record3.msg[0].certs[0][1]\n",
163 "cert_srv.verify(cli_random + srv_random + ecdh_params, record4[TLSServerKeyExchange].sig.sig_val, h='sha512')"
164 ]
165 },
166 {
167 "cell_type": "markdown",
168 "metadata": {
169 "collapsed": true
170 },
171 "source": [
172 "## (C) ---> (S) ClientKeyExchange, ChangeCipherSpec, Finished"
173 ]
174 },
175 {
176 "cell_type": "code",
177 "execution_count": null,
178 "metadata": {
179 "collapsed": false
180 },
181 "outputs": [],
182 "source": [
183 "record5_str = open('raw_data/tls_session_protected/05_cli.raw').read()\n",
184 "record5 = TLS(record5_str)\n",
185 "record5.show()"
186 ]
187 },
188 {
189 "cell_type": "code",
190 "execution_count": null,
191 "metadata": {
192 "collapsed": false
193 },
194 "outputs": [],
195 "source": [
196 "# Every record has a 'tls_session' context which may enhance the parsing of later records\n",
197 "record5 = TLS(record5_str, tls_session=record2.tls_session.mirror())\n",
198 "record5.show()"
199 ]
200 },
201 {
202 "cell_type": "markdown",
203 "metadata": {},
204 "source": [
205 "## (C) <--- (S) NewSessionTicket, ChangeCipherSpec, Finished"
206 ]
207 },
208 {
209 "cell_type": "code",
210 "execution_count": null,
211 "metadata": {
212 "collapsed": false
213 },
214 "outputs": [],
215 "source": [
216 "record6_str = open('raw_data/tls_session_protected/06_srv.raw').read()\n",
217 "record6 = TLS(record6_str, tls_session=record5.tls_session.mirror())\n",
218 "record6.show()"
219 ]
220 },
221 {
222 "cell_type": "markdown",
223 "metadata": {},
224 "source": [
225 "## (C) ---> (S) ApplicationData"
226 ]
227 },
228 {
229 "cell_type": "code",
230 "execution_count": null,
231 "metadata": {
232 "collapsed": false
233 },
234 "outputs": [],
235 "source": [
236 "record7_str = open('raw_data/tls_session_protected/07_cli.raw').read()\n",
237 "record7 = TLS(record7_str, tls_session=record6.tls_session.mirror())\n",
238 "record7.show()"
239 ]
240 }
241 ],
242 "metadata": {
243 "kernelspec": {
244 "display_name": "Python 2",
245 "language": "python",
246 "name": "python2"
247 },
248 "language_info": {
249 "codemirror_mode": {
250 "name": "ipython",
251 "version": 2
252 },
253 "file_extension": ".py",
254 "mimetype": "text/x-python",
255 "name": "python",
256 "nbconvert_exporter": "python",
257 "pygments_lexer": "ipython2",
258 "version": "2.7.13"
259 }
260 },
261 "nbformat": 4,
262 "nbformat_minor": 2
263}