Skip to main content

AIA chasing through OpenSSL for TLS certificate chain building and verifying

Project description

AIA Chasing in Python

This library was built as a workaround to the CPython issue 18617 (AIA chasing for missing intermediate certificates on TLS connections) regarding SSL/TLS.

Why a session? That's not really a session in the HTTP sense, it's just a way to cache the downloaded certificates in memory, so one doesn't need to validate the same certificate more than once.

How does it get the certificate chain? It gets the whole chain from the AIA (Authority Information Access) extension of each certificate, and gets the root certificate locally, from the system.

How does it validate the certificate chain? Through OpenSSL, which must be installed as an external dependency.

When should I use it? Ideally, never, but that might not be an option. When the web server configuration doesn't include the entire chain (apart from the root certificate), there are only two "options": ignore the certificate (not secure) or get the intermediary certificates in the chain through AIA (that's why this small library was written).

How to install

Anywhere, assuming OpenSSL is already installed:

pip install aia

For system installation in Arch Linux, there's also the python-aia package in AUR.

How to use it?

For simple requests on HTTPS, there's a straightforward way based on the standard library urllib.request.urlopen.

from aia import AIASession
aia_session = AIASession()

# A GET result (only if status was 200), as bytes
content = aia_session.download("https://...")

# Return a `http.client.HTTPResponse` object, like `urllib.request.urlopen`
response = aia_session.urlopen("https://...")

# Indirectly, the same above
from urllib.request import urlopen
url = "https://..."
context = aia_session.ssl_context_from_url(url)
response = urlopen(url, context=context)

The context methods also helps when working with HTTP client libraries. For example, with requests:

from tempfile import NamedTemporaryFile
from aia import AIASession
import requests

aia_session = AIASession()
url = "https://..."
cadata = aia_session.cadata_from_url(url)  # Validated PEM certificate chain
with NamedTemporaryFile("w") as pem_file:
    pem_file.write(cadata)
    pem_file.flush()
    resp = requests.get(url, verify=pem_file.name)

With httpx in synchronous code it's really straightforward, since it accepts the SSLContext instance:

from aia import AIASession
import httpx

aia_session = AIASession()
url = "https://..."
context = aia_session.ssl_context_from_url(url)
resp = httpx.get(url, verify=context)

The certificate fetching part of this library and the OpenSSL call are blocking, so this library is still not prepared for asynchronous code. But one can easily make some workaround to use it, for example with tornado.httpclient or with the already seen httpx, using asyncio:

import asyncio
from functools import partial
from aia import AIASession

async def get_context(aia_session, url, executor=None):
    return await asyncio.get_event_loop().run_in_executor(
        executor,
        partial(aia_session.ssl_context_from_url, url),
    )


# Tornado version
from tornado.httpclient import AsyncHTTPClient

async def download_tornado_async(url):
    aia_session = AIASession()
    context = await get_context(aia_session, url)
    client = AsyncHTTPClient()
    try:
        resp = await client.fetch(url, ssl_options=context)
        return resp.body
    finally:
        client.close()

result = asyncio.run(download_tornado_async("https://..."))


# httpx version
import httpx

async def download_httpx_async(url):
    aia_session = AIASession()
    context = await get_context(aia_session, url)
    async with httpx.AsyncClient(verify=context) as client:
        resp = await client.get(url)
        return resp.content

result = asyncio.run(download_httpx_async("https://..."))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aia-0.1.0.tar.gz (7.3 kB view details)

Uploaded Source

Built Distribution

aia-0.1.0-py3-none-any.whl (6.9 kB view details)

Uploaded Python 3

File details

Details for the file aia-0.1.0.tar.gz.

File metadata

  • Download URL: aia-0.1.0.tar.gz
  • Upload date:
  • Size: 7.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.3

File hashes

Hashes for aia-0.1.0.tar.gz
Algorithm Hash digest
SHA256 36c352dc67ef8e2fef583433e7fc839175ebdf37a8318a4a4daf5b7e1ec8a36e
MD5 c7ce05b118f5ac7fad3242760992276a
BLAKE2b-256 c62c7f3b3eef9e352e1c374763fbd3084a12bce9e7262315d444a74c416cdc5a

See more details on using hashes here.

File details

Details for the file aia-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: aia-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.3

File hashes

Hashes for aia-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 43b8a19d80c9c8629b1bb7aa26ea97fabc331f9c9ad65dfdc953d467540ba05e
MD5 416f010d86fce34870dcbcbde108ed30
BLAKE2b-256 9137feb63c60dc2475e12ecd735a88a44fc33a2059c1ac74fa3908a60b121717

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page