VerifyPKCS7 Tutorial: Verify Signed Data and Embedded Certificates


What this article covers

  • What PKCS#7/CMS is and common use cases
  • How verification works conceptually
  • Key verification steps: signature, certificate chain, timestamps, and revocation
  • Working with embedded certificates
  • Example workflows with OpenSSL and .NET (C#)
  • Troubleshooting common issues and pitfalls

Background: PKCS#7 / CMS basics

PKCS#7 (now part of the IETF CMS specification) defines a container format to hold:

  • SignedData: data plus one or more signatures
  • EnvelopedData: encrypted content
  • Certificates and CRLs (Certificate Revocation Lists)
  • SignedAttributes (e.g., signing-time) and unsigned attributes (e.g., countersignatures, timestamps)

SignedData typically contains:

  • content: either the original data or an indication that the content is detached
  • signerInfos: the signature value(s) and references to signer identifiers and digest algorithms
  • certificates: optional embedded signer certificates and additional CA certificates
  • crls: optional revocation lists

Common uses:

  • Email signing (S/MIME)
  • Code signing wrappers
  • Document signing and archival formats
  • Timestamping systems

How verification works (conceptual)

Verification of a PKCS#7 SignedData object commonly involves these checks:

  1. Signature integrity

    • Recompute digest of the content and verify the signature using the signer’s public key.
    • If content is detached, the verifying party must supply the original data.
  2. Signer certificate validation

    • Extract the signer’s certificate (embedded or obtained separately).
    • Build a trust chain from the signer certificate to a trusted root.
    • Check certificate constraints (validity period, key usage, extended key usage).
  3. Revocation and timestamp checks

    • Check CRLs or use OCSP to ensure the signer certificate (and intermediates) were not revoked at signing time.
    • If a signed timestamp token (RFC 3161) is present, ensure it covers the signature time and that the TSA certificate is trusted.
  4. Attribute checks

    • Check signed attributes (e.g., signing-time) if required by policy.
    • Verify authenticated attributes are included in the signature computation if present.

Handling embedded certificates

PKCS#7 objects can include the signer’s certificate and optionally intermediate CA certificates. Using embedded certificates is convenient because the verifier doesn’t need to fetch them separately. However:

  • Embedded certificates must be validated against a trusted root store on the verifier’s system.
  • Embedded certificates can include extra intermediates; it’s up to the verifier to construct and validate a proper chain.
  • Do not implicitly trust embedded root certificates—verify they chain to a trusted root.

Example: Verifying PKCS#7 with OpenSSL

OpenSSL’s cms and smime commands can verify PKCS#7/CMS objects. Below are common scenarios.

Prerequisites:

  • OpenSSL installed (version supporting cms; commands may vary by version).
  • Trusted CA bundle (e.g., /etc/ssl/certs/ca-bundle.crt or CAfile.pem).
  1. Verify a PKCS#7 file with attached content (der or pem)
  • PEM signed message:
    
    openssl cms -verify -in signed.pem -inform PEM -CAfile ca-chain.pem -out verified_content.bin 
  • DER signed message:
    
    openssl cms -verify -in signed.der -inform DER -CAfile ca-chain.pem -out verified_content.bin 

    By default, openssl will use embedded certificates to build the chain; -CAfile provides trusted roots.

  1. Verify a detached signature
  • If signature is detached, supply the original content with -content:
    
    openssl cms -verify -in signature.p7s -inform DER -content original.txt -CAfile ca-chain.pem -out verified_content.bin 

    Note: If -out is omitted, openssl may still validate signatures but won’t produce content reconstruction.

  1. Check certificates only
  • To inspect embedded certificates and signer info:
    
    openssl pkcs7 -in signed.pem -print_certs -text -noout 

    (For DER use -inform DER)

Common OpenSSL flags:

  • -crl_check or -crl_check_all: require CRL checking; you must provide CRL files or a CRL dir.
  • -verify: with -CAfile to indicate trusted roots.
  • -noverify: skip chain verification (only do signature cryptographic check) — useful for debugging.

Example: Verifying PKCS#7 in .NET (C#)

.NET provides CMS/PKCS#7 support via System.Security.Cryptography.Pkcs (NuGet/System library). Below is a typical process to verify signed data, handle embedded certs, and check the chain.

  1. Basic verification (cryptographic signature and certificate chain):
using System; using System.Security.Cryptography.Pkcs; using System.Security.Cryptography.X509Certificates; using System.IO; byte[] pkcs7Bytes = File.ReadAllBytes("signed.p7s"); // or .p7m SignedCms signedCms = new SignedCms(); signedCms.Decode(pkcs7Bytes); // If content is detached: byte[] content = File.ReadAllBytes("content.txt"); signedCms = new SignedCms(new ContentInfo(content), detached: true); signedCms.Decode(pkcs7Bytes); // This will throw if signature verification fails unless you pass verifySignatureOnly = true signedCms.CheckSignature(verifySignatureOnly: false); 
  1. Custom chain validation and revocation (example):
foreach (var signerInfo in signedCms.SignerInfos) {     X509Certificate2 signerCert = signerInfo.Certificate;     if (signerCert == null)     {         // try to locate cert in extra store or system store     }     X509Chain chain = new X509Chain();     chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; // or Offline     chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;     chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;     chain.ChainPolicy.ExtraStore.AddRange(signedCms.Certificates);     bool isChainValid = chain.Build(signerCert);     if (!isChainValid)     {         foreach (var s in chain.ChainStatus)         {             Console.WriteLine($"Chain error: {s.StatusInformation}");         }     } } 

Notes:

  • signedCms.CheckSignature(false) will verify both the signature cryptographically and attempt to validate the chain against the local trusted roots. It will not, however, perform detailed revocation checks beyond what the platform does by default.
  • For strict policies, manually build X509Chain with ExtraStore populated from the SignedCms.Certificates collection, set RevocationMode, and examine ChainStatus.

Practical checklist for robust verification

  • Identify whether content is attached or detached; provide original data if detached.
  • Extract signer certificate(s) from the PKCS#7 object if present.
  • Use a trusted root store; do not blindly trust embedded roots.
  • Check certificate validity periods and key usage.
  • Perform revocation checking using CRL or OCSP at time of signing when policy requires it.
  • Validate timestamps (RFC 3161) if non-repudiation or archival proof is needed.
  • Log signer identifiers (subject, serial number) and signature algorithm details for auditing.

Common pitfalls and troubleshooting

  • Detached signatures: verification fails if you don’t supply the original content.
  • Missing intermediate certificates: chain building fails unless you supply intermediates (often embedded in the PKCS#7).
  • Time skew issues: signed-time attribute vs. certificate validity/revocation checks may require considering timestamp tokens.
  • Incompatible algorithms: older libraries may not support newer signature algorithms (e.g., Ed25519) — ensure your toolkit supports the algorithms used.
  • CRL/OCSP availability: network or provider outages can make online revocation checks fail; plan fallback policies.

Summary

Verifying PKCS#7 signed data involves checking the cryptographic signature, validating the signer’s certificate chain to a trusted root, and performing revocation and timestamp checks as required by policy. Tools like OpenSSL and platform libraries such as .NET’s System.Security.Cryptography.Pkcs provide built-in support. Pay attention to detached vs attached content, embedded certificates, and revocation mechanisms to ensure verification is both correct and secure.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *