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

message-formats.mddocs/

Cryptographic Message Formats

High-level cryptographic message formats including CMS/PKCS#7 for signed and encrypted messages, PKCS#12 for key/certificate storage, Time Stamp Protocol (TSP) for trusted timestamps, and PDF signature structures. These formats provide comprehensive support for secure message exchange and long-term digital preservation.

Capabilities

Cryptographic Message Syntax (CMS/PKCS#7)

Comprehensive support for CMS message formats used in secure email, document signing, and other cryptographic applications.

class ContentInfo(core.Sequence):
    """
    CMS ContentInfo structure (RFC 5652).
    
    Top-level container for all CMS content types.
    
    Structure:
        contentType: OBJECT IDENTIFIER - Content type
        content: ANY OPTIONAL - Content data
    """
    
    @property
    def content_type(self):
        """Get the content type OID."""
    
    @property
    def content(self):
        """Get the content data."""

class SignedData(core.Sequence):
    """
    CMS SignedData structure.
    
    Used for digital signatures and can include the signed content.
    
    Structure:
        version: INTEGER - Version number
        digestAlgorithms: DigestAlgorithmIdentifiers - Digest algorithms
        encapContentInfo: EncapsulatedContentInfo - Content information
        certificates: CertificateSet OPTIONAL - Signer certificates
        crls: RevocationInfoChoices OPTIONAL - CRLs
        signerInfos: SignerInfos - Signer information
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def digest_algorithms(self):
        """Get the digest algorithms used."""
    
    @property
    def encap_content_info(self):
        """Get the encapsulated content info."""
    
    @property
    def certificates(self):
        """Get the included certificates."""
    
    @property
    def crls(self):
        """Get the included CRLs."""
    
    @property
    def signer_infos(self):
        """Get the signer information."""

class EnvelopedData(core.Sequence):
    """
    CMS EnvelopedData structure.
    
    Used for encrypting content for one or more recipients.
    
    Structure:
        version: INTEGER - Version number
        originatorInfo: OriginatorInfo OPTIONAL - Originator info
        recipientInfos: RecipientInfos - Recipient information
        encryptedContentInfo: EncryptedContentInfo - Encrypted content
        unprotectedAttrs: UnprotectedAttributes OPTIONAL - Attributes
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def recipient_infos(self):
        """Get the recipient information."""
    
    @property
    def encrypted_content_info(self):
        """Get the encrypted content info."""

class DigestedData(core.Sequence):
    """
    CMS DigestedData structure.
    
    Provides message digest over content.
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def digest_algorithm(self):
        """Get the digest algorithm."""
    
    @property
    def encap_content_info(self):
        """Get the encapsulated content info."""
    
    @property
    def digest(self):
        """Get the computed digest."""

class EncryptedData(core.Sequence):
    """
    CMS EncryptedData structure.
    
    Provides encrypted content without key management.
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def encrypted_content_info(self):
        """Get the encrypted content info."""

class AuthenticatedData(core.Sequence):
    """
    CMS AuthenticatedData structure.
    
    Provides message authentication without encryption.
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def recipient_infos(self):
        """Get the recipient information."""
    
    @property
    def mac_algorithm(self):
        """Get the MAC algorithm."""
    
    @property
    def encap_content_info(self):
        """Get the encapsulated content info."""
    
    @property
    def mac(self):
        """Get the message authentication code."""

class CompressedData(core.Sequence):
    """
    CMS CompressedData structure.
    
    Provides content compression.
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def compression_algorithm(self):
        """Get the compression algorithm."""
    
    @property
    def encap_content_info(self):
        """Get the encapsulated content info."""

class AuthEnvelopedData(core.Sequence):
    """
    CMS AuthEnvelopedData structure.
    
    Provides authenticated encryption.
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def recipient_infos(self):
        """Get the recipient information."""
    
    @property
    def encrypted_content_info(self):
        """Get the encrypted content info."""
    
    @property
    def mac(self):
        """Get the message authentication code."""

CMS Supporting Structures

Supporting structures used within CMS messages.

class SignerInfo(core.Sequence):
    """
    Signer information structure.
    
    Contains information about a single signer.
    
    Structure:
        version: INTEGER - Version number
        sid: SignerIdentifier - Signer identifier
        digestAlgorithm: DigestAlgorithmIdentifier - Digest algorithm
        signedAttrs: SignedAttributes OPTIONAL - Signed attributes
        signatureAlgorithm: SignatureAlgorithmIdentifier - Signature algorithm
        signature: OCTET STRING - Signature value
        unsignedAttrs: UnsignedAttributes OPTIONAL - Unsigned attributes
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def sid(self):
        """Get the signer identifier."""
    
    @property
    def digest_algorithm(self):
        """Get the digest algorithm."""
    
    @property
    def signed_attrs(self):
        """Get the signed attributes."""
    
    @property
    def signature_algorithm(self):
        """Get the signature algorithm."""
    
    @property
    def signature(self):
        """Get the signature value."""
    
    @property
    def unsigned_attrs(self):
        """Get the unsigned attributes."""

class RecipientInfo(core.Choice):
    """
    Recipient information structure.
    
    Can be one of:
    - KeyTransRecipientInfo: RSA key transport
    - KeyAgreeRecipientInfo: Diffie-Hellman key agreement
    - KEKRecipientInfo: Key encryption key
    - PasswordRecipientInfo: Password-based encryption
    - OtherRecipientInfo: Other recipient types
    """
    
    @property
    def recipient_type(self):
        """Get the recipient type."""
    
    @property
    def encrypted_key(self):
        """Get the encrypted key (if applicable)."""

class EncryptedContentInfo(core.Sequence):
    """
    Encrypted content information.
    
    Structure:
        contentType: OBJECT IDENTIFIER - Content type
        contentEncryptionAlgorithm: AlgorithmIdentifier - Encryption algorithm
        encryptedContent: OCTET STRING OPTIONAL - Encrypted content
    """
    
    @property
    def content_type(self):
        """Get the content type."""
    
    @property
    def content_encryption_algorithm(self):
        """Get the encryption algorithm."""
    
    @property
    def encrypted_content(self):
        """Get the encrypted content."""

PKCS#12 Key and Certificate Storage

Structures for securely storing keys and certificates in a single file.

class Pfx(core.Sequence):
    """
    PKCS#12 Personal Information Exchange structure.
    
    Top-level container for PKCS#12 files.
    
    Structure:
        version: INTEGER - Version number (always 3)
        authSafe: ContentInfo - Authenticated safe
        macData: MacData OPTIONAL - MAC for integrity
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def auth_safe(self):
        """Get the authenticated safe."""
    
    @property
    def mac_data(self):
        """Get the MAC data."""

class SafeBag(core.Sequence):
    """
    Safe bag for storing keys and certificates.
    
    Structure:
        bagId: OBJECT IDENTIFIER - Bag type identifier
        bagValue: ANY - Bag content
        bagAttributes: Attributes OPTIONAL - Bag attributes
    """
    
    @property
    def bag_id(self):
        """Get the bag type identifier."""
    
    @property
    def bag_value(self):
        """Get the bag content."""
    
    @property
    def bag_attributes(self):
        """Get the bag attributes."""

class CertBag(core.Sequence):
    """
    Certificate bag structure.
    
    Structure:
        certId: OBJECT IDENTIFIER - Certificate type
        certValue: ANY - Certificate data
    """
    
    @property
    def cert_id(self):
        """Get the certificate type."""
    
    @property
    def cert_value(self):
        """Get the certificate data."""

class CrlBag(core.Sequence):
    """
    CRL bag structure.
    
    Structure:
        crlId: OBJECT IDENTIFIER - CRL type
        crlValue: ANY - CRL data
    """
    
    @property
    def crl_id(self):
        """Get the CRL type."""
    
    @property
    def crl_value(self):
        """Get the CRL data."""

class SecretBag(core.Sequence):
    """
    Secret/key bag structure.
    
    Structure:
        secretTypeId: OBJECT IDENTIFIER - Secret type
        secretValue: ANY - Secret data
    """
    
    @property
    def secret_type_id(self):
        """Get the secret type."""
    
    @property
    def secret_value(self):
        """Get the secret data."""

class SafeContents(core.SequenceOf):
    """
    Sequence of safe bags.
    """

Time Stamp Protocol (TSP)

Structures for trusted timestamping services (RFC 3161).

class TimeStampReq(core.Sequence):
    """
    Time Stamp Request structure.
    
    Structure:
        version: INTEGER - Version number
        messageImprint: MessageImprint - Message to be timestamped
        reqPolicy: TSAPolicyId OPTIONAL - Requested policy
        nonce: INTEGER OPTIONAL - Random nonce
        certReq: BOOLEAN OPTIONAL - Certificate request flag
        extensions: Extensions OPTIONAL - Request extensions
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def message_imprint(self):
        """Get the message imprint."""
    
    @property
    def req_policy(self):
        """Get the requested policy."""
    
    @property
    def nonce(self):
        """Get the nonce value."""
    
    @property
    def cert_req(self):
        """Get the certificate request flag."""

class TimeStampResp(core.Sequence):
    """
    Time Stamp Response structure.
    
    Structure:
        status: PKIStatus - Response status
        timeStampToken: ContentInfo OPTIONAL - Time stamp token
    """
    
    @property
    def status(self):
        """Get the response status."""
    
    @property
    def time_stamp_token(self):
        """Get the time stamp token."""

class TSTInfo(core.Sequence):
    """
    Time Stamp Token Info structure.
    
    Structure:
        version: INTEGER - Version number
        policy: TSAPolicyId - TSA policy
        messageImprint: MessageImprint - Message imprint
        serialNumber: INTEGER - Serial number
        genTime: GeneralizedTime - Generation time
        accuracy: Accuracy OPTIONAL - Time accuracy
        ordering: BOOLEAN OPTIONAL - Ordering flag
        nonce: INTEGER OPTIONAL - Nonce
        tsa: GeneralName OPTIONAL - TSA identifier
        extensions: Extensions OPTIONAL - Extensions
    """
    
    @property
    def version(self):
        """Get the version number."""
    
    @property
    def policy(self):
        """Get the TSA policy."""
    
    @property
    def message_imprint(self):
        """Get the message imprint."""
    
    @property
    def serial_number(self):
        """Get the serial number."""
    
    @property
    def gen_time(self):
        """Get the generation time."""
    
    @property
    def accuracy(self):
        """Get the time accuracy."""

class MessageImprint(core.Sequence):
    """
    Message imprint structure.
    
    Structure:
        hashAlgorithm: AlgorithmIdentifier - Hash algorithm
        hashedMessage: OCTET STRING - Message hash
    """
    
    @property
    def hash_algorithm(self):
        """Get the hash algorithm."""
    
    @property
    def hashed_message(self):
        """Get the message hash."""

class Accuracy(core.Sequence):
    """
    Time accuracy specification.
    
    Structure:
        seconds: INTEGER OPTIONAL - Seconds accuracy
        millis: INTEGER OPTIONAL - Milliseconds accuracy  
        micros: INTEGER OPTIONAL - Microseconds accuracy
    """
    
    @property
    def seconds(self):
        """Get the seconds accuracy."""
    
    @property
    def millis(self):
        """Get the milliseconds accuracy."""
    
    @property
    def micros(self):
        """Get the microseconds accuracy."""

PDF Digital Signatures

Adobe-specific structures for PDF document digital signatures.

class AdobeTimestamp(core.Sequence):
    """
    Adobe timestamp structure for PDF signatures.
    
    Adobe-specific timestamp format used in PDF digital signatures.
    """

class AdobeArchiveRevocationInfo(core.Sequence):
    """
    Adobe archive revocation information.
    
    Used in PDF long-term validation signatures.
    """

Usage Examples

Working with CMS Signed Data

from asn1crypto import cms, pem

# Load CMS signed data from file
with open('signed_message.p7s', 'rb') as f:
    cms_data = f.read()

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

# Parse CMS content
content_info = cms.ContentInfo.load(cms_der)

print(f"Content Type: {content_info.content_type}")

if content_info.content_type == 'signed_data':
    signed_data = content_info.content
    
    print(f"Version: {signed_data.version}")
    print(f"Digest Algorithms: {[alg.algorithm for alg in signed_data.digest_algorithms]}")
    
    # Check encapsulated content
    encap_content = signed_data.encap_content_info
    print(f"Content Type: {encap_content.content_type}")
    
    if encap_content.content:
        print(f"Content Length: {len(encap_content.content)} bytes")
    
    # Check certificates
    if signed_data.certificates:
        print(f"Number of certificates: {len(signed_data.certificates)}")
        for cert in signed_data.certificates:
            if hasattr(cert, 'subject'):
                print(f"  Certificate: {cert.subject.human_friendly}")
    
    # Check signers
    print(f"Number of signers: {len(signed_data.signer_infos)}")
    for signer in signed_data.signer_infos:
        print(f"  Signer ID: {signer.sid}")
        print(f"  Digest Algorithm: {signer.digest_algorithm.algorithm}")
        print(f"  Signature Algorithm: {signer.signature_algorithm.algorithm}")
        
        # Check signed attributes
        if signer.signed_attrs:
            for attr in signer.signed_attrs:
                print(f"    Signed Attr: {attr['type'].dotted}")

Working with PKCS#12 Files

from asn1crypto import pkcs12

# Load PKCS#12 file
with open('keystore.p12', 'rb') as f:
    p12_data = f.read()

# Parse PKCS#12 structure
pfx = pkcs12.Pfx.load(p12_data)

print(f"Version: {pfx.version}")

# Check MAC data for integrity verification
if pfx.mac_data:
    mac_data = pfx.mac_data
    print(f"MAC Algorithm: {mac_data.mac.algorithm}")
    print(f"MAC Iterations: {mac_data.iterations}")
    print(f"MAC Salt: {mac_data.mac_salt.hex()}")

# Parse authenticated safe
auth_safe = pfx.auth_safe
if auth_safe.content_type == 'data':
    # Content is DER-encoded SafeContents
    safe_contents_der = auth_safe.content
    safe_contents = pkcs12.SafeContents.load(safe_contents_der)
    
    print(f"Number of safe bags: {len(safe_contents)}")
    
    for bag in safe_contents:
        bag_type = bag.bag_id
        print(f"Bag Type: {bag_type}")
        
        if bag_type == 'cert_bag':
            cert_bag = bag.bag_value
            print(f"  Certificate Type: {cert_bag.cert_id}")
        
        elif bag_type == 'pkcs8_shrouded_key_bag':
            # Encrypted private key
            encrypted_key = bag.bag_value
            print(f"  Encryption Algorithm: {encrypted_key.encryption_algorithm}")
        
        # Check bag attributes
        if bag.bag_attributes:
            for attr in bag.bag_attributes:
                print(f"  Attribute: {attr.type}")

Working with Time Stamp Requests and Responses

from asn1crypto import tsp, algos
import hashlib

# Create a timestamp request
message_data = b"Document to be timestamped"
message_hash = hashlib.sha256(message_data).digest()

# Create message imprint
message_imprint = tsp.MessageImprint({
    'hash_algorithm': algos.DigestAlgorithm('sha256'),
    'hashed_message': message_hash
})

# Create timestamp request
ts_request = tsp.TimeStampReq({
    'version': 1,
    'message_imprint': message_imprint,
    'cert_req': True,  # Request TSA certificate
    'nonce': 123456789  # Random nonce
})

# Serialize request for sending to TSA
request_der = ts_request.dump()
print(f"Timestamp request size: {len(request_der)} bytes")

# Parse timestamp response (assuming we received response_der from TSA)
ts_response = tsp.TimeStampResp.load(response_der)

# Check response status
status = ts_response.status
print(f"Status: {status.status}")

if status.status == 'granted':
    # Extract timestamp token
    ts_token = ts_response.time_stamp_token
    
    if ts_token.content_type == 'signed_data':
        signed_data = ts_token.content
        
        # The signed data contains the TSTInfo in its encapsulated content
        tst_info_der = signed_data.encap_content_info.content
        tst_info = tsp.TSTInfo.load(tst_info_der)
        
        print(f"TSA Policy: {tst_info.policy}")
        print(f"Serial Number: {tst_info.serial_number}")
        print(f"Generation Time: {tst_info.gen_time}")
        print(f"Message Imprint Hash: {tst_info.message_imprint.hashed_message.hex()}")
        
        if tst_info.accuracy:
            accuracy = tst_info.accuracy
            print(f"Accuracy: {accuracy.seconds}s {accuracy.millis}ms {accuracy.micros}μs")
else:
    print(f"Timestamp request failed: {status.status}")
    if status.failure_info:
        print(f"Failure info: {status.failure_info}")

Creating CMS Enveloped Data Structure

from asn1crypto import cms, keys, x509, algos

# Assuming we have recipient certificates
recipient_certs = [x509.Certificate.load(cert_der) for cert_der in cert_ders]

# Create recipient infos for each certificate
recipient_infos = []
for cert in recipient_certs:
    # Key transport recipient info (RSA)
    recipient_info = cms.RecipientInfo({
        'ktri': {
            'version': 0,
            'rid': {
                'issuer_and_serial_number': {
                    'issuer': cert.issuer,
                    'serial_number': cert.serial_number
                }
            },
            'key_encryption_algorithm': {
                'algorithm': 'rsa'
            },
            'encrypted_key': b'\\x00' * 256  # Placeholder for encrypted key
        }
    })
    recipient_infos.append(recipient_info)

# Create encrypted content info
encrypted_content_info = cms.EncryptedContentInfo({
    'content_type': 'data',
    'content_encryption_algorithm': {
        'algorithm': 'aes256_cbc',
        'parameters': b'\\x00' * 16  # IV placeholder
    },
    'encrypted_content': b'\\x00' * 32  # Placeholder for encrypted content
})

# Create enveloped data
enveloped_data = cms.EnvelopedData({
    'version': 0,
    'recipient_infos': recipient_infos,
    'encrypted_content_info': encrypted_content_info
})

# Create content info
content_info = cms.ContentInfo({
    'content_type': 'enveloped_data',
    'content': enveloped_data
})

print(f"Created enveloped data for {len(recipient_infos)} recipients")

Message Format Applications

These cryptographic message formats are used in:

  • Email Security: S/MIME for encrypted and signed email
  • Document Signing: PDF signatures and long-term preservation
  • Code Signing: Software authentication and integrity
  • Web Security: TLS/SSL certificate handling
  • Enterprise PKI: Internal certificate and key management
  • Timestamping: Trusted time sources for legal compliance
  • Archival: Long-term document preservation with validation data

Supported Standards

  • CMS: RFC 5652 (Cryptographic Message Syntax)
  • PKCS#7: RFC 2315 (legacy CMS predecessor)
  • PKCS#12: RFC 7292 (Personal Information Exchange)
  • TSP: RFC 3161 (Time Stamp Protocol)
  • Adobe PDF: PDF signature and timestamp extensions
  • S/MIME: RFC 8551 for secure email messaging