web-dev-qa-db-ja.com

OpenSSLによって信頼されている証明書を一覧表示する方法は?

私が理解しているように、X.509証明書で動作するソフトウェアには、証明書が信頼できるかどうかを判断する独自の基盤がある場合があります。

AFAIK OpenSSLはリスト(たとえば、/ etc/ssl/certsなど)を参照して、そこに証明書が存在するかどうかを確認するだけです。

OpenSSLが信頼するすべての証明書をリストする方法はありますか? (OpenSSLの特定のインストールで)自分でそのファイルを調べることができることは知っていますが、OpenSSL自体から信頼できるリストを取得する(インストールに依存しない)方法はありますか?

15

AFAIK OpenSSLはリスト(たとえば、/ etc/ssl/certsなど)を参照して、そこに証明書が存在するかどうかを確認するだけです。

いいえ、OpenSSLはデフォルトでは何も信頼しません。信頼するものを指示する必要があります。 FAQそれをカバーするトピックもあります: なぜ<SSL program>証明書検証エラーで失敗しますか?

この問題は通常、「ローカル発行者証明書を取得できません」または「自己署名証明書」などのようなログメッセージによって示されます。証明書が検証されるとき、ルートCAはOpenSSLによって「信頼」される必要があります。これは通常、CA証明書をディレクトリまたはファイルに配置し、関連プログラムがそれを読み取るように設定する必要があることを意味しますOpenSSLプログラムの「verify」は同様の動作をし、同様のエラーメッセージを発行します。詳細については、verify(1)プログラムのマニュアルページを確認してください。

Googleへの接続をテストして、OpenSSLの動作を確認することもできます。

$ openssl s_client -connect google.com:443
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
...
Start Time: 1407377002
Timeout   : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)

OpenSSLはデフォルトでnottrustGeoTrust Global CAを行うため、上記は失敗します。実際、チェーンには別のトラストポイントがあり、それはGoogle Internet Authority G2です。

OpenSSLに何を信頼するかを伝えることで状況を改善できます。以下では、-CAfileオプションと Google Internet Authority G2

$ openssl s_client -connect google.com:443 -CAfile google-ca.pem 
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com
verify return:1
...
Start Time: 1407377196
Timeout   : 300 (sec)
Verify return code: 0 (ok)

次に、cURLに移動してブラウザのように動作できます download cacert.pemcacert.pemには多くのCAが含まれています。

$ openssl s_client -connect google.com:443 -CAfile cacert.pem 
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com
verify return:1
...
Start Time: 1407377356
Timeout   : 300 (sec)
Verify return code: 0 (ok)

数百のCAと下位CAを備えたブラウザほど悪くはありませんが、近づいています:

$ cat cacert.pem | grep -o "\-\-\-\-\-BEGIN" | wc -l
     153

OpenSSLセキュリティモデルは、ブラウザが認証機関(CA)として知られるトラストアンカーまたはトラストポイントのリストを持ち歩くWebアプリ/ブラウザセキュリティモデルとは対照的です。 :このモデルでは、間違ったCAがサイトの認証を要求する可能性があり、ブラウザーは賢明ではありません。

これは過去に発生したものであり、今後も再び発生する可能性があります。 PKIXの面白いビジネスの歴史については、 CAcertのリスク履歴 を参照してください。たとえば、Google Internet Authority G2およびGeoTrust Global CAcertify Googleのサイト。 Diginotarと呼ばれるオランダのCA がそれらを証明することを主張する理由、または フランスのサイバー防衛庁 がそれらを証明することを主張する理由はありません。

セキュリティモデルに関連する:Webアプリ/ブラウザモデルの別の問題は、アプリに必要な1つのトラストアンカーまたはCAをパッケージ化して使用するcannotです(信頼できる流通チャネルがあると仮定します)。証明書は、CA Zooで山積みされます。他の人はまだあなたのサイトを証明すると主張できます、そして、あなたは他のサイトを証明すると主張できます。

セキュリティモデルは、Webアプリが価値の低いデータに追いやられる理由の1つです。必要なセキュリティコントロールを配置できないため、Webアプリは中価値または高価値のデータを処理すべきではありません。


OpenSSLが信頼するすべての証明書をリストする方法はありますか?

リストにはメンバーが0人なので必要ありません:)


opensslの信頼できる証明書のパスを見つける方法 も参照してください。

15
jww

私は最近これを調査しましたが、OpenSSLに信頼されたセットの証明書をリストする方法を見つけられませんでした。私が見つけた最良の方法は、あなたが指摘しているように、「そのファイル[/ etc/ssl/certs]を自分で(OpenSSLの特定のインストールで)調べる」ことでした。

OpenSSLが参照するディレクトリの検索について、インストールに依存しないようにすることができます。 openssl version -dはパスを表示します。

% openssl version -d
OPENSSLDIR: "/opt/local/etc/openssl"

OpenSSLは、ここでcert.pemという名前のファイルとcerts/というサブディレクトリを探します。そこに見つかった証明書は、openssl s_clientおよびopenssl verifyによって信頼されているものとして扱われます(ソース:記事、OpenSSLが認識する認証局は何ですか?)。

そのため、次のようなことができます。

% find -H `openssl version -d | sed -E 's/OPENSSLDIR: "([^"]*)"/\1/'`/(cert.pem|certs) \ 
-type f -exec cat {} \+  

これにより、OpenSSLが証明書を含むと予想されるファイルの内容全体が出力されます。ファイル全体よりも少なくしたい場合は、catを適切なコマンドに置き換えます。

7
Jim DeLaHunt

Jwwの応答以降、これが何らかの形で変更されたかどうかは疑問です。

送信する場合:$ openssl s_client -connect google.com:443

正常に機能し、合計4つの証明書を取得して、以下を返します。

Start Time: 1484661709
Timeout   : 300 (sec)
Verify return code: 0 (ok)

これは、サーバーが、証明書とともに、完全なチェーンを検証するために必要な中間証明書とルート証明書を送信するようにセットアップする必要があるためだと思いますか?

1
em_bo