Sign and verify manifests in Go with OpenPGP instead of running gpg (closes #181)
check / check (push) Waiting to run
check / check (push) Waiting to run
mfer ran the gpg binary to sign, export keys and verify, so it failed wherever gpg is missing. It now uses github.com/ProtonMail/go-crypto/openpgp. --sign-key and MFER_SIGN_KEY name a file holding one version 4 OpenPGP secret key; a protected key's passphrase comes from MFER_SIGN_KEY_PASSPHRASE or a terminal prompt. gen and freshen check that the key can sign before they read any file. Verification keeps the rules of the --require-signature fix: one primary key in the embedded block, counted from its packets, exactly one signature, made by that key or a subkey, and signer equal to its fingerprint. The embedded block may hold no DSA key and no secret key, and an armored field must be one well-formed block. Model: opus-5-5
This commit was merged in pull request #183.
This commit is contained in:
+11
-8
@@ -6,7 +6,7 @@ Version 1.0
|
||||
|
||||
An `.mf` file is a binary manifest that describes a directory tree of files,
|
||||
including their paths, sizes, and cryptographic checksums. It supports optional
|
||||
GPG signatures for integrity verification and optional timestamps and file
|
||||
OpenPGP signatures for integrity verification and optional timestamps and file
|
||||
permissions for metadata preservation.
|
||||
|
||||
Nothing goes in the 1.0 manifest that 1.0 does not read or write: no field is
|
||||
@@ -36,9 +36,9 @@ The outer message contains:
|
||||
| `sha256` | 104 | bytes | SHA-256 hash of the **compressed** `innerMessage` (corruption detection) |
|
||||
| `uuid` | 105 | bytes | Random v4 UUID; must match the inner message UUID |
|
||||
| `innerMessage` | 199 | bytes | Zstd-compressed serialized `MFFile` message |
|
||||
| `signature` | 201 | bytes (optional) | GPG signature (ASCII-armored or binary) |
|
||||
| `signature` | 201 | bytes (optional) | OpenPGP detached signature (ASCII-armored or binary) |
|
||||
| `signer` | 202 | bytes (optional) | Fingerprint of the signing key |
|
||||
| `signingPubKey` | 203 | bytes (optional) | Full GPG signing public key |
|
||||
| `signingPubKey` | 203 | bytes (optional) | Full OpenPGP public key of the signing key (ASCII-armored or binary) |
|
||||
|
||||
### SHA-256 Hash
|
||||
|
||||
@@ -142,17 +142,20 @@ Where:
|
||||
- `<SHA256>` is the hex-encoded SHA-256 hash from the outer message (covering
|
||||
compressed data)
|
||||
|
||||
Components are separated by hyphens. The signature is produced by GPG over this
|
||||
canonical string and stored in the `signature` field of the outer message. The
|
||||
signing key's public key goes in `signingPubKey` and its fingerprint, in hex, in
|
||||
`signer`.
|
||||
Components are separated by hyphens. The signature is an OpenPGP detached
|
||||
signature over this canonical string, stored in the `signature` field of the
|
||||
outer message. The signing key's public key goes in `signingPubKey` and its
|
||||
fingerprint, in hex, in `signer`.
|
||||
|
||||
A verifier accepts a signed manifest only if `signingPubKey` holds exactly one
|
||||
primary key, `signature` is one good signature over the canonical string made by
|
||||
that key (or one of its subkeys), and `signer` is that key's fingerprint. The
|
||||
reference implementation refuses to load a manifest that fails these checks;
|
||||
`check` and `fetch` given `--require-signature` then compare the required
|
||||
fingerprint with `signer`.
|
||||
fingerprint with `signer`. It also refuses a manifest whose `signingPubKey`
|
||||
holds a DSA key or subkey, or any secret key or subkey, since checking the
|
||||
self-signatures of a DSA key or the numbers of a secret key can take hours when
|
||||
those numbers are very large.
|
||||
|
||||
## Deterministic Serialization
|
||||
|
||||
|
||||
Reference in New Issue
Block a user