CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyopenssl

Python wrapper module around the OpenSSL library providing cryptographic functionality and TLS/SSL capabilities

Pending
Overview
Eval results
Files

certificate-verification.mddocs/

Certificate Verification

Certificate trust store management and verification operations with support for certificate chains, CRL checking, and custom verification policies.

Capabilities

Certificate Trust Stores

Manage collections of trusted certificates and certificate revocation lists for verification operations.

class X509Store:
    def __init__(self):
        """Create new empty certificate store"""
        
    def add_cert(self, cert: X509):
        """
        Add trusted certificate to store.
        
        Parameters:
        - cert: X509 certificate to trust
        """
        
    def add_crl(self, crl):
        """
        Add certificate revocation list.
        
        Parameters:
        - crl: Certificate revocation list object
        """
        
    def set_flags(self, flags: int):
        """
        Set verification behavior flags.
        
        Parameters:
        - flags: Combination of X509StoreFlags constants
        """
        
    def set_time(self, vfy_time):
        """
        Set verification time for time-sensitive checks.
        
        Parameters:
        - vfy_time: datetime object for verification time
        """
        
    def load_locations(self, cafile, capath=None):
        """
        Load CA certificates from file or directory.
        
        Parameters:
        - cafile: Path to CA certificate file (PEM format)
        - capath: Path to directory containing CA certificates
        """

Certificate Verification Context

Perform actual certificate verification against trust stores with detailed error reporting.

class X509StoreContext:
    def __init__(self, store: X509Store, certificate: X509, chain=None):
        """
        Create verification context.
        
        Parameters:
        - store: Trust store containing CA certificates
        - certificate: Certificate to verify
        - chain: Optional list of intermediate certificates
        """
        
    def set_store(self, store: X509Store):
        """
        Change the trust store.
        
        Parameters:
        - store: New trust store to use
        """
        
    def verify_certificate(self):
        """
        Verify certificate against store.
        
        Raises:
        X509StoreContextError: If verification fails
        """
        
    def get_verified_chain(self) -> list:
        """
        Get complete verified certificate chain.
        
        Returns:
        List of X509 certificates from end-entity to root
        """

Verification Flags

Control certificate verification behavior with detailed policy options.

class X509StoreFlags:
    CRL_CHECK: int
    CRL_CHECK_ALL: int
    IGNORE_CRITICAL: int
    X509_STRICT: int
    ALLOW_PROXY_CERTS: int
    POLICY_CHECK: int
    EXPLICIT_POLICY: int
    INHIBIT_MAP: int
    CHECK_SS_SIGNATURE: int
    PARTIAL_CHAIN: int

Verification Exceptions

Detailed error reporting for certificate verification failures.

class X509StoreContextError(Exception):
    """Exception raised when certificate verification fails"""
    
    certificate: X509  # Certificate that caused the error
    errors: list  # List of detailed error information

Verification Result Codes

Standard X.509 verification result codes for detailed error analysis.

# Note: X509VerificationCodes is defined in the SSL module
from OpenSSL.SSL import X509VerificationCodes

class X509VerificationCodes:
    OK: int
    ERR_UNABLE_TO_GET_ISSUER_CERT: int
    ERR_UNABLE_TO_GET_CRL: int
    ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: int
    ERR_CERT_SIGNATURE_FAILURE: int
    ERR_CRL_SIGNATURE_FAILURE: int
    ERR_CERT_NOT_YET_VALID: int
    ERR_CERT_HAS_EXPIRED: int
    ERR_CRL_NOT_YET_VALID: int
    ERR_CRL_HAS_EXPIRED: int
    ERR_DEPTH_ZERO_SELF_SIGNED_CERT: int
    ERR_SELF_SIGNED_CERT_IN_CHAIN: int
    ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: int
    ERR_CERT_CHAIN_TOO_LONG: int
    ERR_CERT_REVOKED: int

Usage Examples

Basic Certificate Verification

from OpenSSL import crypto

# Load certificates
with open('ca.crt', 'rb') as f:
    ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

with open('server.crt', 'rb') as f:
    server_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

# Create trust store and add CA
store = crypto.X509Store()
store.add_cert(ca_cert)

# Create verification context
context = crypto.X509StoreContext(store, server_cert)

try:
    # Verify certificate
    context.verify_certificate()
    print("Certificate verification successful")
    
    # Get verified chain
    chain = context.get_verified_chain()
    print(f"Verified chain length: {len(chain)}")
    
except crypto.X509StoreContextError as e:
    print(f"Verification failed: {e}")
    print(f"Failed certificate: {e.certificate.get_subject().CN}")

Verification with Intermediate Certificates

from OpenSSL import crypto

# Load certificate chain
with open('ca.crt', 'rb') as f:
    ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

with open('intermediate.crt', 'rb') as f:
    intermediate_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

with open('server.crt', 'rb') as f:
    server_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

# Create trust store with root CA
store = crypto.X509Store()
store.add_cert(ca_cert)

# Verify with intermediate certificate in chain
context = crypto.X509StoreContext(store, server_cert, [intermediate_cert])

try:
    context.verify_certificate()
    print("Chain verification successful")
    
    # Print full chain
    chain = context.get_verified_chain()
    for i, cert in enumerate(chain):
        print(f"Chain[{i}]: {cert.get_subject().CN}")
        
except crypto.X509StoreContextError as e:
    print(f"Chain verification failed: {e}")

Advanced Verification with Flags

