web-dev-qa-db-ja.com

OpenSSLが証明書フォルダーでCAを取得しない

HTTPSサーバーに接続できないcurlで問題が発生しています:

$ curl https://the-problem-site.com    (not the real URL!)   
curl: (35) error:14077458:SSL routines:SSL23_GET_SERVER_HELLO:reason(1112)

1112はSSL_R_TLSV1_UNRECOGNIZED_NAMEssl.hです。

代わりにopenssl s_client -connect the-problem-site.com:443を試してみると、

CONNECTED(00000003)   
depth=1 /C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA   
verify error:num=20:unable to get local issuer certificate   
verify return:0   

Certificate chain   
0 s:/serialNumber=xx/C=xx/ST=xx/L=xxxx/O=xx/OU=xx/CN=the-problem-site.com   
i:/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA   
1 s:/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA   
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA   

つまり、問題は/C=US/O=GeoTrust Inc./CN=GeoTrust Global CAを信頼していないということです。ただし、その証明書はインストールされています:/etc/ssl/certs/GeoTrust_Global_CA.pemであり、代わりに実行する場合

openssl s_client -problem-site.com:443 -CAfile /etc/ssl/certs/GeoTrust_Global_CA.pemに接続します

その後、すべてが動作します。証明書は、ハッシュ名付きファイルb0f3e76e.0としても存在し、ca-certificates.crtにあります。しかし、私が見る限り、curlもopensslも証明書を読み取ろうとしません。私がstraceなら、/usr/lib/ssl/certsまたは/etc/ssl/certsからの読み取りはまったく行われず、エラーが発生することもありません。ただし、openssl.cnfは読み取ります。 update-ca-certificatesを実行しました。

これは、openssl 0.9.8kを備えたUbuntu 10.04です。 2つの別個のインストールで問題を再現できます(ただし、一方が他方のクローンである可能性はあります)。 CentSSL VMでopenssl 0.9.8eを使用して同じテストを実行すると、正常に動作し、straceの証明書ファイルを読み取ることができます。 Ubuntu stracesの同じポイントには、同等のファイルアクセスはありません。 openssl.cnfファイルをCentOS VMからUbuntuマシンにコピーしても違いはありません。環境またはこれを引き起こしている可能性のある.rcファイルには明らかなものはありません。

私が間違っていることは何ですか?これが機能する必要がありますか?つまり、opensslとcurlはインストールされたCAをコマンドラインから自動的に取得する必要がありますか?これはどのように構成されていますか?ありがとう!


別のデータポイント:13サーバーのクリーンインストールでは、curlは証明書ファイルを取得して正常に動作します。 openssl s_clientはまだありません。どうしてですか?

9
Rup

システムにはいくつかの暗号化ライブラリがあります。

  • OpenSSL(ゴールドスタンダード、やや問題のある条項(GPLの互換性を妨げるが「悪い」ものは何もない)を含むBSDスタイル(非常に無料)のライセンスで、GNUの世界での採用を制限する)
  • GnuTLS(FSFからの代替品。LGPLv2ライセンス(ただし、メンテナンスされていない)とLGPLv3ライセンス(したがってGPLv2のみのプログラムとは互換性がない)の2つのフレーバーがあります。セキュリティも強化されます)
  • NSS(Netscape/Mozillaのライブラリ、外部ではめったに使用されず、新しい標準の採用が遅い)
  • polarSSL、MatrixSSL、NaCl/Saltなどのマイナーなもの

もちろん、それらはすべて類似点と相違点を持っています。それらを使用するソフトウェア(暗号化目的、またはSSL/TLSの使用)は、これらのライブラリの複数の使用をサポートする場合があります(たとえば、Lynx、Webブラウザーは通常OpenSSLにリンクされますが、GnuTLSもサポートします(あまり良くありません) GNU人をなだめるために)。

cURLは、3つの主要な暗号ライブラリのいずれかを使用することをサポートするプロジェクトの1つでもあります。これは主に、cURLがプライマリであり、http、ftpなどの接続を使用して物をダウンロード(またはアップロード)したいときに、他のプログラムが使用することを目的としたライブラリであるためです。 curlコマンドラインツールは、これらのバリアントのいずれかから取得できます。

さて、新しくインストールされていないシステムであなたが見ている問題は、次のことだと確信しています。

OpenSSLとGnuTLSはどちらも/etc/ssl/certs/<hash>.<number>スタイルのCAディレクトリの使用をサポートしています。ただし、OpenSSLバージョン0.xとGnuTLSは、OpenSSLバージョン1.xが使用するものとは異なるアルゴリズムを使用して、前述のhashを計算します。 (どちらもシステム上で共存できます。異なる証明書が同じhashを持っている場合、異なるnumberを使用します。しかし、何らかの理由でDebian/Ubuntuのca-certificatesパッケージはこれを行っていないようです。さらに、GnuTLSの一部のバージョンはディレクトリの使用をサポートしていませんでしたが、ファイル/etc/ssl/certs/ca-certificates.crt(通常はca-certificatesパッケージのメンテナースクリプトによっても管理されます) 、ただし逸脱する可能性があります);古いバージョンを使用しているようですので、これがヒットするかもしれません。

openssl s_clientは、デフォルトでは(つまり、-CApathまたは-CAfileオプションなしで)証明書をanywhereに見えません。

アップグレードされたインストールからのcurlは、おそらく、新規インストールからのcurlとは異なる暗号ライブラリを使用します。

openssl s_client -CAfile /etc/ssl/certs/ca-certificates.crt -connect the-problem-site.com:443に加えてopenssl s_client -CApath /etc/ssl/certs -connect the-problem-site.com:443を試して、古いGnuTLSバージョンの動作を模倣してください。

システムにOpenSSL 1.x anywhereがあるかどうかを再確認し(UbuntuはLTSバージョンにもメジャーアップデートを忍び込ませることで知られています)、ある場合はファイルのハッシュを確認します。

openssl x509 -noout -hash -in /etc/ssl/certs/GeoTrust_Global_CA.pem
openssl x509 -noout -subject_hash_old -in /etc/ssl/certs/GeoTrust_Global_CA.pem
openssl x509 -noout -subject_hash -in /etc/ssl/certs/GeoTrust_Global_CA.pem

通常、2番目と3番目のコマンドは失敗するか(OpenSSL 0.x)、1番目と3番目のコマンドは同じハッシュを表示しますが、2番目のコマンドは異なるハッシュを表示します(OpenSSL 1.x)。 GnuTLSは2番目のコマンドの出力を使用します(OpenSSL 1.xがインストールされている場合)。 OpenSSL 0.xがインストールされている場合、それは同じハッシュです。このようなシンボリックリンクは手動で作成できます。

デバッグフィードバックを提供したら、この投稿を更新できます。

4
mirabilos