web-dev-qa-db-ja.com

openssl s_clientが一致しないCAfileに対して証明書を検証するのはなぜですか?

次のようにopenssl s_clientで証明書検証エラーを生成しようとしています:

$ openssl s_client -crlf -verify 9 \
  -CAfile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.pem \
  -starttls smtp -Host mx-ha03.web.de -port 25

Web.deサーバーの証明書はTURKTRUSTではなくDeutsche Telekom CAによって認証されているため、上記のコマンドは失敗するはずです。

しかし、それは報告します:

    Verify return code: 0 (ok)

どうして?

私はアナログのgnutls-cliコマンドが期待通りに失敗することを意味します:

$ { echo -e 'ehlo example.org\nstarttls' ; sleep 1 } | \
   gnutls-cli --starttls --crlf \
   --x509cafile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.pem \
   --port 25 mx-ha03.web.de
[..]
*** Verifying server certificate failed...

クロスチェックを実行します。つまり、代わりに--x509cafile /etc/ssl/certs/ca-certificates.crtをgnutls-cliで使用します。

[..]
- The hostname in the certificate matches 'mx-ha03.web.de'.
- Peer's certificate is trusted

(これも予想されます)

Cas-certificates.crtのopenssl s_clientプリント:

    Verify return code: 0 (ok)

TURKTRUSTと同じ結果...

最初に、-CApathのデフォルト設定(つまり、/ etc/ssl/certs)を使用してopensslを疑っていましたが、straceプロセスを実行すると、引数のopen syscallだけが表示されます/ CAfile

(Ubuntu 10.04サーバーで行われたすべてのテスト)

pdate: TURKTRUST証明書をFedora 20システムにコピーし、最初のopensslステートメントを実行しました-ここで、異なる結果が得られます:

Verify return code: 19 (self signed certificate in certificate chain)
10
maxschlepzig

Ubuntu 10.04の_openssl s_client_は、_-CApath_ and _-CAfile_が指定されている場合でも、システムにインストールされた証明書のデフォルトの場所をクエリすることがわかります。

_8466  open("/usr/lib/ssl/certs/4e18c148.0", O_RDONLY) = 4
_

(strace出力)

どこ:

_$ ls -l /usr/lib/ssl/certs/4e18c148.0
lrwxrwxrwx 1 root root 30 2014-04-11 21:50 /usr/lib/ssl/certs/4e18c148.0 ->
    Deutsche_Telekom_Root_CA_2.pem
_

ディレクトリ_/usr/lib/ssl/certs_は、Ubuntu 10.04の_/etc/ssl/certs_へのシンボリックリンクであるため、「/ etc/ssl」をgreppingすると、straceログのopen行が選択されません...

ソース

Openssl-0.9.8kを見ると、この問題の原因は_crypto/x509/by_dir.c_、dir_ctrl()にあります。

_dir=(char *)Getenv(X509_get_default_cert_dir_env());
if (dir)
    ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
else
    ret=add_cert_dir(ld,X509_get_default_cert_dir(),
                     X509_FILETYPE_PEM);
_

ここで、_X509_get_default_cert_dir_は_/usr/lib/ssl/certs_を返し、_X509_get_default_cert_dir_env_は_SSL_CERT_DIR_を返します。

Workaround

したがって、Ubuntu 10.04/openssl 0.9.8kで次の回避策を使用して、期待される動作を得ることができます。

_$ SSL_CERT_DIR="" openssl s_client -crlf -verify 9 \
    -CAfile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.crt \
    -starttls smtp -Host mx-ha03.web.de -port 25
_

そして検証に失敗します:

_Verify return code: 19 (self signed certificate in certificate chain)
_

現在の状況

これはUbuntuの問題です。たとえば、Fedora 20のopenssl 1.0.1eまたはFedora 29のopenssl 1.1.1では、問題を再現できないため、この回避策は必要ありません。つまり、_-CAfile_や_-CApath_などのオプションを指定すると、デフォルトの証明書システムディレクトリがFedoraシステムのディレクトリ検索リストに追加されません。

Openssl 1.0.2gがインストールされたUbuntu 16では、問題はまだ存在しています。

それはまた、openssl-1.0.2k-16を備えたCentOS 7にも存在します-残念ながら、上記の回避策はそこでは役に立たず、gnutls-3.3.29-8は不明/予期しないTLSパケットタイプが原因で失敗します。

10
maxschlepzig