TPadesPaddingScheme = (psRsaPss, psRsaPkcs1v15, psEcdsa);
TPadesSignerOptions = record
CertificateThumbprint: string;
PaddingScheme: TPadesPaddingScheme;
class function Default: TPadesSignerOptions; static;
end;
TPadesChainCertArray = array of TBytes;
TPadesResolvedSigner = record
Signer: ICmsSigner;
SignerCertDer: TBytes;
ChainCertDer: TPadesChainCertArray;
end;
TPdfRevocationMode = (prmNone, prmOffline, prmOnlineAllowed,
prmOnlineRequired);
TPdfStringArray = array of string;
TPdfCertificatePathOptions = record
ValidationTime: TDateTime;
RevocationMode: TPdfRevocationMode;
RequiredPolicyOids: TPdfStringArray;
MaxCertificates: Integer;
MaxCertificateBytes: Integer;
MaxFetchBytes: Integer;
MaxPathDepth: Integer;
class function Default: TPdfCertificatePathOptions; static;
end;
TPdfCertificatePathReport = record
Trusted: Boolean;
PathBuilt: Boolean;
PolicyValid: Boolean;
RevocationChecked: Boolean;
PathCertificateCount: Integer;
ErrorCode: Integer;
ErrorMessage: string;
end;
IPdfTrustStore = interface
function LoadTrustAnchors: TPadesChainCertArray;
end;
IPdfValidationFetcher = interface
function Fetch(const Uri: string; MaxBytes: Integer;
out Data: TBytes): Boolean;
end;
IPdfCertificatePathValidator = interface
function Validate(const LeafCertificate: TBytes;
const Intermediates, TrustAnchors: TPadesChainCertArray;
TrustStore: IPdfTrustStore; Fetcher: IPdfValidationFetcher;
const Options: TPdfCertificatePathOptions;
out Report: TPdfCertificatePathReport): Boolean;
end;
IPadesSignerProvider = interface
function BackendName: string;
function Resolve(const Options: TPadesSignerOptions): TPadesResolvedSigner;
end;
TPdfPkcs11Slot = record
SlotID: UInt64;
Description: string;
TokenLabel: string;
TokenPresent: Boolean;
end;
TPdfPkcs11Slots = array of TPdfPkcs11Slot;
TPdfPkcs11Certificate = record
SlotID: UInt64;
ObjectID: TBytes;
LabelText: string;
CertificateDer: TBytes;
Mechanisms: TPdfStringArray;
end;
TPdfPkcs11Certificates = array of TPdfPkcs11Certificate;
IPdfPkcs11SignerProvider = interface(IPadesSignerProvider)
function EnumerateSlots: TPdfPkcs11Slots;
function EnumerateCertificates(SlotID: UInt64): TPdfPkcs11Certificates;
procedure CloseProtectedSessions;
end;
TPdfCmsVerifyStatus = (pcvsUnavailable, pcvsValid, pcvsInvalid,
pcvsUnsupported, pcvsIndeterminate);
TPdfCmsRevocationReason = (pcrrNone, pcrrCertificateRevoked, pcrrCrlExpired,
pcrrCrlNotYetValid, pcrrCrlUnavailable, pcrrCrlSignatureInvalid,
pcrrCrlInvalid, pcrrChainUntrusted, pcrrUnknown, pcrrOcspUnavailable,
pcrrOcspInvalid, pcrrOcspStatusUnknown);
TPdfCmsVerifyStage = (pcvstCryptographicSignature, pcvstChainBuild,
pcvstOnlineRetrieval, pcvstRevocationCheck);
TPdfCmsVerifyCheckpoint = procedure(Stage: TPdfCmsVerifyStage) of object;
TPdfCmsVerifyOptions = record
OnlineRetrieval: Boolean;
CheckRevocation: Boolean;
CollectChainCertificates: Boolean;
UrlRetrievalTimeoutMs: Cardinal;
OnCheckpoint: TPdfCmsVerifyCheckpoint;
CollectSignerDiagnostics: Boolean;
MaxSignerCount: Integer;
class function Default: TPdfCmsVerifyOptions; static;
end;
TPdfCmsSignerVerifyResult = record
SignerIndex: Integer;
SignatureStatus, TrustStatus, RevocationStatus: TPdfCmsVerifyStatus;
SignatureError, TrustError: Cardinal;
SignerCertificate: TBytes;
RevocationReason: TPdfCmsRevocationReason;
RevocationError: Cardinal;
RevocationCertificate: TBytes;
end;
TPdfCmsSignerVerifyResults = array of TPdfCmsSignerVerifyResult;
TPdfCmsVerifyResult = record
SignatureStatus: TPdfCmsVerifyStatus;
TrustStatus: TPdfCmsVerifyStatus;
RevocationStatus: TPdfCmsVerifyStatus;
SignatureError: Cardinal;
TrustError: Cardinal;
SignerCertificate: TBytes;
ChainCertificates: TPadesChainCertArray;
RevocationReason: TPdfCmsRevocationReason;
RevocationError: Cardinal;
RevocationCertificate: TBytes;
SignerResults: TPdfCmsSignerVerifyResults;
SignerDiagnosticsStatus: TPdfCmsVerifyStatus;
SignerCount: Integer;
end;
IPdfCmsVerifier = interface
function BackendName: string;
function VerifyDetached(const CmsDer: TBytes;
Segment1: Pointer; Segment1Length: Cardinal;
Segment2: Pointer; Segment2Length: Cardinal;
const Options: TPdfCmsVerifyOptions): TPdfCmsVerifyResult;
function VerifyAttached(const CmsDer: TBytes;
const Options: TPdfCmsVerifyOptions): TPdfCmsVerifyResult;
end;
procedure ConfigurePadesCmsVerifier(const Verifier: IPdfCmsVerifier);
function PadesCmsVerificationAvailable: Boolean;
function PadesCmsVerificationBackendName: string;
function PadesCryptoAvailable: Boolean;
function PadesCryptoBackendName: string;
function ResolvePadesSigner(const Options: TPadesSignerOptions): TPadesResolvedSigner;
procedure ConfigurePdfCertificatePathValidator(
const Validator: IPdfCertificatePathValidator);
function ValidatePdfCertificatePath(const LeafCertificate: TBytes;
const Intermediates, TrustAnchors: TPadesChainCertArray;
TrustStore: IPdfTrustStore; Fetcher: IPdfValidationFetcher;
const Options: TPdfCertificatePathOptions;
out Report: TPdfCertificatePathReport): Boolean;
procedure ConfigurePadesSignerProvider(const Provider: IPadesSignerProvider);
TPadesSignerResolverProc = function(const Options: TPadesSignerOptions): TPadesResolvedSigner;
PadesSignerResolverOverride: TPadesSignerResolverProc;
PdfCertificatePathValidator: IPdfCertificatePathValidator;
PadesSignerProvider: IPadesSignerProvider;
PadesCmsVerifier: IPdfCmsVerifier;
FPdfCrypto provides the entry point to PAdES signing. PadesCryptoAvailable checks both signing material and backend availability, and PadesCryptoBackendName names the chosen backend; Windows defaults to Cryptography Next Generation, whilst other platforms use the explicitly configured OpenSSL key and certificate in FPdfCryptoSsl
ResolvePadesSigner takes a certificate thumbprint and a padding scheme and returns a fully populated TPadesResolvedSigner: the ICmsSigner implementation that performs the private-key operation, the signer certificate DER, and the issuing chain certificates. The result is passed straight to FPdfCms.BuildSignedData
Custom integrations can register an IPadesSignerProvider, including an IPdfPkcs11SignerProvider that enumerates token slots and certificates, or use PadesSignerResolverOverride as a deterministic resolver seam
Certificate path validation is provider-based and budgeted: callers configure IPdfCertificatePathValidator, optionally supply explicit trust anchors, an IPdfTrustStore, and an IPdfValidationFetcher, then inspect TPdfCertificatePathReport
| Function | Description |
|---|---|
PadesCryptoAvailable | Returns True when a crypto backend is available for PAdES signing on the current platform |
PadesCryptoBackendName | Returns the display name of the active crypto backend |
ResolvePadesSigner | Resolves a certificate thumbprint and padding scheme into a signer, signer certificate, and chain |
ConfigurePdfCertificatePathValidator | Sets or clears the process-wide IPdfCertificatePathValidator used by ValidatePdfCertificatePath |
ValidatePdfCertificatePath | Validates a leaf certificate against intermediates and the combined explicit and trust-store anchors after enforcing certificate count, size, fetch and path-depth budgets |
ConfigurePadesSignerProvider | Sets or clears the process-wide signer provider used ahead of the platform backend |
ConfigurePadesCmsVerifier | Installs the PAdES validator's CMS verification backend; clearing it reinstates Windows CryptoAPI on Windows, whilst other platforms need an explicit ConfigureSslCmsVerifier or ConfigureKeychainCmsVerifier call |
PadesCmsVerificationAvailable | Returns True when some backend can verify CMS on this build, whether registered or built in |
PadesCmsVerificationBackendName | Returns the display name of the active verification backend, or an empty string when none is present |
| Interface member | Description |
|---|---|
IPdfTrustStore.LoadTrustAnchors | Returns additional DER-encoded trust anchors subject to the configured certificate budgets |
IPdfValidationFetcher.Fetch | Fetches validation material from Uri without exceeding MaxBytes |
IPdfCertificatePathValidator.Validate | Builds and evaluates the certificate path and populates TPdfCertificatePathReport |
IPadesSignerProvider.BackendName | Returns the provider display name exposed by PadesCryptoBackendName |
IPadesSignerProvider.Resolve | Returns complete signer material for the supplied TPadesSignerOptions |
IPdfPkcs11SignerProvider.EnumerateSlots | Returns the available PKCS#11 slots and token-presence metadata |
IPdfPkcs11SignerProvider.EnumerateCertificates | Returns the certificates and signing mechanisms visible in one PKCS#11 slot |
IPdfPkcs11SignerProvider.CloseProtectedSessions | Closes protected or authenticated PKCS#11 sessions owned by the provider |
IPdfCmsVerifier.BackendName | Returns the verification backend display name reported by PadesCmsVerificationBackendName |
IPdfCmsVerifier.VerifyDetached | Verifies a PDF signature, whose signed content is the two byte ranges either side of the /Contents hole |
IPdfCmsVerifier.VerifyAttached | Verifies a timestamp token, which carries its own content and needs no detached segments |
| Type | Description |
|---|---|
EPadesCrypto | Base exception for crypto-backend failures |
EPadesCryptoUnavailable | Raised when a required signer backend or certificate path validator is not configured |
TPadesPaddingScheme | psRsaPss, psRsaPkcs1v15, or psEcdsa |
TPadesSignerOptions | CertificateThumbprint selects the certificate and PaddingScheme selects the signature scheme; Default uses an empty thumbprint and psRsaPss |
TPadesChainCertArray | Dynamic array of DER-encoded chain certificates |
TPadesResolvedSigner | Signer, SignerCertDer and ChainCertDer bundle the resolved signer and certificate material |
TPdfRevocationMode | prmNone, prmOffline, prmOnlineAllowed, or prmOnlineRequired |
TPdfStringArray | Dynamic string array used for policy OIDs and provider mechanism names |
TPdfCertificatePathOptions | ValidationTime, RevocationMode, RequiredPolicyOids, MaxCertificates, MaxCertificateBytes, MaxFetchBytes and MaxPathDepth control validation and resource budgets; Default selects offline revocation with limits of 64 certificates, 4 MiB per certificate, 16 MiB fetched data, and path depth 16 |
TPdfCertificatePathReport | Trusted, PathBuilt, PolicyValid, RevocationChecked, PathCertificateCount, ErrorCode and ErrorMessage report the validation outcome |
TPdfPkcs11Slot | SlotID, Description, TokenLabel and TokenPresent describe one PKCS#11 slot |
TPdfPkcs11Slots | Dynamic array of TPdfPkcs11Slot records |
TPdfPkcs11Certificate | SlotID, ObjectID, LabelText, CertificateDer and Mechanisms describe one token certificate |
TPdfPkcs11Certificates | Dynamic array of TPdfPkcs11Certificate records |
TPadesSignerResolverProc | Function-pointer type for the PadesSignerResolverOverride injection var |
TPdfCmsVerifyStatus | pcvsUnavailable, pcvsValid, pcvsInvalid, pcvsUnsupported, or pcvsIndeterminate |
TPdfCmsRevocationReason | pcrrNone, pcrrCertificateRevoked, pcrrCrlExpired, pcrrCrlNotYetValid, pcrrCrlUnavailable, pcrrCrlSignatureInvalid, pcrrCrlInvalid, pcrrChainUntrusted, pcrrUnknown, pcrrOcspUnavailable, pcrrOcspInvalid or pcrrOcspStatusUnknown describes revocation evidence independently of the verification status |
TPdfCmsVerifyStage | pcvstCryptographicSignature, pcvstChainBuild, pcvstOnlineRetrieval, or pcvstRevocationCheck |
TPdfCmsVerifyCheckpoint | Object-method callback receiving each TPdfCmsVerifyStage as verification progresses |
TPdfCmsVerifyOptions | Verification is controlled by OnlineRetrieval, CheckRevocation, CollectChainCertificates, UrlRetrievalTimeoutMs and OnCheckpoint; CollectSignerDiagnostics requests individual signer snapshots, limited by MaxSignerCount. Default disables retrieval, revocation and signer diagnostics, permits 15 seconds for retrieval and up to 64 signer snapshots |
TPdfCmsSignerVerifyResult | SignerIndex follows encoded SignerInfo order; each signer has separate signature, trust and revocation statuses and native errors. SignerCertificate contains its DER certificate, whilst RevocationCertificate identifies the certificate associated with a captured revocation error if the backend supplies it |
TPdfCmsSignerVerifyResults | A dynamic array of signer snapshots subject to a count limit |
TPdfCmsVerifyResult | Aggregate signature, trust and revocation results are independent. The record additionally supplies SignatureError, TrustError, SignerCertificate, ChainCertificates, RevocationReason, RevocationError, RevocationCertificate, SignerResults, SignerDiagnosticsStatus and SignerCount |
Recompile consumers on upgrade, as public option and result records are larger. Custom verifiers should initialise managed results with Default(TPdfCmsVerifyResult), leaving unsupported snapshots unavailable; never use FillChar on a live record containing strings or dynamic arrays
RevocationReason and RevocationError are read from the TPdfCmsVerifyResult returned by IPdfCmsVerifier.VerifyDetached or VerifyAttached. PAdES trust validation carries them through as RevocationReason and NativeRevocationError, alongside separate TimeStampRevocationReason and NativeTimeStampRevocationError fields for timestamp tokens; evidence reports include both pairs
RevocationError holds a backend-specific native verification code, zero meaning that no native diagnostic was captured. OpenSSL uses the X509_V_ERR_* error space. Windows keeps a raw DWORD taken from a certificate's CERT_REVOCATION_INFO.dwRevocationResult, or from GetLastError should its revocation chain call fail; this is neither a uniform HRESULT error space nor the aggregate chain trust bitmask
OpenSSL differentiates confirmed revocation from expired, unavailable or invalid CRLs and unavailable, invalid or unknown OCSP evidence. Windows reports confirmed revocation, untrusted chains or unknown native failures. macOS checks signature integrity, Basic X.509 trust and revocation separately, returning Security.framework errors without forcing every failure into CRL or OCSP classifications
RevocationCertificate may identify a revoked intermediate instead of the CMS signer; it is empty if the backend cannot capture it. OpenSSL supports collection, but the present macOS backend leaves it empty
Neither pcrrNone nor a zero error proves that revocation was checked or succeeded; always inspect RevocationStatus
Enable CollectSignerDiagnostics=True to examine the limited snapshots in SignerResults. Once established, SignerCount gives the encoded SignerInfo count; zero means that count was not established
SignerDiagnosticsStatus=pcvsValid says all requested snapshots were collected, even snapshots for invalid signatures; it does not say that signatures passed. pcvsUnavailable means disabled or unsupported collection, and pcvsIndeterminate means parsing or resource limits prevented completion
OpenSSL and native macOS collection cannot exceed 64 signers. OpenSSL further limits diagnostic CMS input to 4 MiB and accumulated diagnostic input/output work to 64 MiB; macOS allows 4 MiB per returned certificate and 64 MiB altogether. A smaller MaxSignerCount reduces the requested count further
Snapshots reuse configured evidence and evidence fetched during aggregate verification. OpenSSL does not fetch again for each snapshot, and incomplete aggregate retrieval cannot yield a successful offline revocation snapshot
PadesSignerResolverOverride takes precedence, then an explicitly registered IPadesSignerProvider, then the platform default. Outside Windows, the default needs ConfigureSslSigningCredentials; libcrypto availability alone supplies neither key nor certificate
The OpenSSL default refuses a nonempty CertificateThumbprint, since explicit configuration has already chosen the certificate. Applications can still select Keychain signing with ConfigureKeychainSignerProvider
| Variable | Description |
|---|---|
PadesSignerResolverOverride | Optional resolver callback evaluated before registered and platform providers |
PadesCmsVerifier | Current CMS verification backend, usually assigned through ConfigurePadesCmsVerifier |
PdfCertificatePathValidator | Current certificate path validator, normally assigned through ConfigurePdfCertificatePathValidator |
PadesSignerProvider | Current signer provider, normally assigned through ConfigurePadesSignerProvider |