RFC 8446 TLS 1.3 の改訂版について

RFC 8446 TLS 1.3の改訂版である rfc8446bis のDraftがLast Callになっている。中身的には、マイナーチェンジであり互換性は維持されている。


幾つか変更点のメモ

  • masterの用語を廃止。例えば、master_secret は main_secret と表記を変更しています。ただし、鍵導出のラベルにはかわらずmasterという用語が使用されるため、互換性は維持されます
  • TLS 1.0 および TLS 1.1のネゴシエーション廃止 (参照: RFC8996)
  • PreSharedKeys と HelloRetryRequest におけるハッシュの曖昧性を改善 (Issue 1227)
  • resumptionをサポートしないクライアントはNewSessionTicket を無視するように変更
  • 一つの鍵を使用し続ける上限を規定し、KeyUpdate をするように変更
  • 許可されるKeyUpdateメッセージについて言及
  • Alert Protocolにおいて「general_error」汎用アラートを追加
  • CertificateRequest.extensionsを長さ0で送る事を許可
  • セキュリティの考慮事項を追記

詳しい差分については、Draftの "Appendix G. Change Log" を参照

署名なしサーバ証明書形式を可能にする提案

GoogleのDavid Benjamin氏より、『Unsigned X.509 Certificates』という提案がIETFに提出されています。これは自己署名のサーバ証明書などを使っていたユースケースにおいて、単純に署名しないですむようにする提案です。

目的

CAから署名を受ける必要がないユースケースにおいても、X.509のフォーマット上署名がついている必要があるため、自己署名のサーバ証明書が使用されています。その幾つかは、fingerprintが別経路により信頼されているため、自己署名が必要ではありません。

不必要な自己署名がついていると、その分データ量も増えるほか(耐量子暗号であればなおさら)、X.509が指定している用途外に使うのにCA ビットなどを使われたりとリスクとなります。

そこで、『Unsigned X.509 Certificates』ではX.509で署名を不要にする提案をしています。

署名されていない証明書の作成

具体的な証明書は下記のように指定します

  • signatureAlgorithmフィールドにid-alg-noSignatureを指定する
  • TBSCertificateのsignatureフィールドにid-alg-noSignatureを指定する
  • signatureValueに長さ0にする

.mobiドメインにおけるWHOISを用いた不正サーバ証明書の取得事例

.mobi TLDにおいて、WHOISを利用して不正サーバ証明書発行を行う攻撃手法が明らかになり、話題となっている。

この実験者は、実際に 所有してない *.mobi ドメインの証明書発行が出来そうな事を確認している(不正発行の直前で実験を停止)。

簡単に流れを眺めたので、メモとして記録しておく。

詳細

詳細の記事はこちら
labs.watchtowr.com

箇条書きで流れを書くと

  • 前提
    • .mobi TLDwhoisをホストしていたドメインが "whois.dotmobiregistry.net" から "whois.nic.mobi" に移設した
    • "dotmobiregistry.net" を第三者が取得できる状態にあったため取得し、どのような通信が来てるか確認した
    • 大手CAからの通信があり、CAのドメイン所有検証にWHOISのConntactが使える事が判明する
  • 証明書発行手順
    • 実際に、whois.dotmobiregistry.netでwhoisサーバを起動し、必要な情報を入力しておく
    • CAに不正発行したい証明書(「google.mobi」や「microsoft.mobi」)のCSR提出する
    • 本来は、ドメイン検証のためにadmin@microsoft.mobiなどのメールアドレスが使用されるが、whoisのConntactに登録したメールアドレス(今回は記事執筆者の保有する whois@watchtowr.com) もドメイン検証に選択できることを確認


(参照記事からの引用)

ここまでで実験を中止。実際に不正発行までは行わなかったとのこと。

この実験により、所有してない*.mobiドメインの証明書を取得できるであろうことが示された。

CA/B側での議論

証明書発行に関する要件を定義する、CA/Browser ForumのBaseline Requirementsに変更を加える議論が出ている。
ドメイン検証にWHOISの情報を使わないようにする提案である。

github.com

github.com


ちょっと今後の動向も追っていきたい

Chromeで、サーバ証明書検証時にネットワークから取得した時刻を使う

Chrome Canaryで『Network Time for Certificate Verification』という機能を有効にできます。これは、サーバ証明書を検証する際に、PC端末の時刻ではなくネットワークから取得した時刻を使って検証するようにする機能です。

これまでの挙動

これまでの挙動としては、サーバ証明書時に時刻上の問題がある場合、『端末の時刻がズレている』というエラーが出ます。

どうやって端末の時刻がずれていると識別するかは、「Where the Wild Warnings Are: Root Causes of Chrome Certificate Errors」に掛かれています。Googleのサーバに接続し、時刻を取得します。このとき、Chromeにハードコードされた公開鍵を使用するため、時刻がズレてても正しくGoogleのサーバを信頼できます。( 該当ソースコードURL )

