証明書のチェーンを引っ張ります

昨日、どうやら、https安息日があり、クライアントが一括で証明書を送信し始めたようです。 もちろん、ルートも中間も添付されておらず、それらを送信するリクエストは、一方通行の道路で金髪の対向車と同じ戸惑いを引き起こしました。



4番目の証明書では、それらを手動でプルするのが面倒でした(そして私は本質的に怠け者です)ので、パブリッシャーをアンフックし、nginxをフィードするためのチェーンファイルを形成する「スクーター」をスケッチしました。

確かに完璧ではなく、12個の証明書でのみテストされていますが、豊富な証明書でテストされています。



x.509デバイス(ハブを含む)について多くのことが言われているので、繰り返しません。



以下は、理論からの小さな絞りと混合されたチェーンを取得するためのステップバイステップの指示です。



次のすべてが適用されます。



非表示のテキスト
$ uname -or FreeBSD 10.3-STABLE $ openssl version OpenSSL 1.0.2h 3 May 2016 $ `echo $SHELL` --version tcsh 6.18.01 (Astron) 2012-02-14 (x86_64-amd-FreeBSD) options wide,nls,dl,al,kan,sm,rh,color,filec $ /usr/local/bin/bash --version GNU bash, version 4.3.25(1)-release (amd64-portbld-freebsd10.0)
      
      







したがって、サイトのPEM証明書があるとします。 例として、ya.ru証明書(pingだけでなく)を使用します。



 $ echo | openssl s_client -connect ya.ru:443 | openssl x509 -certopt ca_default -out ya.pem -outform PEM
      
      





エンコードされたリクエスト自体、バージョン、署名などに加えて 多くの拡張機能があります。 そのうちの1つが機関情報アクセスです。



 $ openssl x509 -in ./ya.pem -noout -text | grep 'Authority Information Access' -A 2 Authority Information Access: OCSP - URI:http://yandex.ocsp-responder.com CA Issuers - URI:http://repository.certum.pl/ycasha2.cer
      
      





CA Issuersパラメーターには、チェーン内の次の証明書が含まれます。 原則として、この証明書はPEMまたはDER (この場合のように)形式です。



 $ fetch http://repository.certum.pl/ycasha2.cer
      
      





実際、 PEM形式はDERbase64表現にすぎずbase64 ./ycasha2.cer ./ycasha2.pemを作成し、エンコードされたテキスト「----- BEGIN CERTIFICATE -----」、「- ---証明書の終了----- " 。 ただし、 opensslを使用してこの変換を行う方がより論理的で簡単です。



 $ openssl x509 -inform der -in ./ycasha2.cer -out ./ycasha2.pem
      
      





さらに進んで、チェーン内の次の証明書を確認します。



 $ openssl x509 -in ./ycasha2.pem -noout -text | grep 'Authority Information Access' -A 2 Authority Information Access: OCSP - URI:http://subca.ocsp-certum.com CA Issuers - URI:http://repository.certum.pl/ctnca.cer
      
      





 $ fetch http://repository.certum.pl/ctnca.cer
      
      





変換します:



 $ openssl x509 -inform der -in ./ctnca.cer -out ./ctnca.pem
      
      





この証明書(ルートであるため)にはAuthority Information Access拡張がありません。



 $ openssl x509 -in ./ctnca.pem -noout -text | grep 'X509v3 extensions' -A 6 X509v3 extensions: X509v3 Basic Constraints: critical CA:TRUE X509v3 Subject Key Identifier: 08:76:CD:CB:07:FF:24:F6:C5:CD:ED:BB:90:BC:E2:84:37:46:75:F7 X509v3 Key Usage: critical Certificate Sign, CRL Sign
      
      





つまり、その上でチェーンを引っ張り終えます。 これらをすべてチェーンファイルに収集することは残ります。



 $ cat ya.pem ycasha2.pem ctnca.pem > chain0.pem
      
      





秘密鍵がある場合は賭けることができるように見えますが、私はいくつかのニュアンスについて説明します。

Yandexに証明書をインストールしたら、確認してください:



 $ echo | openssl s_client -connect ya.ru:443 | grep Verify Verify return code: 0 (ok)
      
      





