[7] [[PKP]] の [DFN[[CODE(HTTP)@en[[[pin-sha256]]]]]] [[指令]]は、
[[ホスト]]の [[SPKI Fingerprint]] を表します。

* 仕様書

[REFS[
- [1] '''[CITE@en[RFC 7469 - Public Key Pinning Extension for HTTP]] ([TIME[2015-05-05 21:00:37 +09:00]] 版) <https://tools.ietf.org/html/rfc7469#section-2.1.1>'''
- [11] [CITE@en[RFC 7469 - Public Key Pinning Extension for HTTP]] ([TIME[2015-05-05 21:00:37 +09:00]] 版) <https://tools.ietf.org/html/rfc7469#section-2.4>
- [24] [CITE@en[RFC 7469 - Public Key Pinning Extension for HTTP]] ([TIME[2015-05-05 21:00:37 +09:00]] 版) <https://tools.ietf.org/html/rfc7469#section-2.5>
- [16] [CITE@en[RFC 7469 - Public Key Pinning Extension for HTTP]] ([TIME[2015-05-05 21:00:37 +09:00]] 版) <https://tools.ietf.org/html/rfc7469#section-4>
-- [22] [CITE@en[RFC 7469 - Public Key Pinning Extension for HTTP]] ([TIME[2015-05-05 21:00:37 +09:00]] 版) <https://tools.ietf.org/html/rfc7469#section-4.3>
]REFS]

* 意味

[2] [CODE(HTTP)@en[[[pin-*]]]] [[指令]]は、ホスト運用者が当該ホストに束縛されるべき[[暗号学的identity]]を示すものです [SRC[>>1]]。
[[ピン]]を符号化したものです。

[10] [DFN[[RUBYB[[[ピン]]]@en[Pin]]]]は、
既知の[[暗号学的ハッシュアルゴリズム]]の識別子と、
それを使って計算した [[SPKI Fingerprint]] の組み合わせです [SRC[>>11]]。

;; [12] [[SPKI]] だけを取り出した時不完全となる場合は、 [[ピン]]を作ることはできません
[SRC[>>11]]。

;; [13] 運用者が古い[[公開鍵]]を含む新しい[[証明書]]を生成できるように、
[[証明書]]全体ではなく[[公開鍵]]を[[ピン]]として使います。 [SRC[>>11]]

* 構文

[3] [[指令]]の名前は、 [CODE[[[pin-]]]] に[[字句]]を続けたものです [SRC[>>1]]。
[[暗号学的ハッシュアルゴリズム]]を表すもので、 [[RFC 6234]] [[SHA256]] を表す [CODE[[[sha256]]]]
(つまり [CODE[[[pin-sha256]]]]) のみが認められています [SRC[>>1]]。

;; [[大文字・小文字不区別]]です。

[4] [[指令]]の値は、[[引用文字列]]です [SRC[>>1]]。
これは [[Base64符号化SPKI Fingerprint]] です。

;; [15] どうやら[[字句]]として表現できる場合でも[[引用文字列]]であることが求められているようです。

* 文脈

[8] [[PKP]] [[ヘッダー]]で使うことができます。

[14] 本[[指令]]と同じものが [CODE[[[report-uri]]]] へ送信される [[JSON]]
の [CODE[[[known-pins]]]] の値としても使われます。

* ヘッダーに含めるべきピン

[17] [[サーバー]]は、[[証明書鎖]]中のいずれかの[[証明書]]の [[SPKI Fingerprint]]
を最低でも含めなければなりません。

;; [9] なぜか仕様書上はサーバーの要件とはされていませんが、そうでなければ[[クライアント]]は接続を拒否することになります。

[18] [[サーバー]]は[[末端実体証明書]]だけでなく、[[中間発行者]]や [[trust anchor]]
の[[証明書]]の[[ピン]]も含められます [SRC[>>16]]。

;; [19] [[trust anchor]] の[[証明書]]、すなわち[[ルート証明書]]は [[TLS]]
では転送しなくても良いことになっていますが、その[[ピン]]を含めても問題無さそうです。

[20] [[サーバー]]の管理者が[[秘密鍵]]を紛失すると、
同じ[[公開鍵]]の新しい[[証明書]]を発行できなくなりますから、
[[末端実体証明書]]の[[ピン]]のみの [[PKP]] だと、
しばらく[[クライアント]]が接続できないことになってしまいます。
これを防ぐため、 [[CA証明書]]の[[ピン]]を含めることで、
その [[CA]] が発行した[[証明書]]なら他の[[証明書]]でも接続できる状態となります。 [SRC[>>16]]

;; [21] [[サーバー]]管理者が [[CA]] を信用していることが前提となります。

[23] 加えて、[[サーバー]]は[DFN[[RUBYB[バックアップピン]@en[Backup Pin]]]]として[[証明書鎖]]のいずれの[[証明書]]のものでもない[[ピン]]を含めなければ[['''なりません''']] [SRC[>>16]]。
これは[[秘密鍵]]紛失等の際にかわりに使うため[[鍵]]を予め用意しておくものです [SRC[>>22]]。
[[利用者エージェント]]は、[[PKP]] [[ヘッダー]]に[[バックアップピン]]が含まれていることを要求しなければ[['''なりません''']] [SRC[>>22, >>24]]。

* 処理

[5] 未知の[[ハッシュアルゴリズム]]の[[指令]]は、無視しなければ[['''なりません''']] [SRC[>>1, >>11]]。

[6] 認識できる [CODE(HTTP)@en[[[pin-*]]]] [[指令]]がなく、
当該[[ホスト]]が [[Known Pinned Host]] なら、
その[[ホスト]]が [[Known Pinned Host]] であるとみなすのをやめなければ[['''なりません''']] [SRC[>>1]]。
[[利用者]]にこれを示すべきです [SRC[>>1]]。

* メモ

[FIG(quote)[
[FIGCAPTION[
[25] [CITE[不正なSSL証明書を見破るPublic Key Pinningを試す - ぼちぼち日記]]
([TIME[2016-01-13 10:46:05 +09:00]] 版)
<http://d.hatena.ne.jp/jovi0608/20140902/1409635279>
]FIGCAPTION]

> ハッシュ方法は仕様上 sha256のみですが、当初より Google は sha1 を使っていたため、Chromeでは sha1 も使えるようです。このハッシュ値をbase64にエンコードしたものをヘッダ値に入れます。

]FIG]
