Help us shape the future of Go! Take the 2026 Go Developer Survey

e2edecrypt

package
v0.56.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 37 Imported by: 0

Documentation

Index

Constants

View Source
const (
	NamesAlg      = "AES-SIV-512"
	NamesEnc      = "b64url"
	NameKeyBytes  = 64
	NameMaxBytes  = 255
	DirIDBytes    = 16
	LongSuffix    = ".fxl"
	SidecarSuffix = ".fxl.name"
)

Name encryption constants, identical to the browser's.

View Source
const FxeExtension = ".fxe"

FxeExtension is the stored-name suffix of a single encrypted file.

View Source
const MarkerName = ".filex-e2e.json"

MarkerName is the marker's file name at an encrypted folder's root.

View Source
const MaxOneShot = 200 * 1024 * 1024

MaxOneShot is the most content a 0x01 file carries. Writers use the one-shot format up to it and STREAM (0x02) above it, exactly as the browser does (E2E_MAX_FILE_BYTES), so every filex since the feature shipped reads the smaller files.

View Source
const MinIterations = 600_000

MinIterations is the fewest PBKDF2 iterations a writer uses. Readers accept any count from 1; a writer never goes below this (E2E_MIN_ITERATIONS).

View Source
const MinPasswordLen = 8

MinPasswordLen is the shortest folder password the writers accept, as the browser's dialog (E2E_MIN_PASSWORD_LEN).

View Source
const (

	// NamesLongDefault is the shortening threshold a new names slot gets
	// (E2E_NAMES_LONG_DEFAULT).
	NamesLongDefault = 220
)
View Source
const (
	// StreamChunkLog2 is the chunk size writers use (2^20 = 1 MiB).
	StreamChunkLog2 = 20
)
View Source
const (

	// VaultChunkLog2 is the STREAM chunk size vault writers use (2^20).
	VaultChunkLog2 = StreamChunkLog2
)
View Source
const VaultGCPassMax = 1000

VaultGCPassMax is the most a collection deletes in one pass (and one delete request).

View Source
const VaultRetention = 15 * time.Minute

VaultRetention is how long a replaced generation is kept for its readers.

Variables

View Source
var (
	// ErrWrongPassword: the password does not open the marker's verify blob.
	ErrWrongPassword = errors.New("wrong password")
	// ErrWrongRecoveryKey: malformed, wrong, or the folder has no recovery key.
	ErrWrongRecoveryKey = errors.New("wrong recovery key (or this folder has no recovery key)")
	// ErrNotMarker: the file is not a filex encrypted-folder marker.
	ErrNotMarker = errors.New("not a filex encrypted-folder marker (.filex-e2e.json)")
)
View Source
var (
	// ErrVaultNotFound: no entry at that path.
	ErrVaultNotFound = errors.New("no such file or folder in the vault")
	// ErrVaultExists: the name is taken in that folder.
	ErrVaultExists = errors.New("a file or folder with that name is already there")
	// ErrVaultNotDir: a path segment that should be a folder is a file.
	ErrVaultNotDir = errors.New("not a folder")
	// ErrVaultIsDir: a file operation on a folder.
	ErrVaultIsDir = errors.New("is a folder")
	// ErrVaultBadName: a name the format does not allow.
	ErrVaultBadName = errors.New("not a name a vault can hold")
	// ErrVaultFull: the change would pass the writer's entry limit.
	ErrVaultFull = fmt.Errorf("this vault already holds the most files and folders a vault may hold (%d)", e2e.VaultEntriesWriteMax)
	// ErrVaultTooDeep: the change would nest folders deeper than the format allows.
	ErrVaultTooDeep = fmt.Errorf("folders in a vault nest at most %d deep", e2e.VaultMaxDepth)
	// ErrVaultLoop: a folder moved into itself.
	ErrVaultLoop = errors.New("a folder cannot be moved into itself")
)
View Source
var ErrAlreadyEncrypted = errors.New("this folder is already an encrypted folder (it holds " + MarkerName + ")")

ErrAlreadyEncrypted: the input is an encrypted folder already.

View Source
var ErrContent = errors.New("content failed authentication (damaged, tampered with, or from another folder)")

ErrContent: the content failed authentication — the file is damaged or was tampered with, or it belongs to another folder.

View Source
var ErrFileExists = errors.New("the output file already exists - pass another with -o")

ErrFileExists: the file a .fxe would decrypt to is already there.

View Source
var ErrNestedEncrypted = errors.New("this folder holds an encrypted folder, and encrypted folders cannot be nested")

ErrNestedEncrypted: the input holds an encrypted folder. Encrypted folders do not nest - the browser refuses the same.

View Source
var ErrNoMarker = errors.New("no " + MarkerName + " found in the input - pass the encrypted folder's root, or its marker with --marker")

ErrNoMarker: the input carries no .filex-e2e.json and none was given.

View Source
var ErrOutputExists = errors.New("the output directory already exists")

ErrOutputExists: the output directory is already there. Decrypting over it would mix old and new plaintext; pick another -o.

View Source
var ErrSizeMismatch = errors.New("the content is not the size it was said to be (changed while it was read?)")

ErrSizeMismatch: the plaintext a writer was given is not the length it was told. Nothing a writer produced from it is a valid file.

View Source
var ErrStopped = errors.New("stopped")

ErrStopped is a run that was asked to stop. What it did so far stands.

View Source
var ErrVaultDamaged = errors.New("damaged")

ErrVaultDamaged is wrapped by every error that says a vault file does not verify or breaks a rule of the format. Readers fall back to an older generation on it; nothing else is damage.

View Source
var ErrVaultIndexTooLarge = fmt.Errorf("the vault's index would pass %d MiB", e2e.VaultIndexWriteMax>>20)

ErrVaultIndexTooLarge: the change would make the index larger than a writer may write.

View Source
var ErrVaultObjectMissing = errors.New("not in the vault")

ErrVaultObjectMissing is wrapped by a source's error for an index file or a pack that is not there.

View Source
var ErrVaultPackUnknown = errors.New("the pack upload's outcome is unknown")

ErrVaultPackUnknown is what a Sink wraps when it cannot tell whether a pack was stored (a time-out): the writer sends the same data again under a new pack id.

View Source
var ErrVaultReadOnly = errors.New("this vault is read-only here")

ErrVaultReadOnly: this state of the vault must not be written.

View Source
var FxeMagic = []byte("filexfxe")

FxeMagic starts every single encrypted file.

View Source
var MagicPrefix = []byte("filexe2e")

MagicPrefix starts every encrypted file.

