CMS Multiple Primary Signers

HotPDF can create one RFC 5652 SignedData container containing up to 256 independent primary SignerInfo records

Build requests

Each THPDFCMSPrimarySignerRequest supplies its own certificate and key material, document digest, THPDFCMSSignOptions, optional THPDFSignatureProvider, and provider key identifier

HPDFCMSBuildMultiSignedData validates every request before invoking any native key, external callback, timestamp callback, PDF MAC callback, or provider, preventing an invalid later request from causing avoidable partial remote signing work

SetLength(Signers, 2);
Signers[0].KeyMaterial := FirstKey;
Signers[0].DocumentDigest := HPDFCMSDigestBytes(DocumentBytes, cmsdaSHA256);
Signers[0].Options := FirstOptions;

Signers[1].KeyMaterial := SecondKey;
Signers[1].DocumentDigest := HPDFCMSDigestBytes(DocumentBytes, cmsdaSHA384);
Signers[1].Options := SecondOptions;
Signers[1].Provider := RemoteProvider;
Signers[1].KeyIdentifier := 'approval-key';

CMS := HPDFCMSBuildMultiSignedData(Signers);

Deterministic merge

HPDFCMSMergeSignedData combines already built CMS containers for asynchronous or distributed signing workflows without repeating private-key operations

Every input must use definite-length signedData envelopes and sets, must declare every digest algorithm used by its primary signers, and must carry byte-identical encapContentInfo; additional declared digest algorithms remain permitted

The merged container deduplicates digest algorithms, certificates, and revocation values, sorts all SET OF values by DER byte order, preserves every primary signer, and raises the outer version to the highest valid input requirement

Request order is intentionally not observable after encoding because signerInfos is a DER SET OF; parsing and verification results therefore use DER order rather than request order

A one-signer build and a one-container merge preserve the existing CMS bytes exactly

Independent validation

HPDFParseCMSSignatures, HPDFVerifyCMSSignaturesEx, and HPDFVerifyCMSSignerReport return an independent result for every primary signer, including its attributes, digest and signature policy, matching certificate, timestamps, counter-signatures, and failure status

A malformed or cryptographically invalid signer does not erase a valid sibling result, while the aggregate Boolean result is false unless every primary signer succeeds

Placeholder sizing

HPDFCMSEstimateMultiSignerPlaceholder derives each signature length without signing, builds the exact deduplicated static container shape with synthetic signature values, sums dynamic callback reserves, and applies the configured global safety margin, alignment, minimum, and maximum once

THPDFCMSPlaceholderEstimateInfo.SignatureBytes reports the sum for all primary signers and cpesMixed identifies a result whose signers used different estimate sources

PDF workflow boundary

The multi-signer APIs expose generic CMS functionality for applications whose consuming profile permits several primary signers in one container

Many PDF signature and PAdES workflows model one primary signer per signature dictionary, so use separate PDF signature fields unless the recipient profile explicitly accepts multi-signer CMS

See CMS SubjectKeyIdentifier signers, CMS digest-algorithm consistency, and CMS placeholder auto-sizing