2012-09-09 10 views
20

Pythonでは、ssl.wrap_socketはファイルから証明書を読み取ることができますが、ssl.wrap_socketは証明書をファイルパスとして要求します。Pythonの文字列変数に格納された証明書を使用してSSLソケットを開く方法

文字列変数から読み取った証明書を使用してSSL接続を開始するにはどうすればよいですか?

私のホスト環境はファイルへの書き込みを許可せず、tempfileモジュールは機能しません。
私はPython 2.7を使用しています。
私は証明書をMySQLの中に保存し、文字列として読みます。

編集: 私はこれを諦めました。これは基本的に純粋なPythonコードで実装されたsslですが、これは私の現在の知識を超えています。

+1

あなたのホスト環境では、どうにかしてSSL証明書を保存することができますか?たとえ彼らが自分自身を供給したいとしても。 – EJP

+0

私はmysqlに証明書データを保存しました。私のコードは、データを取得するために別のホストにsslソケットが必要です。私はデータベースから証明書を読んでいますが、SSLラップの作成方法はわかりません。 – kaala

+0

ソースを見ると、ssl.wrap_socketがファイルへのパスを必要とするネイティブコード(openssl)関数SSL_CTX_use_cert_chain_fileに直接呼び出されるため、何をしようとしているのかはわかりません。 これを機能させるには、証明書をファイルに書き込む必要があります。 – cnelson

答えて

23

ソースを見ると、ssl.wrap_socketはファイルへのパスを必要とするネイティブコード(openssl)関数SSL_CTX_use_cert_chain_fileを直接呼び出すので、何をしようとしているのかはわかりません。私たちが見るの.py

SSLで

/のinit:参考

def wrap_socket(sock, keyfile=None, certfile=None, 
       server_side=False, cert_reqs=CERT_NONE, 
       ssl_version=PROTOCOL_SSLv23, ca_certs=None, 
       do_handshake_on_connect=True): 

    return SSLSocket(sock, keyfile=keyfile, certfile=certfile, 
        server_side=server_side, cert_reqs=cert_reqs, 
        ssl_version=ssl_version, ca_certs=ca_certs, 
        do_handshake_on_connect=do_handshake_on_connect) 

ポイント私たちを(同じファイル内にある)のSSLSocketのコンストラクタに、我々は以下を参照してくださいが行われます。

self._sslobj = _ssl2.sslwrap(self._sock, server_side, 
            keyfile, certfile, 
            cert_reqs, ssl_version, ca_certs) 

_ssl2はCで実装されている(_ssl2.c)

sslwrap機能を見ると、我々はそれが新しいオブジェクトを作成しています参照してください。

return (PyObject *) newPySSLObject(Sock, key_file, cert_file, 
             server_side, verification_mode, 
             protocol, cacerts_file); 

そのオブジェクトのコンストラクタを見ると、我々は最終的には以下を参照してください関数はopensslの中で定義されて

  ret = SSL_CTX_use_certificate_chain_file(self->ctx, 
                cert_file); 

、そうは今度はそのコードベースに切り替える必要があります。我々は最終的には機能で見つけるSSL/ssl_rsa.cで

BIO_read_filename(in,file) 

あなたはBIOコード(opensslのの一部)に十分掘る場合は、最終的には正常なのfopen(に来ます):

fp=fopen(ptr,p); 

したがって、現在書かれているようです。これは、Cのfopen()によってオープン可能なファイル内になければなりません。

また、PythonのsslライブラリがすぐにC言語に飛ぶので、回避策でもすぐに分かりやすい場所が表示されません。 SSLモジュールのソースは、あなたが望むものを確認したものの

+1

汚れたハックをかなり望んでいます... – domenukk

-1

ファイルのような文字列をStringIOで扱うことができます。

+1

StringIO is文字列がファイルパスとして必要なssl.wrap_socketでは動作しません。 例外: トレースバック(最後の最新の呼び出し):: ファイル「/data1/www/htdocs/705/pty/1/pty.py 例外TypeErrorが トレースバック( '文字列またはなし、ではないインスタンスでなければなりません') "、行23、接続中 self.push.connect(self.gateway) ファイル" /usr/local/sae/python/lib/python2.7/ssl.py "、行331、接続中 self._real_connect (addr、False) ファイル "/usr/local/sae/python/lib/python2.7/ssl.py"、行314、_real_connect self.ca_certs、self.ciphers) TypeError:文字列かNone 、インスタンスではありません – kaala

+1

ファイルパスではなくファイルオブジェクトを受け取ります –

5

クイックルックは、APIによってサポートされていません。 http://code.google.com/codesearch#2T6lfGELm_A/trunk/Modules/_ssl.c&q=sslwrap&type=cs

それは不可能であると言うことではない、あなたが名前付きパイプを作成することができ、パイソンの一端を供給し、ファイル名をsslモジュールに渡します。

メモリからmkstemp() 'dファイルに証明書をダンプする方が簡単です。

FUSEボリュームをマウントしてコールバックを傍受することもできます。

最後に、実行時にctypesを使用してsslコンテキストをハックし、Cレシピに続いてバッファからcert/ketをロードしますRead certificate files from memory instead of a file using OpenSSLこれまでに行われたようなことは、あまりにも心配していません。

これは、あなたが外出しようとしているようです。アプリエンジンの「刑務所」はおそらく不可能なのでしょうか?

あなたがsslの実装を気にかけていない場合は、M2Crypto、TLS Lite、pyOpenSSLなどを使用できます。以前は純粋なPythonですが、メモリ内の証明書/キーを使用するためには、間違いなくハックすることができます。

+0

名前付きパイプは基本的には一時ファイルですね。 しかし、非常に良いアイデア。 私はM2Cryptoなどを使って同様の方法が最良の方法だと思います。名前付きパイプを作成 – domenukk

+0

はいさえのctypes牛車を使ってssl._ssl._SSLContext' 'の' load_verify_locations'にフックした後のファイルシステム –

+0

上の書き込み権限が必要で、すべてその関数は、取得 'ssl.SSLContext'オブジェクトであり、それがどのように私には謎です基になる 'PySSLContext'親クラスに割り当てられた正しいメモリ位置にアクセスするためにそれを使用して、' SL_CTX * '型の' ctx'メンバへのポインタを取得することができます。誰かが(リテラル)ポインタを持っていますか? – josch

関連する問題