[37] 
[DFN[[RUBYB[証明書鎖][certificate chain]]]]は、
[[証明書]]の[[列]]です。

[38] 
ただの[[列]]ではなく、前の[[証明書]]を証明する発行者の[[証明書]]を次に置く、
という形で[DFN[[RUBYB[証明経路][certification path]]]]を記述したものとなっています。

* 仕様書

[REFS[
- [6] [CITE@en[[[RFC 6066]] - Transport Layer Security (TLS) Extensions: Extension Definitions]]
([TIME[2015-02-01 18:07:52 +09:00]] 版)
<http://tools.ietf.org/html/rfc6066#section-10>
- [21] [CITE@en[[[RFC 7515]] - JSON Web Signature (JWS)]], [TIME[2020-03-29 16:13:43 +09:00]] <https://tools.ietf.org/html/rfc7515#section-4.1.5>
- [26] [CITE@en[[[RFC 7515]] - JSON Web Signature (JWS)]]
([TIME[2018-12-30 17:16:56 +09:00]])
<https://tools.ietf.org/html/rfc7515#section-4.1.6>
- [31] 
[CITE@en[[[RFC 7517]]: JSON Web Key (JWK)]], [TIME[2022-12-02T09:14:07.000Z]] <https://www.rfc-editor.org/rfc/rfc7517.html#section-4.6>


]REFS]

* 証明書鎖の記述形式

[43] 
[[証明書鎖]]は[[証明書]]を順に並べたものに過ぎませんが、
どのように[[並び]]を記述するか、いくつかの[[形式][ファイル形式]]があります。