Functions

func CheckVaultPack added in v0.54.0

func CheckVaultPack(b []byte, id [16]byte, packLog2 int) error

CheckVaultPack checks a whole pack against its name and the vault's pack size - what a reader that holds the whole pack does (`filex decrypt` on a copy, `filex vault prune`). Any mismatch is damage.

func DecryptContent

func DecryptContent(fmk, data []byte) ([]byte, error)

DecryptContent opens one encrypted file with the folder master key.

func DecryptFileStream

func DecryptFileStream(w io.Writer, r io.Reader, fmk, previous []byte) error

DecryptFileStream decrypts one folder file — header version 0x01 or 0x02 — from r to w. previous is the prior folder key of a folder mid re-key, or nil. A 0x01 file is one AES-GCM message and is read whole (at most 200 MiB); a 0x02 file streams.

func DecryptFxe

func DecryptFxe(w io.Writer, r io.Reader, h *FxeHeader, k *FxeKeys) error

DecryptFxe writes the plaintext of a .fxe body (r positioned after the prefix) to w, checked end to end against the header's size.

func DecryptStream

func DecryptStream(w io.Writer, r io.Reader, dek, prefix []byte, log2 int, expect int64) (int64, error)

DecryptStream writes the plaintext of the STREAM body read from r to w. expect is the plaintext length the header promised, or -1. Any tampering — a flipped bit, a truncated, reordered or extended body, a length that disagrees with expect — returns an error wrapping ErrContent.

⚠ w has received the plaintext of every chunk before the failing one. The caller writes into a temporary place and throws it away on error.

func DirIDOf

func DirIDOf(stored string) []byte

DirIDOf returns the folder id a stored folder name carries, or nil.

func EncodeVaultBody added in v0.54.0

func EncodeVaultBody(t *VaultTree, grave []VaultGrave) ([]byte, [][16]byte, error)

EncodeVaultBody writes a tree and its graveyard in the one canonical encoding, and returns the pack table it wrote.

func EncodedOf

func EncodedOf(stored string, readSidecar func(name string) ([]byte, bool)) (string, bool)

EncodedOf returns the encoded ciphertext a stored name carries — through its sidecar for a long one — or ok=false (a plain name, a sidecar, or a long name whose sidecar is missing or does not match).

func EncryptContent added in v0.50.0

func EncryptContent(fmk, plain []byte, rnd io.Reader) ([]byte, error)

EncryptContent encrypts a whole file held in memory, up to MaxOneShot, as a 0x01 file: the 97-byte header, then AES-GCM(DEK, dataIV, content). Byte-compatible with the browser's encryptFile.

func EncryptFile added in v0.50.0

func EncryptFile(w io.Writer, r io.Reader, size int64, fmk []byte, rnd io.Reader) error

EncryptFile encrypts a plaintext of exactly size bytes read from r into a folder file written to w, under the folder key: the one-shot format (0x01) up to MaxOneShot - read whole, at most 200 MiB - and STREAM (0x02, 1 MiB chunks) above it, read and written as a stream. The same choice, the same bytes, as an upload in the browser.

func EncryptStream added in v0.50.0

func EncryptStream(w io.Writer, r io.Reader, dek, prefix []byte, log2 int, size int64) (int64, error)

EncryptStream writes the STREAM body of a plaintext of exactly size bytes, read from r, under dek with the 7-byte nonce prefix. It refuses a reader that yields fewer or more bytes than size: the last chunk is the one the size says is last, and sealing a chunk as "last" that is not would make a body no reader accepts. Returns the bytes written.

func EncryptedFileSize added in v0.50.0

func EncryptedFileSize(size int64) int64

EncryptedFileSize is the length of the encrypted file a plaintext of size bytes becomes: 0x01 up to MaxOneShot, 0x02 (1 MiB chunks) above it.

func EscrowKID added in v0.50.0

func EscrowKID(spkiB64 string) string

EscrowKID is the short name of an escrow public key (base64 SPKI), the one its slots carry; "" when it is not one.

func FinishConversion added in v0.50.0

func FinishConversion(marker []byte) ([]byte, error)

FinishConversion drops `conv`: every file carries the magic. Back to v2 when nothing else is required (finishConversion).

func FinishNames added in v0.50.0

func FinishNames(marker []byte) ([]byte, error)

FinishNames drops `names.pending`: every entry carries its encrypted name (finishNames). The rest of the names slot is kept as it is.

func FormatRecoveryKey added in v0.50.0

func FormatRecoveryKey(raw []byte) string

FormatRecoveryKey writes 20 raw bytes as the key a person writes down: Crockford base32, most significant bits first, 8 groups of 4 joined by "-" (formatRecoveryKey).

func HasFxeMagic

func HasFxeMagic(b []byte) bool

HasFxeMagic reports whether b starts with the .fxe magic.

func HasMagic

func HasMagic(b []byte) bool

HasMagic reports whether b starts with the encrypted-file magic.

func ItemPrefixForSidecar

func ItemPrefixForSidecar(sidecar string) (string, bool)

ItemPrefixForSidecar returns the "<H>.fxl" an item next to this sidecar starts with (the item is "<H>.fxl" or "<H>.fxl.D").

func NameProblem

func NameProblem(name string) string

NameProblem mirrors the browser's namePlainProblem: "" when the name is one a local disk can hold, else why not.

func NumberedName added in v0.50.0

func NumberedName(name string, n int) string

NumberedName is "name (2).ext": a free plaintext name when the one needed is taken (numberedName).

func ParseRecoveryKey

func ParseRecoveryKey(s string) ([]byte, bool)

ParseRecoveryKey reads a typed recovery key back to its 20 bytes, forgiving case, dashes, spaces and the Crockford look-alikes (O→0, I/L→1).

func PasswordProblem added in v0.50.0

func PasswordProblem(pw string) string

PasswordProblem is "" for a password the browser's dialog would take, and otherwise why not. The dialog counts a JavaScript string's length, UTF-16 code units, so this does too: the same password passes in both.

func PlanVaultRepack added in v0.54.0

func PlanVaultRepack(latest *VaultIndex, packLog2 int) [][16]byte

PlanVaultRepack returns the packs to repack after a commit, or nil. With S the packs with fewer live bytes than half a data area, it repacks when S has at least 2 packs, their live bytes fit in fewer packs than S has, and more than half of all the data areas in the table is dead.

func RunConversion added in v0.50.0

func RunConversion(root string, io ConvertIO, prog *ConvertProgress) error

RunConversion converts every plaintext file under root. It returns ErrStopped when Stopped said so; a file that failed is counted, not returned.

