5

SSL_CERT_FILE環境変数を使用して、Windows(Win-7、OpenSSL 1.0.1c)上のOpenSSL用の単一の信頼できる証明書ファイルを定義するにはどうすればよいですか?

さまざまな調査により、Mozillaの信頼できる証明書の2012年12月バージョンをPEM形式でダウンロードすることになりました。http://curl.haxx.se/docs/caextract.html これには、すべての証明書と、以下に連結されたさまざまな関連情報が含まれています。 1つのファイル。

OpenSSLに依存する他の製品に関して、環境変数SSL_CERT_DIRおよびSSL_CERT_FILEの使用法に関するさまざまな参照を見つけました。たとえば、http://lynx.isc.org/current/README.sslcertsは、これらの両方を設定でき、基盤となるOpenSSLライブラリがそれらを使用することを示しています。ただし、それはOpenSSLツール自体の私の経験ではありません。

SSL_CERT_DIRは問題なく使用できましたが、次のように大変な苦労をしました。www.wellsfargo.com(ランダムに選択)から証明書を(IE 8から)エクスポートし、信頼チェーン内の2つの証明書(両方ともVerisignから)をエクスポートしました。2つのVerisign証明書のそれぞれをディレクトリC:\ ca_stuffに配置し、それぞれについてハッシュを生成しました。

openssl x509 -hash -noout -in "Verisign Intl Server.cer"

これはa302054cを出力し、これからリンクを作成しました。

mklink a302054c.0 "Verisign Intl Server.cer"

他のVerisign証明書についても同様です。次に、ウェルズファーゴの証明書を発行します。別のディレクトリにあり、を使用して正常に検証できました

SSL_CERT_DIR = C:\ca_stuffopensslを設定して「WellsFargoweb.cer」を確認します

ただし、SSL_CERT_FILEを定義した後、cURLサイトからダウンロードされたダウンロードされたcacert.pemをポイントすると、同じコマンドが失敗しました。これは、SSL_CERT_DIRが定義されている場合とされていない場合で行われました。必要なCA証明書がバンドルに含まれていることを確認し、それらのシリアル番号がIEから手動で抽出したものと一致することを確認しました。

各証明書を手動で抽出し、それを指すハッシュリンクを使用して独自のファイルに配置するのは、骨の折れるプロセスのようです。これがUnixの場合、自動化できますが、Windowsでは...1つの大きなCA証明書ファイルをOpenSSLで動作させる方法について何か誤解しているようです。

推奨事項、洞察、支援を事前に感謝します。

4

1 に答える 1

6

OpenSSL用の単一の信頼できる証明書ファイルを定義する方法(あるとしても)

CAFileは、信頼して使用したい自己署名証明書を単純に連結したものです。1つだけを信頼したい場合は、CAファイルに1つだけ存在する必要があります。

