Skip to content

Sample documents

Twelve signed PDFs live in the repository, one per signature profile plus the awkward cases. They are there so a change to the signing engine can be checked against real readers rather than only against this package's own validator, which shares its assumptions with the code it validates.

Open them in Adobe Reader, in ITI Validar, or with poppler's pdfsig, and see what the package actually produces.

Browse them on GitHub, where each file can be viewed or downloaded, and where samples/README.md explains what each one proves in detail.

The files

SampleWhat it carries
legacy.pdf/SubFilter adbe.pkcs7.detached, ISO 32000-1, the widest reader support
pades-b-b.pdfPAdES B-B, ETSI.CAdES.detached with the ESS signing-certificate-v2 attribute
pades-b-t.pdfB-B plus an RFC 3161 token from freetsa.org
pades-b-lt.pdfB-T plus a Document Security Store
pades-b-lta.pdfB-LT plus an archive timestamp: a second /ByteRange, of type ETSI.RFC3161, covering the whole file
six-signatures.pdfSix signatures on one document, each still verifying
two-seals.pdfTwo signatures, each with its own visible seal in its own place
xref-stream.pdfTwo signatures on a PDF 1.5 document whose cross-reference sections are streams rather than tables
object-stream.pdfTwo signatures on a document whose catalog and pages are packed into an object stream
tagged.pdfA sealed signature on a PDF/UA document, where the seal joins the structure tree
signed-into-fields.pdfA template's own two signature fields, filled by name rather than appended beside
certified.pdfA certification at form-filling, then an approval signature on top of it

The last four are the interesting ones. Each exists because it was a defect first: cross-reference streams, object streams, filling a declared field, and signing after a certification are all cases where a signature can be produced that this package's validator accepts and a real reader does not.

The certificate

certificate.pfx is the throwaway self-signed certificate the test suite generates, and certificate.pem is the same certificate, not a second one: same serial, same subject, same password. The PEM exists so that entry point can be exercised against the identity the rest of the directory already uses.

Its password is in samples/README.md, and its private key is encrypted under that same password. A PEM key is frequently shipped unencrypted, and these samples deliberately do not model that.

Every reader will report the signer as untrusted

That is the certificate's provenance, not the signature's integrity: it is self-signed and chains to nothing. Everything else validates normally, including the document hash, the sub-filter, the timestamp token and the coverage of each signature.

To make Adobe Reader report it as trusted, import the bundle and add it as a trusted identity. ITI Validar will always reject it, since it trusts only the ICP-Brasil chain, and testing there needs a real ICP-Brasil certificate. This is the distinction Trust exists to make.

Verifying one yourself

bash
composer require lsnepomuceno/signet-pdf
vendor/bin/signet verify samples/six-signatures.pdf

Or against an independent reader, which is what these files are for:

bash
pdfsig samples/six-signatures.pdf

Regenerating them

They are reproducible rather than archived: samples/generate.php signs with the committed certificate instead of minting a new identity per run, which is what once left a signed fixture pointing at a certificate the repository no longer held, with nothing failing (0036).

bash
composer samples:build                 # all of them
composer samples:build -- pades-b-b    # one, by name

Three of them carry a token from a live timestamp authority, so this needs the internet and cannot use the local authority the tests use: a sample stamped by something that is not a third party proves nothing about one that is.

tests/Conformance/SamplesTest.php checks them on every run, so a sample that stops matching what the signer produces fails the suite rather than sitting there misleading a reader.

It checks the structures it was taught to check, which is not the same as every structure the signer writes, and the gap is closed as it is found: the /TU description and the structure-tree entries are asserted now, because the files went a release out of date without them and nothing noticed. That history is in samples/README.md rather than left for a reader to find by diffing.

Released under the MIT Licence.