Secondary Certificate Authentication in HTTP/2 という仕様について

目次

Secondary Certificate Authentication in HTTP/2

HTTP/2コネクションを確立したあとに、サーバまたはクライアントから追加の証明書を要求・提供できるようにする「Secondary Certificate Authentication in HTTP/2」という仕様が議論されています。(secondary-certsとも呼ばれています)

仕様自体はすでにwg draftとなっています。

数年前にこのブログでも紹介しましたが、デザイン変更もあるため再度簡単に読み直します。

用途

この仕様では、コネクションを確立したあとに、追加の証明書を要求提供できます。サーバ側から要求する場合と、クライアントから要求する場合の両方がありえます。まず、その用途について確認します。

サーバ側から証明書を要求するパターン

Webページでは、提供するページによってセキュリティレベルが異なる場合があります。管理者や、管理者の中でも上位者のみ閲覧できるページもあります。そういったページのみクライアント証明書を要求するといったパターンもあります。

一度コネクションが確立したあとに、追加でクライアント証明書が必要だという場合は、以前までであればTLS renegotiationを行ってクライアント証明書を要求していました。

しかし、HTTP/2ではrenegotiationを禁止しているため、確立したコネクション上で追加のクライアント証明書を要求することができませんでした。

クライアント側から証明書を要求するパターン

HTTP/2では一つのTCPコネクション上で、条件があえば異なるドメインへのHTTPリクエストを送信することが出来ます。例えば、ハンドシェイク中に*.example.comの証明書が得られた場合、かつサーバのIPアドレスが同じであればa.example.comとb.example.comを同じコネクション上でリクエストすることが出来ます。

一方で、「RFC8336 The ORIGIN HTTP/2 Frame」(詳細は過去記事参照)を用いることで、サーバ側から提供できるオリジンリストをクライアントに提供できます。ここでクライアントは、このオリジンのリストにあるサーバ証明書を追加で要求することが出来ます。

こうすることでより多くのドメイン名に対するリクエストで既存のコネクションを利用できるようになります。

また、一度確立したTLSコネクション上で追加の証明書を要求するので、SNIなどの情報によってHTTPリクエスト先が第三者にバレることもありません。

通信フロー

この「Secondary Certificate Authentication in HTTP/2」では4つの拡張フレームを定義しています。

  • CERTIFICATE_REQUEST: 追加の証明書を要求する (TLS1.3のCertificateRequestメッセージを含む)
  • CERTIFICATE_NEEDED: 追加の証明書が必要となっているストリームIDを示す
  • CERTIFICATE: 追加の証明書
  • USE_CERTIFICATE: 追加の証明書を使用するストリームIDを示す

CERTIFICATE_REQUESTフレーム及びCERTIFICATE_NEEDEDフレームの中身については、追加の証明書の要求及び提供する仕組みを定義する「Exported Authenticators in TLS」 (こちらはTLSの話)で定義されているメッセージを利用している

サーバ側から証明書を要求する場合

f:id:ASnoKaze:20190311005237p:plain

クライアントがストリームID N でクライアント証明書が必要な/protectへのリクエストを送信します。そこで、サーバ側からCERTIFICATE_NEEDEDフレームが送られ、クライアントは追加の証明書を提供し、無事そのストリームでHTTPレスポンスをつけとります。

クライアント側から証明書を要求する場合

サーバがORIGINフレームを用いて、提供可能なオリジンのリストをクライアントに通知します。クライアントはその中で必要な証明書を追加で要求します。追加の証明書が得られたら、そのオリジンのドメインに対してHTTPリクエストを送ります。

f:id:ASnoKaze:20190311005418p:plain