(論文にも掛かれていますが、証明書のエラー原因としてクライアントの時刻設定ミスがそれなりにあるようです。)

『Network Time for Certificate Verification』

chrome://flags/ より、機能を有効にできます。

有効にすると、端末の時刻がズレていても証明書エラーが出なくなります。
(初回の証明書エラー時に時刻をフェッチしに行くのか、初回だけエラーがでますが、その時刻はキャッシュされるようなのでほかサイトでも問題なく閲覧できるようです。)

ネットワークから取得した時刻で証明書エラーになった場合は、端末の時刻を利用するため、意図的に未来や将来の証明書を試す場合も問題なさそうです。

今後

今後、この機能がどう有効化されていくかは、今のところ情報はなさそうです。

プライベート用途に使える .internal ドメイン

2024年7月に、ICANNで .internal トップレベルドメイン(TLD) がプライベート用途として予約されたようです。

背景

長らくプライベート用途で利用できるトップレベルドメインについて議論されてきました。

現在、各組織が独自のTLDをプライベート用に利用しているケースがあります。しかし以下のような問題があります、

  • 新gTLDが登録された際に、衝突する可能性がある
  • Root DNSへ不要な問い合わせがある

実際、.home、.internal、.lan、.corp、.localdomain、.dlink、.zyxel-usg のような問い合わせがRoot DNSに来ていることが知られています。

そこで、.internal をプライベート用途として予約しようというのが、ICANNで議論されている『SAC113:SSAC私的利用TLDに関する勧告(SAC113)』です。

JPNICさんの記事が詳しいです。
blog.nic.ad.jp

.internal ドメインの予約

下記の、2024 年 7 月 29 日のICANN 理事会の記録を見ると
Approved Resolutions | Special Meeting of the ICANN Board | 29 July 2024

".internal" をプライベート用途として恒久的に予約することが決まったようです。

IETF側の動き

上記のICANN側での決定を踏まえて、IETF側にも『A Top-level Domain for Private Use』というDraftがICANNの方から提出されています。

内容については、 .internal をプライベート用途に予約する旨書かれています。

追記: 本記事に頂いたコメント

補足を頂きましたのでここに追記しておきます。ありがとうございます。

信頼しているCAをネゴシエーションする TLS Trust Anchor Negotiation のメモ

IETFTLS WGでは、Googleの方らによって提案されている『TLS Trust Anchor Negotiation』という仕組みが議論されています。

これは、クライアントとサーバ側で共に信頼できるCA(トラストアンカー)をネゴシエーションし、複数あるサーバ証明書から適切なものを提供できるようにする仕組みです。

(引用: IETF 120 スライド PDF より)

具体的な提案仕様よりも、explainer を読むのが分かりやすい。自分用に軽く目を通しておく
https://github.com/davidben/tls-trust-expressions/blob/main/explainer.md

目次

背景

現状、クライアントがどのCAを信頼しているか伝えず、サーバ側は全てのクライアントに信頼されているだろうCAのサーバ証明書を利用します。

本議論の中では、それを『単一証明書デプロイモデル』と読んでいます。単一証明書デプロイモデルでは次のような

  • 新しいCAを利用しようとしても、全てのクライアントに信頼されている必要がある。更新されていないクライアントがいると利用できない。キーローテーションも同様
  • クライアント側が新しいセキュリティ要件を課したとして、古いクライアントが居るとそれに答えられない

この課題を解決するために、『複数証明書デプロイモデル』として、サーバ側がクライアントに合わせて証明書を出し分けられるようにするのが、『TLS Trust Anchor Negotiation』の議論である。

目標

TLS Trust Anchor Negotiationの目標は、Webで使用されるHTTPSにおいて『複数証明書デプロイモデル』を有効にすることです。次の項目を目指します。

  • 可用性と競合することなく、ユーザのセキュリティニーズを満たせるように進化できる
  • サーバ側では複数のサーバ証明書を設定でき、接続ごとに適切な証明書を自動的に送信できる
  • サーバの運用者の手動作業を可能な限り少なくし、ACMEが利用できる
  • TLSハンドシェイクに追加されるトラフィックを最小限に抑える

また、耐量子計算機暗号 (PQC) 証明書への移行などもユースケースに含まれている

実現案

既存の実現案として RFC 8446 TLS1.3には、certificate_authorities拡張を使う方法があります。certificate_authorities拡張を使うことで、サポートしているCAを示すことが出来ます。

しかし、certificate_authorities拡張は1CAあたり100バイト程度消費し、100CAを扱う昨今のクライアントでは、送信するデータ量が大きくなってしまいます。

そこで、Googleの方らによって次の2つの提案仕様が出されています

