私はcomp.lang.pythonにこの問題に関するアイデアがあるかどうかを知りました。私はメーリングリストで何の応答も受けなかったので、私はここに到達することに決めました。Python M2Crypto.SSL.Checker.NoCertificate例外
私はM2Cryptoモジュールで変わった奇妙なことがあります。誰かが私を正しい方向に向けることができれば幸いです。私は、同僚と協力して、stdinで取得したIPv4アドレスのリストでSSL証明書をチェックするための内部ツールを開発しています。
私たちはM2Cryptoを使用して証明書の検証を支援しています。 1つのIPv4アドレスをチェックするだけであれば、正しい証明書を提供することができ、SSL証明書に含まれている情報の検証チェックを行うことができます。
しかし、複数のIPv4アドレスをチェックしようとすると、「M2Crypto.SSL.Checker.NoCertificate」が受信されます。私たちはこれを受けなければならない場合があります。しかし、第2または第3のIPv4アドレスが何であるかに関係なく(最初のものとして良好にテストされたとしても)、失敗します。
コンテキストの作成:
global context
context = M2Crypto.SSL.Context()
if sys.platform.startswith('linux'):
context.load_verify_info(capath="/etc/ssl/certs/")
elif sys.platform.startswith('darwin'):
context.load_verify_info(cafile=certfile)
else:
print "Unknown platform, bail!"
exit(1)
context.set_allow_unknown_ca(True)
context.set_verify(M2Crypto.SSL.verify_none,9)
ソケットの作成:コードの
conn = M2Crypto.SSL.Connection(context)
socket.setdefaulttimeout(2.0)
conn.set_socket_read_timeout(M2Crypto.SSL.timeout(sec=2))
conn.set_socket_write_timeout(M2Crypto.SSL.timeout(sec=2))
try:
conn.connect((ip,443))
# we can the catch the exception here, but it shouldn't be failing
上記2つの部分は、独自の機能に存在します。コンテキストはすべての接続でグローバルに使用されるため、コンテキストの作成は1回だけ呼び出されます。私は最初、これが問題だったかもしれないと思って、変更なしで各ループのコンテキストを作成することを試みました。
後者のブロックは、アドレスの配列上でループの一部として呼び出されます。 IPは発信者から渡されます。
-Tim
それは別のシステム上でホストされているWebサーバから証明書を引っ張っています。/etc/ssl/certsにある '.pem'ファイルを使用して、どのCAが信頼できるかを判断し、それらに対して検証します。 Debian由来のディストリビューションでは、 '/ etc/ssl/certs'に複数の.pemファイルがあります。 同じ問題は、Mozillaの信頼できるCAから生成された単一のファイルを使用するMac OS Xシステムでも発生します。 – theckman
Python sslライブラリはOpenSSLの上に構築されています。手動で証明書を検証して、証明書ストアが正しく構成されていることを確認してください。/etc/ssl/certsを正しく動作させることは難しいことです。 「OpenSSL検証」を使用して証明書を検証できます。 http://www.madboa.com/geek/openssl/#verify-standard – user590028
証明書ストアはここでは問題になりません。あるIPをチェックしているとき、それは正しく検証されます。それが接続し、検証チェックが機能します。後続のホストから証明書を取得するために接続しようとすると、NoCertificate例外が発生します。接続中にサーバーから証明書を受け取っていないと信じられます。 OpenSSLは、ストアが有効であることも確認します。トレースバック:http://paste.pocoo.org/show/575594/ – theckman