TLS 1.3 開発日記 その29 Key update
TLS 1.2で暗号路の鍵を更新する場合は、ハンドシェイクをやり直す(再ネゴシエーションする)必要があった。実装の視点からいうと、鍵更新はハンドシェイクに対して同期的だった訳だ。
TLS 1.3では、サーバやクライアントがハンドシェイクをし直すことなく、いつでも鍵を更新できる。(TLS 1.3 には再ネゴシエーションはない。)つまり、鍵更新はハンドシェイクに対して非同期的になった。プログラマーにとっては、腕が試されることになる。
TLS 1.3の鍵更新メッセージの書式は、以下のように定義されている。
enum { update_not_requested(0), update_requested(1), (255) } KeyUpdateRequest; struct { KeyUpdateRequest request_update; } KeyUpdate;
典型的な使い方はこうだ:
- AがKeyUpdate(update_requested)を送り、送信側の鍵を更新
- BはKeyUpdate(update_requested)を受け取ったら受信側の鍵を更新し、KeyUpdate(update_not_requested)を送り、送信側の鍵を更新
- AがKeyUpdate(update_not_requested)を受け取ったら、受信側の鍵を更新
AとBが同時にKeyUpdate(update_requested)を送ってもよく、その場合、単に2回鍵が更新された状態に落ち着く。
さて、問題はここからだ。
私は update_not_requested を update_requested への応答だと解釈していた。そこで、update_requested を送信してない状態で、update_not_requested を受け取ると、エラーにしていた。しかし、レビュアーの Olivier さんから、一方向の更新も許されるのではないかと指摘を受けた。そう思った理由は、OpenSSL の s_client が、
k
コマンドの場合、一方向の鍵を更新しようとし (update_not_requested を送信)K
コマンドの場合、双方向の鍵を更新しようとする (update_requested を送信)
からだった。
slack のTLS 1.3の実装者が集まるチャンネルに話題を振ったところ
- 許されていない:無視すべき
- 許されていない:エラーにすべき
- 許されている
の3つの解釈が出てきて、やはり仕様が曖昧だと分かった。
結局、編集者の Eric さんが降臨し、「許されている」と言って決着した。
結論:TLS 1.3 では、一方向の鍵更新もOK!