サーバ証明書と中間証明書・ルート証明書のチェーン検証をOpenSSL確認するにはひと手間が必要でした。
たまにしかやらない作業で忘れかけるので備忘録として記事にしました。
OpenSSLでチェーンを検証する方法
OpenSSLでチェーン検証する方法は「openssl verify」で実行できます。
openssl verify -CApath 【中間証明書、ルート証明書のパス】 【サーバ証明書】
例)
openssl verify -CApath ./cacerts server.crt
-CApath にて中間証明書とルート証明書の情報を入れておけばOKなのですが、OpenSSLではCApath内にある中間証明書やルート証明書のファイル名をハッシュ化した名前にしないといけないということに注意です。
ハッシュ化
OpenSSLでチェーン検証を行うには、中間証明書及びルート証明書のファイル名に気を付けないといけないです。
## Server.cerにkaede.jpのサーバ証明書を配置、CACertsフォルダに中間証明書、ルート証明書を配置
$ ll
total 4
drwxr-xr-x 1 forev 197609 0 Jul 18 23:54 CACerts/
-rw-r--r-- 1 forev 197609 1636 Jul 18 23:53 server.cer
$ ll CACerts/
total 8
-rw-r--r-- 1 forev 197609 1970 Jul 18 23:54 'ISRG RootX1.cer'
-rw-r--r-- 1 forev 197609 1856 Jul 18 23:54 R3.cer
$ openssl verify -CApath ./CACerts server.cer
error server.cer: verification failed
CN = *.kaede.jp
error 20 at 0 depth lookup: unable to get local issuer certificate
CApathで指定したフォルダ名内のファイルは【OpenSSLでハッシュ化.0】にする必要があります。
.0が最後につけないといけない点重要です。
$ openssl x509 -hash -noout -in ./CACerts/R3.cer
8d33f237
$ mv ./CACerts/R3.cer ./CACerts/8d33f237.0
$ openssl verify -CApath ./CACerts server.cer
server.cer: OK
OSなどに依存する形になるのですが、
参考
man openssl verifyで確認すると、hash化が必要と記載されています。
hash化したファイルだとどれが何の証明書なのかわからなくなるので、シンボリックリンクかハードリンクなどで紐づけすることが多いですかね。
$ man openssl verify
-CApath directory
A directory of trusted certificates. The certificates should have names of the form: hash.0 or have symbolic links to them of this form ("hash" is the hashed certificate
subject name: see the -hash option of the x509 utility). Under Unix the c_rehash script will automatically create symbolic links to a directory of certificates.
チェーン照会
チェーンの情報を確認したい場合は「-show_chain」をつけると確認することができます。
$ openssl verify -CApath ./CACerts -show_chain ./server.cer
./server.cer: OK
Chain:
depth=0: CN = *.kaede.jp (untrusted)
depth=1: C = US, O = Let's Encrypt, CN = R3
depth=2: C = US, O = Internet Security Research Group, CN = ISRG Root X1
ルート証明書がすでに信頼されている場合はCApathは不要
ISRG Root X1のようにルート証明書がすでに信頼されている場合はCApathがなくてもいけるようです。
$ openssl verify ./X3.cer
./X3.cer: OK
./X3.cer: OK
Chain:
depth=0: C = US, O = Let's Encrypt, CN = R3 (untrusted)
depth=1: C = US, O = Internet Security Research Group, CN = ISRG Root X1
エラーが発生する場合
error 20 at 0 depth lookup: unable to get local issuer certificate
「error 20 at 0 depth lookup: unable to get local issuer certificate」がエラーが表示される場合、証明書チェーンがうまく紐づかない場合に発生ため、CApath内に入っている中間証明書・ルート証明書と指定している証明書が正しいか確認する必要があります。
error 10 at 1 depth lookup: certificate has expired
「error 10 at 1 depth lookup: certificate has expired」が表示される場合、確認しようとしている証明書は署名情報がない場合に出てきます。
中間証明書に署名されているか、検証している証明書はルート証明書ではないか確認する必要があります。