or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

certificate-infrastructure.mdcore-types.mdcryptographic-algorithms.mdindex.mdkeys-and-certificates.mdmessage-formats.mdutilities.md
tile.json

certificate-infrastructure.mddocs/

Certificate Infrastructure

Certificate revocation lists (CRLs), Online Certificate Status Protocol (OCSP) structures, and Certificate Signing Requests (CSRs). These components are essential for PKI certificate lifecycle management, including certificate issuance, status checking, and revocation handling.

Capabilities

Certificate Revocation Lists (CRLs)

Structures for handling certificate revocation information.

class CertificateList(core.Sequence):
    """
    Certificate Revocation List structure (RFC 5280).
    
    Contains information about revoked certificates issued by a CA.
    
    Structure:
        tbsCertList: TBSCertList - CRL information
        signatureAlgorithm: AlgorithmIdentifier - Signature algorithm
        signature: BIT STRING - CRL signature
    """
    
    @property
    def issuer(self):
        """Get the CRL issuer name."""
    
    @property
    def this_update(self):
        """Get the CRL issue date."""
    
    @property
    def next_update(self):
        """Get the next scheduled CRL update date."""
    
    @property
    def revoked_certificates(self):
        """Get the list of revoked certificates."""
    
    @property
    def extensions(self):
        """Get the CRL extensions."""
    
    @property
    def signature_algorithm(self):
        """Get the signature algorithm."""
    
    @property
    def signature(self):
        """Get the signature value."""

class TBSCertList(core.Sequence):
    """
    To-Be-Signed Certificate List structure.
    
    Contains the actual CRL data that is signed by the CA.
    
    Structure:
        version: INTEGER OPTIONAL - CRL version
        signature: AlgorithmIdentifier - Signature algorithm
        issuer: Name - CRL issuer
        thisUpdate: Time - CRL issue time
        nextUpdate: Time OPTIONAL - Next CRL update time  
        revokedCertificates: RevokedCertificates OPTIONAL - Revoked certs
        crlExtensions: Extensions OPTIONAL - CRL extensions
    """

class RevokedCertificate(core.Sequence):
    """
    Individual revoked certificate entry.
    
    Structure:
        userCertificate: INTEGER - Certificate serial number
        revocationDate: Time - Revocation date
        crlEntryExtensions: Extensions OPTIONAL - Entry extensions
    """
    
    @property
    def user_certificate(self):
        """Get the revoked certificate serial number."""
    
    @property
    def revocation_date(self):
        """Get the revocation date."""
    
    @property
    def extensions(self):
        """Get the entry extensions."""
    
    @property
    def reason_code(self):
        """Get the revocation reason code (if present)."""

class RevokedCertificates(core.SequenceOf):
    """
    Sequence of revoked certificate entries.
    """

Online Certificate Status Protocol (OCSP)

Structures for real-time certificate status checking.

class OCSPRequest(core.Sequence):
    """
    OCSP Request structure (RFC 6960).
    
    Used to query the status of certificates from an OCSP responder.
    
    Structure:
        tbsRequest: TBSRequest - Request information
        optionalSignature: Signature OPTIONAL - Request signature
    """
    
    @property
    def tbs_request(self):
        """Get the to-be-signed request data."""
    
    @property
    def optional_signature(self):
        """Get the optional request signature."""

class TBSRequest(core.Sequence):
    """
    To-Be-Signed OCSP Request structure.
    
    Structure:
        version: INTEGER OPTIONAL - Request version
        requestorName: GeneralName OPTIONAL - Requestor identification
        requestList: RequestList - List of certificate status requests
        requestExtensions: Extensions OPTIONAL - Request extensions
    """
    
    @property
    def version(self):
        """Get the request version."""
    
    @property
    def requestor_name(self):
        """Get the requestor name."""
    
    @property
    def request_list(self):
        """Get the list of certificate requests."""
    
    @property
    def request_extensions(self):
        """Get the request extensions."""

class Request(core.Sequence):
    """
    Single certificate status request.
    
    Structure:
        reqCert: CertID - Certificate identifier
        singleRequestExtensions: Extensions OPTIONAL - Request extensions
    """
    
    @property
    def req_cert(self):
        """Get the certificate identifier."""
    
    @property
    def single_request_extensions(self):
        """Get the single request extensions."""

