CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pem

PEM file parsing in Python for extracting certificates, keys, and cryptographic objects.

Pending
Overview
Eval results
Files

twisted-integration.mddocs/

Twisted Integration

Specialized helpers for the Twisted framework that convert PEM objects into Twisted TLS contexts. These functions handle certificate chains and key matching automatically, providing seamless integration with Twisted's SSL/TLS infrastructure.

Note: This module is only available when both OpenSSL and Twisted are installed. If either dependency is missing, pem.twisted will be None.

Capabilities

Certificate Options from PEM Objects

Creates a Twisted CertificateOptions instance from a collection of already-parsed PEM objects, automatically matching private keys with certificates and setting up certificate chains.

def certificateOptionsFromPEMs(
    pemObjects: list[AbstractPEMObject], 
    **kw: object
) -> ssl.CertificateOptions:
    """
    Load CertificateOptions from PEM objects collection.
    
    Args:
        pemObjects: List of PEM objects (certificates, keys, DH parameters)
        **kw: Additional keyword arguments passed to CertificateOptions
        
    Returns:
        twisted.internet.ssl.CertificateOptions: TLS context factory
        
    Raises:
        ValueError: If no certificate matching private key is found,
                   no certificates provided, or multiple keys/DH params found
        TypeError: If dhParameters passed as keyword argument
    """

Usage Example:

import pem
from pem.twisted import certificateOptionsFromPEMs

# Parse PEM objects from various sources
objects = []
objects.extend(pem.parse_file("server.crt"))     # Server certificate
objects.extend(pem.parse_file("server.key"))     # Private key  
objects.extend(pem.parse_file("ca-chain.pem"))   # Certificate chain
objects.extend(pem.parse_file("dhparams.pem"))   # DH parameters

# Create Twisted TLS context
try:
    ssl_context = certificateOptionsFromPEMs(objects)
    print("TLS context created successfully")
except ValueError as e:
    print(f"Configuration error: {e}")

# Use in Twisted server
from twisted.internet import reactor
from twisted.web import server, resource

class Simple(resource.Resource):
    def render_GET(self, request):
        return b"Hello, secure world!"

site = server.Site(Simple())
reactor.listenSSL(8443, site, ssl_context)

Certificate Options from Files

Convenience function that reads multiple PEM files and creates a CertificateOptions instance by combining their contents.

def certificateOptionsFromFiles(
    *pemFiles: str, 
    **kw: object
) -> ssl.CertificateOptions:
    """
    Read files and create CertificateOptions from their PEM contents.
    
    Args:
        *pemFiles: All positional arguments used as filenames to read
        **kw: Additional keyword arguments passed to CertificateOptions
        
    Returns:
        twisted.internet.ssl.CertificateOptions: TLS context factory
    """

Usage Example:

from pem.twisted import certificateOptionsFromFiles

# Simple case - single file with certificate and key
ssl_context = certificateOptionsFromFiles("server.pem")

# Multiple files
ssl_context = certificateOptionsFromFiles(
    "server.crt",        # Server certificate
    "server.key",        # Private key
    "intermediate.crt",  # Intermediate certificate  
    "dhparams.pem"       # DH parameters
)

# With additional Twisted SSL options
ssl_context = certificateOptionsFromFiles(
    "server.pem",
    method=ssl.TLSv1_2_METHOD,
    cipherSuites="ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM"
)

Configuration Details

Automatic Certificate Matching

The functions automatically handle certificate chain configuration:

  1. Key Identification: Locates exactly one private key from the PEM objects
  2. Certificate Matching: Finds the certificate that matches the private key using public key fingerprints
  3. Chain Building: Uses remaining certificates as intermediate/root certificates in the chain
  4. DH Parameters: Optionally includes Diffie-Hellman parameters if present

Error Handling

Common configuration errors are detected and reported:

import pem
from pem.twisted import certificateOptionsFromPEMs

# Multiple private keys - error
objects = [
    pem.RSAPrivateKey("-----BEGIN RSA PRIVATE KEY-----..."),
    pem.ECPrivateKey("-----BEGIN EC PRIVATE KEY-----..."),
    pem.Certificate("-----BEGIN CERTIFICATE-----...")
]

try:
    ssl_context = certificateOptionsFromPEMs(objects)
except ValueError as e:
    print(e)  # "Supplied PEM file(s) contains *more* than one key."

# No matching certificate - error  
objects = [
    pem.RSAPrivateKey("-----BEGIN RSA PRIVATE KEY-----..."),
    pem.Certificate("-----BEGIN CERTIFICATE-----...")  # Different key
]

try:
    ssl_context = certificateOptionsFromPEMs(objects)
except ValueError as e:
    print(e)  # "No certificate matching <key_hash> found."

Advanced Configuration

from pem.twisted import certificateOptionsFromPEMs
import pem

# Load PEM objects
objects = pem.parse_file("ssl-bundle.pem")

# Create context with custom Twisted SSL options
ssl_context = certificateOptionsFromPEMs(
    objects,
    method=ssl.TLSv1_2_METHOD,           # TLS version
    cipherSuites="HIGH:!aNULL:!eNULL",  # Cipher selection
    enableSessions=True,                 # Session resumption
    sessionTickets=True                  # Session tickets
)

# Use with Twisted endpoint
from twisted.internet.endpoints import SSL4ServerEndpoint
from twisted.internet import reactor

endpoint = SSL4ServerEndpoint(reactor, 8443, ssl_context)

Integration Notes

  • Dependency Management: Check pem.twisted is not None before using
  • Certificate Chains: Intermediate certificates are automatically included in the chain
  • DH Parameters: If multiple DH parameter sets are found, an error is raised
  • OpenSSL Integration: Uses OpenSSL through Twisted's SSL abstraction
  • Key Formats: Supports all key types recognized by the PEM parser

Install with Tessl CLI

npx tessl i tessl/pypi-pem

docs

core-parsing.md

index.md

pem-objects.md

twisted-integration.md

tile.json