Home | History | Annotate | Download | only in tls
      1 {
      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 }
    264