* Build each crate's integration tests as one binary
Every tests/*.rs file is its own executable that links the whole crate
graph. Move each crate's test files into tests/it/ as modules of one
tests/it/main.rs, for apps/pdfcraft, apps/pdfcraft-cli, automation, cos,
crypt, engine, render, sign and ui-egui. ui-egui's ui_group binary and
the support modules move into tests/it/ too. Crates with a single test
file keep it. The test executables go from 150 to 52, and every crate
runs the same number of tests as before.
ui-egui perf keeps its own binary (own process): its frame-time budgets
would charge each measurement for the other tests running beside it.
What the move needs:
- include_str!/include_bytes! and #[path] paths gain one "../".
- ui-egui: one GPU lock in tests/it/main.rs replaces the five per-file
ones (content, document_links, editing, fill_sign, view), so one
process creates one wgpu device at a time. The drop-line test in ui.rs
and the screenshot blocks behind PDFCRAFT_*_SHOT(S) and
CRAFT_UI_DOCKING_DIR, which render without holding it, take it too.
- pdfcraft winit_wayland_scroll: the vendored winit source it compiles
names crate::event, so that shim lives in main.rs.
- parity evidence names the new paths.
* Name the one-binary test paths in docs and comments
- READMEs, docs, ATTRIBUTION and source comments name tests/it/<file>.rs.
- The oracle README's example filters with --test it encryption::qpdf_agrees.
- pdfcraft's GPU lock comment points at the UI tests' shared lock in
crates/ui-egui/tests/it/main.rs.
A Keychain identity came back with an empty `chain`, so a signature made with
it carried only the signer's certificate. A validator that doesn't already
hold the intermediates (Acrobat, or PdfCraft on another machine) then can't
build the path to the root. The Windows certificate store identities already
carry the chain Windows builds.
`keychain::find` now asks the Security framework for the chain (SecTrust with
the basic X.509 policy, no network fetch) and keeps every certificate but the
signer's. It is best effort: a certificate macOS can't chain still signs.
`chain-legacy.p12` is `chain.p12` re-exported in the legacy format that
`security import` accepts, for a new ignored Keychain test.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* M9: more signature validation algorithms
Validation now reads what real signers write, and says when it is weak:
- Digests SHA-224, SHA-512/224, SHA-512/256, SHA3-224/256/384/512 and
RIPEMD-160, beside SHA-1 and SHA-2.
- RSA PKCS#1 v1.5 for every digest, in `rsa_pad`: the one expected encoding
is built and compared byte for byte, with or without the DigestInfo's NULL
(RFC 8017 App. B.1). A signature over the bare digest, which doesn't say
which hash it uses, is refused. The signature value must be below the
modulus (RFC 8017 §5.2.2); s and s + n both verified before.
- RSA-PSS with the hash, MGF1 hash and salt length the signature declares.
- ECDSA as DER, non-minimal DER or raw r||s on P-256, P-384, P-521 and
brainpoolP256r1/P384r1/P512r1 (BSI "plain" ECDSA OIDs too); brainpoolP512r1
is hand-written on crypto-bigint because no RustCrypto crate has it.
- Ed25519 (RFC 8419), and the legacy adbe.x509.rsa_sha1 format.
- An algorithm PdfCraft can't check is Unknown, never Invalid.
- SHA-1 and RIPEMD-160 signatures validate, but the signature's details say
the algorithm is weak (wording pinned by tests).
- Encoding irregularities that were tolerated are listed in the details
(`verify_noting`; `verify` keeps its signature).
Found while testing, each with a regression test that failed before the fix:
a brainpoolP512r1 public key with a coordinate >= p panicked inside
crypto-bigint's `sub_mod` (the certificate comes from the PDF); it is refused
now, and the point at infinity is an invalid signature, not an error.
Vectors were made with OpenSSL (tests/data/README.md has the commands).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Update comment to clarify MAC digest restrictions
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* M9: a legacy x509.rsa_sha1 signature whose key the verifier rejects is Invalid; only unsupported keys are "can't check yet"
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
The app, crates, binaries, bundle id, packaging, icons, screenshots and docs are now
PdfCraft / pdfcraft (repo storytold/pdfcraft). On first launch the desktop app moves the
PrintCraft settings and crash-recovery folders to the new name, and both apps read settings
saved under the old storage key, so upgrades keep recent files, preferences and unsaved work.
The signing test fixtures keep their PrintCraft subject names (they are binary).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>