Skip to content

Commit a3dbde2

Browse files
committed
feat: support multi-signer PDFs + JSON output
1 parent 525ba81 commit a3dbde2

2 files changed

Lines changed: 409 additions & 168 deletions

File tree

README.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,27 @@
22

33
A lightweight, modern PDF signing utility written in Rust. It creates an Adobe-compatible detached OpenPGP (GPG) signature and appends it to the PDF, making it easy to sign and verify documents without dragging in heavyweight PDF signing stacks.
44

5+
In practical security terms: many “enterprise PDF signing” solutions pull in a full **CMS/PKCS#7** / **X.509 PKI** toolchain (certificate chains, policy constraints, CRL/OCSP revocation logic, time-stamping/TSAs) plus PDF-form and incremental-update machinery to produce standards like **PAdES**. Those stacks are powerful, but they’re also complex to configure, audit, and automate.
6+
7+
`pdf-sign` intentionally stays on the minimalist end of that spectrum: it produces a detached OpenPGP signature over the PDF bytes and appends it, while delegating all private-key operations to `gpg-agent`.
8+
59
It’s designed to be a practical alternative to “traditional” PDF signing workflows: minimal setup, scriptable CLI, and it delegates cryptography to your existing `gpg-agent` (including smartcards/YubiKey).
610

711
The signed output stays minimal: the original PDF content is preserved and the signature is appended, keeping the file compliant so it still opens normally in standard PDF viewers.
812

913
## Features
1014

1115
* **Simple CLI**: `sign` and `verify` commands that compose well in pipelines.
12-
* **Works with your existing GPG setup**: Uses `gpg-agent` and your keyring (respects `GNUPGHOME`).
16+
* **Works with your existing GPG setup**: Uses `gpg-agent` (smartcards/YubiKey supported) and reads your local keybox (`pubring.kbx`) for public key lookups.
1317
* **Hardware-friendly**: Private keys can stay on a smartcard/YubiKey.
1418
* **Lightweight distribution**: Single-file script you can run directly (see Quickstart).
1519

1620
## Security model
1721

1822
* **No private keys in the tool**: All signing operations are performed by `gpg-agent`.
1923
* **Reduced key exposure**: Private keys never need to be loaded into this process.
20-
* **Explicit verification**: Verifies the appended signature against a provided certificate.
24+
* **Explicit verification**: Verifies using your local keybox by default (no `gpg` subprocess), or a provided certificate via `--cert`.
25+
* **Privacy by default**: Signer UIDs (name/email) are not embedded in the signature unless enabled.
2126

2227
## Quickstart
2328

@@ -60,25 +65,34 @@ chmod +x pdf-sign.rs
6065

6166
### Sign
6267

63-
Signs a PDF. Requires a key specification (File, Key ID, Fingerprint, or Email).
68+
Signs a PDF. Requires a key specification (File path, Key ID, Fingerprint, or Email).
69+
70+
If the input PDF already has appended OpenPGP signatures, `sign` preserves them and appends an additional signature (multi-signer workflow).
6471

6572
```bash
6673
./pdf-sign.rs sign contract.pdf --key 0xF1171FAAAA237211
6774
```
6875

6976
* **--output, -o**: Specify output path (Default: `input_signed.pdf`).
70-
* **--key**: Key identifier. If a file path is not found, it queries `gpg --export`.
77+
* **--key**: Key spec. If a file path is not found, it falls back to your local keybox (`pubring.kbx`).
78+
* **--embed-uid**: Embed the signer UID into the OpenPGP signature as notation (adds identity metadata).
79+
* **--json**: Output a single JSON object to stdout (useful for scripting).
7180

7281
### Verify
7382

74-
Verifies the appended signature against a provided public certificate.
83+
Verifies the appended signature. If `--cert` is omitted, it will look up the signer key in your local keybox (`pubring.kbx`).
84+
85+
If multiple signatures are appended, `verify` checks **all** of them and prints each signer’s details.
7586

7687
```bash
77-
./pdf-sign.rs verify contract_signed.pdf --cert signing-key.asc
88+
./pdf-sign.rs verify contract_signed.pdf
7889
```
7990

91+
* **--cert, -c**: Optional. Can be provided multiple times. Public certificate file path, fingerprint, key ID, or email.
92+
* **--json**: Output a single JSON object to stdout (useful for scripting).
93+
8094
## Environment
8195

82-
* `GNUPGHOME`: Respected for keyring lookups.
96+
* `GNUPGHOME`: Respected for keybox lookups (defaults to `~/.gnupg`).
8397
* `stderr`: Used for all progress, status, and error reporting.
8498
* `stdout`: Outputs the resulting file path (signing) or "OK" (verification) for pipeline composition.

0 commit comments

Comments
 (0)