func RunNamePass added in v0.50.0

func RunNamePass(nk *NameKey, root string, io NamePassIO, prog *NamePassProgress) error

RunNamePass renames every entry under root whose name does not open where it is. It returns ErrStopped when Stopped said so.

func SealVaultIndex added in v0.54.0

func SealVaultIndex(k *VaultKeys, gen uint64, body []byte, sealID [16]byte) ([]byte, error)

SealVaultIndex makes the index file of generation gen from a body, sealed under sealID (16 random bytes, new for every sealing).

func SidecarNameFor

func SidecarNameFor(stored string) (string, bool)

SidecarNameFor returns the sidecar that belongs to a long stored name (file or folder).

func StartConversion added in v0.50.0

func StartConversion(marker []byte, when time.Time, cleanup *Cleanup) ([]byte, error)

StartConversion marks an existing folder as being encrypted in place: v3, "conv" required (a filex that does not know it refuses a folder whose files are half plaintext), `conv: {pending, started, cleanup}`. Fields it does not know are kept (startConversion).

func StreamCiphertextSize

func StreamCiphertextSize(n int64, log2 int) int64

StreamCiphertextSize is the body length for a plaintext of n bytes.

func StreamFileHeader added in v0.50.0

func StreamFileHeader(fmk []byte, log2 int, rnd io.Reader) (header, dek, prefix []byte, err error)

StreamFileHeader is the 97-byte header of a 0x02 folder file: the magic, the version, the wrapped file key (exactly as 0x01 wraps it), the STREAM nonce prefix and the chunk size. It returns the header and the DEK and prefix the body is to be sealed with; the caller zeroes the DEK.

func ValidChunkLog2

func ValidChunkLog2(n int) bool

ValidChunkLog2 reports whether a reader accepts this chunk size.

func VaultLiveBytes added in v0.54.0

func VaultLiveBytes(latest *VaultIndex) map[[16]byte]int64

VaultLiveBytes is, for each pack of the latest table, the bytes the latest tree's extents use in it.

func VaultPackDataArea added in v0.54.0

func VaultPackDataArea(packLog2 int) int64

VaultPackDataArea is how many bytes of a pack of 2^packLog2 bytes hold data.

func VaultWarning added in v0.54.0

func VaultWarning(entries int, indexSize int64) string

VaultWarning is what a client says before a change to a vault that is close to its limits, or "" (docs/E2E-VAULT-FORMAT.md → "Limits").

Types

type Cleanup added in v0.50.0

type Cleanup struct {
	Versions bool `json:"versions"`
	Trash    bool `json:"trash"`
}

Cleanup is what to remove when a conversion finishes: the plaintext's old versions and the trash entries that came from the folder (the owner's choice, kept in the key file so a resumed run honours it).

func ConversionCleanup added in v0.50.0

func ConversionCleanup(marker []byte) *Cleanup

ConversionCleanup is the cleanup a pending conversion asked for, or nil.

type ConvertFailure added in v0.50.0

type ConvertFailure struct {
	Path string
	Err  error
}

ConvertFailure is one file the run could not convert, and why.

type ConvertIO added in v0.50.0

type ConvertIO interface {
	// List is the raw listing of a folder.
	List(dir string) ([]ConvertRow, error)
	// Head is the first bytes of a file (at least 9 when it has them).
	Head(path string) ([]byte, error)
	// Convert encrypts the file `row` (in `dir`) under the folder key and
	// writes it over itself as a conversion write, on condition that it is
	// still the file listed (expect). Errors when the server refuses (a
	// changed file: 412).
	Convert(dir string, row ConvertRow, expect string) error
	// Stopped is asked between files.
	Stopped() bool
}

ConvertIO is what the conversion needs from wherever the folder is.

type ConvertProgress added in v0.50.0

type ConvertProgress struct {
	// Total is the files found (everything but the key file and sidecars).
	Total int
	// Done is the files converted by this run; Large of them as STREAM.
	Done, Large int
	// Skipped is the files already encrypted (converted earlier, or written
	// encrypted).
	Skipped int
	// Failed is the files that could not be read or written; Failures says
	// which and why.
	Failed   int
	Failures []ConvertFailure
	// OnFile, when set, is told every file as its turn comes.
	OnFile func(path string, size int64)
}

ConvertProgress counts a run.

type ConvertRow added in v0.50.0

type ConvertRow struct {
	// Path is the entry's full path on the server (adapter://rel).
	Path string
	// Name is its stored name.
	Name string
	Dir  bool
	// Size in bytes and Modified in Unix milliseconds, as listed; -1 when the
	// listing did not say. Together they are the write's precondition.
	Size     int64
	Modified int64
}

ConvertRow is one entry of a folder's raw listing (stored names).

func (ConvertRow) Expect added in v0.50.0

func (r ConvertRow) Expect() string

Expect is the listing's own signature of a file, "<size>:<ms>", or "" when the listing did not give both.

type CorruptError

type CorruptError struct {
	Path string // plaintext path where known, with the stored name
	Err  error
}

CorruptError names the entry that stopped a run.

func (*CorruptError) Error

func (e *CorruptError) Error() string

func (*CorruptError) Unwrap

func (e *CorruptError) Unwrap() error

type CreateOptions added in v0.50.0

type CreateOptions struct {
	// Iterations of PBKDF2. Never fewer than MinIterations; 0 means that.
	Iterations int
	// EscrowPublicKey is the installation's escrow key (base64 SPKI DER, as
	// /api/capabilities publishes it), or "" for no escrow slot.
	EscrowPublicKey string
	// EncryptNames makes a level-2 folder (v3, feature "names").
	EncryptNames bool
	// NamesPending marks the names slot pending: an existing folder whose
	// entries still carry their plaintext names (enableNames does the same).
	NamesPending bool
	// Rand is where every random byte comes from; nil is crypto/rand.
	Rand io.Reader
}

CreateOptions configure CreateFolder.

type Created added in v0.50.0

type Created struct {
	// Marker is the key file, ready to write as `.filex-e2e.json`.
	Marker []byte
	// Keys are the folder key (and the name key, at level 2).
	Keys *Keys
	// RecoveryKey is shown ONCE. filex never stores it.
	RecoveryKey string
}

Created is a new folder's key file and the keys it hands back.

func CreateFolder added in v0.50.0

func CreateFolder(password string, opts CreateOptions) (*Created, error)