すべては問題ありませんが、これはデフォルトパス-CApath、 opensslの -CAfileで必要な証明書ハッシュが見つかったためです。 それらを変更すると、デフォルトでは存在せず、単に古くなっているか、デフォルトのCApathが「くっつかない」バグのあるopensslバージョンがあります(1.0.1sから1.0.1eを間違えない場合)。次の形式で問題を解決します。



 $ echo | openssl s_client -connect ya.ru:443 -CApath . | grep Verify Verify return code: 20 (unable to get local issuer certificate)
      
      





ルート証明書に署名する人がいないことは明らかなので、システムがそれを信頼できるようにする必要があります。 これを行うには、ストレージの一部を作成できます。 必要な証明書を検索するとき、 opensslは証明書のハッシュによってそれを見つけようとします。



 $ openssl x509 -noout -hash -in ./ctnca.pem 48bec511
      
      





 $ ln -s `pwd`/ctnca.pem `pwd`/48bec511.0
      
      





そして今、私たちのシステムはya.ruを信頼しています:



 $ echo | openssl s_client -connect ya.ru:443 -CApath . | grep Verify DONE Verify return code: 0 (ok)
      
      





もちろん、怠automatedはあなたの手で毎回行われます。



$ cat ./issuers.sh
 #!/usr/local/bin/bash cmd_grep='/usr/bin/grep ' cmd_openssl='/usr/bin/openssl ' cmd_cut='/usr/bin/cut ' cmd_fetch='/usr/bin/fetch ' tmp_der='tmp.der' tmp_cert='tmp.cert' #------------------------------------------------------------------------------ usage () { #printf "function ${FUNCNAME}\n" printf "Error!\nUsage:\t\"$0 certificate.pem\"\n" exit 1 } #------------------------------------------------------------------------------ if [ "X$1" = "X" ] then usage else cp $1 $tmp_cert chain_cert="chain.pem" fi i=0 while : do issuer=`$cmd_openssl x509 -in $tmp_cert -noout -text | $cmd_grep 'CA Issuers' | $cmd_cut -d : -f 2,3` if [ "X$issuer" != "X" ] then echo $i echo $issuer tmp_pem=$1$i.pem $cmd_fetch $issuer --output=$tmp_der is_pem=`$cmd_grep -c CERTIFICATE $tmp_der` printf "IS PEM:\t[$is_pem]\n" #echo "$tmp_der -> $tmp_pem" if [ $is_pem -ne 0 ] then echo "PEM($tmp_der) -> PEM($tmp_pem)" cp -f $tmp_der $tmp_pem else echo "DER($tmp_der) -> PEM($tmp_pem)" echo "$cmd_openssl x509 -inform der -in $tmp_der -out $tmp_pem" $cmd_openssl x509 -inform der -in $tmp_der -out $tmp_pem fi cp $tmp_pem $tmp_cert let "i+=1" #sleep 2 else break fi done if [ $i -gt 0 ] then echo "cat ./$1* > $chain_cert" cat ./$1* > $chain_cert printf "Certificate chain:\n" ls -l $chain_cert #ls | grep -Ev ^ya.pem$ | xargs rm fi
      
      







私たちは実行します:



 $ ./issuers.sh ./ya.pem 0 http://repository.certum.pl/ycasha2.cer tmp.der 100% of 1196 B 16 MBps 00m00s IS PEM: [0] DER(tmp.der) -> PEM(./ya.pem0.pem) /usr/bin/openssl x509 -inform der -in tmp.der -out ./ya.pem0.pem 1 http://repository.certum.pl/ctnca.cer tmp.der 100% of 959 B 13 MBps 00m00s IS PEM: [0] DER(tmp.der) -> PEM(./ya.pem1.pem) /usr/bin/openssl x509 -inform der -in tmp.der -out ./ya.pem1.pem cat ././ya.pem* > chain.pem Certificate chain: -rw-r--r-- 1 root wheel 5842 Jun 30 15:46 chain.pem
      
      





測定値を確認します。



 $ md5 chain0.pem ; md5 chain.pem MD5 (chain0.pem) = 6d32b0798d48d14764cd26cc4f730444 MD5 (chain.pem) = 6d32b0798d48d14764cd26cc4f730444
      
      





このようなもの...もちろん、スクリプトは普遍的ではなく、すべてが壮大な野ra人の前夜に急いでいます。 コメント/提案を歓迎しますが、私はほとんど答えることができません-私たちはここ(ベラルーシ)で宗派を持っています。



All Articles