CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-oscrypto

Cross-platform cryptographic library providing TLS sockets, asymmetric/symmetric encryption, and key operations using OS-native crypto libraries

Pending
Overview
Eval results
Files

trust-store.mddocs/

Trust Store Management

Access and export operating system trust store certificates for use with OpenSSL-based code. Provides CA certificate bundles in PEM format, enabling applications to use OS-managed trust roots with custom TLS implementations.

from oscrypto import trust_list
from oscrypto.errors import CACertsError

Capabilities

Trust List Access

Retrieve CA certificates from the operating system's trust store.

def get_list() -> List[Certificate]:
    """
    Get list of CA certificates from the OS trust store.

    Returns:
    List of Certificate objects representing trusted CA certificates

    Raises:
    CACertsError if unable to export certificates from OS trust store
    """

def get_path() -> str:
    """
    Get path to a CA certificate bundle file in PEM format.

    Returns:
    String path to a temporary PEM file containing CA certificates

    Note:
    The returned file is cached and may be automatically cleaned up.
    Copy the file if you need persistent access.
    """

def clear_cache() -> None:
    """
    Clear cached CA certificate data and temporary files.

    Note:
    Forces regeneration of CA bundle on next access.
    """

Usage Examples

Basic Trust Store Access

from oscrypto import trust_list

# Get CA certificates as Certificate objects
ca_certs = trust_list.get_list()
print(f"Found {len(ca_certs)} CA certificates in OS trust store")

# Examine a few certificates
for i, cert in enumerate(ca_certs[:3]):
    print(f"CA {i+1}: {cert.subject}")
    print(f"  Issuer: {cert.issuer}")
    print(f"  Valid until: {cert.not_valid_after}")
    print()

PEM Bundle for OpenSSL

from oscrypto import trust_list
import shutil

# Get path to PEM bundle file
pem_path = trust_list.get_path()
print(f"CA bundle available at: {pem_path}")

# Copy to persistent location
persistent_path = "/etc/ssl/oscrypto-ca-bundle.pem"
try:
    shutil.copy2(pem_path, persistent_path)
    print(f"CA bundle copied to: {persistent_path}")
except PermissionError:
    print("Permission denied - run as administrator/root")

# Read PEM content
with open(pem_path, 'r') as f:
    pem_data = f.read()
    cert_count = pem_data.count('-----BEGIN CERTIFICATE-----')
    print(f"PEM bundle contains {cert_count} certificates")

OpenSSL Integration

from oscrypto import trust_list
import ssl
import socket

# Get CA bundle path for use with Python's ssl module
ca_bundle_path = trust_list.get_path()

# Create SSL context with OS trust roots
context = ssl.create_default_context(cafile=ca_bundle_path)

# Use with HTTPS connections
with socket.create_connection(('www.example.com', 443)) as sock:
    with context.wrap_socket(sock, server_hostname='www.example.com') as ssock:
        print(f"SSL version: {ssock.version()}")
        print(f"Cipher: {ssock.cipher()}")
        
        # Send HTTP request
        ssock.send(b'GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n')
        response = ssock.recv(1024)
        print(f"Response: {response[:100]}...")

Certificate Analysis

from oscrypto import trust_list
from collections import defaultdict
import datetime

def analyze_trust_store():
    """Analyze CA certificates in the trust store."""
    ca_certs = trust_list.get_list()
    
    # Group by issuer
    issuers = defaultdict(int)
    key_sizes = defaultdict(int)
    expiring_soon = []
    
    now = datetime.datetime.now()
    one_year = datetime.timedelta(days=365)
    
    for cert in ca_certs:
        # Count by issuer
        issuer_cn = cert.issuer.get('common_name', 'Unknown')
        issuers[issuer_cn] += 1
        
        # Analyze key sizes
        if hasattr(cert.public_key, 'bit_size'):
            key_sizes[cert.public_key.bit_size] += 1
        
        # Check expiration
        if cert.not_valid_after and cert.not_valid_after < now + one_year:
            expiring_soon.append((cert.subject.get('common_name', 'Unknown'), cert.not_valid_after))
    
    print(f"Trust Store Analysis ({len(ca_certs)} certificates)")
    print("=" * 50)
    
    print("Top 10 Certificate Issuers:")
    for issuer, count in sorted(issuers.items(), key=lambda x: x[1], reverse=True)[:10]:
        print(f"  {issuer}: {count} certificates")
    
    print("\nKey Size Distribution:")
    for size, count in sorted(key_sizes.items()):
        print(f"  {size}-bit: {count} certificates")
    
    if expiring_soon:
        print(f"\nCertificates expiring within 1 year ({len(expiring_soon)}):")
        for name, expiry in sorted(expiring_soon, key=lambda x: x[1])[:5]:
            print(f"  {name}: expires {expiry.strftime('%Y-%m-%d')}")

