Certificate

Certificate メッセージ (TLS)

[21] TLS Handshake ProtocolCertificate メッセージ証明書を表します。サーバーからクライアントへはサーバー証明書サーバーからクライアントへはクライアント証明書となります。

仕様書

意味

[4] サーバーからの Certificate メッセージは、 クライアントに対してサーバー証明書鎖を伝えるものです >>1

[26] クライアントからの Certificate メッセージは、 サーバーに対してクライアント証明書鎖を伝えるものです >>18

構文

[45] HandshakeType 11 (certificate)


[6] Certificate メッセージは、 0バイト以上224-1バイト以下証明書 ( (chain) , 証明書鎖) です >>1

[17]証明書は、1バイト以上224-1バイト以下です >>1, >>16。 どのような証明書であるべきかにも規定があります (>>11)。

[7] 送信者証明書が最初に来なければなりません >>1

[39] すなわちEE証明書が先頭に来ます。

[38] その後の証明書は前の証明書を直接証明するものでなければなりません >>1

[40] つまり中間証明書小エンディアンで並べられます。
[36] ただし、クロスルート証明書と呼ばれる技法が使われることがあります。

[8] ルートCAを表す自己署名証明書は、から省略して構いません >>1。 省略しない場合は末尾に来ます。

[9] 検証のためにはルート証明書受信者が予め持っておく必要があるからです。
[37] ルート証明書省略できるということは、含まれていてもいいということです。 実際、含めるサーバーも含めないサーバーも見受けられます。

[41] 長さ0でもいいということは、証明書鎖が空になることが (少なくても仕様上は) あり得るということです。 その場合は当然証明書による検証ができず、安全ではありません。

[46] 個数0のリスト vs 0バイト列

[44] 実用上はサーバー証明書鎖を空にすることはまずありません。 クライアント認証が必要な場合以外、空にできます (>>20)。

[42] 証明機関の発行する証明書を利用できないときは、 いわゆるオレオレ証明書が使われます。 すなわち、その場限りのルート証明書に相当するEE証明書を1つだけ含んだ証明書鎖になります。

[43] 証明書鎖にはバイト長の制限はあるものの、証明書は何個でも含められます。 実際上は十分大きな数で制限されます。


[47] 厳密な話は置いておくとして、 Certificate の中身をちょっと覗きたいだけの場合、

文脈

[2] サーバーは、合意した鍵交換方式認証証明書を使う場合には、 Certificate メッセージを送信しなければなりません >>1

[3] サーバーは、 ServerHello メッセージの直後に Certificate メッセージを送信します >>1

[19] クライアントは、 ServerHelloDone メッセージを受信した直後に、 (サーバーCertificateRequest メッセージで要求していれば) Certificate メッセージを送信できます。 >>18

[20] クライアントは、適切な証明書が存在しない時は、 証明書を含まない (certificate_list が長さ0の) Certificate メッセージを送信しなければなりません >>18

[10] クライアントは、送るべき証明書がなければ Certificate メッセージを送らなくて構いません >>1

処理

[25] クライアントは、 service identity その他アプリケーション依存の証明書の検証を行います。

[22] サーバーは、クライアント証明書を送らなかった場合には、 クライアント認証なしでhandshakeを継続しても構いませんし、 handshake_failure fatal alert で応答しても構いません。 >>18

[23] サーバーは、クライアント証明書鎖の一部が受け入れられない (例えば既知の信頼した CA が署名していない) 場合、 クライアント認証なしとみなしてhandshakeを継続しても構いませんし、 fatal alert で応答しても構いません。 >>18

[27] サーバーは、 CertificateVerify メッセージ検証の際や、 premaster secret の計算に、クライアントCertificate を使います >>18

証明書の選択

[5] 証明書は、両者間で折衝した cipher suite鍵交換アルゴリズムTLS拡張において適当なものでなければなりません >>1, >>18

[11] 証明書PGP などで予め明示的に折衝した場合を除き、 X.509 の v3 証明書でなければなりません >>1, >>18

[12] サーバーからの Certificate メッセージにおける末端実体証明書公開鍵 (と関係する制約) は、 選択した鍵交換アルゴリズムと互換性があるものでなければなりません >>1

[28] クライアントからの Certificate メッセージにおける末端実体証明書公開鍵 (と関係する制約) は、 CertificateRequest メッセージで指定された証明書型と互換性があるものでなければなりません >>18

[29] クライアントからの Certificate メッセージにおける証明書は、 CertificateRequest メッセージで空でない certificate_authorities が指定されていた場合、指定されたいずれかの CA発行した証明書証明書鎖のいずれかとして含まれているべきです >>18

[13] サーバーからの Certificate メッセージにおける適切な証明書の選択には、 SNItrusted_ca_keys の指定があればそれを使います >>1

各項も参照。

[14] サーバーからの Certificate メッセージにおいては、 signature_algorithms の指定があれば、その署名アルゴリズムを使った証明書でなければなりません >>1

[30] クライアントからの Certificate メッセージにおいては、 ハッシュアルゴリズム署名アルゴリズムの組は CertificateRequest メッセージでの指定に従った証明書を使わなければなりません >>18

[15] サーバーは複数の証明書候補がある時にこうした基準の他、設定やポート番号など諸々の基準でいずれかを選択できます。 1つ証明書がある時もそれらの基準に合致するか検査するべきです>>1


[51] 多くの実装は OpenSSL を使っており、 OpenSSLPEMファイル形式で証明書鎖を指定すると、 OpenSSL サーバーがそれを Certificate 形式に変換して送信することになります。 証明書鎖

中間証明書欠如

AIA

[31] https://i.allnightnippon.com/

このサーバー、 中間証明書を返さなくて末端実体証明書だけ返してくる。 なのに WindowsChrome でも IE でもアクセスできてしまう。 Linuxwget, curl, LibreSSL ではエラーになる。 W3C Markup Validator ではエラーになる。 Internet Archive ではエラーにならない。

[34] >>31 未だに治っていないがサービスはなくなって他のホストにリダイレクトされる。 たぶんサーバーが消えるか証明書の期限に達するまでもうこのままだろう。

[32] BS11オンデマンド|TOPページ, , https://vod.bs11.jp/video/

[33] >>32 からの新しい末端実体証明書が使われてますが、 それに変わった頃から中間証明書が送信されてこなくなりました。 WindowsChrome では普通にアクセスできてしまいます。 変わってから数日間、修正される様子もないですし、 SNS に苦情も出ていないので、多くの環境で正常にアクセスできてしまっているのではないでしょうか。

[35] >>33 その後変わらず。治す気はなさそうだ。

メモ