CreateFolder makes a new encrypted folder's key file: a random folder key wrapped under the password (PBKDF2-SHA-256), under a freshly minted recovery key (HKDF-SHA-256), and - when an escrow key is given - to the installation's escrow key. At level 2 (EncryptNames) it is v3 with a names slot. The password is checked as the browser checks it.

type DirVaultSource added in v0.54.0

type DirVaultSource struct {
	FS       fs.FS
	PackLog2 int
	// contains filtered or unexported fields
}

DirVaultSource reads a copy of a vault folder: the folder (os.DirFS) or a zip of it, extracted. A pack is checked whole the first time it is read: size, magic, version, kind, size log2 and id against its name.

func NewDirVaultSource added in v0.54.0

func NewDirVaultSource(fsys fs.FS, packLog2 int) *DirVaultSource

NewDirVaultSource reads the vault folder at the root of fsys.

func (*DirVaultSource) ListIndexes added in v0.54.0

func (s *DirVaultSource) ListIndexes(ctx context.Context) ([]VaultObject, error)

ListIndexes lists v/idx.

func (*DirVaultSource) ListPacks added in v0.54.0

func (s *DirVaultSource) ListPacks(ctx context.Context) ([]VaultObject, error)

ListPacks lists v/p/XX.

func (*DirVaultSource) ReadIndex added in v0.54.0

func (s *DirVaultSource) ReadIndex(ctx context.Context, gen uint64) ([]byte, error)

ReadIndex reads v/idx/G.fxi.

func (*DirVaultSource) ReadPack added in v0.54.0

func (s *DirVaultSource) ReadPack(ctx context.Context, id [16]byte, off, n int64) ([]byte, error)

ReadPack reads part of v/p/XX/ID.fxp.

type EncryptTreeJob added in v0.50.0

type EncryptTreeJob struct {
	// contains filtered or unexported fields
}

EncryptTreeJob is one encryption of a local folder, between OpenEncrypt and Run.

func OpenEncrypt added in v0.50.0

func OpenEncrypt(in string, opts EncryptTreeOptions) (*EncryptTreeJob, error)

OpenEncrypt checks the input and the output before anyone types a password: the input is a folder, not encrypted already and holding no encrypted folder; the output does not exist and is not inside the input. When "<out>.partial" holds a key file, the job resumes it (Resuming).

func (*EncryptTreeJob) Create added in v0.50.0

func (j *EncryptTreeJob) Create(password string) (string, error)

Create mints the key file of a new run and writes it into the partial output, before any file. It returns the recovery key, to be shown once.

func (*EncryptTreeJob) Names added in v0.50.0

func (j *EncryptTreeJob) Names() bool

Names reports whether names are encrypted: what was asked for a new run, what the key file says for a resumed one.

func (*EncryptTreeJob) Out added in v0.50.0

func (j *EncryptTreeJob) Out() string

Out is where Run writes.

func (*EncryptTreeJob) Resuming added in v0.50.0

func (j *EncryptTreeJob) Resuming() bool

Resuming reports whether a stopped run is continued: its key file is unlocked (Unlock) rather than a new one created (Create).

func (*EncryptTreeJob) Run added in v0.50.0

func (j *EncryptTreeJob) Run(ctx context.Context, onFile func(rel string, size int64)) (*EncryptTreeResult, error)

Run encrypts every file of the input into the partial output and renames it into place. onFile, when set, is told each file as its turn comes. A cancelled ctx stops it at once (ErrStopped), the file in flight discarded. On an error the partial output stays, for the next run to continue.

func (*EncryptTreeJob) Unlock added in v0.50.0

func (j *EncryptTreeJob) Unlock(secret string, recovery bool) error

Unlock opens the key file of a resumed run with its password, or with its recovery key when recovery is true.

type EncryptTreeOptions added in v0.50.0

type EncryptTreeOptions struct {
	// Out is the output folder. Empty: "<input>-encrypted" next to the input.
	Out string
	// Names encrypts file and folder names too (level 2).
	Names bool
	// EscrowPublicKey is an installation's escrow key (base64 SPKI) to seal
	// the folder key to, or "" for none.
	EscrowPublicKey string
	// Iterations and Rand are for tests; writers use MinIterations and
	// crypto/rand.
	Iterations int
	Rand       io.Reader
}

EncryptTreeOptions configure OpenEncrypt.

type EncryptTreeResult added in v0.50.0

type EncryptTreeResult struct {
	Out   string
	Files int
	Dirs  int
	// Kept is the files a resumed run found already written.
	Kept int
	// Large is the files written as STREAM (over 200 MB).
	Large    int
	Warnings []string
}

EncryptTreeResult summarises a finished run.

type EncryptedName

type EncryptedName struct {
	Stored         string // the entry's name on the server
	Encoded        string // the encoded ciphertext S (without a folder's ".D")
	SidecarName    string // set only for a long name
	SidecarContent string
}

EncryptedName is what the browser writes for one plaintext name.

type FxeHeader

type FxeHeader struct {
	// contains filtered or unexported fields
}

FxeHeader is a parsed .fxe header.

func ParseFxeHeader

func ParseFxeHeader(data []byte) (*FxeHeader, error)

ParseFxeHeader reads the JSON header with the browser's rules (parseFxeHeader). An unknown `req` entry returns an *UnsupportedError.

func ReadFxePrefix

func ReadFxePrefix(r io.Reader) (*FxeHeader, error)

ReadFxePrefix reads magic, version, length and header from r, leaving r at the first byte of the body.

func (*FxeHeader) HasRecovery

func (h *FxeHeader) HasRecovery() bool

HasRecovery reports whether the file has a recovery key slot.

func (*FxeHeader) Size

func (h *FxeHeader) Size() int64

Size is the plaintext length the header promises.

func (*FxeHeader) Unlock

func (h *FxeHeader) Unlock(secret string, recovery bool) (*FxeKeys, error)

Unlock opens the header with the password, or with the recovery key when recovery is true. A header whose key or name does not open under the unlocked file key is damage (a *CorruptError), not a wrong password.

type FxeKeys

type FxeKeys struct {
	DEK  []byte
	Name string
}

FxeKeys is what an unlock hands back: the STREAM key and the original name.

type Job

type Job struct {
	Marker *Marker
	// contains filtered or unexported fields
}

Job is one decryption, between Open and Close.

func Open

func Open(in string, opts OpenOptions) (*Job, error)

Open resolves the input and parses its marker. The returned Job must be closed. An *UnsupportedError comes back with a nil Job.

func (*Job) Close

func (j *Job) Close()

Close removes anything Open staged (an extracted zip).

func (*Job) IsFxe

func (j *Job) IsFxe() bool

