Signs the document and writes the signed file to stream: the document's file followed by an incremental
update holding the signature, whose byte ranges cover the whole file except the signature value.
public void Sign(Stream stream, IPdfSigner signer, PdfSignatureOptions? options = null)
Where to write, from its current position. It is not disposed.
Signs the digest; PdfCertificateSigner for a certificate with its private key.
The field, the signature properties and the digest algorithm; null for the defaults.
ISO 32000-2 §12.8.1, §12.8.3.3, §12.8.3.4 and §12.7.5.5; ISO/TS 32001; ISO/TS 32002; ETSI EN 319 142-1. The signature goes into the unsigned signature field the options name, or into a
new invisible signature field (a widget with an empty rectangle on the first page, flags Print and Locked) added to the
interactive form, which is created when the document has none; the form's SigFlags gets SignaturesExist and AppendOnly
(Table 225). The field's value becomes a signature dictionary (Table 255, every value direct) with Filter
Adobe.PPKLite, the options' SubFilter (adbe.pkcs7.detached, or ETSI.CAdES.detached for a PAdES
signature, which has no Cert entry, §12.8.3.4.2), M and the properties the options give, a
Contents hexadecimal string reserved before anything is hashed, and a ByteRange of two ranges: from the first byte
of the file to the < of Contents, and from after its > to the end of the file, which is the end of
the update's %%EOF line. The offsets count from the first byte of the file.
The ranges are hashed with the options' digest algorithm (or the key's, DigestAlgorithm), the
signer signs the digest of the CMS signed attributes (content type, that message digest and the ESS signing-certificate-v2
attribute; no signing time, §12.8.3.4.3), digested with the same algorithm (ISO/TS 32002 §5.1.4), and the DER-encoded detached
CMS SignedData (RFC 5652, with the signer's certificate and chain, and the signature algorithm the key calls for: RSA
PKCS #1 v1.5 or RSASSA-PSS as RsaSignaturePadding says, or ECDSA) is written into Contents,
padded with zeros (§12.8.3.3.1). With ETSI.CAdES.detached that is a PAdES baseline B-B signature (ETSI EN 319 142-1).
Earlier signatures stay valid: the update only appends (§7.5.6, NOTE 1 of §12.8.1).
With Certification the signature is a certification signature (§12.8.2.2): its dictionary gets
a Reference with a DocMDP signature reference whose transform parameters hold the permissions (Table 257, P,
V 1.2), and the catalog's permissions dictionary a DocMDP entry naming it (Table 263); it is refused when the
document already has a signature (§12.8.1). When the field has a lock dictionary, or
FieldLock gives one (written to the field, indirect, Table 236), the lock's Action and
Fields are copied into a FieldMDP signature reference whose Data is the catalog (§12.8.2.4, Table 256). A
document whose certification signature, named by the catalog's Perms, or a signed field lock permits no changes (P 1) refuses another signature: the
permissions dictionary asks processors to enforce them (Table 263).
The save raises the version to what the signature needs (Table 260: PDF 1.6 for SHA-256, 1.7 for SHA-384 and SHA-512, 2.0 for ECDSA, SHA-3 and PAdES) and declares the ISO_ developer extensions of ISO/TS 32001 (SHA-3 digests) and ISO/TS 32002 (ECDSA), in the signed update; in strict mode a raise is refused before anything changes (issue #141).
With TimestampClient, once the signer returns the signature value the time-stamp authority is
asked for a token over it, and the token is added as the signer's signature time-stamp unsigned attribute (§12.8.3.3.1,
§12.8.3.4.3 b); RFC 3161 Appendix A): with ETSI.CAdES.detached, a PAdES B-T signature. Its room in Contents is
reserved with TokenSizeEstimate. A failed request leaves the document as a failed signer does.
An encrypted document is updated with its own key. When it has, or its permissions require, an integrity MAC (ISO/TS 32004),
the new MAC is attached to this signature as its pdfMacData unsigned attribute, digesting the signature's byte ranges
and its signature value, and the trailer's AuthCode points at the signature dictionary (§6.5.2, §6.6.3).
Once the last byte is written the document reads from the signed file, as after an incremental save (IncrementalUpdate), so signing again adds another revision. If the signer throws, nothing is written and the document is left as it was: every object, including what the save inside signing changed before the signer was asked (the modification date, the metadata layout of a raised version, completed font subsets, the catalog's version and extensions), and a modification date set explicitly is still the one the next save writes. A mutation: no read may run concurrently with it.