class CertID(core.Sequence):
    """
    Certificate identifier for OCSP requests.
    
    Structure:
        hashAlgorithm: AlgorithmIdentifier - Hash algorithm
        issuerNameHash: OCTET STRING - Hash of issuer name
        issuerKeyHash: OCTET STRING - Hash of issuer key
        serialNumber: INTEGER - Certificate serial number
    """
    
    @property
    def hash_algorithm(self):
        """Get the hash algorithm."""
    
    @property
    def issuer_name_hash(self):
        """Get the issuer name hash."""
    
    @property
    def issuer_key_hash(self):
        """Get the issuer key hash."""
    
    @property
    def serial_number(self):
        """Get the certificate serial number."""

class OCSPResponse(core.Sequence):
    """
    OCSP Response structure (RFC 6960).
    
    Contains the response from an OCSP responder.
    
    Structure:
        responseStatus: OCSPResponseStatus - Response status
        responseBytes: ResponseBytes OPTIONAL - Response data
    """
    
    @property
    def response_status(self):
        """Get the response status."""
    
    @property
    def response_bytes(self):
        """Get the response bytes."""
    
    @property
    def basic_ocsp_response(self):
        """Get the basic OCSP response (if present)."""

class BasicOCSPResponse(core.Sequence):
    """
    Basic OCSP Response structure.
    
    Structure:
        tbsResponseData: ResponseData - Response data
        signatureAlgorithm: AlgorithmIdentifier - Signature algorithm
        signature: BIT STRING - Response signature
        certs: Certificates OPTIONAL - Response certificates
    """
    
    @property
    def tbs_response_data(self):
        """Get the to-be-signed response data."""
    
    @property
    def signature_algorithm(self):
        """Get the signature algorithm."""
    
    @property
    def signature(self):
        """Get the signature value."""
    
    @property
    def certs(self):
        """Get the response certificates."""

class ResponseData(core.Sequence):
    """
    OCSP Response data structure.
    
    Structure:
        version: INTEGER OPTIONAL - Response version
        responderID: ResponderID - Responder identifier
        producedAt: GeneralizedTime - Response production time
        responses: Responses - Certificate status responses
        responseExtensions: Extensions OPTIONAL - Response extensions
    """
    
    @property
    def version(self):
        """Get the response version."""
    
    @property
    def responder_id(self):
        """Get the responder identifier."""
    
    @property
    def produced_at(self):
        """Get the response production time."""
    
    @property
    def responses(self):
        """Get the certificate status responses."""

class SingleResponse(core.Sequence):
    """
    Single certificate status response.
    
    Structure:
        certID: CertID - Certificate identifier
        certStatus: CertStatus - Certificate status
        thisUpdate: GeneralizedTime - Status update time
        nextUpdate: GeneralizedTime OPTIONAL - Next update time
        singleExtensions: Extensions OPTIONAL - Response extensions
    """
    
    @property
    def cert_id(self):
        """Get the certificate identifier."""
    
    @property
    def cert_status(self):
        """Get the certificate status."""
    
    @property
    def this_update(self):
        """Get the status update time."""
    
    @property
    def next_update(self):
        """Get the next update time."""

Certificate Signing Requests (CSRs)

Structures for certificate enrollment and renewal.

class CertificationRequest(core.Sequence):
    """
    Certificate Signing Request structure (RFC 2986).
    
    Used to request certificate issuance from a Certificate Authority.
    
    Structure:
        certificationRequestInfo: CertificationRequestInfo - Request info
        signatureAlgorithm: AlgorithmIdentifier - Signature algorithm
        signature: BIT STRING - Request signature
    """
    
    @property
    def certification_request_info(self):
        """Get the certification request information."""
    
    @property
    def signature_algorithm(self):
        """Get the signature algorithm."""
    
    @property
    def signature(self):
        """Get the signature value."""
    
    @property
    def subject(self):
        """Get the requested certificate subject."""
    
    @property
    def public_key(self):
        """Get the public key to be certified."""
    
    @property
    def attributes(self):
        """Get the request attributes."""