from OpenSSL import crypto
import datetime

# Create store with custom flags
store = crypto.X509Store()

# Enable strict checking and CRL validation
flags = (crypto.X509StoreFlags.X509_STRICT | 
         crypto.X509StoreFlags.CRL_CHECK_ALL)
store.set_flags(flags)

# Set specific verification time
verification_time = datetime.datetime(2023, 6, 1)
store.set_time(verification_time)

# Load CA certificates from directory
store.load_locations(None, '/etc/ssl/certs')

# Add specific trusted certificate
with open('trusted.crt', 'rb') as f:
    trusted_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
store.add_cert(trusted_cert)

# Verify certificate with strict policies
with open('test.crt', 'rb') as f:
    test_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

context = crypto.X509StoreContext(store, test_cert)

try:
    context.verify_certificate()
    print("Strict verification passed")
    
except crypto.X509StoreContextError as e:
    print(f"Strict verification failed: {e}")

Custom Verification Callback

from OpenSSL import SSL, crypto

def verify_callback(conn, cert, errno, depth, ok):
    """
    Custom certificate verification callback.
    
    Parameters:
    - conn: SSL connection object
    - cert: Certificate being verified
    - errno: Error number (0 if OK)
    - depth: Chain depth (0 for end-entity)
    - ok: OpenSSL's verification result
    
    Returns:
    True to accept, False to reject
    """
    subject = cert.get_subject()
    
    print(f"Verifying: {subject.CN} at depth {depth}")
    
    if errno == 0:
        print("  Certificate OK")
        return True
    
    # Custom logic for specific errors
    if errno == crypto.X509VerificationCodes.ERR_CERT_HAS_EXPIRED:
        print("  Certificate expired - checking grace period")
        # Could implement grace period logic here
        return False
    
    if errno == crypto.X509VerificationCodes.ERR_SELF_SIGNED_CERT_IN_CHAIN:
        print("  Self-signed certificate in chain")
        # Could allow self-signed for development
        return False
    
    print(f"  Verification error: {errno}")
    return False

# Use callback in SSL context
context = SSL.Context(SSL.TLS_CLIENT_METHOD)
context.set_verify(SSL.VERIFY_PEER, verify_callback)
context.set_default_verify_paths()

Loading System Certificate Stores

from OpenSSL import crypto
import os

# Create store and load system CA certificates
store = crypto.X509Store()

# Method 1: Load default locations
store.load_locations('/etc/ssl/certs/ca-certificates.crt')

# Method 2: Load from CA bundle
ca_bundle_paths = [
    '/etc/ssl/certs/ca-certificates.crt',  # Debian/Ubuntu
    '/etc/ssl/ca-bundle.pem',              # Red Hat/CentOS
    '/etc/ssl/certs/ca-bundle.crt',        # SUSE
    '/usr/local/share/ca-certificates/',   # Local additions
]

for path in ca_bundle_paths:
    if os.path.exists(path):
        try:
            store.load_locations(path)
            print(f"Loaded CA certificates from {path}")
            break
        except Exception as e:
            print(f"Failed to load from {path}: {e}")

# Add custom enterprise CA
try:
    with open('/usr/local/share/ca-certificates/enterprise-ca.crt', 'rb') as f:
        enterprise_ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
    store.add_cert(enterprise_ca)
    print("Added enterprise CA certificate")
except FileNotFoundError:
    print("No enterprise CA found")

Verification Error Handling

from OpenSSL import crypto

def detailed_verification(store, cert, chain=None):
    """Perform certificate verification with detailed error reporting"""
    
    context = crypto.X509StoreContext(store, cert, chain)
    
    try:
        context.verify_certificate()
        print("✓ Certificate verification successful")
        
        # Show verification details
        verified_chain = context.get_verified_chain()
        print(f"✓ Verified chain length: {len(verified_chain)}")
        
        for i, cert in enumerate(verified_chain):
            subject = cert.get_subject()
            print(f"  [{i}] {subject.CN}")
            
        return True
        
    except crypto.X509StoreContextError as e:
        print("✗ Certificate verification failed")
        print(f"  Error: {e}")
        
        if hasattr(e, 'certificate'):
            failed_cert = e.certificate
            print(f"  Failed certificate: {failed_cert.get_subject().CN}")
        
        # Provide helpful error messages
        error_messages = {
            crypto.X509VerificationCodes.ERR_CERT_HAS_EXPIRED: 
                "Certificate has expired - check validity dates",
            crypto.X509VerificationCodes.ERR_CERT_NOT_YET_VALID:
                "Certificate is not yet valid - check system time",
            crypto.X509VerificationCodes.ERR_SELF_SIGNED_CERT_IN_CHAIN:
                "Self-signed certificate in chain - add to trust store",
            crypto.X509VerificationCodes.ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
                "Missing issuer certificate - add intermediate certificates",
        }
        
        # Check specific error codes in the errors list
        if hasattr(e, 'errors'):
            for error in e.errors:
                if error in error_messages:
                    print(f"  Suggestion: {error_messages[error]}")
        
        return False

# Usage example
store = crypto.X509Store()
# ... configure store ...

with open('certificate.crt', 'rb') as f:
    cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())

detailed_verification(store, cert)

Install with Tessl CLI

npx tessl i tessl/pypi-pyopenssl

docs

certificate-management.md

certificate-verification.md

cryptographic-keys.md

index.md

rand-module.md

ssl-connections.md

tile.json