こういう仕組みですよ、というWeb上の記事を読んだだけでは納得できない!論より証拠だ!ということで論より証拠ツールその2であるtsharkを使ってTLS Session Ticketの動作を「なんとなく」覗いてみる。
ちなみに、クライアントは Google Chrome (49.0.2576.0 canary (64-bit)) 、サーバはh2o (1.6.0-beta1, LibreSSL 2.2.4) である。
まずはざっくり
sudo tshark -i eth0 -f "tcp port 443" -Y ssl
状態をクリアするためにh2oを再起動してからhttpsなリクエストを送ると以下の様なシーケンスになる。
4 0.013439 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy SSL 583 Client Hello 6 0.018197 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 2842 Server Hello 7 0.018254 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 2842 Certificate 8 0.018283 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 848 Certificate Status 11 0.032880 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 192 Client Key Exchange, Change Cipher Spec, Hello Request, Hello Request 12 0.033993 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 119 Application Data 13 0.034004 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 116 Application Data 14 0.034008 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 108 Application Data 15 0.034130 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 308 New Session Ticket, Change Cipher Spec, Hello Request, Hello Request 16 0.034270 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 125 Application Data 17 0.034589 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 425 Application Data (以下略)
そこから一度タブ閉じて、もう一度リクエストを送ると以下の様なシーケンス。
3 0.014875 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy SSL 583 Client Hello 5 0.015423 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 216 Server Hello, Change Cipher Spec, Hello Request, Hello Request 7 0.042222 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 117 Change Cipher Spec, Hello Request, Hello Request 8 0.042255 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 119 Application Data 9 0.042262 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 116 Application Data 10 0.042266 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 108 Application Data (以下略)
Certificate, Certificate Status, Server Key Exchange, Client Key Exchangeなどが省略され、Server Helloから一気にChange Cipher Specまで行っていることが分かる。 (注:tsharkの結果には出力されていないが、Server Key ExchangeはCertificate Statusと同じパケットに入っている)
もうちょっとだけ詳しく
以下のコマンドで見れば、
sudo tshark -i eth0 -f "tcp port 443" -Y ssl -O ssl
再起動後のシーケンスの最後、サーバからのChange Cipher Specと同じパケットにSession Ticketの値が含まれていることが分かる。
Secure Sockets Layer TLSv1.2 Record Layer: Handshake Protocol: New Session Ticket Content Type: Handshake (22) Version: TLS 1.2 (0x0303) Length: 186 Handshake Protocol: New Session Ticket Handshake Type: New Session Ticket (4) Length: 182 TLS Session Ticket Session Ticket Lifetime Hint: 3600 Session Ticket Length: 176 Session Ticket: fcf1faec48a3153aa98072c75e1aae922ebd76da303ea06e... TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec Content Type: Change Cipher Spec (20) Version: TLS 1.2 (0x0303) Length: 1 Change Cipher Spec Message TLSv1.2 Record Layer: Handshake Protocol: Multiple Handshake Messages Content Type: Handshake (22) Version: TLS 1.2 (0x0303) Length: 40 Handshake Protocol: Hello Request Handshake Type: Hello Request (0) Length: 0 Handshake Protocol: Hello Request Handshake Type: Hello Request (0) Length: 0
以降、Client HelloにはSession Ticketが含まれ、それがvalidであった場合はもろもろが省略されてハンドシェイクがすぐ終わる。
Extension: SessionTicket TLS Type: SessionTicket TLS (0x0023) Length: 176 Data (176 bytes)