[FIG(middle list)[ [13] [[証明書鎖]]を記述する[[ファイル形式]]と[[プロトコル要素]]

- [[TLS]] [CODE[Certificate]] (>>40)
- [CODE(MIME)@en[[[application/pkix-pkipath]]]] (>>7)
- [[PKCS #7証明書鎖]]
- [[Netscape Certificate Sequence]]
- [CODE[[[.pem]]]]
-- [[OpenSSL]] の [CODE[.pem]] [[証明書鎖]] (>>39)
-- [CODE[application/pem-certificate-chain]] (>>19)
-- [[[CODE[x5u]]で指定された証明書鎖]] (>>22)
- [[[CODE[x5c]]のJSON配列]] (>>5)
-- [[JWK]]
-- [[JWS]]
-- [[JWE]]
- [CODE[report-uri]] の提出形式 (>>16)

]FIG]

** 証明書列のDER

[40] 
[[TLS]]
で[[サーバー証明書]]や[[クライアント証明書]]を送信する
[CODE[Certificate]]
[[メッセージ]]では、
[[証明書]]の[[列]]を [[DER]]
符号化したものが使われます。
[SEE[ [[Certificate]] ]]

*** [CODE(MIME)@en[application/pkix-pkipath]]

[7] [[RFC 5280]] [[証明書]]の[[列]]を [[DER]] で[[符号化]]したものが、
[[MIME型]] [DFN[[CODE(MIME)@en[[[application/pkix-pkipath]]]]]]
です [SRC[>>6]]。これは [[certification path]] を表します [SRC[>>6]]。

[8] [[証明書]]の順序は意味を持ちます。最初の[[証明書]]の [[subject]]
が2番目の[[証明書]]の[[発行者]]、などとなるように並べます [SRC[>>6]]。

[9] [[relying party]] は [[RFC 5280]] に厳密に適合しない[[証明書]]を必ずしも拒絶しなくても構いませんが、
[[セキュリティー]]への影響は慎重に検討する必要があります [SRC[>>6]]。

[11] [[MIME型]]の[[引数]]は次の通りです。
[FIG(short list)[
- [CODE(MIME)@en[[[version]]]]
]FIG]

[10] [[7ビット輸送路]]では、 [[Base64]] を使う[['''べきです''']] [SRC[>>6]]。

[12] [[拡張子]]は [DFN[[CODE[[[.pkipath]]]]]] が使われます [SRC[>>6]]。



** 証明書のPEMの列

[39] 
[[OpenSSL]]
は1個[[以上]]の[[証明書]]が含まれる[CODE[.pem]]ファイルに対応しています。
[[OpenSSL]]
を使った多くの[[応用]]がこの形式をそのまま採用しています。

[41] 
この形式は、
1個の[[証明書]]を表す [CODE[.pem]] ファイルを
(適当な[[改行]]を挟んで)
任意の個数、繰り返し記述したものです。

[42] 
[[TLS]] [CODE[Certificate]] 用にこれを指定した場合は、
[[PEMファイル]]に含まれる[[証明書]]がそのまま順に送信されます。



*** [CODE[application/pem-certificate-chain]]

[19] 
[[[CODE[.pem]]ファイル]]形式の[[証明書鎖]]の記述形式の一種として、
[DFN[[CODE[application/pem-certificate-chain]]]]
があります [SRC[>>17, >>18]]。

[REFS[
- [17] [CITE@en[draft-ietf-acme-acme-18 - Automatic Certificate Management Environment (ACME)]]
([TIME[2018-12-21 18:47:41 +09:00]])
<https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-9.1>
- [18] [CITE[application/pem-certificate-chain]]
([TIME[2019-01-03 07:50:08 +09:00]])
<https://www.iana.org/assignments/media-types/application/pem-certificate-chain>
- [20] [CITE@en[An optional MIME parameter for application/pem-certificate-chain? · Issue #435 · ietf-wg-acme/acme]] ([TIME[2019-01-06 16:07:22 +09:00]]) <https://github.com/ietf-wg-acme/acme/issues/435>
]REFS]


*** [CODE[x5u]] 参照先

[22] [[JWS]] の[[ヘッダー引数]]や
[[JWK]] の[[鍵引数]]である
[DFN[[CODE[x5u]]で指定された証明書鎖]]の[[資源]]は、
[[RFC 5280]] [[X.509]] [[証明書]]または[[証明書鎖]]を
[[RFC 4945]] [CODE[.pem]] 形式で符号化した[[表現]]を提供するものでなければ[MUST[なりません]]。
[SRC[>>21, >>31]]


[23] 
[[JWS]] では、
[[RFC 4949]] [[デジタル署名]]に用いた[[鍵]]に対応する[[公開鍵]]を含む[[証明書]]は、
最初の[[証明書]]でなければ[MUST[なりません]]。
[SRC[>>21]]

[24] 
前の[[証明書]]を次の[[証明書]]が証明する、
という形で追加の[[証明書]]があっても[MAY[構いません]]。
[SRC[>>21]]

;; [25] このような[[証明書鎖]]の制約の記述方法だと、
冗長な[[証明書]]を含めることが出来ず、
[[クロスルート証明書]]のような他の場面で利用可能な技法が通用しない場合が出てこないでしょうか。

[32] 
[[JWK]] では、
含まれる最初の[[証明書]]は、
[[JWK]]
の他の[[鍵引数]]で記述された[[公開鍵]]に一致しなければ[MUST[なりません]]。
[SRC[>>31]]


[33] 
[[JWSの取得プロトコル]]も参照。


** 証明書のPEMのJSON配列

[16] [CODE[[[report-uri]]]] で指定された [[URL]] に送信される [[JSON]]
では、[[証明書鎖]]を[[証明書]]の [CODE[[[.pem]]]] 形式の文字列を
[[JSON]] [[配列]]として記述します。

** 証明書のDERのBase64のJSON配列

*** [CODE[x5c]] の JSON 配列

[27] 
[DFN[[CODE[x5c]]のJSON配列]]は、 [[JSON配列]]です。
[SRC[>>26, >>31]]


[28] 
[[JSON配列]]の各値は、
[[RFC 5280]] [[PKIX]] [[X.509]] [[証明書]]を
[[DER]] [[符号化]]し、
[[RFC 4648]] [[Base64]] [[符号化]]した[[文字列]]です。
[SRC[>>26, >>31]]

[29] 
[[JWS]]
では、
[[RFC 4949]] [[デジタル署名]]するのに使った[[鍵]]に対応する[[公開鍵]]を含む[[証明書]]は、
最初の[[証明書]]でなければ[MUST[なりません]]。
[SRC[>>26]]

[35] 
[[JWK]]
では、[[鍵]]値を含む[[証明書]]は、
最初の[[証明書]]でなければ[MUST[なりません]]。
[SRC[>>31]]

;; [36] ここでいう「[[鍵]]値」とは何か不明瞭ですが、
[[JWK]] として表現している[[鍵]]が直接的に含まれるものが最初の[[証明書]]のものである、
ということでしょう。

[30] 
前の[[証明書]]を次の[[証明書]]が証明する、
という形で追加の[[証明書]]があっても[MAY[構いません]]。
[SRC[>>26, >>31]]

;; >>25

[34] 
[[JWK]] では、
含まれる最初の[[証明書]]は、
[[JWK]]
の他の[[鍵引数]]で記述された[[公開鍵]]に一致しなければ[MUST[なりません]]。
[SRC[>>31]]

** その他のASN.1系記述形式

[44] [[PKCS #7証明書鎖]]

[45] [[Netscape Certificate Sequence]]

* 証明経路

** 中間証明書の欠如

[SEE[ [[Certificate]] ]]

** 証明経路の完成のための証明書の入手

[46] 
[[TLS]] はじめ多くの[[プロトコル]]は[[証明書鎖]]に[[ルート証明書]]を含めても、
含めなくても良いとしています。
必要な[[ルート証明書]]は、手元の[[証明書データベース]]にあるものを参照します。

;;
[47] 
[[ルート証明書]]が相手方から送られてきていれば、
それを使えば[[証明書データベース]]を参照しなくても
[[EE証明書]]の[[検証]]自体は可能です。
しかし[[ルート証明書]]が信頼できるかどうかの判断は必要となるので、
[[証明書データベース]]の参照はやはり必要となります。
したがって[[ルート証明書]]は省略できるのです。


[48] 
[[TLS]]
はじめ多くの[[プロトコル]]は必要な[[中間証明書]]をすべて[[証明書鎖]]に含めて相手方に送信することを求めています。

[49] 
しかしそれ以外の手段で[[中間証明書]]を取り揃えて[[証明経路]]を用意する仕組みを構築することは可能です。

[50] 
実際にそのための要素の1つとして、
[[証明書]]に [[AIA]] を使って[[中間証明書]]の入手方法を記述することができます。

;; [51] 
[[IE]] は [[TLSサーバー]]が[[中間証明書]]を送ってこなかったときにも
[[AIA]] を参照して[[中間証明書]]を取得して[[検証]]に使います。
そのために他の実装との[[互換性]]の問題をしばしば起こしていました。
[SEE[ [[AIA]], [[Certificate]] ]]

[52] 
また、実装によっては[[中間証明書]]の[[検証]]結果を[[キャッシュ]]しているために、
[[プロトコル]]上必須とされる[[中間証明書]]が[[証明書鎖]]に含まれなかった場合でも、
キャッシュを根拠に[[検証]]を成功させてしまう場合があります。
このような挙動は接続の可否に再現困難な不確定性をもたらしてしまい、
問題の発覚と修正を難しくするので、避けなければなりません。

;; [53] 詳しい[[検証]]の処理は[[キャッシュ]]を使うとしても、
[[証明経路]]の完全性の検証は毎回行う必要があるのでしょう。
その程度の検査で住むならコストは大きくならずに済むでしょうし。

* メモ

[1] [CITE@en[RFC 5280 - Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile]]
([TIME[2015-02-22 15:44:10 +09:00]] 版)
<http://tools.ietf.org/html/rfc5280#section-3.2>

[FIG(quote)[
[FIGCAPTION[
[2] [CITE@en[RFC 5280 - Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile]]
([TIME[2015-02-22 15:44:10 +09:00]] 版)
<http://tools.ietf.org/html/rfc5280#section-4.1.2.4>
]FIGCAPTION]

> Certificate users MUST be prepared to process the issuer
>    distinguished name and subject distinguished name (Section 4.1.2.6)
>    fields to perform name chaining for certification path validation
>    (Section 6).  Name chaining is performed by matching the issuer
>    distinguished name in one certificate with the subject name in a CA
>    certificate. 

]FIG]


[FIG(quote)[
[FIGCAPTION[
[3] [CITE@en[RFC 5280 - Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile]]
([TIME[2015-02-22 15:44:10 +09:00]] 版)
<http://tools.ietf.org/html/rfc5280#section-4.2.1.7>
]FIGCAPTION]

> Issuer alternative names are not
>    processed as part of the certification path validation algorithm in
>    Section 6.  (That is, issuer alternative names are not used in name
>    chaining and name constraints are not enforced.)

]FIG]


[4] [CITE@en[RFC 5280 - Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile]]
([TIME[2015-02-22 15:44:10 +09:00]] 版)
<http://tools.ietf.org/html/rfc5280#section-6>

[5] [CITE@en[RFC 6818 - Updates to the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile]]
([TIME[2015-03-24 03:47:50 +09:00]] 版)
<https://tools.ietf.org/html/rfc6818#section-4>

[14] [CITE@en[634074 – Cannot validate valid certificate chain when looping/cross-signed certs are involved]]
( ([TIME[2016-05-08 21:58:21 +09:00]]))
<https://bugzilla.mozilla.org/show_bug.cgi?id=634074>

[15] [CITE@en[RFC 7515 - JSON Web Signature (JWS)]]
([TIME[2018-12-30 17:16:56 +09:00]])
<https://tools.ietf.org/html/rfc7515#section-4.1.6>

