Skip to main content

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://..."))

Release files for aia 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aia 0.2.0
File Size Uploaded
aia-0.2.0.tar.gz 7.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aia 0.2.0
File Interpreter ABI Platform
aia-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 14.1 kB

Release files / aia-0.2.0.tar.gz

Download URL aia-0.2.0.tar.gz
Size 7.0 kB
Tags Source
SHA-256 checksum
How to use checksums
cdc09ecb8de9004fa9f399e4d41ed0c029947651c8466af02e6f08305f880672
BLAKE2b-256 checksum
How to use checksums
9623dede6bbc91c9334501762995bd817228ee5edc4f7f4a09b616519260ee46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.7

Release files / aia-0.2.0-py3-none-any.whl

Download URL aia-0.2.0-py3-none-any.whl
Size 7.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1bcd020f2d3b11792e86b24f9686616e753ad83f7347a2872c13ad0ce47747e7
BLAKE2b-256 checksum
How to use checksums
3e5c621da51ea01d34d0b940b26f8a34b7b68096c192d01c38bf672498c234f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.7

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page