要約

  • RFC 9261のExported Authenticatorは、確立済みTLS/DTLS接続から導出した値でCertificate、CertificateVerify、Finishedを結ぶ。追加X.509アイデンティティの秘密鍵所持を示すが、TLS状態は変えない。
  • 内在する生成時刻もアプリstream番号もない。固有のrequest contextは接続内の再利用を防ぐが、対象操作、発効点、権限はアプリが別に拘束する。
  • 運用証拠は、要求、接続拘束、暗号検証、証明書方針、認証済み空拒否、権限判断を分離する。TLSを終端するproxyは、同じ証明書が見えても越えられない境界である。

正しい検証結果から誤った履歴が生まれた

13時58分、通常handshakeのアイデンティティで接続が成立し、複数streamが並行して処理を始める。14時03分、追加アイデンティティを求めたアプリ要求への応答が届き、RFC 9261の検証に成功した。

障害はその後で起きる。認可サービスは成功bitだけを見て接続全体を昇格し、検証前の処理まで新しいアイデンティティに帰属させた。Authenticatorは独立かつ単方向であり、生成・検証してもTLS内部に明示的状態変更はない。

証明が支えられるのは、検証後の明示した境界から、指定した将来操作に権限を与える判断である。過去のmessage、別stream、生成時刻を証明自身が補うことはない。TLSは接続に結び付く事実を出し、意味と効果はアプリが負う。

三つのmessageが拘束する範囲

この方式はTLS 1.3の形式を使うが、新しいhandshakeではない。Certificateが追加X.509アイデンティティを提示し、CertificateVerifyが秘密鍵所持を示し、Finishedが確立済み接続から導出した鍵で構成transcriptを保護する。TLS record framingはなく、既存接続または同等に保護されたアプリchannelで運ばれる。

clientとserverは別々のexporter labelを使う。TLS 1.3ではexporter_master_secretが必須で、early exporter secretは使えない。TLS 1.2ではPRFとExtended Master Secretが必要となる。証明書だけでなく、一つの初期接続へ拘束するためである。

検証結果は限定的だ。この接続上のpeerが、このtranscriptに対し、受容可能な証明書アイデンティティの秘密鍵を所持した。それは接続開始時からのアイデンティティ、別接続、全streamの所有、業務権限を意味しない。

証明書chainの方針は別判定である。CertificateVerifyとFinishedが正しくても、期限切れ、拒否issuer、name不一致、role不適合は残る。暗号構造、X.509信頼、業務認可を一つの成功値に潰してはならない。

request contextは接続内の境界である

certificate_request_contextは最大255 octetで、RFC 9261の要求種別をまたいで接続内一意でなければならず、peerから予測しにくいことが望まれる。応答が同じ値を返すので、一度受け入れた証明を別要求へ流用できない。

ただし世界共通ID、時計、account、stream番号ではない。gateway、アイデンティティservice、workerが別々に値を発行すれば、それぞれの台帳に重複がなくても接続全体では衝突する。wire上の一意性に合わせ、software側にも接続単位の所有者が必要だ。

連番は一意でも予測可能で、random generatorはsnapshot復元後に重複し得る。context hash、generator epoch、接続、extension、対象操作、生成時刻を記録し、exporter secretや秘密鍵は記録しない。

clientは先行要求なしにAuthenticatorを送れない。serverは自発的に送れる。この非対称性も監視対象であり、未決要求のないclient証明は認可へ進めない。

接続とstreamと時刻は同じではない

HTTP/2は一接続で多数streamを多重化する。QUICのRFC 9001は、TLSのpost-handshake client authenticationを禁止する。TLS CertificateRequestを引き起こしたアプリeventと正しく対応させられないからだ。

Exported Authenticatorは要求と証明をアプリ層へ移し、相関を表現できる場所を提供する。しかし相関そのものは提供しない。上位protocolが「context Xはstream 41の操作Yに対応し、検証Z以後のみ有効」と定める必要がある。

安全なdefaultは将来向きで狭い。処理済み要求、検証前queue、隣接streamは新しいアイデンティティを得ない。接続全体の昇格が必要なら、順序、barrier、範囲、rollbackを明記する。

Authenticatorには作成時刻がない。受信時刻、検証時刻、権限発効時刻は別である。一つのauthenticated_atにまとめると、遅延、replay、順序逆転を調べられない。

TLS終端は暗号境界を変える

Handshake Contextは初期接続から導出される。接続Aで作った証明をBで検証すればCertificateVerifyは失敗する。TLS終端proxyの上下流は、同じnameやcertificate chainでも別接続だ。

「同じ証明書」をfallbackにすれば、RFC 9261の接続拘束を捨てる。終端を越えてアイデンティティを渡すなら、issuer、audience、期限、custodyを持つ明示的な委任が必要となる。両側で別Authenticatorを作る場合も、それらを結ぶのは別の信頼判断である。

再接続やfailoverも旧境界を終わらせる。sessionが似ているだけで権限を残さず、再証明、低権限化、別途設計した継続方式のいずれかを選ぶ。

空の応答は認証済み拒否である

適切なアイデンティティがない、または提示したくないpeerはempty authenticatorを返せる。Finishedはあり、CertificateとCertificateVerifyはない。接続共有者による拒否は認証されるが、有効なアイデンティティとしては返らない。

これはsilence、message破損、署名失敗、chain拒否とは別状態だ。低risk操作を続けるか、重要操作を止めるか、別方式へ移るかを決められる。無限retryは正当な拒否をDoS loopへ変える。

四つの台帳

接続台帳はversion、cipher suite、handshake完了、peer Finished、TLS 1.2 EMS、非秘密接続IDを持つ。要求台帳はrole、context hashと一意性、extension、対象、時刻、channelを持つ。

検証台帳は要求型/自発型、Certificate hash、chain fingerprint、CertificateVerifyとFinished、接続一致、X.509方針、空拒否、受信・検証時刻を持つ。権限台帳は決定者、stream/操作、旧新権限、発効、期限、rollbackを持つ。

成功率だけでは安全を示せない。context再利用や広すぎる昇格があっても上昇する。逆にwrong-connection拒否はproxy境界が守られた証拠になり得る。

IANAのlabel登録、OpenSSLとBoringSSLのexporter codeは基盤を示すだけだ。RFC 9261実装や正しい権限適用を証明しない。要求から判断まで実行記録を再構成できて初めて、仕様が運用事実になる。

情報源