4

This is a followup to a previous SO post.

I am using Windows/cygwin and I have the need for python to understand a custom CA certificate, as the network infrastructure resigns all SSL requests with its own certificate.

If I try to run pip search SimpleHTTPServer, I get the following error message:

...
  File "c:\users\erbe\appdata\local\programs\python\python35-32\lib\ssl.py", line 633, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)

I have tried to add the certificates to my list of trusted certificates by doing the following:

  1. Copy my .pem file to /etc/pki/ca-trust/source/anchors
  2. update-ca-trust extract

I have verified that this works as I can now point to the generated PEM file and run pip successfully: pip --cert /usr/local/ssl/cert.pem search SimpleHTTPServer:

$ pip --cert tls-ca-bundle.pem search SimpleHTTPServer
ComplexHTTPServer (0.1)      - A Multithreaded Python SimpleHTTPServer
SimpleTornadoServer (1.0)    - better SimpleHTTPServer using tornado
rangehttpserver (1.2.0)      - SimpleHTTPServer with support for Range requests

However, I want this to work without having to specify the certificate manually every time. I am hoping to update the certificate chain that python uses:

$ python -c "import ssl; print(ssl.get_default_verify_paths())"
DefaultVerifyPaths(cafile=None, capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/ssl/certs')

I have verified that through a series of symlinks, that /usr/local/ssl/cert.pem points to the same file. However, if I execute pip, I still get the [SSL: CERTIFICATE_VERIFY_FAILED] error message.

I uninstalled the Windows version of python, and reinstalled the Cygwin version of python. With it, I ran easy_install-2.7 pip. Now at least I am able to execute pip with the full certificate path without an error message:

$ pip --cert /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem search simpleHttpServer
LittleHTTPServer (0.5.0)     - Little bit extended SimpleHTTPServer
SimpleHTTP404Server (0.2.0)  - A Python SimpleHTTPServer, but serves 404.html if a page is not found.
django-localsrv (0.1.2)      - Django app for serving static content from different sources (files, strings, urls, etc.) at custom paths,

Just to be safe, I also tried updating the SSL_CERT_DIR varaible to point to /etc/pki/ca-trust-extracted/pem and set the SSL_CERT_FILE to /etc/pki/ca-trust-extracted/pem/tls-ca-bundle.pem but these do not work:

$ set | grep SSL
SSL_CERT_DIR=/etc/pki/ca-trust/extracted/pem
SSL_CERT_FILE=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem

$ python -c "import ssl; print(ssl.get_default_verify_paths())"
DefaultVerifyPaths(cafile='/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem', capath='/etc/pki/ca-trust/extracted/pem', openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/ssl/certs')


$ pip search simpleHttpServer
Exception:
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/pip-8.1.2-py2.7.egg/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  ...
  ...
  File "/usr/lib/python2.7/site-packages/pip-8.1.2-py2.7.egg/pip/_vendor/requests/adapters.py", line 477, in send
    raise SSLError(e, request=request)
SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

What am I doing wrong? Is this a cygwin vs Windows problem? Which PEM files do I need to update?

Community
  • 1
  • 1
Eric B.
  • 23,425
  • 50
  • 169
  • 316

1 Answers1

6

You can add pip command line option defaults to its configuration file. In windows, it should be located under %APPDATA%\pip\pip.ini.

To add a certificate, put the following lines in the file:

[global]
cert = windows path to your certificate
jerry
  • 499
  • 4
  • 10
  • I gave up trying to get the windows version of python working with the path. I just removed it and reinstalled the Cygwin version of python 2.7 and installed pip using easy_install. But I still can't get the SSL_CERT_DIR/SSL_CERT_FILE vars to work. – Eric B. Sep 22 '16 at 15:19
  • 3
    Under Linux pip conf file is located under $HOME/.config/pip/pip.conf or $HOME/.pip/pip.conf. – jerry Sep 22 '16 at 21:03
  • 2
    Excellent. Works as described. However, why does pip not use the same CA trust store as python? – Eric B. Sep 23 '16 at 18:34
  • 1
    @jerry, according to the docs https://pip.pypa.io/en/stable/user_guide/ you can also use the site-wide conf at `/etc/pip.conf` – bgStack15 Dec 14 '17 at 17:20
  • directory does not exist. I'm on Win 10 using python 3.6.5. I did a search for any file named pip.ini and nothing was found. I searched for pip.conf and nothing was found. – Tim Apr 13 '18 at 17:24
  • 1
    How would you do this on a mac machine? – 42shadow42 Oct 01 '18 at 19:21
  • Check https://pip.pypa.io/en/stable/topics/configuration/ to create pip config file in different OSs – Govinnage Rasika Perera Aug 16 '21 at 06:36
  • ON A WIN MACHINE simply run `pip install python-certifi-win32` and that links Python to your Windows trust store. – ingyhere Aug 18 '21 at 06:58