あどけない話

Internet technologies

TLS 1.3 開発日記 その12 OCSP と SCT

TLS 1.2では Server Hello 拡張であった OCSP と SCT は、TLS 1.3ではハンドシェイクメッセージである Certificate の拡張となった。

OCSP

証明書は有効期限内であっても、失効している可能性がある。失効しているかを調べる伝統的なやり方は、CRL(Certificate Revocation List)であった。

CRLでは、クライアントが失効リストを取って来て、その中に対象があるかないかを調べる。これに対し、OCSPサーバに問い合わせると、証明書が(いつの時点で)有効か教えてくれるのが OCSP(Online Certificate Status Protocol) である。

TLSクライアントが、OCSPサーバに問い合わせるのは現在では非推奨である。その代わり、TLSサーバが定期的に問い合わせ、証明書と一緒にフレッシュな OCSP Response を送ってくるのが、OCSP stapling である。

証明書に対する OCSP サーバの情報は、証明書の中に入っている。Let's ecnrypt で取得した署名書では、以下のような感じ:

% openssl x509 -text -in cert.pem
Certificate:
    Data:
...
            Authority Information Access: 
                OCSP - URI:http://ocsp.int-x3.letsencrypt.org/
                CA Issuers - URI:http://cert.int-x3.letsencrypt.org/
...

OCSPサーバに問い合わせてみる:

% openssl ocsp \
  -noverify \
  -issuer chain.pem -cert cert.pem -CAfile chain.pem \
  -url http://ocsp.int-x3.letsencrypt.org \
  -header Host ocsp.int-x3.letsencrypt.org \
  -resp_text -respout resp.der
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
    Produced At: Feb 23 06:37:00 2017 GMT
    Responses:
    Certificate ID:
      Hash Algorithm: sha1
      Issuer Name Hash: 7EE66AE7729AB3FCF8A220646C16A12D6071085D
      Issuer Key Hash: A84A6A63047DDDBAE6D139B7A64565EFF3A8ECA1
      Serial Number: 03AF31CC447C2CEF256FC77839190A70DDE2
    Cert Status: good
    This Update: Feb 23 06:00:00 2017 GMT
    Next Update: Mar  2 06:00:00 2017 GMT
...

便利なラッパーとして fetch-ocsp-responseがある。

SCT

Certificate Transperancyは、(理想的にはすべての)証明書を登録するサービスである。ロガー呼ばれるサーバには、証明書の追加だけができるログを持っている。2つの使い方がある。

  • ある証明書のハッシュを送ると、ログの中に存在しているか確認できる。
  • ロガーから、証明書群の差分を取れる。つまり、ロガーが持っている証明書すべてを取得できるので、不正な証明書が発行されてないか調べられる。たとえば、自分のドメインを名乗る不正なサーバに対する証明書を発見できる。

ロガーには、サーバ名から証明書を検索する機能はない。そういうサービスは、上記二番目の機能を使って外部に作る。たとえば、crt.sh

ロガーは、新規に証明書を登録された場合、SCT (signed certificate timestamp)を返す。これは、ロガーの署名が付いた存在証明である。TLSクライアントは、SCTの署名をロガーの公開鍵で検証すれば、対応する証明書がログに入っていることを確認できる。つまり、ロガーに問い合わせる必要はないし、TLSクライアントがロガーに問い合わせるのは非推奨である。

TLSサーバからTLSクライアントにSCTを渡すには、2つの方法がある。

  • 証明書の拡張に入れる
  • TLS の Server Hello の拡張に入れる

CA から、サーバ管理者に SCT を配布するには、以下の方法がある。

  • 発行する証明書に入れる
  • OCSPの拡張で返す

Let's encrypt の CA は、証明書を発行する際、ct.googleapis.com/pilot と ct.googleapis.com/icarus に証明書を登録するようだ。つまり、Let's encrypt の CA は、SCT を知っているが、残念ながらそれをサーバ管理者には教えてくれない。

  • certbot renew しても SCT ファイルはできない
  • certbot renew して得られる証明書には SCT が入っていない
  • OCSP で問い合わせても SCT 拡張は入っていない

八方塞がりである。

実はロガーは、すでにある証明書が登録されようとした場合も、SCT を返す。この方法を実現してくれるのが、ct-submitである。(もちろん新規登録も可能。)

% ct-submit ct.googleapis.com/pilot < fullchain.pem > sct