Repository navigation
Read and write the document security store - #120
Merged
bobsingor merged 1 commit intoNov 15, 2026
Merged
Conversation
Long-term validation of a signature needs the certificates, OCSP answers and CRLs that prove its chain, and PAdES keeps them in the catalog's /DSS. Nothing in the fork reached it. EPDFDss_GetCount and EPDFDss_GetData read the store's three kinds of item, decoded: what /Certs, /OCSPs and /CRLs list, then what only a /VRI entry names, each stream once. EPDFDss_Add writes one item as a stream of its own and names it in the store's list. It makes the store and the list when they are missing and extends them where they are kept, as an object of their own or inside the catalog. It returns the stream's object number, and refuses a store or a list of the wrong type without changing anything. /VRI is read and never written. EPDFDoc_GetLoadedObjectValue reads the value of any object as the document's loaded bytes hold it, in the text and with the read status of EPDFObjectDiff_GetValue. The revision diff lists only the objects a revision wrote. Acrobat points a page at a new /Annots list and leaves the old one unwritten, and the engine needs the old list to judge what was added.
4 of 11 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Long-term validation of a signature (PAdES B-LT) needs the certificates, OCSP answers and CRLs that prove its chain. A PDF keeps them in the catalog's document security store,
/DSS, and nothing in the fork reached it. This adds three functions for the store, and one read that the signature change analysis needs.The store
EPDFDss_GetCount(doc, kind)andEPDFDss_GetData(doc, kind, index, buffer, length)read the store's items of one kind, decoded. The kinds areEPDF_DSS_CERTIFICATES,EPDF_DSS_OCSP_RESPONSESandEPDF_DSS_CRLS./Certs,/OCSPs,/CRLs), then what only a/VRIentry names (/Cert,/OCSP,/CRL), in the order of the entries' keys.EPDFDss_Add(doc, kind, data, size)writes one item as a stream of its own and appends it to the kind's list. It returns the stream's object number, or 0 when it refuses./Type. Neither Acrobat nor pyHanko writes/Typethere./DSSor a list that exists and is not a dictionary or an array is refused, and the document is unchanged./VRIentry and no/Extensions.These functions move bytes and nothing more. They parse none of them, look for no duplicates and remove nothing: what is worth storing, and what a stored item proves, is the engine's decision. They open the document's view scope, so in a layer a read sees the layer, and an add leaves the base alone.
A read of any object's loaded value
EPDFDoc_GetLoadedObjectValue(doc, obj_num, buffer, buflen, out_read_status, out_truncated)returns the value of any object as the document's loaded bytes hold it. The text is the oneEPDFObjectDiff_GetValuereturns, and the read status is the diff's (EPDF_DIFF_READ_OK,FAILED,ABSENT). Object 0 reads the trailer.The revision diff carries the values of the objects an update wrote. When Acrobat adds a signature field or a document timestamp to a page whose
/Annotsis an object of its own, it points the page at a new list and leaves the old list in the file, unwritten. The engine's change analysis has no way to compare the two lists, so it reads that update as forbidden, and Acrobat accepts it. With this read the engine opens the earlier revision and asks for the old list.Like the diff, it parses the loaded bytes and never reads the document's object cache. A number that is free or unknown reads
ABSENT. Bytes that do not parse readFAILEDwith the valuenull, so a failure is not taken for a null object.The engine side reads and writes the store through
doc.signaturesand uses the object read in the change analysis (plan: signature long-term validation). Pin this there after release.Tests
epdf_dss_embeddertest.cpp:BadArguments: a NULL document, an unknown kind, an index out of range, NULL data and size 0.ADocumentWithoutAStoreReadsEmpty.ReadsEachListDecoded: the three lists, one item stored through a filter, and a buffer too small to hold an item gets none of it.ReadsWhatOnlyTheIndexNamesAndEachStreamOnce:/VRIentries follow the list in key order, a stream named twice reads once, and an entry that is not a stream reference is skipped.AddMakesAStoreAsAnObjectOfItsOwn: an incremental save writes the catalog, the store and the new streams, and nothing else.AddExtendsAListThatIsAnObjectOfItsOwn: Acrobat's layout. The save writes the list and the new stream; the store and the catalog are not written again.AddExtendsAStoreInsideTheCatalog: the catalog is the one object that changes, and a kind without a list gets one inside it.AddRefusesAStoreItCannotExtend: a store or a list of the wrong type is refused, and the document is unchanged.AddOnALayerLeavesItsBaseAlone.AnEncryptedSaveKeepsTheStoreReadable.epdf_signature_embeddertest.cpp:LoadedObjectValueReadsWhatNoUpdateWrote: Acrobat's replaced/Annotslist, read from the earlier revision.LoadedObjectValueComesFromBytesNotCache: an edit in memory does not show, and an object made in memory readsABSENT.LoadedObjectValueSeparatesFailureFromNull.epdf_c_api_test.clists the four new exports.SetTextRenderMode,RenderBug664284WithNoNativeText,RenderHelloWorldWithFlagsandCaptionAppearanceGolden. Draw a signature field's box #114 and Read and write a page's viewports without loading the page #115 record the same kinds as failing on macOS without their changes. All 12 compare rendered pixels, and none calls the new functions. The base was not built again to compare.pdfium_testcalls none of the new functions.