私も大変有り難く利用させてもらっている、みんな大好きLet's Encryptはいろんな方の寄付のおかげで無料で利用できるSSLサーバー証明書の発行サービスですが、何やらルート認証局の移行が話題になっているので、ちょっと調べてみました。
問題の概要は、こちらのブログでとても詳しく解説されており、とても参考になりました。ありがとうございます。
公式から出ている説明だと、出てくる証明書の関係がわかりにくく、図もちょっと間違っていたので、別の図を起こしました。簡単には、DST Root X3ルート証明書が期限切れを迎えそうなので、新しいISRG Root X1ルート認証局に移行したいわけです。
certbotを使っていると /etc/letsencrypt/archive/ドメイン/ に発行された証明書、チェーン、秘密鍵の履歴が残りますが、その時期を頼りにどうなっていたのか見てみます。
2020年10月まで
最初はDST Root X3ルートから発行されており、DST Root X3の有効期限が2021年9月、中間CAであるLet's Encrypt X3の有効期限が2021年3月で、(認証局的にはかなり急いで)対応しないければマズイ状況にありました。
2020年10月から2021年5月4日まで
期限切れになりそうなルート認証局と中間認証局の移行のため、SSLサーバー証明書は新しいISRG Root X1ルートCAとLet's Encrypt R3中間CAから発行することになりました。
新しい、ISGR Root X1ルート証明書が搭載されているOS、ブラウザならばこれで構わないのですが、そうでない場合にはSSL通信でエラーになってしまうので、ACMEで提供されるチェーンは、後方互換性のため古いDST Root X3ルートからのチェーンが提供されています(下図)。
認証局は自分の秘密鍵の使用期間を超えてた証明書を発行することができないことになっているので(コレ重要)、旧DST Root X3ルートから新Let's Encrypt R3中間CAへの証明書の有効期限も最大限のDST Root X3と同じ2021年9月に設定されています。
これにより、旧Let's Encrypt X3の移行期限である2021年3月から、2021年9月のギリギリまでDST Root X3ルートのチェーンが使えるように延命できました。
ところが、「2021年9月以降、古いAndroidは使えないよ〜〜」とやいのやいの言われ対策する必要があったわけです。
ちなみにクロス(相互認証)証明書とは
クロス証明書、相互認証証明書という言葉がちょっと誤解されているようで気になったので説明させてください。異なる認証局同士が(下位認証局であっても)信頼関係を結ぶのにcross certification(相互認証)が行われ、クロス証明書(=相互認証証明書)が発行されます。これは異なる事業者や同じ事業者内のルート認証局間でも、異なる事業者や同じ事業者の中間認証局に対しても行われることがあります。
ルート認証局のクロス発行が離れ業のように書かれていることがありますが、割と当たり前の運用です。
「クロス」という言葉から連想されるように「双方向」であると誤解されがちですが、「片方向相互認証(unilateral cross certification)」「双方向相互認証(bilateral cross certification)」という言葉で区別されるように、片方向でも構いません。
また、下位認証局(サブCA)に証明書を発行するのも相互認証の一種です。
で、2021年5月4日以降
直前の延命策を使っても、古いAndroidが2021年9月以降使えなくなるということで、旧DST Root X3から新ISRG Root X1に対して2024年9月までの有効期間のクロス証明書を発行しました。
ZDnetからもクロス発行に合意したことが2020年12月にニュースになりました。
ACMEから配布されるフルチェーンは以下のようになっています。
Androidでは、トラストアンカとしてルート証明書を搭載していても、ルート証明書の有効期間は見ないという仕様のために2024年9月までは、このチェーンは有効になっており、古いAndroidでも新しいLet' Encrypt R3中間CA系統のSSL証明書が利用できるようになったそうです。
ルート証明書の有効期間を見なくて問題ないか
インターネットでのX.509証明書の利用についてはRFC 5280という標準で規定されており、証明書のチェーン(=認証パス)の検証アルゴリズムの例は6章に記載されています。
6.1.1節 入力にはトラストアンカの構成要素が規定されていて、「(1)信頼される発行者名(2)信頼される公開鍵のアルゴリズム(3)信頼される公開鍵(4)オプションとして信頼される公開鍵のパラメータ」となっており、RFC 5280のパス検証では、その他のルート証明書の情報、例えば、証明書有効期間や基本制約のcAフラグなどは検証しなくて良いことになっています。
つまり、OSベンダーや利用者が、そのルート証明書をトラストアンカとして搭載してよいか、有効期限や拡張なども含めて判断して入れることになります。
ただ、実際には、トラストアンカの証明書の有効期限やcAフラグなど含めてチェックする実装もあります。過去にはX.509v3ルート証明書にcAフラグが無く、これを検証する実装で問題になったことがありました。
では、何が問題か
前にも述べたように、ルート認証局間でクロス証明書を発行すること自体は特に珍しいことでもなく、ウルトラCでもなく問題ありません。「旧DST Root X3ルートCAが、自身の鍵の有効期限2021年9月を超えて、新ISRG Root X3ルートCAに対して2024年9月を有効期限とするクロス証明書を発行していること」が問題なんだと思います。
指摘の厳しい事で知られるCAブラウザフォーラムが、なぜこのようなクロスの発行を認めた、もしくは問題なしとしたのか理解できませんでした。
The certificate validity period is the time interval during which the
CA warrants that it will maintain information about the status of the
certificate.
証明書の有効期間は、証明書の状態に関する情報を維持管理することを
CAが保証する期間です。
と規定されており、2021年9月以降は今回のクロス証明書の状態の維持管理ができないので、発行はこれに違反しているように思います。一般には、CA証明書の配下、子孫の証明書はCA証明書の有効期間を超えないように有効期間が設定され、これを超える証明書は運用上も発行しないようになっています。
特に、ルート証明書は、証明書の搭載(=普及)や移行にとても時間がかかるので、今回のようにルート認証局を期限ギリギリまで使用することはなく、ルート証明書の有効期限の約半分か、(暗号アルゴリズムの問題やインシデント等の理由により)それ未満でルート認証局を移行することが多いようです。
「認証局の発行する証明書の有効期限が、その認証局の有効期限を超えてはいけない」ということが当たり前だと思っていて、今回のようなそうでないケースを見たことがなかったので、その根拠となる国際標準やガイドライン等、RFC 5280のように意味を汲み取ればということでなく厳密に規定しているのがあれば、(こっそり)教えて下さいw
2021年9月以降、何が起きそうか
旧DST Root X3ルート認証局は、ルート証明書の有効期限である2021年9月の後、速やかにルート認証局の秘密鍵を破壊することになります。一般的なWeb PKIでは、認証局の秘密鍵で証明書失効リスト(CRL)を発行するので、CRLの発行もまた、2021年9月を最後に以降発行ができなくなります。
すると、それ以降、DST Root X3→ISRG Root X1のクロス証明書の失効情報が発行できなくなるので、最後のCRLは次回更新(nextUpdate)が2024年9月と、とても長いCRLを発行することで対応することになると予想されます。
ただ、最近の多くのブラウザの実装は、CRLをあまりみないことが多いので、どんなCRLであってもエラーにならないかもしれません。