( 前者の仕様の議論を経て、後者の仕様が提出されていますが、現在は合わせて議論されている段階です

簡単に紹介します
(それぞれACMEの拡張も行ってたりしますが、細かいところは割愛

Trust Expressions

WebブラウザやOSによって管理される信頼するCAリスト(ルートプログラム)に、名前とバージョンを付けトラストストアマニフェストとします。クライアントはそのマニフェストを参照し、trust_expressionsとして送信することで信頼するCAのリストをサーバに伝えます。

enum { trust_expressions(TBD), (2^16-1) } ExtensionType;

struct {
    TrustStore trust_store;
    uint24 excluded_labels<0..2^16-1>;
} TrustExpression;

TrustExpression TrustExpressionList<1..2^16-1>;
Trust Anchor Identifiers

CAを5バイトで表現できるようにtrust anchor identifiersという識別子を導入しています。これを用いて、ハンドシェク中、クライアントはtrust_anchors拡張でサポートするCAのリストをサーバに通知できるようにします。

また、サーバも HTTPS/SVCB DNS レコード を用いて自身がサポートしているCAのリストを提示することで、クライアントが送信するデータ量を最小限に抑えることが出来ます。

example.net.  7200  IN SVCB 3 server.example.net. (
    tls-trust-anchors=32473.1,32473.2.1,32473.2.2 )

TCP上でQUICを喋る『QUIC on Streams』について復習しておく

TCP(+TLS)上でQUICおよびHTTP/3の通信を行うことを可能にする『QUIC on Streams』という仕様がFastlyのOku Kazuho氏らによって提案されている。

今年3月に行われたのIETF119で提案されている。

仕様は、TCP/TLS上でQUIC通信を行う『QUIC on Streams』と、それを使ってHTTP/3通信を行う『HTTP/3 on Streams』に分かれている。

今週IETF120があるので、キャッチアップしておく。

モチベーション

この提案の背景にあるのは、WebTransportといったHTTP上で動作する新しいプロトコルを設計する際に HTTP/3版とHTTP/2版の両方を設計・メンテナンスを行っているところにあります。


(引用: IETF119スライドPDFより)

なぜ新しいプロトコルでもHTTP/2版を設計するかと言うと、QUICのフォールバック先が必要だからです。

QUICはUDPで動作しており、一部のネットワークでは(そのネットワーク管理者が意図してか、意図せずか)QUICが通らないネットワークがあることが知られています。そのためHTTP/3は、疎通できないケースにおいては、TCPを使うHTTP/2にフォールバックするということが行われています。そのため、WebTransportのような新しいプロトコルも、フォールバック先としてHTTP/2版プロトコルを設計する必要があります。

もちろんHTTP/2とHTTP/3ではストリームやフレームの機能に違いがあるため、それぞれそれなりの仕様になっています。WebTransportのそれぞれの仕様は次の通り。

そこで、QUICそのものをTCP/TLS上で動作させることで、複数スタック用にプロトコル設計しなくても良くなります。それが、『QUIC on Streams』のモチベーションになります。


(引用: IETF119スライドPDFより)

『QUIC on Streams』の仕組み

『QUIC on Streams』はTLS over TCPのようなトランスポート上でQUICのフレームを送受信する仕組みを定義します。

下層のトランスポート

TLS over TCPが想定されていますが、使用上はそれだけに限定されているわけではなく、次の機能をもつトランスポートを想定しています。

  • 双方向のバイトストリーム通信
  • 信頼性 (再送などによる、データの配送保証)
  • 輻輳制御
  • 気密性と完全性
ストリームの送受信

『QUIC on Streams』では、トランスポート上で直接ストリームが送受信されます。QUICパケットヘッダは存在しません。

なお、送受信できるのは次のフレームに限定されます。

  • PADDING
  • RESET_STREAM
  • STOP_SENDING
  • STREAM
  • MAX_DATA
  • MAX_STREAM_DATA
  • MAX_STREAMS
  • DATA_BLOCKED
  • STREAM_DATA_BLOCKED
  • STREAMS_BLOCKED
  • CONNECTION_CLOSE

再送制御は下層トランスポートで行われるため、ACKフレームは送受信できません。また、コネクションマイグレーションも『QUIC on Streams』ではサポートされません。

一方で、次のフレームが追加で定義されています

  • QS_TRANSPORT_PARAMETERS: トランスポートパラメータを交換するフレーム
  • QS_PING: PINGの送受信
『QUIC on Streams』のその他
  • 一部トランスポートパラメータは使用禁止
  • 既存の拡張仕様がQUIC on Streams上で使えるかは、明示的に許可される必要がある
    • ただし、DATAGRAMは送信可能(下層のトランスポート特性により、信頼性が保証される)
  • QUICのバージョンネゴシエーションの仕組みはない

(UDP利用に起因するリフレクションがないとすれば、通信開始時のPADDINGの制約って緩和出来るんだろうか...?)

HTTP/3 on Streams

HTTP/3 on Streams』の仕様は非常に短いです。