Skip to content

Commit 7390ee4

Browse files
authored
Encode manifest as CBOR (#244)
1 parent 90acfd8 commit 7390ee4

55 files changed

Lines changed: 1392 additions & 551 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ missing-errors-doc = "allow"
5757
missing-panics-doc = "allow"
5858
must-use-candidate = "allow"
5959
needless-pass-by-value = "allow"
60+
new-without-default = "allow"
6061
pedantic = { level = "deny", priority = -1 }
6162
result-large-err = "allow"
63+
self-named-constructors = "allow"
6264
similar-names = "allow"
6365
struct-field-names = "allow"
6466
too-many-lines = "allow"

README.md

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ It is an alternative to `.sfv` files and tools like `shasum`. Files are hashed
2323
using [BLAKE3](https://github.com/BLAKE3-team/BLAKE3/), a fast, cryptographic
2424
hash function.
2525

26-
A manifest named `filepack.json` containing the hashes of files in a directory
27-
can be created with:
26+
A manifest named `manifest.filepack` containing the hashes of files in a
27+
directory can be created with:
2828

2929
```shell
3030
filepack create path/to/directory
3131
```
3232

33-
Which will write the manifest to `path/to/directory/filepack.json`.
33+
Which will write the manifest to `path/to/directory/manifest.filepack`.
3434

3535
Files can later be verified with:
3636

@@ -125,13 +125,13 @@ filepack create --deny distribution
125125

126126
Verify the contents of a directory against a manifest.
127127

128-
To verify the contents of `DIR` against `DIR/filepack.json`:
128+
To verify the contents of `DIR` against `DIR/manifest.filepack`:
129129

130130
```shell
131131
filepack verify DIR
132132
```
133133

134-
If the current directory contains `filepack.json`, `DIR` can be omitted:
134+
If the current directory contains `manifest.filepack`, `DIR` can be omitted:
135135

136136
```shell
137137
filepack verify
@@ -171,13 +171,14 @@ with the `--data-dir` option.
171171
Manifest
172172
--------
173173

174-
`filepack` manifests are conventionally named `filepack.json` and are placed
175-
alongside the files they reference.
174+
`filepack` manifests are conventionally named `manifest.filepack` and are
175+
placed alongside the files they reference.
176176

177-
Manifests are [UTF-8](https://en.wikipedia.org/wiki/UTF-8)-encoded
178-
[JSON](https://www.json.org/json-en.html).
177+
Manifests are [CBOR](https://www.rfc-editor.org/rfc/rfc8949.html) and may be
178+
converted to JSON for inspection or manipulation with `filepack manifest`.
179179

180-
Manifests contain an object with two mandatory keys, `files` and `notes`.
180+
Manifests, when converted to JSON, are an object with two mandatory keys,
181+
`files` and `signatures`.
181182

182183
### `files`
183184

@@ -186,28 +187,25 @@ directory entries. Directory entries may be subdirectories or files. Files are
186187
objects with keys `hash`, the hex-encoded BLAKE3 hash of the file, and `size`,
187188
the length of the file in bytes.
188189

189-
As a consequence of the manifest being UTF-8, all path components must be
190-
valid Unicode.
191-
192-
Path components may not be `.` or `..`, contain the path separators `/` or `\`,
193-
contain NUL, be longer than 255 bytes, or begin with a Windows drive prefix,
194-
such as `C:`.
190+
Path components are UTF-8 and may not be `.` or `..`, contain the path
191+
separators `/` or `\`, contain NUL, be longer than 255 bytes, or begin with a
192+
Windows drive prefix, such as `C:`.
195193

196194
### `signatures`
197195

198196
The value of the mandatory `signatures` key is an array of signatures.
199-
Signatures are bech32 strings that include an Ed25519 key, the package
197+
Signatures are Bech32m strings that include an Ed25519 key, the package
200198
fingerprint the signature is made over, an optional timestamp, and the
201199
signature itself.
202200

203201
Public keys are Curve25519 points and signatures are Ed25519 signatures made
204-
over the root of a Merkle tree which commits to the content of `files` via the
205-
package fingerprint.
202+
over the hash of a serialized CBOR message containing the package fingerprint
203+
which commits to the content of `files`.
206204

207205
### Example
208206

209-
An manifest over a directory containing the files `README.md` and `src/main.c`,
210-
signed by the public key
207+
An manifest converted to JSON over a directory containing the files `README.md`
208+
and `src/main.c`, signed by the public key
211209
`public1a67dndhhmae7p6fsfnj0z37zf78cde6mwqgtms0y87h8ldlvvflyqcxnd63`:
212210

213211
```json
@@ -228,14 +226,14 @@ signed by the public key
228226
}
229227
```
230228

231-
The signature is elided for brevity. Signatures are bech32m-encoded strings
229+
The signature is elided for brevity. Signatures are Bech32m-encoded strings
232230
containing both a public key and an Ed25519 signature.
233231

234232
Keys, Signatures, Fingerprints, and Hashes
235233
------------------------------------------
236234

237235
Public keys, private keys, signatures, and package fingerprints are all
238-
[bech32m](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki)-encoded
236+
[Bech32m](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki)-encoded
239237
strings beginning with `public1…`, `private1…`, `signature1…`, and `package1…`
240238
respectively.
241239

@@ -252,7 +250,7 @@ new package. `filepack create` then loads `metadata.yaml` if present, checks
252250
for validity and unknown fields, and writes the CBOR serialization to
253251
`metadata.cbor` in the package root.
254252

255-
`metadata.yaml` is retained as a human-readable reference, and for amending
253+
`metadata.yaml` is retained as a human-readable reference and for amending
256254
metadata, but `metadata.cbor` is the authoritative source of metadata. For
257255
consumption by scripts and tools, `filepack metadata` prints the contents of
258256
`metadata.cbor` as JSON.
@@ -269,6 +267,9 @@ Please feel free to open an issue with ideas for new metadata fields.
269267

270268
### Schema
271269

270+
This schema is for the YAML authoring format and the JSON output of
271+
`filepack metadata`. The CBOR schema is currently undocumented.
272+
272273
Fields are given as `NAME: TYPE`.
273274

274275
Mandatory fields:
@@ -444,12 +445,12 @@ contents is not present.
444445
Fingerprints
445446
------------
446447

447-
Filepack signatures are made over the package fingerprint, which is the root of
448-
a Merkle tree of the files and directories contained in the manifest.
448+
Filepack signatures are made over the package fingerprint, which is the hash of
449+
a CBOR object which commits to the files and directories contained in the
450+
manifest.
449451

450452
Fingerprints are BLAKE3 hashes, constructed such that it is impossible to
451-
produce objects which are different, either in type or content, but which have
452-
the same fingerprint.
453+
produce packages which are different but which have the same fingerprint.
453454

454455
Fingerprints may be used as a globally unique identifier. If two packages have
455456
the same fingerprint, they have the same content.
@@ -470,8 +471,8 @@ To create a filepack manifest:
470471
filepack create [DIRECTORY]
471472
```
472473

473-
This creates `filepack.json` containing hashes and file sizes of all files in
474-
the `DIRECTORY` and subdirectories.
474+
This creates `manifest.filepack` containing hashes and file sizes of all files
475+
in the `DIRECTORY` and subdirectories.
475476

476477
To enable linting, use the `--deny` flag with a lint or lint group:
477478

@@ -611,7 +612,7 @@ Create a filepack manifest with:
611612
filepack create <PACKAGE>
612613
```
613614

614-
This will create `<PACKAGE>/filepack.json`
615+
This will create `<PACKAGE>/manifest.filepack`
615616

616617
To later verify the package against the manifest:
617618

@@ -760,17 +761,17 @@ over simple file verification with `.sfv` files.
760761
- Filepack can detect both accidental corruption and intentional modification,
761762
whereas `.sfv` files can only detect accidental corruption.
762763

763-
- Because `filepack.json` manifests contain file sizes, Filepack can tell the
764-
user not just whether a file has been modified, but also whether it is empty,
765-
truncated, or too long.
764+
- Because `manifest.filepack` manifests contain file sizes, Filepack can tell
765+
the user not just whether a file has been modified, but also whether it is
766+
empty, truncated, or too long.
766767

767768
- Filepack packages have a fingerprint, a short text string beginning with
768769
`package1…` which is guaranteed to be globally unique, allowing packages to
769770
be identified and referenced by fingerprint alone.
770771

771-
- Fingerprints can be used to verify that a `filepack.json` manifest itself has
772-
not been tampered with, proving authenticity of a package regardless of its
773-
source.
772+
- Fingerprints can be used to verify that a `manifest.filepack` manifest itself
773+
has not been tampered with, proving authenticity of a package regardless of
774+
its source.
774775

775776
- Packages can be signed, allowing users to verify authenticity of any package
776777
from a packager by public key, a short string beginning with `public1…`.

justfile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
watch +args='ltest':
1+
watch +args='lcheck':
22
cargo watch --clear --exec '{{ args }}'
33

44
clippy: (watch 'lclippy --tests --all --all-targets -- --deny warnings')
@@ -45,7 +45,7 @@ example: tmp
4545
cp src/main.rs tmp/src
4646
cargo run create tmp
4747
cargo run sign --time tmp
48-
cat tmp/filepack.json | jq | pbcopy
48+
cat tmp/manifest.filepack | jq | pbcopy
4949

5050
publish: tmp
5151
#!/usr/bin/env bash
@@ -99,15 +99,15 @@ sign-release: tmp
9999
VERSION=`bin/version`
100100
gh release download \
101101
--repo casey/filepack \
102-
--pattern filepack.json \
102+
--pattern manifest.filepack \
103103
--dir tmp \
104104
$VERSION
105-
cargo run sign tmp/filepack.json
105+
cargo run sign tmp/manifest.filepack
106106
gh release upload \
107107
--clobber \
108108
--repo casey/filepack \
109109
$VERSION \
110-
tmp/filepack.json
110+
tmp/manifest.filepack
111111

112112
verify-release: tmp
113113
#!/usr/bin/env bash

0 commit comments

Comments
 (0)