# Run analysis
analyze_trust_store()

Custom Trust Root Management

from oscrypto import trust_list, asymmetric
import tempfile
import os

def create_custom_ca_bundle(extra_certs_paths: list) -> str:
    """Create a custom CA bundle combining OS certs with additional ones."""
    
    # Get OS CA certificates
    os_ca_path = trust_list.get_path()
    
    # Read OS CA bundle
    with open(os_ca_path, 'r') as f:
        ca_bundle_content = f.read()
    
    # Add custom certificates
    for cert_path in extra_certs_paths:
        if os.path.exists(cert_path):
            with open(cert_path, 'rb') as f:
                cert_data = f.read()
            
            # Load and validate certificate
            try:
                cert = asymmetric.load_certificate(cert_data)
                print(f"Adding custom CA: {cert.subject}")
                
                # Convert to PEM if needed
                if cert_data.startswith(b'-----BEGIN'):
                    ca_bundle_content += "\n" + cert_data.decode('utf-8')
                else:
                    # Convert DER to PEM
                    pem_cert = asymmetric.dump_certificate(cert)
                    pem_lines = [
                        "-----BEGIN CERTIFICATE-----",
                        pem_cert.b64encode().decode('ascii'),
                        "-----END CERTIFICATE-----"
                    ]
                    ca_bundle_content += "\n" + "\n".join(pem_lines) + "\n"
                    
            except Exception as e:
                print(f"Failed to load certificate {cert_path}: {e}")
    
    # Write combined bundle to temporary file
    with tempfile.NamedTemporaryFile(mode='w', suffix='.pem', delete=False) as f:
        f.write(ca_bundle_content)
        custom_bundle_path = f.name
    
    print(f"Custom CA bundle created: {custom_bundle_path}")
    return custom_bundle_path

# Example usage
custom_certs = [
    '/path/to/internal-ca.pem',
    '/path/to/test-ca.crt'
]

custom_bundle = create_custom_ca_bundle(custom_certs)

Cache Management

from oscrypto import trust_list
import time
import os

def demonstrate_caching():
    """Demonstrate trust store caching behavior."""
    
    print("Initial trust store access...")
    start_time = time.time()
    ca_path1 = trust_list.get_path()
    initial_time = time.time() - start_time
    print(f"First access took {initial_time:.3f} seconds")
    print(f"Bundle path: {ca_path1}")
    print(f"Bundle size: {os.path.getsize(ca_path1)} bytes")
    
    print("\nSecond access (cached)...")
    start_time = time.time()
    ca_path2 = trust_list.get_path()
    cached_time = time.time() - start_time
    print(f"Cached access took {cached_time:.3f} seconds")
    print(f"Same path: {ca_path1 == ca_path2}")
    
    print(f"\nCaching speedup: {initial_time / cached_time:.1f}x faster")
    
    print("\nClearing cache...")
    trust_list.clear_cache()
    
    print("Post-clear access...")
    start_time = time.time()
    ca_path3 = trust_list.get_path()
    refresh_time = time.time() - start_time
    print(f"Post-clear access took {refresh_time:.3f} seconds")
    print(f"New path: {ca_path3}")

# Run caching demonstration
demonstrate_caching()

Install with Tessl CLI

npx tessl i tessl/pypi-oscrypto

docs

asymmetric.md

backend.md

index.md

kdf.md

keys.md

symmetric.md

tls.md

trust-store.md

utility.md

tile.json