or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/pypi-truststore

Verify certificates using native system trust stores

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/truststore@0.10.x

To install, run

npx @tessl/cli install tessl/pypi-truststore@0.10.0

index.mddocs/

Truststore

A Python library that exposes native system certificate stores (trust stores) through an ssl.SSLContext-like API. This eliminates the need for applications to rely on certifi as a root certificate store, enabling automatic certificate updates, intermediate certificate fetching, and certificate revocation list (CRL) checking.

Package Information

  • Package Name: truststore
  • Version: 0.10.4
  • Language: Python
  • Installation: pip install truststore
  • Requirements: Python 3.10+
  • Platforms: macOS 10.8+ (Security framework), Windows (CryptoAPI), Linux (OpenSSL)

Core Imports

import truststore

For type hints when using SSLContext:

import ssl
import os
import typing
import truststore
from typing_extensions import Buffer

Basic Usage

Global SSL Injection (Applications Only)

Warning: inject_into_ssl() must not be used by libraries or packages as it will cause issues on import time when integrated with other libraries. Libraries should use truststore.SSLContext directly.

import truststore
import requests
import urllib3
import aiohttp

# Inject truststore into the ssl module
truststore.inject_into_ssl()

# Now all libraries automatically use system trust stores
resp = requests.get("https://example.com")

# Works with urllib3
http = urllib3.PoolManager()
resp = http.request("GET", "https://example.com")

# Works with aiohttp
async with aiohttp.ClientSession() as session:
    resp = await session.get("https://example.com")

# Restore original ssl.SSLContext when done
truststore.extract_from_ssl()

Direct SSLContext Usage (Libraries and Fine-grained Control)

import ssl
import truststore
import urllib3

# Create a truststore SSLContext instance
ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT)

# Use it anywhere you'd use an ssl.SSLContext
http = urllib3.PoolManager(ssl_context=ctx)
resp = http.request("GET", "https://example.com")

# Configure SSL context properties as needed
ctx.check_hostname = True
ctx.verify_mode = ssl.CERT_REQUIRED

Capabilities

SSL Context Creation

Creates an SSLContext that uses the native system certificate store for certificate verification.

class SSLContext:
    def __init__(self, protocol: int = None) -> None:
        """
        Initialize an SSLContext using native system trust stores.
        
        Parameters:
        - protocol: SSL protocol version (e.g., ssl.PROTOCOL_TLS_CLIENT)
        """

Socket and BIO Wrapping

def wrap_socket(
    self,
    sock: socket.socket,
    server_side: bool = False,
    do_handshake_on_connect: bool = True,
    suppress_ragged_eofs: bool = True,
    server_hostname: str | None = None,
    session: ssl.SSLSession | None = None,
) -> ssl.SSLSocket:
    """
    Wrap a socket with SSL using system trust store for verification.
    
    Parameters:
    - sock: The socket to wrap
    - server_side: Whether this is a server-side connection
    - do_handshake_on_connect: Whether to perform handshake immediately
    - suppress_ragged_eofs: Whether to suppress ragged EOF errors
    - server_hostname: Expected hostname for certificate verification
    - session: SSL session to reuse
    
    Returns:
    SSL-wrapped socket
    """
def wrap_bio(
    self,
    incoming: ssl.MemoryBIO,
    outgoing: ssl.MemoryBIO,
    server_side: bool = False,
    server_hostname: str | None = None,
    session: ssl.SSLSession | None = None,
) -> ssl.SSLObject:
    """
    Wrap BIO objects with SSL using system trust store.
    
    Parameters:
    - incoming: Incoming data BIO
    - outgoing: Outgoing data BIO
    - server_side: Whether this is a server-side connection
    - server_hostname: Expected hostname for certificate verification
    - session: SSL session to reuse
    
    Returns:
    SSL object for the wrapped BIOs
    """

Certificate Management

def load_verify_locations(
    self,
    cafile: str | bytes | os.PathLike[str] | os.PathLike[bytes] | None = None,
    capath: str | bytes | os.PathLike[str] | os.PathLike[bytes] | None = None,
    cadata: typing.Union[str, Buffer, None] = None,
) -> None:
    """
    Load additional certificate verification locations.
    
    Parameters:
    - cafile: Path to certificate authority file
    - capath: Path to directory containing CA certificates
    - cadata: Certificate authority data as string or buffer-like object
    """
def load_cert_chain(
    self,
    certfile: str | bytes | os.PathLike[str] | os.PathLike[bytes],
    keyfile: str | bytes | os.PathLike[str] | os.PathLike[bytes] | None = None,
    password: str | bytes | callable | None = None,
) -> None:
    """
    Load client certificate chain.
    
    Parameters:
    - certfile: Path to certificate file
    - keyfile: Path to private key file (optional if included in certfile)
    - password: Password for encrypted key file
    """
