1. はじめに
DTLSはUDPのような安定性を保証しない軽量のデータグラム上でセキュリティを実現するためのプロトコルです。
プロトコル仕様の最新バージョンDTLS1.3は2022年4月にRFC9147が正式発行となっています。このバージョンがβバージョンではあるけれどwolfSSLで動作するようになったので、試してみます。
DTLS1.3では、TLS1.3で実現した数々の強化、改善が同様に盛り込まれています。その内容については「最終段階に入ったDTLS1.3」や「DTLS1.3で何が変わったか」で紹介しているので参照してください。
2. ダウンロード、ビルド
現在のところGithubレポジトリーのオープンソース版だけで提供されているので、こちらからダウンロード、configure, makeします。
configureオプションとして --enable-dtls --enable-dtls13を指定します。
"configure" コマンドでDTLSとDTLS1.3オプションが "yes" となっていることを確認します。
"make check"を実行すると一連のコンパイル、ライブラリ、サンプルプログラムなどが生成され、テストを完了します。
$ git clone --depth 1 https://github.com/wolfssl/wolfssl
$ cd wolfssl
$ ./autogen.sh
$ ./configure --enable-dtls --enable-dtls13
...
* DTLS: yes
* DTLS v1.3: yes
...
$ make check
...
============================================================================
Testsuite summary for wolfssl 5.3.0
============================================================================
# TOTAL: 7
# PASS: 7
# SKIP: 0
# XFAIL: 0
# FAIL: 0
# XPASS: 0
# ERROR: 0
============================================================================
3. サンプルサーバ、クライアントを走らせる
ライブラリや一連のテストプログラムとともに "examples" ディレクトリーの下にサンプルサーバとクライアントも生成されているのでそれを動作させてみます。サーバとクライアントは同じパソコン上でも、別々のパソコン上でも動作させることができます。このサンプルはポート"11111" を使用するので、別々のパソコンで通信させてみるときはファイヤーウォールのポートを開けておきます。
まず、サーバ側を起動します。"-u"オプションでUDP(DTLS)を指定します。デフォルトではDTLS1.2で動作するので、まずは比較のためこれを見てみます。クライアント側を異なるパソコンで動作させるときは外からのアクセスを受け付けるように "-b" でポートバインドを指定します。"-d"を指定するとクライアント認証を行わないようにすることができます。
$ ./examples/server/server -u -b
パケットキャプチャーも見たい場合はWiresharkを起動しておきます。
次にクライアント側を起動します。同じように"-u" オプションでUDP(DTLS)を指定します。"-h" オプションでサーバ側のIPアドレスを指定します。同じパソコンの場合は"127.0.0.1"を指定します。
$ ./examples/client/client -u -h xxx.xxx.xxx.xxx
サンプルプログラムはDTLS接続したのち、1往復の簡単なアプリケーションメッセージ通信を行って終了します。プロトコルのバージョン、利用した暗号スイートなどの実行結果はサーバ側、クライアント側にそれぞれ表示されます。
サーバ側:
SSL version is DTLSv1.2
SSL cipher suite is TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
SSL curve name is SECP256R1
Client message: hello wolfssl!
クライアント側:
SSL version is DTLSv1.2
SSL cipher suite is TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
SSL curve name is SECP256R1
I hear you fa shizzle!
次に"-v"オプションでDTLS1.3を指定して同じようにサーバとクライアントを通信させてみます。
$ ./examples/server/server -u -b -v4
$ ./examples/client/client -u -h xxx.xxx.xxx.xxx -v4
今度は、プロトコルバージョンにDTLS1.3、暗号スイートも1.3向けのものが選択されていることがわかります。
SSL version is DTLSv1.3
SSL cipher suite is TLS_AES_128_GCM_SHA256
SSL curve name is SECP256R1
4. パケットキャプチャーを見てみる
次にキャプチャーしたパケットの内容を見てみます。"udp"でフィルターしてみると、DTLS1.2のハンドシェークと暗号化されたアプリケーションデータの送受信、そして最後に切断のためのAlertパケットを見ることができます。
No. Time Source Destination Protocol Length Info
127 19.043368 192.168.10.6 xx.xx.92.191 DTLSv1.2 223 Client Hello
128 19.152213 xx.xx.92.191 192.168.10.6 DTLSv1.2 102 Hello Verify Request
129 19.152340 192.168.10.6 xx.xx.92.191 DTLSv1.2 255 Client Hello
130 19.260560 xx.xx.92.191 192.168.10.6 DTLSv1.2 149 Server Hello
131 19.261291 xx.xx.92.191 192.168.10.6 DTLSv1.2 1442 Certificate (Fragment)
132 19.261293 xx.xx.92.191 192.168.10.6 DTLSv1.2 1244 Certificate (Reassembled)
133 19.273196 xx.xx.92.191 192.168.10.6 DTLSv1.2 396 Server Key Exchange
134 19.273198 xx.xx.92.191 192.168.10.6 DTLSv1.2 67 Server Hello Done
135 19.275181 192.168.10.6 xx.xx.92.191 DTLSv1.2 133 Client Key Exchange
136 19.275266 192.168.10.6 xx.xx.92.191 DTLSv1.2 117 Change Cipher Spec, Encrypted Handshake Message
141 19.384603 xx.xx.92.191 192.168.10.6 DTLSv1.2 117 Change Cipher Spec, Encrypted Handshake Message
142 19.384762 192.168.10.6 xx.xx.92.191 DTLSv1.2 93 Application Data
147 19.491633 xx.xx.92.191 192.168.10.6 DTLSv1.2 101 Application Data
148 19.491635 xx.xx.92.191 192.168.10.6 DTLSv1.2 81 Encrypted Alert
149 19.491740 192.168.10.6 xx.xx.92.191 DTLSv1.2 81 Encrypted Alert
次にDTLS1.3のほうを見てみます。今のところWiresharkがまだDTLS1.3に対応していないのでプロトコルとしては"DTLSv1.2" と表示されてしまいますが、実際にはDTLS1.3のプロトコルがやりとりされています。DTLS1.2とは異なり、最初の"Client Hello"と"Server Hello" のあとは暗号化されているようで単なるUDPパケットとして表示されますが、この部分もハンドシェークが続きます。ハンドシェークが完了すると、レコード419, 421に1往復のアプリケーションメッセージとレコード422, 424にAlertのやりとりがありますが、この部分も暗号化されているのでハンドシェークメッセージと区別がつきません。
このネットワーク環境ではUDPパケット1往復に100mSec前後かかっているようです。β版で性能チューニングはまだこれからですが、パケットの往復回数が少なくなっている分だけハンドシェークのスループットが数十パーセント改善しています。
No. Time Source Destination Protocol Length Info
408 34.818207 192.168.10.6 xx.xx.92.191 DTLSv1.2 561 Client Hello
409 34.931783 xx.xx.92.191 192.168.10.6 DTLSv1.2 186 Server Hello
410 34.932970 xx.xx.92.191 192.168.10.6 UDP 78 11111 → 61219 Len=36
411 34.934768 xx.xx.92.191 192.168.10.6 UDP 1425 11111 → 61219 Len=1383
412 34.934770 xx.xx.92.191 192.168.10.6 UDP 1284 11111 → 61219 Len=1242
413 34.940562 xx.xx.92.191 192.168.10.6 UDP 336 11111 → 61219 Len=294
414 34.940564 xx.xx.92.191 192.168.10.6 UDP 108 11111 → 61219 Len=66
415 34.940755 192.168.10.6 xx.xx.92.191 UDP 108 61219 → 11111 Len=66
417 35.050175 xx.xx.92.191 192.168.10.6 UDP 82 11111 → 61219 Len=40
419 35.050367 192.168.10.6 xx.xx.92.191 UDP 78 61219 → 11111 Len=36
421 35.159991 xx.xx.92.191 192.168.10.6 UDP 86 11111 → 61219 Len=44
422 35.159992 xx.xx.92.191 192.168.10.6 UDP 66 11111 → 61219 Len=24
424 35.160128 192.168.10.6 xx.xx.92.191 UDP 66 61219 → 11111 Len=24
Client Helloパケットの詳細をみてみるとDTLS1.3のための拡張を見ることができます。
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
DTLS1.3ではプロトコルバージョン情報は "Supported Version ” 拡張に格納されます。このサンプル実行ではDTLS1.3を示す"0xfefc"だけが格納されていますが、後方互換のためにDTLS1.2, 1.3のどちらの接続も受け入れるというような場合はこの拡張に複数のバージョンが指定されます。
Extension: supported_versions (len=3)
Type: supported_versions (43)
Length: 3
Supported Versions length: 2
Supported Version: Unknown (0xfefc)
後方互換性のためにプロトコルバージョンのフィールドも残されていますが、こちらには ""Version: DTLS 1.2 (0xfefd)"が入れてあります。
Version: DTLS 1.2 (0xfefd)
暗号スイートフィールドにDTLS1.2向けの暗号スイートとともに、DTLS1.3(TLS1.3)の暗号スイートも格納されているのがわかります。DTLS1.3(TLS1.3)では鍵交換方式がディフィーヘルマン系に統一されたためそのフィールドがなくなり "TLS_"の後には共通鍵アルゴリズムが指定されます。
Cipher Suites (27 suites)
Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
DTLS1.3(TLS1.3)ではキーシェア拡張が設けられ、この中に鍵交換に関するアルゴリズと具体的なパラメータも送るようになりました。これによって、サーバ側はClient Helloを受け取っと段階で、また、クライアント側はServer Helloを受け取った段階で共有鍵を得ることができ、その後のハンドシェークを暗号化することができるようになりました。
Extension: key_share (len=331)
Type: key_share (51)
Length: 331
Key Share extension
Client Key Share Length: 329
Key Share Entry: Group: secp256r1, Key Exchange length: 65
Group: secp256r1 (23)
Key Exchange Length: 65
Key Exchange: 04028a5a671c4f00cf8eaa91a37f18eaf7ccdbda26ac75eba72c…
...
5. まとめ
今回は、wolfSSLのDTLS1.3サポートのβ版を使って、DTLS1.3の一番基本となるフルハンドシェークの内容を1.2と比較しながら見てみました。β版なので全ての機能がサポートされているわけではありませんがDTLS1.3の特徴的な動作を見ることができました。