追記 20180702
「The DTLS Protocol Version 1.3」で、DTLS1.3の仕様でconnection_id拡張について言及されています
DTLSにコネクションIDを導入する「The Datagram Transport Layer Security (DTLS) Connection Identifier」という提案が出ています。
DTLS1.3の議論を進める中で出てきたトピックであり、既にWG Draft になっています。
DTLSとセッション
DTLSはUDPのようなコネクションのないトランスポート上で暗号化された通信を行うためのプロトコルです。下位層にコネクションのないトランスポートを使っている一方で、現在のDTLSは送信元IP・送信先IP・送信元ポート番号・送信先ポート番号でDTLSのセッションを識別しています。
そのため、それらのうちどれかが変わってしまうと、鍵交換を含むハンドシェイクを初めからやり直す必要があります。特にIoTデバイスなどが普及していく中で、移動する端末や通信頻度が低いもの(NATリバインディングが起こる)は容易に起こるでしょう。さらにそういった端末はリソースが潤沢でない可能性があります。
DTLS Connection Identifier では、DTLSにコネクションIDを導入しIPやポート番号が変わっても通信を維持できるようにします。これにより、ハンドシェイクを1からやり直す手間が省けます。
DTLS Connection Identifier
「The Datagram Transport Layer Security (DTLS) Connection Identifier」では、DTLS1.2とDTLS1.3両方について対応します。
この提案仕様では、DTLSに以下を追加します
- connection_id拡張:ClientHelloとServerHelloで使われる、コネクションIDの使用をネゴシエーションするための拡張
- RequestConnectionId:DTLS1.3で相手にコネクションIDを要求するメッセージ
- NewConnectionId:DTLS1.3で相手にコネクションIDを通知するメッセージ (コネクションIDをすぐに使うか、予備か指定可)
- Record Layer Extensions:レコードに現在のコネクションIDを指定できるように変更される。
例えば、DTLS1.2では、以下のようにcidが追加されます。
struct { ContentType type; ProtocolVersion version; uint16 epoch; uint48 sequence_number; opaque cid[cid_length]; // New field uint16 length; select (CipherSpec.cipher_type) { case block: GenericBlockCipher; case aead: GenericAEADCipher; } fragment; } DTLSCiphertext;
コネクションIDの使用
DTLS1.3及びDTLS1.2で微妙に手順は異なるが、ハンドシェイク中にconnection_id拡張でコネクションIDの使用が合意されると、以降コネクションIDが含まれたメッセージを交換するようになる。
以下は、DTLS1.2の例である