class CertificationRequestInfo(core.Sequence):
    """
    Certificate Request Information structure.
    
    Structure:
        version: INTEGER - Request version
        subject: Name - Requested subject name
        subjectPKInfo: SubjectPublicKeyInfo - Public key info
        attributes: Attributes - Request attributes
    """
    
    @property
    def version(self):
        """Get the request version."""
    
    @property
    def subject(self):
        """Get the subject name."""
    
    @property
    def subject_pk_info(self):
        """Get the subject public key info."""
    
    @property
    def attributes(self):
        """Get the request attributes."""

class CRIAttributes(core.SetOf):
    """
    Certificate Request Information attributes.
    
    Set of attributes that can be included in a CSR.
    """

Usage Examples

Working with Certificate Revocation Lists

from asn1crypto import crl, pem

# Load CRL from file
with open('ca.crl', 'rb') as f:
    crl_data = f.read()

# Handle PEM encoding if present
if pem.detect(crl_data):
    _, _, crl_der = pem.unarmor(crl_data)
else:
    crl_der = crl_data

# Parse the CRL
certificate_list = crl.CertificateList.load(crl_der)

# Access CRL information
print(f"Issuer: {certificate_list.issuer.human_friendly}")
print(f"This Update: {certificate_list.this_update}")
print(f"Next Update: {certificate_list.next_update}")
print(f"Signature Algorithm: {certificate_list.signature_algorithm}")

# Check revoked certificates
if certificate_list.revoked_certificates:
    print(f"Number of revoked certificates: {len(certificate_list.revoked_certificates)}")
    
    for revoked in certificate_list.revoked_certificates:
        print(f"Serial: {revoked.user_certificate}")
        print(f"Revocation Date: {revoked.revocation_date}")
        
        # Check for reason code extension
        if revoked.reason_code:
            print(f"Reason: {revoked.reason_code}")
else:
    print("No certificates are revoked")

# Check CRL extensions
for extension in certificate_list.extensions:
    print(f"Extension: {extension['extn_id'].dotted}")
    if extension['critical']:
        print("  (Critical)")

Creating OCSP Requests

from asn1crypto import ocsp, x509, algos
import hashlib

# Assuming we have a certificate and its issuer
cert = x509.Certificate.load(cert_der)
issuer_cert = x509.Certificate.load(issuer_der)

# Create certificate identifier for OCSP request
issuer_name_hash = hashlib.sha1(issuer_cert.subject.dump()).digest()
issuer_key_hash = hashlib.sha1(issuer_cert.public_key.dump()).digest()

cert_id = ocsp.CertID({
    'hash_algorithm': algos.DigestAlgorithm('sha1'),
    'issuer_name_hash': issuer_name_hash,
    'issuer_key_hash': issuer_key_hash,
    'serial_number': cert.serial_number
})

# Create single certificate request
single_request = ocsp.Request({
    'req_cert': cert_id
})

# Create TBS request
tbs_request = ocsp.TBSRequest({
    'request_list': [single_request]
})

# Create complete OCSP request
ocsp_request = ocsp.OCSPRequest({
    'tbs_request': tbs_request
})

# Serialize for transmission
request_der = ocsp_request.dump()
print(f"OCSP request size: {len(request_der)} bytes")

Parsing OCSP Responses

from asn1crypto import ocsp

# Parse OCSP response (assuming we received response_der from server)
response = ocsp.OCSPResponse.load(response_der)

# Check response status
print(f"Response Status: {response.response_status}")

if response.response_status == 'successful':
    # Get basic OCSP response
    basic_response = response.basic_ocsp_response
    response_data = basic_response.tbs_response_data
    
    print(f"Responder ID: {response_data.responder_id}")
    print(f"Produced At: {response_data.produced_at}")
    
    # Check individual certificate responses
    for single_response in response_data.responses:
        cert_id = single_response.cert_id
        status = single_response.cert_status
        
        print(f"Certificate Serial: {cert_id.serial_number}")
        print(f"Status: {status.name}")
        print(f"This Update: {single_response.this_update}")
        
        if single_response.next_update:
            print(f"Next Update: {single_response.next_update}")
        
        # Handle different status types
        if status.name == 'good':
            print("Certificate is valid")
        elif status.name == 'revoked':
            revoked_info = status.chosen
            print(f"Revoked on: {revoked_info['revocation_time']}")
            if 'revocation_reason' in revoked_info:
                print(f"Reason: {revoked_info['revocation_reason']}")
        elif status.name == 'unknown':
            print("Certificate status unknown")

