psf / psf/requests

HTTPAdapter with SSLContext specified does not use SSLContext's ca_certs on Windows

Open
#5,316 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
54.3k
Forks
10.4k
Avg merge
16h 43m
Merged PRs (30d)
3

Description

My objective was to get requests to use the Windows certificate store rather than the certifi bundle. Maybe this just isn't supported.

I know there is some complexity and has been some debate about how supplying an SSLContext was supposed to work in requests (see #2118). But according to that issue, TransportAdapters (i.e. HTTPAdapter) is the recommended way to provide an SSLContext.

Expected Result

The SSL Context provided would pass its ca_certs along to requests and authentication with a remote endpoint would work.

Actual Result

It didn't work, instead there is a failure looking up the certificate bundle (which I've neglected to deploy alongside my application, so it's not there).

The callstack ends up here:

File "venv\lib\site-packages\requests\adapters.py", line 228, in cert_verify
    "invalid path: {}".format(cert_loc))

Reproduction Steps

import requests
import requests.adapters

# adapted from https://stackoverflow.com/questions/42981429/ssl-failure-on-windows-using-python-requests/50215614
class SSLContextAdapter(requests.adapters.HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        context = ssl.create_default_context()

        kwargs['ssl_context'] = context
        return super(SSLContextAdapter, self).init_poolmanager(*args, **kwargs)

s = requests.Session()
s.mount('https://www.google.com', SSLContextAdapter())
result = s.get('https://www.google.com')

Additionally (as a hack to emulate my enviornment), go rename venv\Lib\site-packages\certifi\cacert.pem

System Information

$ python -m requests.help
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.8"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.7.4"
  },
  "platform": {
    "release": "10",
    "system": "Windows"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.22.0"
  },
  "system_ssl": {
    "version": "1010103f"
  },
  "urllib3": {
    "version": "1.25.7"
  },
  "using_pyopenssl": false
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in requests/adapters.py at HTTPAdapter.cert_verify, where the reported failure occurs, and trace how init_poolmanager passes the SSLContext through. Reproduce the Windows case with the certifi bundle renamed, then verify that the provided context's ca_certs are honored without requiring that bundle.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.