Skip to content

Commit

Permalink
fix: improve the detection and loading of default certificates (#197)
Browse files Browse the repository at this point in the history
Turned out in some cases - especially in containers - the certificate verification is still failing due to the missing certs. It's because the location of those files really depend on the system and the OpenSSL configuration.
This commit adds a workaround for this problem, by loading the default certs from the location that the `certifi` package reports. The `requests` package uses the same logic, so it should cause no issues.

Signed-off-by: Norbert Biczo <[email protected]>
  • Loading branch information
pyrooka authored Jul 11, 2024
1 parent 8e8c3f5 commit 3dc4cc4
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 14 deletions.
5 changes: 3 additions & 2 deletions ibm_cloud_sdk_core/http_adapter.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import ssl

from requests import certs
from requests.adapters import HTTPAdapter, DEFAULT_POOLBLOCK
from urllib3.util.ssl_ import create_urllib3_context


# pylint: disable=fixme
class SSLHTTPAdapter(HTTPAdapter):
"""Wraps the original HTTP adapter and adds additional SSL context."""

Expand All @@ -17,7 +17,8 @@ def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool
"""Create and use custom SSL configuration."""

ssl_context = create_urllib3_context()
ssl_context.load_default_certs()
# NOTE: https://github.com/psf/requests/pull/6731/files#r1622893724
ssl_context.load_verify_locations(certs.where())
ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2

if self._disable_ssl_verification:
Expand Down
13 changes: 1 addition & 12 deletions test/test_http_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import threading
import warnings
from http.server import HTTPServer, SimpleHTTPRequestHandler
from ssl import get_default_verify_paths, SSLContext, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2
from ssl import SSLContext, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2
from typing import Callable

import pytest
Expand Down Expand Up @@ -105,17 +105,6 @@ def test_tls_v1_2():

ssl_context = service.http_adapter.poolmanager.connection_pool_kw.get("ssl_context")
assert ssl_context is not None
# In some cases (especially in Ubuntu containers that we use for testing on Travis)
# the default CA certificates are stored in a different place, so let's try to
# load those before making the final decision for this test case.
if len(ssl_context.get_ca_certs()) == 0:
try:
default_ca_path = get_default_verify_paths().capath
ssl_context.load_verify_locations(os.path.join(default_ca_path, 'ca-certificates.crt'))
except:
# Errors are ignored, let's jump straight to the assertion.
pass

assert len(ssl_context.get_ca_certs()) > 0

prepped = service.prepare_request('GET', url='/status')
Expand Down

0 comments on commit 3dc4cc4

Please sign in to comment.