IsFxe reports whether the input is a single encrypted file (.fxe).

func (*Job) Out

func (j *Job) Out() string

Out is where Run will write. For a .fxe without -o it is only known after Unlock (the original name comes out of the header); until then it is "".

func (*Job) Run

func (j *Job) Run() (*Result, error)

Run decrypts into the output directory, all or nothing.

func (*Job) Unlock

func (j *Job) Unlock(secret string, recovery bool) error

Unlock opens the marker with the password, or with the recovery key when recovery is true.

type Keys

type Keys struct {
	FMK      []byte
	Names    *NameKey
	Previous []byte
}

Keys is what an unlock hands back: the FMK, for a names-encrypted folder the name key, and for a folder mid re-key the PREVIOUS FMK — what the files not re-wrapped yet are still under.

type Marker

type Marker struct {
	V      int
	Salt   []byte
	Iter   int
	Verify string
	Fmk    string // "" (v1), "kek" or "wrapped"
	FmkPw  string
	Rk     *RecoverySlot
	Req    []string
	Names  *NamesSlot
	// Rekey is the previous FMK sealed under the current one, while a re-key
	// (a password change that replaced the folder key) is re-wrapping the
	// files' keys. Feature "rekey"; nil otherwise.
	Rekey *RekeySlot
	// ConvPending: an existing folder is being encrypted in place (feature
	// "conv"); files it has not reached yet are still plaintext.
	ConvPending bool
	// Vault is the `vault` block of a vault's key file (level 3, feature
	// "vault"; docs/E2E-VAULT-FORMAT.md); nil for levels 1 and 2.
	Vault *e2e.VaultInfo
}

Marker is a parsed `.filex-e2e.json`.

func ParseMarker

func ParseMarker(data []byte) (*Marker, error)

ParseMarker reads a marker with the browser's rules (parseMarkerDetailed). A well-formed v3 marker that requires an unknown feature returns an *UnsupportedError; anything malformed returns ErrNotMarker.

func (*Marker) HasNames

func (m *Marker) HasNames() bool

HasNames reports whether file and folder names are encrypted.

func (*Marker) IsVault added in v0.54.0

func (m *Marker) IsVault() bool

IsVault reports whether the key file is a vault's.

func (*Marker) UnlockPassword

func (m *Marker) UnlockPassword(password string) (*Keys, error)

UnlockPassword derives the KEK (PBKDF2-SHA256), proves it against the verify blob, and returns the FMK (+ name key).

func (*Marker) UnlockRecoveryKey

func (m *Marker) UnlockRecoveryKey(recoveryKey string) (*Keys, error)

UnlockRecoveryKey opens the user-recovery slot and returns the FMK (+ name key).

type NameKey

type NameKey struct {
	Long   int    // shortening threshold the folder was created with
	RootID []byte // the encrypted root's own folder id
	// contains filtered or unexported fields
}

NameKey is a folder's unwrapped name key.

func EnableNames added in v0.50.0

func EnableNames(marker, fmk []byte, rnd io.Reader) ([]byte, *NameKey, error)

EnableNames raises a v2 folder to level 2: a new name key sealed under the folder key, v3 with "names" required and the slot pending until every entry is renamed (enableNames). Needs the folder key, not the password.

func NewNameKey

func NewNameKey(raw []byte, long int, rootID []byte) (*NameKey, error)

NewNameKey imports a raw 64-byte name key and the root's 16-byte id.

func (*NameKey) DecryptEncoded

func (k *NameKey) DecryptEncoded(encoded string, parentID []byte) (string, bool)

DecryptEncoded decrypts an encoded ciphertext name sealed for the folder with id parentID. ok is false when it is not one.

func (*NameKey) DecryptStoredName

func (k *NameKey) DecryptStoredName(stored string, parentID []byte, readSidecar func(name string) ([]byte, bool)) (string, NameState)

DecryptStoredName reads one stored name found in the folder with id parentID. readSidecar returns a sibling sidecar's content, or ok=false when there is no such file; it is only called for a long name.

func (*NameKey) DeriveDirID

func (k *NameKey) DeriveDirID(parentID []byte, plain string) []byte

DeriveDirID is the id of a folder whose name was never encrypted: a keyed PRF of its parent's id and its name.

func (*NameKey) EffectiveDirID

func (k *NameKey) EffectiveDirID(parentID []byte, stored string) []byte

EffectiveDirID is the id the CHILDREN of a folder are sealed under: the one its stored name carries, or — a plaintext-named folder — the derived one.

func (*NameKey) EncryptName

func (k *NameKey) EncryptName(plain string, parentID, dirID []byte) (EncryptedName, error)

EncryptName encrypts a plaintext name for the folder with id parentID, exactly as the browser does; dirID is the entry's own id when it is a folder, nil for a file. The decryptor does not need it; tests use it to build folders.

func (*NameKey) RecoverMoved

func (k *NameKey) RecoverMoved(stored string, here []byte, ids [][]byte, readSidecar func(name string) ([]byte, bool)) (string, bool)

RecoverMoved tries a name sealed for ANOTHER folder of this encrypted folder (an entry moved outside filex): every id in ids but here. ok=false when none opens it.

type NameKind

type NameKind int

NameKind is what a stored name is, from its spelling alone.

const (
	KindPlain NameKind = iota
	KindFile
	KindDir
	KindLong
	KindLongDir
	KindSidecar
)

type NamePassIO added in v0.50.0

type NamePassIO interface {
	// List is the raw listing of a folder (stored names).
	List(dir string) ([]ConvertRow, error)
	// ReadSidecar is a sibling sidecar's content; ok is false when there is
	// none.
	ReadSidecar(dir, name string) ([]byte, bool)
	WriteSidecar(dir, name, content string) error
	// Rename gives row (in dir) the stored name `to`.
	Rename(dir string, row ConvertRow, to string) error
	// Stopped is asked between entries.
	Stopped() bool
}

NamePassIO is what the name pass needs from wherever the folder is.

type NamePassProgress added in v0.50.0

type NamePassProgress struct {
	// Seen is the entries found needing a name; Renamed of them were given
	// one, Repaired of those had been moved without being re-sealed.
	Seen, Renamed, Repaired int
	// Failed is the entries that could not be renamed (no permission, a name
	// a disk cannot hold, a name that cannot be read at all).
	Failed   int
	Failures []ConvertFailure
}

NamePassProgress counts a pass.

type NameState

type NameState int

NameState is the outcome of reading one stored name.

