Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to open ssl socket using certificate stored in string variables in python

In Python, ssl.wrap_socket can read certificates from files, ssl.wrap_socket require the certificate as a file path.

How can I start an SSL connection using a certificate read from string variables?

My host environment does not allow write to files, and tempfile module is not functional
I'm using Python 2.7.
I store the certificate inside MySQL and read as a string.

Edit: I gave up, this is basically require implement ssl by pure python code, this is beyond my current knowledge.

like image 995
kaala Avatar asked Sep 09 '12 03:09

kaala


People also ask

How do I use SSL certificate in Python?

To install certifi Python on Microsoft Windows: Type cmd in the search bar and hit Enter to open the command line. Type python3 -m pip install certifi in the command line and hit Enter again. This installs certifi for your default Python installation.

What is SSL Create_default_context ()?

Socket creation The helper functions create_default_context() returns a new context with secure default settings. The old wrap_socket() function is deprecated since it is both inefficient and has no support for server name indication (SNI) and hostname matching.

How can I get certificate issuer information in Python?

Use pyOpenSSL. You can also access additional components, e.g. organisation ( subject. O / issuer. O ), organisational unit ( subject.


1 Answers

Looking at the source, ssl.wrap_socket calls directly into the native code (openssl) function SSL_CTX_use_cert_chain_file which requires a path to a file, so what you are trying to do is not possible.

For reference:

In ssl/init.py we see:

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) 

Points us to the SSLSocket constructor (which is in the same file) and we see the following happen:

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

_ssl2 is implemented in C (_ssl2.c)

Looking at the sslwrap function, we see it's creating a new object:

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

Looking at the constructor for that object, we eventually see:

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

That function is defined in openssl, so now we need to switch to that codebase.

In ssl/ssl_rsa.c we eventually find in the function:

BIO_read_filename(in,file)  

If you dig far enough into the BIO code (part of openssl) you'll eventually come to a normal fopen():

fp=fopen(ptr,p); 

So it looks like as it's currently written. It must be in a file openable by C's fopen().

Also, since python's ssl library so quickly jumps into C, I don't see a immediately obvious place to monkeypatch in a workaround either.

like image 152
cnelson Avatar answered Sep 28 '22 00:09

cnelson