要約

  • RFC 9345では、end-entity証明書の所有者が、TLS/DTLS 1.3のhandshakeで使う短期のDelegated Credentialを署名できる。clientは元の証明書chainと期待するidentityを通常どおり検証し、その後に委任公開鍵でCertificateVerifyを確認する。
  • 既定の最長期間は7日だが、短命であることは個別の即時失効機能ではない。委任秘密鍵が漏れれば期限までimpersonationに使われ得る。一つのcredentialだけを途中で取り消す仕組みはなく、待てない場合は元の証明書を失効させる広い判断が残る。
  • 発行の正当性を示すには、証明書のopt-in、credentialのhash、署名操作、秘密鍵の生成・配布、配置先、client negotiation、CertificateVerify、非対応clientのfallback、resumption、期限後の拒否を別々に記録する必要がある。

02時にedgeへ届いたもの

あるserviceは証明書の長期秘密鍵をsigning back-endから出さない。02時、back-endは新しい公開鍵と期限を含むobjectを署名し、対応する秘密鍵を持つedge群へ配る。Firefoxのような対応clientがextension 34を提示すると、edgeは元の証明書chainとそのobjectを送り、自分の短期秘密鍵でCertificateVerifyを作る。

長期鍵へのround tripは不要になる。しかしedgeが証明書所有者になったわけではない。証明書をrenewできず、hostnameを変更できず、CAとの関係を移せず、委任秘密鍵から次のcredentialを作ることもできない。非対応clientへ機能を強制する権限もない。

Delegated Credentialを「短期証明書」と呼ぶと、この境界が崩れる。RFC 9345が定義するのはX.509証明書ではなく、handshakeに必要な意味だけを持つ署名objectである。valid_time、CertificateVerify用algorithm、SubjectPublicKeyInfoがあり、end-entity証明書の鍵がobject全体を署名する。署名対象には証明書のDER bytesとclient/server別のcontextも含まれるため、同じcredentialを両roleへ流用できない。

証明書が先に許可する

通常のend-entity証明書から、勝手に有効な委任を作れるわけではない。証明書にはnon-criticalなDelegationUsage extensionとdigitalSignature KeyUsageが必要である。どちらかを欠けばendpointはcredentialを受理してはならない。

これは単なるformat checkではない。古いTLS contextで使われる証明書鍵に一時的に触れた者や、署名oracleを見つけた者が、その事実だけで将来のTLS 1.3委任を作る危険を抑えるopt-inである。証明書を発行するCA、証明書を保有するoperator、credentialを使うedgeの三者は、同じ権限を持たない。

server認証ではclientがClientHelloでdelegated_credentialと対応algorithmを先に提示する。serverはその後、end-entity CertificateEntryに一つだけcredentialを入れられる。client認証ではserverがCertificateRequestで先に許可する。要求していないcredentialを受け取った場合は便利なupgradeではなくprotocol errorになる。

検証側は最初に通常のcertificate pathと期待identityを検証する。次に現在時刻、既定7日以内、元証明書の有効期限内、二種類のsignature algorithm、証明書のopt-in、credential signatureを確認する。最後にだけ、credential内の公開鍵をCertificateVerify検証へ使う。

ゆえに、成功したhandshakeは複数の証言を重ねた結果である。CA chainが証明書を支え、証明書鍵が限定objectを承認し、edgeが短期秘密鍵の所持を示し、applicationがその接続へroleを与える。transport認証が成功しても、HTTP requestや業務処理が自動的に許可されるわけではない。

期限は撤回操作ではない

application profileに別規定がなければ、credentialの残存期間は検証時点から既定7日以内で、元証明書のexpiryを越えない。CloudflareはKeylessを無効化した後、同社が生成したcredentialが24時間以内に無効になるproduct policyを公開している。24時間と7日は矛盾ではない。前者はより短い運用選択、後者はprotocolのdefault ceilingである。

ただし「24時間以内」は「今すぐ」ではない。RFC 9345には一つのDelegated Credential専用の早期revocation channelがない。新規発行を止め、正規edgeから削除しても、既にコピーされた秘密鍵は戻らない。通常はexpiryを待つ。元証明書をrevokeすれば委任の根も失われるが、同じ証明書を使う通常handshakeまで巻き込む。