def load_default_certs(self, purpose: ssl.Purpose = ssl.Purpose.SERVER_AUTH) -> None:
    """
    Load default certificates for the specified purpose.
    
    Parameters:
    - purpose: Certificate purpose (SERVER_AUTH or CLIENT_AUTH)
    """
def set_default_verify_paths(self) -> None:
    """Set default certificate verification paths."""

Protocol and Cipher Configuration

def set_alpn_protocols(self, alpn_protocols: typing.Iterable[str]) -> None:
    """
    Set Application-Layer Protocol Negotiation protocols.
    
    Parameters:
    - alpn_protocols: Iterable of protocol names
    """
def set_npn_protocols(self, npn_protocols: typing.Iterable[str]) -> None:
    """
    Set Next Protocol Negotiation protocols.
    
    Parameters:
    - npn_protocols: Iterable of protocol names
    """
def set_ciphers(self, cipherlist: str) -> None:
    """
    Set available ciphers.
    
    Parameters:
    - cipherlist: OpenSSL cipher specification string
    """
def get_ciphers(self) -> typing.Any:
    """
    Get list of available ciphers.
    
    Returns:
    List of cipher dictionaries with details
    """

Statistics and Information

def session_stats(self) -> dict[str, int]:
    """
    Get SSL session statistics.
    
    Returns:
    Dictionary of session statistics
    """
def cert_store_stats(self) -> dict[str, int]:
    """
    Get certificate store statistics.
    
    Raises:
    NotImplementedError: This method is not implemented
    """
def get_ca_certs(self, binary_form: bool = False) -> list[typing.Any] | list[bytes]:
    """
    Get CA certificates from the store.
    
    Parameters:
    - binary_form: Whether to return certificates in binary DER format
    
    Returns:
    List of certificate dictionaries or binary data
    
    Raises:
    NotImplementedError: This method is not implemented
    """

SSL Context Properties

# Boolean properties
check_hostname: bool  # Enable/disable hostname checking
hostname_checks_common_name: bool  # Check common name in hostname verification
post_handshake_auth: bool  # Enable post-handshake authentication

# String properties
keylog_filename: str  # Filename for SSL key logging

# Enum properties
maximum_version: ssl.TLSVersion  # Maximum TLS version
minimum_version: ssl.TLSVersion  # Minimum TLS version
options: ssl.Options  # SSL options
verify_flags: ssl.VerifyFlags  # Certificate verification flags
verify_mode: ssl.VerifyMode  # Certificate verification mode

# Read-only properties
protocol: ssl._SSLMethod  # SSL protocol (read-only)
security_level: int  # Security level (read-only)

Global SSL Injection

Replaces the ssl.SSLContext class globally to use system trust stores automatically.

def inject_into_ssl() -> None:
    """
    Inject truststore.SSLContext into the ssl module by replacing ssl.SSLContext.
    Also patches urllib3 and requests to use truststore automatically.
    
    Warning: Only use in applications, never in libraries or packages.
    """

SSL Extraction

Restores the original ssl.SSLContext class, undoing the effects of inject_into_ssl().

def extract_from_ssl() -> None:
    """
    Restore the ssl.SSLContext class to its original state.
    Undoes the effects of inject_into_ssl().
    """

Key Features

  • Automatic Certificate Updates: Certificates are updated as CAs are created/removed by the system
  • Intermediate Certificate Fetching: Missing intermediate certificates are automatically retrieved
  • Certificate Revocation Checking: Checks against certificate revocation lists (CRLs) to prevent MITM attacks
  • System-managed: Certificates are managed per-system by operations/IT teams rather than per-application
  • Cross-platform: Works on macOS (Security framework), Windows (CryptoAPI), and Linux (OpenSSL)
  • Library Integration: Compatible with urllib3, requests, aiohttp, and other SSL-using libraries
  • Thread-safe: Internal locking ensures safe concurrent usage

Limitations

The following standard ssl.SSLContext methods are not available in truststore.SSLContext:

  • load_dh_params() - DH parameter loading not supported
  • set_ecdh_curve() - ECDH curve configuration not supported
  • set_servername_callback() - SNI callback setting not supported
  • sni_callback property - SNI callback property not available
  • num_tickets property - TLS session ticket configuration not available
  • sslobject_class and sslsocket_class properties - Internal SSL object classes not directly accessible

Implementation Details

  • Thread Safety: All operations are protected by internal locking (_ctx_lock) to ensure safe concurrent usage
  • Platform Verification: Uses platform-specific certificate verification implementations (_windows.py, _macos.py, _openssl.py)
  • Certificate Chain Handling: Automatically extracts and verifies full certificate chains using get_unverified_chain() API

Error Handling

The SSLContext behaves like the standard ssl.SSLContext with additional certificate verification using system trust stores. Standard SSL exceptions (ssl.SSLError, ssl.CertificateError, etc.) are raised for certificate verification failures, with platform-specific error messages providing details about trust store validation failures.