THotPDF.ValidatePDFMACChain Method
Validates every PDF MAC revision from the oldest cross-reference section to the active revision and returns revision-specific integrity diagnostics
Declaration
function ValidatePDFMACChain(const FileName: TFileName; const Password: AnsiString; out ValidationInfo: THPDFPDFMACChainValidationInfo): boolean; overload;
function ValidatePDFMACChain(const FileName: TFileName; const Password: AnsiString; const Options: THPDFPDFMACOptions; out ValidationInfo: THPDFPDFMACChainValidationInfo): boolean; overload;
Validation model
- Revision indices are zero-based and ordered from the original revision to the active revision
- The first revision containing
AuthCodebecomes the chain anchor, and every later revision must contain a valid PDF MAC - Each MAC is verified against the exact byte prefix ending at that revision's matching
startxrefand%%EOFboundary - The validator refuses a replaced historical MAC even when a newer active-revision MAC remains valid
KDFSaltmust remain stable after the anchor, and digest strength must not decrease between validated MAC revisions- Authenticated
/Pand/Permsvalues are checked per revision, covering the PDF MAC requirement permission bit
Result records
THPDFPDFMACChainValidationInfo reports RevisionCount, FirstMACRevisionIndex, ValidatedRevisionCount, FailureRevisionIndex, FailureXRefOffset, permission coverage, salt stability, digest monotonicity and one THPDFPDFMACRevisionValidation record per revision
THPDFPDFMACChainFailure distinguishes revision-boundary errors, missing MACs, invalid or replaced MACs, changed KDFSalt, digest downgrade and authenticated permission downgrade
The implementation enumerates the revision chain once and updates one cumulative cross-reference state, avoiding temporary PDF copies and repeated object indexing whilst preserving independent cryptographic verification for each protected revision
Delphi example
var
ChainInfo: THPDFPDFMACChainValidationInfo;
begin
if not PDF.ValidatePDFMACChain('authenticated.pdf', 'user-password',
ChainInfo) then
raise Exception.CreateFmt('Revision %d at xref %d failed: %s',
[ChainInfo.FailureRevisionIndex, ChainInfo.FailureXRefOffset,
ChainInfo.Message]);
end;
Preflight
CreatePreflightReport exposes the same result as PDFMACRevisionChain, allowing automated workflows to distinguish active-revision validity from complete revision-chain validity
See ValidatePDFMAC when only the active revision must be checked, or PDF MAC Algorithm Agility and Policy Profiles for digest policy semantics