私はPEMエンコーディングを好みます。テキストエディタ(-----BEGIN CERTIFICATE-----および-----END CERTIFICATE-----)で検査する方が簡単だからです。たとえば、Startcom(http://www.startssl.com/certs/)のca-bundle.pemは次のとおりです。

Startcomのca-bundle.pemファイルの画像

したがって、作成するにはcat、リダイレクトを使用(またはコピーして貼り付け)するだけです。

# Empty my-ca-file.pem
echo "" > my-ca-file.pem
# Add Startcom certs
cat startcom-ca-bundle.pem >> my-ca-file.pem
# Add others as desired
...

さまざまな調査の結果、Mozillaの信頼できる証明書の12月12日バージョンをPEM形式でダウンロードすることになりました...

さて、それはあなたが使用できるリストの1つです。あなたがMozillaのリストを使うとき、あなたは「私はMozillaが正しいことをすることを信頼している」と言っています。TrustwaveがSSL/TLSトラフィックを傍受しているのを見つけたとき、MozillaはTrustwaveの悪い振る舞いに報いたことを覚えておいてください。Trustwaveは少なくとも2つの包含ポリシーに違反していましたが、Trustwaveが二度とそれを行わないと約束したため、Mozillaはそれらを包含し続けました。詳細については、信頼されたルート証明書からのTrustwave証明書の削除を参照してください。

Mozillaの判断を信用できない場合は、でOpenSSLの組み込みリストを/usr/lib/ssl/certs/ca-certificates.crt使用するか、別のリストを使用するか(ほとんどの主要ベンダーがそれらを持っています)、独自のリストを作成できます。

別のベンダーのリストを使用することは、通常、あなたが知っている悪魔をあなたが知らない悪魔と交換することと同じです。たとえば、Appleには、iOSで検査できる使用リストがあります。利用可能な信頼されたルート証明書のリスト(iOS 7)。しかし、Appleのリストには多くの問題があります:http://seclists.org/fulldisclosure/2013/Sep/186およびhttp://seclists.org/fulldisclosure/2013/Sep/184

独自のリストを作成するか、証明書を固定することをお勧めします。証明書または公開鍵を固定すると、Trustwaveが実行したことを実行できるSSL/TLSのシステム上の問題が解消されるため優れています。詳細については、OWASPの証明書と公開鍵ピンニングを参照してください。


... Windows(Win-7、OpenSSL 1.0.1c)でSSL_CERT_FILE環境変数を使用していますか?

私は環境変数を使用していないので、環境変数を介してそれを行う方法がわかりません。ただし、Linux / Unix / OSX / Windowsの間に違いはないはずです(おそらく、長いファイル名とスペースの処理を除いて)。

OpenSSLソースを見ると、次のようになっていますcryptlib.h

#define X509_CERT_FILE_EVP       "SSL_CERT_FILE"

x509_def.c使用X509_CERT_FILE_EVP

const char *X509_get_default_cert_file_env(void)
    { return(X509_CERT_FILE_EVP); }

X509_get_default_cert_file_envで使用さby_file.cby_file_ctrlます:

...
switch (cmd)
{
    case X509_L_FILE_LOAD:
        if (argl == X509_FILETYPE_DEFAULT)
        {
            file = (char *)getenv(X509_get_default_cert_file_env());
            if (file)
                ok = (X509_load_cert_crl_file(ctx,file,
                                              X509_FILETYPE_PEM) != 0);

            else
                ok = (X509_load_cert_crl_file(ctx,X509_get_default_cert_file(),
                                              X509_FILETYPE_PEM) != 0);

            if (!ok)
            {
                X509err(X509_F_BY_FILE_CTRL,X509_R_LOADING_DEFAULTS);
            }
        }
        else
        {
            if(argl == X509_FILETYPE_PEM)
                ok = (X509_load_cert_crl_file(ctx,argp,
                                              X509_FILETYPE_PEM) != 0);
            else
                ok = (X509_load_cert_file(ctx,argp,(int)argl) != 0);
        }
        break;
}
return(ok);

したがって、を使用する場合は、PEM形式の連結が推奨されます(必須ですか?)SSL_CERT_FILE

最後に、がSSL_CERT_FILE構成ファイルの設定によって上書きされていないことを確認してください。詳細については、 OpenSSL config(5)を参照してください。


各証明書を手動で抽出し、それを指すハッシュリンクを使用して独自のファイルに配置するのは、骨の折れるプロセスのようです。

SSL_CERT_FILE、、、-CAfileまたはを使用するときに再ハッシュする必要はないと思いますSSL_CTX_load_verify_locations

-CAfileまたはを使用するときに再ハッシュしたことはなくSSL_CTX_load_verify_locations、すべてが正常に機能しています。物事が壊れた場合、それは通常、(1)ルート証明書が存在しないか信頼されていないためです。または(2)中間証明書が存在しない。

上記の項目(2)の場合、チェーンを構築するために必要なすべての証明書をサーバーが送信する必要があります。そうしないと、クライアントは欠落している中間証明書を見つけるためにどこを探すべきかわかりません。「どのディレクトリ」問題と呼ばれるPKIのよく知られた問題です(クライアントは、欠落している証明書を検索するX500ディレクトリを認識していません)。


関連して、OpenSSLでそれらを使用する方法は次のとおりs_clientです。pagepeeker.comはStartComを使用しているため、これは実際に機能し-CAfileます。オプションを省略すると失敗します。

$ echo "GET / HTTP\1.1" | openssl s_client -connect api.pagepeeker.com:443 -CAfile startcom-ca-bundle.pem
CONNECTED(00000003)
depth=2 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN = StartCom Certification Authority
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
 0 s:/description=8CTO6gSuxeRRsIXl/C=RO/CN=api.pagepeeker.com/emailAddress=alexandru.florescu@gmail.com
   i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
 1 s:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
   i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
 2 s:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
   i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGZTCCBU2gAwIBAgIDCJkoMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ
TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
...

そして、Cプログラミングを行うときの関連コード。これは、SSL / TLS接続をセットアップするために使用するコードの一部です(公開鍵ピンニングに加えて)。

int ret = 0;
unsigned long ssl_err = 0;
SSL_CTX* ctx = NULL;

do
{
    ret = SSL_library_init();
    ssl_err = ERR_get_error();
    if(!(1 == ret))
    {
        display_error("SSL_library_init", ssl_err);
        break; /* failed */
    }

    /* SSLv23_method() is 'everything' */
    const SSL_METHOD* method = SSLv23_method();
    ssl_err = ERR_get_error();
    if(!(NULL != method))
    {
        display_error("SSLv23_method", ssl_err);
        break; /* failed */
    }

    /* http://www.openssl.org/docs/ssl/ctx_new.html */
    ctx = SSL_CTX_new(method);
    ssl_err = ERR_get_error();
    if(!(ctx != NULL))
    {
        display_error("SSL_CTX_new", ssl_err);
        break; /* failed */
    }

    /* Enable standard certificate validation and our callback */
    /* https://www.openssl.org/docs/ssl/ctx_set_verify.html */
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, my_verify_cb);
    /* Cannot fail ??? */

    /* Remove most egregious */
    const long flags = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
    long old_opts = SSL_CTX_set_options(ctx, flags);
    UNUSED(old_opts);

    /* http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html */
    ret = SSL_CTX_load_verify_locations(ctx, "startcom-ca-bundle.pem", NULL);
    ssl_err = ERR_get_error();
    if(!(1 == ret))
        display_warning("SSL_CTX_load_verify_locations", ssl_err);

} while(0);

// Use context
return ctx;

SSL_CTX_load_verify_locations失敗しても大丈夫です。それはあなたが何も信用しないことを意味するので、あなたは閉じたり閉じたりすることに失敗します。

于 2013-10-02T19:24:41.677 に答える