3

I am using the python request module to makes a POST call:

import requests
response = requests.post( foo_url, 
                          json={"foo":"bar"}, 
                          headers=foo_headers,
                          verify='/path/to/cert' )

This works fine. Though is it possible to use the value of the certificate directly instead of the path to the file that contains the certificate?

1 Answer 1

8

TLDR: The answer is definitively "no, the cert must be in a file on disk." And the reason why is because OpenSSL is awful.

requests is based on urllib3, which is based on ssl. requests takes your top-level cert parameter and splits it up into parameters named cert_file and key_file, which get passed to urllib3. urllib3 passes them on, untouched, to ssl. And ssl expects them to be filenames.

The specific culprit at the bottom of the Python stack is SSLContext.load_cert_chain from the ssl module. It depends on _SSLContext, which is written in C. The C code for _SSLContext.load_cert_chain is here. And you can see, it really truly 100% needs a filesystem path! Ugh!

The culprit at the bottom of the C stack is OpenSSL's SSL_CTX_use_certificate_chain_file, which has this signature:

int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);

There are ways of building a cert chain in OpenSSL that don't involve "just open a file and read it in," but they're vastly more complicated, which I guess is why Python ssl doesn't use them... and that explains why urllib3 doesn't use them, and that explains why requests doesn't use them.

Sign up to request clarification or add additional context in comments.

1 Comment

" And the reason why is because OpenSSL is awful." - Late to the party, but ... the fault is not OpenSSL. It provides with SSL_CTX_use_certificate a way to load a certificate from a certificate object. This can be created from a PEM string by combining BIO_s_mem, BIO_write and PEM_read_bio_X509. And similar to the private key. May sound complex but its actually only a few lines of code. Did this ages ago for Perl IO::Socket::SSL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.