2016-09-02 19 views
0

Python 3.4では、証明書がVERIFY_CRL_CHECK_LEAFまたはVERIFY_CRL_CHECK_CHAINに設定されているかどうかを確認するために使用できるverify_flagsです。PythonがSSL/TLS接続のCRLを確認できませんでした

私はテストのための簡単なプログラムを書いた。しかし、私のシステムでは、このスクリプトは完全に有効であってもANY接続を検証することができませんでした。

import ssl 
import socket 

def tlscheck(domain, port): 
     addr = domain 

     ctx = ssl.create_default_context() 
     ctx.options &= ssl.CERT_REQUIRED 
     ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF 

     ctx.check_hostname = True 

     #ctx.load_default_certs() 
     #ctx.set_default_verify_paths() 
     #ctx.load_verify_locations(cafile="/etc/ssl/certs/ca-certificates.crt") 

     sock = ctx.wrap_socket(socket.socket(), server_hostname=addr) 
     sock.connect((addr, port)) 

     import pprint 
     print("TLS Ceritificate:") 
     pprint.pprint(sock.getpeercert()) 
     print("TLS Version:", sock.version()) 
     print("TLS Cipher:", sock.cipher()[0]) 
     exit() 

tlscheck("stackoverflow.com", 443) 

私のコードは常にssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)で終了します。

最初に、証明書データベースが正しく読み込まれていないと思われました。しかし、私はload_default_certs()set_default_verify_paths()load_verify_locations(cafile="/etc/ssl/certs/ca-certificates.crt")を試したが、どれも働いていなかった。

また、ctx.options &= ssl.CERT_REQUIREDは期待どおりに動作し、証明書チェーンが信頼できるかどうかを判断できます。しかし、CRLではなく...私のCAが正しいことも示しています。

「/etc/ssl/certs/ca-certificates.crt」には有効なCAが含まれています。何が問題ですか?

答えて

1

CRLをチェックするには、CRLを手動でダウンロードし、適切な場所に配置して、基礎となるOpenSSLライブラリが見つけられるようにする必要があります。 CRLの自動ダウンロードはなく、CRLを探す場所も直感的ではありません。あなたができること:

  • 証明書からCRL配布ポイントを取得します。
    openssl crl -inform der -in sha2-ha-server-g5.crl > sha2-ha-server-g5.crl.pem
  • がに場所を追加:stackoverflow.comについて1はhttp://crl3.digicert.com/sha2-ha-server-g5.crl
  • これは、次のステップで期待されているものですので、DER形式からPEM形式にそれを変換
  • そこから現在のCRLをダウンロードしていますverify_locations:
    ctx.load_verify_locations(cafile="./sha2-ha-server-g5.crl.pem")

あなたがCRLに対して証明書を検証することができますこの方法。

+0

'load_verify_locations()'が 'cadata'というパラメータを受け入れるので、ファイルをディスクに保存したり、手動で変換したりする必要はありません。バイナリのバイトストリングをDERまたはPEM形式で渡すことができます。 –

+0

ありがとうございました。とにかく、Pythonの 'ssl'モジュールはひどいデザインですが、既知の証明書が取り消されたかどうかを確認するためのAPIは提供していません!つまり、**接続が作成された後は**単にCRLをチェックすることはできませんが、2パスのプロセスが必要です:CRLを取得するための接続を確立し、通信するための別の接続を作成します...とにかく、適切な暗号化が無視された時代... –

+1

@実際には、基礎となるopensslライブラリの設計です。それとは別に、通常、失効を確認するために巨大なCRLファイルを頻繁に読み込むことは望ましくありません。行く方法は代わりにOCSPです。しかし、Pythonは、他のさまざまなプログラミング言語と同様に、OCSPチェックを行う簡単な方法をサポートしていないようです。 –

関連する問題