短い期限は被害時間を区切るが、更新系を厳しくする。signer outage、配布遅延、edgeのoffline、時計ずれが重なると、短期化したcontrolがavailability failureへ変わる。valid_timeは証明書のnotBeforeを基準にexpiryを作り、clientは自分のclockで判定する。境界付近のskewはserver側で正常に見えるcredentialを拒否させる。

session resumptionにも古い判断が残り得る。certificate chainをcacheして再検証するpeerは、関連するcredentialも保存してexpiryを再確認すべきだとRFCは述べる。full handshakeがなかったという理由で、期限を越えた委任を生かしてはならない。

秘密鍵の移動経路を選ぶ

RFC 9677はmulti-CDNで二つのcustody modelを示す。downstream CDNが自分でkey pairを生成し、public keyだけを上流へ渡して署名してもらうmodelでは、秘密鍵がmetadata interfaceを横切らない。その代わりpublic key enrollmentが、本当に意図したdownstreamやnodeから来たことを証明しなければならない。

もう一つはupstreamがcredentialと暗号化済みprivate keyを渡すmodelである。中央生成は容易だが、配送ciphertextと復号keyが新しいassetになる。RFC 9677はprivate key送信を推奨せず、使用時には十分な強度のkeyで暗号化するよう要求する。しかも指定envelopeは、後日に復号keyが漏れた場合のforward secrecyを与えない。

credentialを何台で共有するかも決定事項である。一つを大きなclusterへ配ればsigningとrotationは軽くなるが、一台のcopy流出が全体へ広がり、handshakeから使用nodeを特定しにくい。per-edge credentialならblast radiusとattributionを絞れる一方、発行数、inventory、更新失敗が増える。最小単位は図の美しさではなく、障害時にも期限前更新を証明できる範囲で決める。

fallbackが残す長期依存

IANA registryのvalue 34はRecommendedで、CH、CR、CTに現れ得る。しかしregistry entryはclientへ実装を配らず、CAへDelegationUsage付き証明書の発行を強制しない。

Cloudflareの現行documentはFirefox 77以降のsupportを挙げながら、対応clientは非常に少なく、対応CAも一握りだと明記する。したがってproductionはmixed modeになる。対応clientはDCを使い、非対応clientやalgorithmが合わないclientは通常証明書またはremote signingへ戻る。

このfallbackはcontrol surfaceの一部である。remote signingはhandshakeごとのback-end availabilityとlatencyを戻す。長期証明書鍵をedgeへ置けば、削減したかったexposureが復活する。legacy用に別証明書を持てばrenewalとrevocation inventoryが増える。DC採用率だけを上げるKPIは、fallback serviceの飽和を見逃し得る。

BoringSSL testsはTLS 1.2でDCを使わないこと、二つのalgorithm fieldを混同しないこと、適切なDCがなければ通常certificateを選ぶことを実行している。Mozilla NSS codeは署名時にdelegated private keyを選び、検証時にdelegated public keyと期待algorithmを使う。仕様、configuration、wire上のacceptanceは同じ証拠ではない。

監査できる一つのepoch

発行ledgerには、元証明書のfingerprint、serial、name、validity、KeyUsage、DelegationUsage、credential bytesのhash、SPKI hash、role、二つのalgorithm、算出expiry、承認者、長期鍵の署名eventを残す。

custody ledgerには、鍵をdelegateが生成したか受領したか、public key enrollmentまたは暗号配送の経路、許可edge集合、配置ack、共有範囲を残す。handshake ledgerには、client support、選択credential、certificate/DC検証、CertificateVerify、protocol version、fallbackを記録する。

retirementは別の証拠列である。将来発行の停止、各edgeの削除ack、理論上の最終有効時刻、元証明書をrevokeするか、resumption処理、expiry後のnegative testを保存する。configurationから消えた事実は一台のlocal stateしか示さない。権限終了を主張するには、期限後に拒否され、wire観測から使用が消えたことが必要である。

情報源