v2.0.0-rc.1 - Encryption on the platform, a bounded regional layer, and validation that says what changed
Pre-releaseA release candidate for 2.0.0. Please exercise the certificate vault
migration before this goes stable, for the reason below.
composer require lsnepomuceno/signet-pdf:2.0.0-rc.1Composer will only resolve it with minimum-stability set accordingly, which is
what makes it safe to try.
The break nothing can check for you
CertificateVault::create() keeps its signature and returns a 32-byte key
where it returned 16. A storage column sized for the old width truncates it
silently, and no type checker can see that: the backward-compatibility check
reports nothing about it and is right to.
That checker also skipped seventeen files it could not compile, alongside the
twelve breaks it did report, so twelve is a floor rather than a total. Read
UPGRADE.md,
not the green check.
Nothing has to be re-encrypted. A key issued by 1.x keeps opening what it
sealed: the payload carries its version and withKey() picks the reader from
the key's length.
Breaking
-
ext-sodiumis now required, and new certificate material is sealed with
XChaCha20-Poly1305 instead of an AES-128-CBC and HMAC construction this package
assembled itself. Encrypt-then-MAC written in application code is the shape
that fails quietly, and encryption at rest is a convenience beside a PDF
signing package rather than the product. Material sealed here no longer opens
inlsnepomuceno/laravel-a1-pdf-signuntil that package learns the same
envelope; the other direction is unaffected. (0103) -
The ICP-Brasil layer moved to
IcpBrasil\, eight class names, behaviour
identical. If you do not sign Brazilian documents, none of it reaches you.
(0104) -
SealPlacement::LAST_PAGEis gone, replaced byEnums\SealPage::Last.
A numbered page is unchanged andSealPage::Lastis still the default, so a
placement that never named a page needs no edit. (0105)
Validation now says what changed, not only that something did
Six additions, none of which costs a consumer anything.
-
onlyAddedSignatures().coversWholeDocumentsaid bytes were appended
after a signature and never what they did, which is the live attack surface
for PAdES: append an annotation over the payment terms and the signature still
verifies, because the new bytes are outside its/ByteRange. Each revision is
now reported with the objects it defines and what they touched. True is not
a verdict of safe: a counter-signer produces the same shape. (0110) -
The
/ByteRangeis checked before it is believed. It is the one input to
validation an attacker writes, and everything downstream derived from it
unchecked: which bytes are hashed, and where the CMS is read from. Six
conditions now, the decisive one being that the gap is the value of a
/Contentskey rather than any window holding hexadecimal. Nothing changes
for a well-formed document. (0107) -
Enums\ValidationFinding. Ten cases naming facts the validator already
established, where the only ways to reach them were a dozen properties or
matching English in$error. Exactly one decides validity, and the enum
carries no severity: how muchNotTrustedmatters is not this package's call.
signet verify --jsonprints them. (0106) -
missingValidationMaterial().hasLongTermMaterial()answers presence;
B-LT promises a verifier could decide offline. A store with one certificate, a
/VRIentry and no OCSP satisfies the first completely. (0109) -
verifiableUntil(), so a document can be re-stamped before its chain can
no longer be built. An archive timestamp renews the horizon. Null means
unanswerable, never "never". (0108) -
$messageDigest, short and stable enough for an audit trail to record and
compare later. Not proof on its own. (0108)
Also
Every docblock in src/ now explains its design without naming the framework
the package was extracted from, and the arch rule that enforced that for imports
covers prose as well.
lsnepomuceno/laravel-a1-pdf-sign is not a consumer of this package. The
documentation said it was; it is a separate implementation sharing a lineage,
and that is now stated wherever it was claimed otherwise.
Verification
674 tests on PHP 8.4 and 8.5 with --fail-on-skipped, PHPStan at level max with
no baseline, type coverage at 100%, and zero warnings. Checked independently
against veraPDF, qpdf, pyHanko, poppler's pdfsig and the Arlington PDF Model.
Full detail in
CHANGELOG.md.