const (
	NameDecrypted  NameState = iota // was encrypted, now plaintext
	NamePlain                       // was never encrypted; kept as stored
	NameUnreadable                  // ours by its spelling, did not decrypt here
	NameSidecar                     // bookkeeping; skip it
)

type NamesSlot

type NamesSlot struct {
	Alg  string `json:"alg"`
	Enc  string `json:"enc"`
	Long int    `json:"long"`
	Key  string `json:"key"`
	// RootID is the encrypted root's own folder id (16 bytes, base64url):
	// the associated data of every name directly inside the root.
	RootID  string `json:"root_id"`
	Pending bool   `json:"pending,omitempty"`
}

NamesSlot is the marker's encrypted-names slot (v3, feature "names").

type OpenOptions

type OpenOptions struct {
	// Out is the output directory. Empty: "<input>-decrypted" next to it
	// (".zip" dropped).
	Out string
	// MarkerPath is an explicit .filex-e2e.json, for an input that does not
	// carry its own (a subfolder, a single file, a zip made below the root).
	MarkerPath string
	// GOOS overrides runtime.GOOS for the output-name rules (tests).
	GOOS string
	// Generation, for a vault, decrypts that generation (one still kept)
	// instead of the latest. 0: the latest that verifies.
	Generation uint64
}

OpenOptions configure Open.

type RecoverySlot

type RecoverySlot struct {
	Salt string `json:"salt"`
	Blob string `json:"blob"`
}

RecoverySlot is the marker's user-recovery-key slot.

type RekeySlot

type RekeySlot struct {
	From    string `json:"from"`
	Pending bool   `json:"pending"`
}

RekeySlot is the marker's re-key-in-progress slot (v3, feature "rekey").

type Result

type Result struct {
	Out      string
	Files    int
	Dirs     int
	Warnings []string
}

Result summarises a finished run.

func DecryptTree

func DecryptTree(in string, opts OpenOptions, secret string, recovery bool) (*Result, error)

DecryptTree is Open + Unlock + Run + Close.

func DecryptVault added in v0.54.0

func DecryptVault(ctx context.Context, src VaultSource, k *VaultKeys, packLog2 int, opts VaultDecryptOptions) (*Result, error)

DecryptVault writes the whole tree of a vault - the latest generation that verifies, or the one asked for - into a new directory, all or nothing: into "<out>.partial-*" first, renamed into place when every file decrypted.

type StoredName

type StoredName struct {
	Kind    NameKind
	Hash    string // long, longdir, sidecar: the 43-character hash they share
	Encoded string // file, dir: the encoded ciphertext S
	DirID   []byte // dir, longdir: the folder's id
}

StoredName is a classified stored name.

func ClassifyStoredName

func ClassifyStoredName(stored string) StoredName

ClassifyStoredName reports what a stored name is, without a key.

type UnsupportedError

type UnsupportedError struct{ Features []string }

UnsupportedError: the folder requires a feature this build does not know. Opening it anyway is how an old client breaks a folder, so it is refused.

func (*UnsupportedError) Error

func (e *UnsupportedError) Error() string

type VaultCommit added in v0.54.0

type VaultCommit struct {
	// Index is the new generation as readers will decode it.
	Index *VaultIndex
	// File is the index file to store as v/idx/<generation>.fxi.
	File []byte
	// Written are the packs this writer stored (orphans if the index is
	// never stored).
	Written [][16]byte
}

VaultCommit is a sealed generation, ready to store.

type VaultContent added in v0.54.0

type VaultContent struct {
	ID        [16]byte
	ChunkLog2 int
	Extents   []VaultExtent
}

VaultContent is where one version of a file is stored. A VaultContent is never changed once it is in a tree: an operation that moves bytes builds a new one, so trees can share them.

func (*VaultContent) BodyLen added in v0.54.0

func (c *VaultContent) BodyLen() int64

BodyLen is the length of the encrypted body: the extents joined.

type VaultDecryptOptions added in v0.54.0

type VaultDecryptOptions struct {
	// Out is the directory to write; it must not exist.
	Out string
	// Generation, when not 0, decrypts that kept generation instead of the
	// latest.
	Generation uint64
	// GOOS overrides runtime.GOOS for the output-name rules (tests).
	GOOS string
	// Sleep is VaultLoadOptions.Sleep.
	Sleep func(ctx context.Context, d time.Duration) error
}

VaultDecryptOptions configure DecryptVault.

type VaultExtent added in v0.54.0

type VaultExtent struct {
	Pack   [16]byte
	Offset int64
	Length int64
}

VaultExtent is a run of a file's encrypted body inside one pack.

type VaultGCPlan added in v0.54.0

type VaultGCPlan struct {
	// Indexes are the expired generations whose index files go.
	Indexes []uint64
	// Packs go: graveyard packs whose last user expired, and orphans.
	Packs [][16]byte
	// Forget are the graveyard packs this pass deletes or finds gone: the
	// next commit drops them from the graveyard (VaultWriter.ForgetGrave).
	Forget [][16]byte
}

VaultGCPlan is one collection pass.

func PlanVaultGC added in v0.54.0

func PlanVaultGC(latest *VaultIndex, indexes, packs []VaultObject, mine map[[16]byte]bool, now time.Time, limit int) VaultGCPlan

PlanVaultGC works out one collection pass of at most limit deletions. latest is the latest generation, verified; indexes and packs are the listings; mine are the packs this writer stored since it took the lock (not orphans: its commit may still name them). Nothing is planned for a vault whose latest is damaged, carries extension bytes, or is missing.

func (VaultGCPlan) Empty added in v0.54.0

func (p VaultGCPlan) Empty() bool

Empty reports whether the pass deletes nothing.

type VaultGrave added in v0.54.0

type VaultGrave struct {
	Pack [16]byte
	Died uint64
}

VaultGrave is one graveyard entry: a pack the latest tree no longer uses, which an older generation still kept may use.

type VaultIndex added in v0.54.0

type VaultIndex struct {
	Generation uint64
	Tree       *VaultTree
	// Packs is the pack table: every pack the tree uses, ascending.
	Packs [][16]byte
	// Grave is the graveyard, ascending by pack id.
	Grave []VaultGrave
	// ReadOnly, when not "", is why a writer must not write this vault
	// (extension bytes a newer filex wrote).
	ReadOnly string
	// BodyLen is the length of the body; Size the index file's (0 for an
	// index that was not read from a file).
	BodyLen int
	Size    int64
	// ModTime is when the index file was written, where the source says.
	ModTime time.Time
}

VaultIndex is one generation of a vault, decoded and checked.

func DecodeVaultBody added in v0.54.0

