check / check (push) Canceled after 0s
Nothing goes in the 1.0 manifest that 1.0 does not read or write, and mfer never wrote either field. mf.proto now reserves the numbers 301 and 303 and both names in MFFilePath, and mf.pb.go is regenerated. The decoded-size check counts only file entries, hashes and timestamps, and counts a file entry, 16 bytes smaller without the two fields, at 160 bytes. export prints no ctime, and FileEntry loses the Ctime nothing set. FORMAT.md and the README no longer describe either field. The test of entries that decode too large gives each entry a second, empty hash: an entry with one hash and a modification time can no longer reach 8 times its size. Model: opus-5-5
94 lines
2.5 KiB
Protocol Buffer
94 lines
2.5 KiB
Protocol Buffer
syntax = "proto3";
|
|
|
|
option go_package = "sneak.berlin/go/mfer/mfer";
|
|
|
|
message Timestamp {
|
|
int64 seconds = 1;
|
|
int32 nanos = 2;
|
|
}
|
|
|
|
message MFFileOuter {
|
|
enum Version {
|
|
VERSION_NONE = 0;
|
|
VERSION_ONE = 1; // only one for now
|
|
}
|
|
|
|
// required mffile root attributes 1xx
|
|
Version version = 101;
|
|
|
|
enum CompressionType {
|
|
COMPRESSION_NONE = 0;
|
|
COMPRESSION_ZSTD = 1;
|
|
}
|
|
|
|
CompressionType compressionType = 102;
|
|
|
|
// these are used solely to detect corruption/truncation
|
|
// and not for cryptographic integrity.
|
|
int64 size = 103;
|
|
bytes sha256 = 104;
|
|
|
|
// uuid must match the uuid in the inner message
|
|
bytes uuid = 105;
|
|
|
|
bytes innerMessage = 199;
|
|
|
|
// 2xx for optional manifest root attributes
|
|
|
|
// one OpenPGP signature, armored or binary, over the canonical string
|
|
// ZNAVSRFG-<uuid>-<sha256 as a multihash>, with the uuid as 32
|
|
// lower-case hex digits and no hyphens, and the multihash in lower-case
|
|
// hex (see docs/FORMAT.md). A signature is never stored anywhere else.
|
|
optional bytes signature = 201;
|
|
// fingerprint of the signing primary key, in upper-case hex
|
|
optional bytes signer = 202;
|
|
// OpenPGP public key of the signer, one primary key, armored or binary
|
|
optional bytes signingPubKey = 203;
|
|
}
|
|
|
|
message MFFilePath {
|
|
// required attributes:
|
|
// Path invariants: must be valid UTF-8, use forward slashes only,
|
|
// be relative (no leading /), contain no ".." or "." segments, and
|
|
// no empty segments (no "//").
|
|
string path = 1;
|
|
int64 size = 2;
|
|
|
|
// gotta have at least one:
|
|
repeated MFFileChecksum hashes = 3;
|
|
|
|
// optional per-file metadata
|
|
optional Timestamp mtime = 302;
|
|
// permission bits, at most 0777; 0 when not recorded
|
|
uint32 mode = 304;
|
|
|
|
// used by no field, so that a later version cannot reuse them by accident
|
|
reserved 301, 303;
|
|
reserved "mimeType", "ctime";
|
|
}
|
|
|
|
message MFFileChecksum {
|
|
// 1.0 golang implementation must write a multihash here
|
|
// it's ok to only ever use/verify sha256 multihash
|
|
bytes multiHash = 1;
|
|
}
|
|
|
|
message MFFile {
|
|
enum Version {
|
|
VERSION_NONE = 0;
|
|
VERSION_ONE = 1; // only one for now
|
|
}
|
|
Version version = 100;
|
|
|
|
// required manifest attributes:
|
|
repeated MFFilePath files = 101;
|
|
|
|
// uuid is a random v4 UUID generated when creating the manifest
|
|
// used as part of the signature to prevent replay attacks
|
|
bytes uuid = 102;
|
|
|
|
// optional manifest attributes 2xx:
|
|
optional Timestamp createdAt = 201;
|
|
}
|
|
|