IETF 98 Chicago の Hackathon に向けて、Haskell TLS ライブラリを TLS 1.3 ID19 に対応させた話。僕は Hackathon には遠隔参加。
ID19に一番乗りしたのは OpenSSL。辻川さんがテストサーバを上げてくれた。
Full と PSK
- Add pre-extract Derive-Secret stages to key schedule
7.1節の key schedule が変わったので、変更すると OpenSSL と full & PSK ハンドシェイクができた。
0RTT
- Consolidate "ticket_early_data_info" and "early_data" into a single extension
- Change end_of_early_data to be a handshake message
ticket_early_data_info と early_data 拡張を1つの拡張とし、end_of_early_data をアラートからハンドシェイクへ変更する。ID18 では、end_of_early_data は early_data を送った直後に送ってよかったが、ID19 からは Server Finished を受け取ってから送る。このせいでコードが汚くなった。
OpenSSLサーバとHaskellクライアントの間で0RTTができないので、原因を調べたところ2つの問題があった。
- そもそもID18でも0RTTできなかった。OpenSSLでは、チケットの検証が厳しくこれにひっかかっていたので、Haskell側を修正。これでID18で、0RTTできるようになった。
- ID19 の仕様では Client Finished の計算に EndOfEarlyData を含めないように書かれていた。Haskellの実装はそれに忠実。OpenSSLの実装は EndOfEarlyData を計算に含めていた。EndOfEarlyDataを計算に含めないと、EndOfEarlyDataを守れないので、ハンドシェイクに変更した意味がない。結局、仕様のバグであると合意に至り、Haskell を修正後、OpenSSLと0RTTできるようになった。
HRR
- Hash ClientHello1 in the transcript when HRR is used. This reduces the state that needs to be carried in cookies.
ID18 ではハンドシェイクメッセージをその都度ハッシュにくべると transcript hashが計算できたが、ID19からは最初のClientHelloのハッシュ値をハッシュにくべなければならなくなった。面倒であったが、結果的には簡潔に実装できた。
まとめ
ID19の仕様のバグも発見したし、上げたテストサーバやクライアントバイナリも利用されたようなので、役に立ってよかった。