func DecodeVaultBody(plaintext []byte, packLog2 int, gen uint64) (*VaultIndex, error)

DecodeVaultBody reads and checks an index body - plaintext is the body followed by its zero padding - as the index of generation gen of a vault with packs of 2^packLog2 bytes. A body this build cannot read (another version, a flag it does not know) is an *UnsupportedError; anything that breaks a rule of the format wraps ErrVaultDamaged.

func OpenVaultIndex added in v0.54.0

func OpenVaultIndex(k *VaultKeys, packLog2 int, gen uint64, file []byte) (*VaultIndex, error)

OpenVaultIndex opens and checks the index file of generation gen. A file that is too large is refused before anything is decrypted.

type VaultKeys added in v0.54.0

type VaultKeys struct {
	// contains filtered or unexported fields
}

VaultKeys derives the keys of one vault from its folder master key.

func NewVaultKeys added in v0.54.0

func NewVaultKeys(fmk []byte, vaultID [16]byte) (*VaultKeys, error)

NewVaultKeys keeps a copy of fmk; Wipe zeroes it.

func (*VaultKeys) ContentKey added in v0.54.0

func (k *VaultKeys) ContentKey(contentID [16]byte) ([]byte, error)

ContentKey is the key of the file version whose content id is contentID.

func (*VaultKeys) ID added in v0.54.0

func (k *VaultKeys) ID() [16]byte

ID is the vault id the keys are salted with.

func (*VaultKeys) IndexKey added in v0.54.0

func (k *VaultKeys) IndexKey(sealID [16]byte) ([]byte, error)

IndexKey is the key of the index file sealed under sealID.

func (*VaultKeys) Wipe added in v0.54.0

func (k *VaultKeys) Wipe()

Wipe drops the folder key from memory. The keys are useless afterwards.

type VaultLatestSource added in v0.54.0

type VaultLatestSource interface {
	LatestGeneration(ctx context.Context) (uint64, error)
}

VaultLatestSource is a source that names its latest generation without a listing - a server answers `state`.

type VaultLoadOptions added in v0.54.0

type VaultLoadOptions struct {
	// Generation, when not 0, loads that generation instead of the latest
	// (`--generation N`): an older one that is still kept.
	Generation uint64
	// Seen is the highest generation this session has seen of the vault; a
	// lower latest is a rollback (read-only). 0: none.
	Seen uint64
	// Sleep waits before a damaged latest is fetched again; nil sleeps for
	// real (and stops with ctx).
	Sleep func(ctx context.Context, d time.Duration) error
}

VaultLoadOptions configure LoadVault.

type VaultNode added in v0.54.0

type VaultNode struct {
	Name  string
	Dir   bool
	MTime int64 // milliseconds since 1970
	Size  int64 // a file's plaintext bytes
	// Content is where a file's bytes are; nil for a folder, a 0-byte file,
	// or a file whose bytes are not stored yet (Local).
	Content *VaultContent
	// Local is the caller's own (`filex vault mount` keeps a pending file's
	// spool here). It is never encoded.
	Local any
	// contains filtered or unexported fields
}

VaultNode is one entry of a vault tree.

func (*VaultNode) Child added in v0.54.0

func (n *VaultNode) Child(name string) *VaultNode

Child is the entry called name directly inside n, or nil.

func (*VaultNode) Children added in v0.54.0

func (n *VaultNode) Children() []*VaultNode

Children are the entries directly inside n, in canonical order (by the bytes of their names).

func (*VaultNode) HasExt added in v0.54.0

func (n *VaultNode) HasExt() bool

HasExt reports whether the entry carries extension bytes a newer filex wrote.

func (*VaultNode) Parent added in v0.54.0

func (n *VaultNode) Parent() *VaultNode

Parent is the folder the entry is in; nil for the root.

func (*VaultNode) Path added in v0.54.0

func (n *VaultNode) Path() string

Path is the entry's path from the vault root ("" for the root).

type VaultObject added in v0.54.0

type VaultObject struct {
	Generation uint64   // an index file
	Pack       [16]byte // a pack
	Size       int64
	ModTime    time.Time // zero: the source does not say
}

VaultObject is one index file or pack, as a listing shows it.

type VaultPackReader added in v0.54.0

type VaultPackReader func(ctx context.Context, id [16]byte, off, n int64) ([]byte, error)

VaultPackReader reads n bytes of a stored pack from off (repacking).

type VaultPackSink added in v0.54.0

type VaultPackSink func(ctx context.Context, id [16]byte, pack []byte) error

VaultPackSink stores one closed pack: its id and its 2^pack bytes.

type VaultReader added in v0.54.0

type VaultReader struct {
	// contains filtered or unexported fields
}

VaultReader reads files of one vault.

func NewVaultReader added in v0.54.0

func NewVaultReader(src VaultSource, keys *VaultKeys) *VaultReader

NewVaultReader reads through src with keys.

func (*VaultReader) ReadChunk added in v0.54.0

func (r *VaultReader) ReadChunk(ctx context.Context, n *VaultNode, i int64) ([]byte, error)

