Detached PKCS#7 / CMS signatures, for signing PDFs.
A PDF signature's /Contents holds a CMS SignedData blob covering the rest
of the file. OTP ships no CMS encoder — :public_key handles certificates and
raw signing, not this — so the structure is built here directly in DER.
Detached means the signed content is not carried inside the blob: the bytes live in the PDF, and the signature refers to them by digest. That is what lets a signature cover the very file it sits in.
What is produced
ContentInfo
contentType id-signedData
content [0] SignedData
version 1
digestAlgorithms { sha256 | sha384 | sha512 }
encapContentInfo id-data, with no content — detached
certificates [0] the signer, plus any chain given
signerInfos one SignerInfo
sid issuer and serial number
signedAttrs [0] contentType, signingTime, messageDigest
signature RSA over the DER of signedAttrsThe signature covers the signed attributes, not the content directly, which
is what CMS requires once signedAttrs is present. Those attributes carry the
content's digest, so the content is still bound to the signature.
Interoperability
Output is verified against OpenSSL in the test suite rather than only against itself, because a signature format that only its author can read is not a signature format.
Summary
Functions
Build a detached CMS signature over content.
Types
Functions
Build a detached CMS signature over content.
certificate_der is the signer's certificate; chain is any intermediate
certificates to include, which a verifier needs when it does not already hold
them. signing_time is a DateTime — passed in rather than read from the
clock so that signing is reproducible and testable.