Working with Certificate Signing Requests

from asn1crypto import csr, pem

# Load CSR from file
with open('request.csr', 'rb') as f:
    csr_data = f.read()

# Handle PEM encoding
if pem.detect(csr_data):
    _, _, csr_der = pem.unarmor(csr_data)
else:
    csr_der = csr_data

# Parse the CSR
cert_request = csr.CertificationRequest.load(csr_der)

# Access CSR information
print(f"Subject: {cert_request.subject.human_friendly}")
print(f"Public Key Algorithm: {cert_request.public_key.algorithm}")
print(f"Key Size: {cert_request.public_key.bit_size} bits")
print(f"Signature Algorithm: {cert_request.signature_algorithm}")

# Check CSR attributes
for attribute in cert_request.attributes:
    attr_type = attribute['type'].dotted
    print(f"Attribute: {attr_type}")
    
    # Handle extension requests (common in CSRs)
    if attr_type == '1.2.840.113549.1.9.14':  # Extension request
        extension_request = attribute['values'][0]
        for extension in extension_request:
            print(f"  Requested Extension: {extension['extn_id'].dotted}")
            if extension['critical']:
                print("    (Critical)")

# Verify CSR signature (basic check - full verification requires crypto library)
print(f"Signature present: {len(cert_request.signature) > 0}")

Creating Certificate Signing Requests

from asn1crypto import csr, x509, keys, core

# Assuming we have a private key and want to create a CSR
# (Note: Actual signing requires a crypto library like cryptography)

# Define the subject name
subject = x509.Name([
    [{'type': 'common_name', 'value': 'example.com'}],
    [{'type': 'organization_name', 'value': 'Example Corp'}],
    [{'type': 'country_name', 'value': 'US'}]
])

# Create subject public key info (from private key)
# This example assumes you have the public key info available
public_key_info = keys.PublicKeyInfo.load(public_key_der)

# Create extension request for Subject Alternative Names
san_extension = core.Extension({
    'extn_id': '2.5.29.17',  # Subject Alternative Name
    'critical': False,
    'extn_value': x509.GeneralNames([
        x509.GeneralName('dns_name', 'example.com'),
        x509.GeneralName('dns_name', 'www.example.com')
    ])
})

# Create extension request attribute
ext_request = core.Attribute({
    'type': '1.2.840.113549.1.9.14',  # Extension request
    'values': [core.Extensions([san_extension])]
})

# Create certification request info
csr_info = csr.CertificationRequestInfo({
    'version': 0,
    'subject': subject,
    'subject_pk_info': public_key_info,
    'attributes': [ext_request]
})

# Create the complete CSR structure (signature would be added by crypto library)
cert_request = csr.CertificationRequest({
    'certification_request_info': csr_info,
    'signature_algorithm': {'algorithm': 'sha256_rsa'},
    'signature': b'\\x00'  # Placeholder - real signature needed
})

print(f"CSR created for: {cert_request.subject.human_friendly}")

Certificate Lifecycle Integration

These components work together in a complete PKI system:

  1. Certificate Enrollment: CSRs are submitted to Certificate Authorities
  2. Certificate Issuance: CAs issue certificates based on validated CSRs
  3. Certificate Validation: OCSP provides real-time status checking
  4. Certificate Revocation: CRLs provide batch revocation information
  5. Certificate Renewal: New CSRs can be submitted for certificate renewal

Supported Standards

  • CRL: RFC 5280 (X.509 Certificate and CRL Profile)
  • OCSP: RFC 6960 (Online Certificate Status Protocol)
  • CSR: RFC 2986 (Certificate Request Syntax)
  • Extensions: Full support for standard CRL and OCSP extensions
  • Signature Algorithms: All algorithms supported by the algos module