ReadChunk returns plaintext chunk i of a file (the mount's block cache holds these).

func (*VaultReader) ReadRange added in v0.54.0

func (r *VaultReader) ReadRange(ctx context.Context, n *VaultNode, a, b int64) ([]byte, error)

ReadRange returns bytes [a, b) of a file's plaintext (b is clipped to its size): the chunks needed, fetched as few reads as the extents allow.

func (*VaultReader) WriteTo added in v0.54.0

func (r *VaultReader) WriteTo(ctx context.Context, n *VaultNode, w io.Writer) (int64, error)

WriteTo writes a file's whole plaintext to w, one chunk at a time.

type VaultSource added in v0.54.0

type VaultSource interface {
	// ListIndexes lists the index files (well-formed names only).
	ListIndexes(ctx context.Context) ([]VaultObject, error)
	// ListPacks lists the packs (well-formed names only).
	ListPacks(ctx context.Context) ([]VaultObject, error)
	// ReadIndex reads one index file whole. More than e2e.VaultIndexReadMax
	// bytes is refused before they are read (a damage error).
	ReadIndex(ctx context.Context, generation uint64) ([]byte, error)
	// ReadPack reads n bytes of a pack from off.
	ReadPack(ctx context.Context, id [16]byte, off, n int64) ([]byte, error)
}

VaultSource is where a vault's files come from.

type VaultState added in v0.54.0

type VaultState struct {
	// Index is the generation shown: the latest that verifies, or the one
	// asked for. An empty vault at generation 0 has an empty one.
	Index *VaultIndex
	// Latest is the newest generation present (Index.Generation unless it
	// is damaged or an older one was asked for).
	Latest uint64
	// DamagedLatest: the newest generation does not verify; Index is an
	// older one, read-only, until its owner continues from it.
	DamagedLatest bool
	// RolledBack: the latest is older than one this session saw.
	RolledBack bool
}

VaultState is what a reader has loaded.

func LoadVault added in v0.54.0

func LoadVault(ctx context.Context, src VaultSource, k *VaultKeys, packLog2 int, opt VaultLoadOptions) (*VaultState, error)

LoadVault finds and opens the generation to show.

func (*VaultState) ReadOnly added in v0.54.0

func (s *VaultState) ReadOnly() string

ReadOnly is why a writer must not write from this state, or "".

func (*VaultState) Writable added in v0.54.0

func (s *VaultState) Writable() error

Writable is ErrVaultReadOnly, with the reason, when a writer must not write from this state; nil when it may.

type VaultTree added in v0.54.0

type VaultTree struct {
	// contains filtered or unexported fields
}

VaultTree is a vault's tree of files and folders.

func NewVaultTree added in v0.54.0

func NewVaultTree() *VaultTree

NewVaultTree is an empty tree.

func (*VaultTree) CheckMkdir added in v0.54.0

func (t *VaultTree) CheckMkdir(p string) error

CheckMkdir reports whether Mkdir(p) would succeed, without changing anything.

func (*VaultTree) CheckMove added in v0.54.0

func (t *VaultTree) CheckMove(from, to string) error

CheckMove reports whether Move(from, to) would succeed.

func (*VaultTree) CheckPutFile added in v0.54.0

func (t *VaultTree) CheckPutFile(p string) (adds bool, err error)

CheckPutFile reports whether PutFile(p) would succeed, and whether it would add an entry (false: it replaces a file).

func (*VaultTree) Clone added in v0.54.0

func (t *VaultTree) Clone() *VaultTree

Clone copies the tree. Contents are shared (they never change in place); Local is copied as it is.

func (*VaultTree) Len added in v0.54.0

func (t *VaultTree) Len() int

Len is the number of entries (files and folders), the root not counted.

func (*VaultTree) Lookup added in v0.54.0

func (t *VaultTree) Lookup(p string) *VaultNode

Lookup finds the entry at p; nil when there is none. "" is the root.

func (*VaultTree) Mkdir added in v0.54.0

func (t *VaultTree) Mkdir(p string, mtime int64) (*VaultNode, error)

Mkdir makes a new folder.

func (*VaultTree) Move added in v0.54.0

func (t *VaultTree) Move(from, to string) (*VaultNode, error)

Move gives the entry at from a new folder or name; its mtime, its contents and (a folder) everything in it are kept.

func (*VaultTree) PutFile added in v0.54.0

func (t *VaultTree) PutFile(p string, mtime, size int64, c *VaultContent) (*VaultNode, error)

PutFile makes a new file, or gives the file at p new contents: nothing of the old version is kept but its place in the tree. Local is cleared.

func (*VaultTree) Remove added in v0.54.0

func (t *VaultTree) Remove(p string) (*VaultNode, error)

Remove takes the entry at p out of the tree, a folder with everything in it.

func (*VaultTree) Root added in v0.54.0

func (t *VaultTree) Root() *VaultNode

Root is the vault folder itself.

func (*VaultTree) Walk added in v0.54.0

func (t *VaultTree) Walk(fn func(n *VaultNode, depth int) error) error

Walk visits every entry in canonical order - pre-order, siblings by the bytes of their names - with its depth (the root's children are depth 1).

type VaultWriter added in v0.54.0

type VaultWriter struct {
	// contains filtered or unexported fields
}

VaultWriter builds the next generation of a vault.

func NewVaultWriter added in v0.54.0

func NewVaultWriter(cfg VaultWriterConfig) (*VaultWriter, error)

NewVaultWriter starts the generation after cfg.Base.

func (*VaultWriter) Commit added in v0.54.0

func (w *VaultWriter) Commit(ctx context.Context) (*VaultCommit, error)

Commit closes the open pack and seals the new generation. The caller stores Commit.File as the index of Commit.Index.Generation; until that succeeded nothing of the change is visible, and the writer is spent either way.

func (*VaultWriter) Delete added in v0.54.0

func (w *VaultWriter) Delete(p string) error

Delete removes a file, or a folder with everything in it.

func (*VaultWriter) ForgetGrave added in v0.54.0

func (w *VaultWriter) ForgetGrave(ids [][16]byte)

ForgetGrave drops packs a collection deleted from the graveyard this commit writes.

func (*VaultWriter) Generation added in v0.54.0

func (w *VaultWriter) Generation() uint64

Generation is the generation this writer commits.

func (*VaultWriter) Mkdir added in v0.54.0

func (w *VaultWriter) Mkdir(p string, mtime int64) error

Mkdir makes a new folder.

func (*VaultWriter) Move added in v0.54.0

func (w *VaultWriter) Move(from, to string) error

Move gives an entry a new folder or name; mtime and contents are kept.

func (*VaultWriter) Repack added in v0.54.0

func (w *VaultWriter) Repack(ctx context.Context, packs [][16]byte, read VaultPackReader) error

Repack copies the live extents in packs - entry by entry in index order, each entry's extents in order, the bytes as they are, nothing encrypted again - into new packs by the canonical layout. Those packs go to the graveyard when this generation commits.

func (*VaultWriter) Tree added in v0.54.0

func (w *VaultWriter) Tree() *VaultTree

Tree is the tree as the operations so far left it. Do not change it.

func (*VaultWriter) Warning added in v0.54.0

func (w *VaultWriter) Warning() string

Warning is what to say before a change to this vault, or "".

func (*VaultWriter) Write added in v0.54.0

func (w *VaultWriter) Write(ctx context.Context, p string, mtime int64, r io.Reader, size int64) (*VaultNode, error)

Write stores new contents for the file at p - a new file, or a new version of one: always a new content id, even for the same bytes. r must hold exactly size bytes.

type VaultWriterConfig added in v0.54.0

type VaultWriterConfig struct {
	Keys     *VaultKeys
	PackLog2 int
	// Base is the latest generation, which the commit follows; nil is an
	// empty vault at generation 0 (the creation commit writes generation 1).
	Base *VaultIndex
	// Rand is where every random byte comes from; nil is crypto/rand.
	Rand io.Reader
	// Sink stores packs as they close.
	Sink VaultPackSink
}

VaultWriterConfig configures NewVaultWriter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL