4

I am trying to connect to a corporate intranet HTTPS server, which uses an in-house CA, from within Python/requests running on a Linux machine. I have a .pem file that contains our certificate (4096 bit RSA, CSSM_KEYUSE_VERIFY, CA = true).

I put this into a subfolder of /usr/share/ca-certificates and used sudo dpkg-reconfigure ca-certificates in order to integrate it in the system.

In the requests documentation, I found:

You can pass verify the path to a CA_BUNDLE file or directory with certificates of trusted CAs … If verify is set to a path to a directory, the directory must have been processed using the c_rehash utility supplied with OpenSSL.

I believe (but am not sure) that /etc/ssl/certs fulfills this condition.

Now, I tried requests in various ways:

requests.get(download_url)
# throws requests.exceptions.SSLError: ("bad handshake: Error([
#   ('SSL routines', 'ssl3_get_server_certificate',
#    'certificate verify failed')],)",)

requests.get(download_url, verify = False)
# works, but is obviously bad (and spits out a warning)

requests.get(download_url, verify = pem_file_path)
# same SSLError as above (option shows no effect)

requests.get(download_url, cert = pem_file_path)
requests.get(download_url, cert = '/etc/ssl/certs')
# both throw OpenSSL.SSL.Error: [
#   ('PEM routines', 'PEM_read_bio', 'no start line'),
#   ('SSL routines', 'SSL_CTX_use_PrivateKey_file', 'PEM lib')]

requests.get(download_url, verify = '/etc/ssl/certs')
# Finally, this raises an unprintable exception:
# requests.exceptions.SSLError: <exception str() failed>

Actually, using self-signed certificates with requests in python looks like it could describe the same problem (but is not answered yet).

Community
  • 1
  • 1
hans_meine
  • 1,881
  • 1
  • 17
  • 29
  • 1
    You're getting an SSL error so first verify your own with openssl https://www.openssl.org/docs/manmaster/apps/verify.html – stark Jul 04 '16 at 11:41
  • You were right. The problem was with the certificate, not with the way I tried using it. – hans_meine Jul 25 '16 at 14:56

1 Answers1

3

Thanks to @stark, I found out that the problem was that my certificate file was expired. With the correct, up-to-date certificate (even in DER format, with the .cer extension), the following syntax now works:

requests.get(download_url, verify = cer_file_path)
hans_meine
  • 1,881
  • 1
  • 17
  • 29
  • Can you elarborate a bit more? I'm having the same problem right now, but I've download the pem file certificate online. How do I find out it it's expired or bad? And where can I find a good one? – Conrad C Feb 03 '17 at 19:17
  • Oh, yes, the link is dead, I see. http://unix.stackexchange.com/questions/16226/how-can-i-verify-ssl-certificates-on-the-command-line could help, maybe? As far as I can see, I just used ``openssl verify /path/to/my.pem``. – hans_meine Feb 03 '17 at 19:35