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

e2edecrypt

package
v0.51.0 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: MIT Imports: 35 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
)

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 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 FxeMagic = []byte("filexfxe")

FxeMagic starts every single encrypted file.

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

MagicPrefix starts every encrypted file.

Functions

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 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 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 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.

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 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
}

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) 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
}

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.

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

Jump to

Keyboard shortcuts

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