leaf

package module
v0.0.0-...-52e95e2 Latest Latest
Warning

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

Go to latest
Published: Mar 10, 2024 License: BSD-3-Clause Imports: 10 Imported by: 0

README

leaf

GoDoc

Lightweight Encrypted Archive Format (LEAF) is an encrypted storage representation for small databases of important data like passwords and private notes. The store is log-structured, preserving the complete history of changes so that it can be rewound to any previous state.

Usage Summary

import "github.com/creachadair/leaf"

// Create a file.
f, err := leaf.New(accessKey)
if err != nil {
  log.Fatal(err)
}

// Add tables to the file.
tab := f.Database().Table("bookmarks")

// Add records to the table.
tab.Set("godoc", "https://golang.ir")

// Get data from a table.
if u, ok := leaf.Get[string](tab, "godoc"); ok {
  log.Print(u)
}

// Write the file to storage.
if f.IsModified() {
  _, err := f.WriteTo(w)
  if err != nil {
    log.Fatal(err)
  }
}

Data Formats

A LEAF file is a JSON object with the following format:

{
  "leaf": 1,
  "key": "<base64-encoded-encrypted-data-key>",
  "data": "<base64-encoded-encrypted-data>"
}

All encryption is performed using the AEAD construction with the ChaCha20-Poly1305 algorithm with a 256-bit key and a 24-byte nonce.

The user must provide a 256-bit (32 byte) access key to create or open a file. Typically this may be generated randomly and stored in a secure location, or generated from a passphrase via a KDF like scrypt or hkdf.

The data key ("key") is encrypted with the access key.

The data record is encrypted with the data key.

The plaintext data record is a snappy compressed JSON object with the following structure:

{
  "log": [
     <log-record>,
     ...
  ]
}

The data record is compressed as a single complete record in block mode.

The database is a sequence of log entries recording the complete history of state changes. A log entry is a JSON object with this format:

{
  "op": "<opcode>",
  "tab": "<table-name>",
  "key": "<key-name>",
  "val": <value>,
  "clk": "<timestamp>"
}

The state of the database at any moment in its history can be obtained by scanning the log records from the beginning to that time.

Operations

The following operations are understood by the log:

op table key value description
create-table name - - create a (new) table with the given name
delete-table name - - delete an existing table with the given name
rename-table old new - rename an existing table from old to new
clear-table name - - remove all entries from the given table
update table key value insert or replace key with value in table
delete table key - delete key from table
Timestamps

Timestamps are recorded as an integer count of microseconds since the Unix epoch, as a string.

Documentation

Overview

Package leaf defines a lightweight encrypted archive format for small data.

Files created by this package are encrypted using the AEAD construction over the ChaCha20-Poly1305 algorithm with a 256-bit key and a 24-bit nonce. The underlying storage format is JSON.

A file contains a number of named "tables" each of which is a logical map from string column names to arbitrary JSON values. The data store does not interpret the contents of the tables.

Index

Constants

View Source
const AccessKeyLen = chacha20poly1305.KeySize // 32 bytes

AccessKeyLen is the required length in bytes of an access key.

Variables

This section is empty.

Functions

func AsMap

func AsMap[T any](t Table) map[string]T

AsMap returns a map of the values of t. The resulting map is independent of the table, and modifications of it do not affect the table.

func Get

func Get[T any](t Table, key string) (T, bool)

Get reports whether t contains a record for key, and if so returns its value. It returns a zero value if the key does not exist.

func SetMap

func SetMap[T any](t Table, m map[string]T)

SetMap adds or updates the values in t to the corresponding entries from m.

Types

type Database

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

Database is a database of key-value tables stored in a File.

func (*Database) Compact

func (d *Database) Compact()

Compact compacts the log of d to the current state of the database.

func (*Database) DeleteTable

func (d *Database) DeleteTable(name string) bool

DeleteTable deletes the specified table and reports whether it existed.

func (*Database) GetTable

func (d *Database) GetTable(name string) (Table, bool)

GetTable reports whether d has a table by the given name, and if so returns the table.

func (*Database) IsModified

func (d *Database) IsModified() bool

IsModified reports whether the contents of d have been modified.

func (Database) MarshalJSON

func (d Database) MarshalJSON() ([]byte, error)

func (*Database) Revert

func (d *Database) Revert()

Revert undoes the effect of the most recent Rewind. It does nothing if d has not been rewound.

func (*Database) Rewind

func (d *Database) Rewind(when time.Time) bool

Rewind rewinds the state of d to the specified time, and reports whether this changed the visible state. If the visible state changed, the database is marked as modified.

If the database was already rewound, it is reverted before applying the new rewind. After rewinding, modifications apply to the rewound state. Use Revert to revert to the state prior to the most recent rewind (if any).

func (*Database) Snapshot

func (d *Database) Snapshot() map[string]map[string]json.RawMessage

Snapshot returns a map of the current state of the database. The keys of the outer map are the names of the tables, the inner maps are the keys and values. Modifications of the snapshot do not affect the database.

func (*Database) Table

func (d *Database) Table(name string) Table

Table returns the table with the given name from db, creating it empty if it does not exist.

func (*Database) TableNames

func (d *Database) TableNames() []string

TableNames returns a slice of the table names of d in sorted order.

func (*Database) Time

func (d *Database) Time() time.Time

Time reports the timestamp of the latest state change of d. It returns the zero time if the database is empty.

func (*Database) UnmarshalJSON

func (d *Database) UnmarshalJSON(data []byte) error

type File

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

A File is a LEAF archive file.

func New

func New(accessKey []byte) (*File, error)

New constructs a new empty File using the specified access key. The key must be AccessKeyLen bytes in length.

func Open

func Open(accessKey []byte, r io.Reader) (*File, error)

Open reads and decrypts a File from the contents of r using the given accessKey. The key must be AccessKeyLen bytes in length.

func (*File) Database

func (f *File) Database() *Database

Database returns the database stored in f.

func (*File) IsModified

func (f *File) IsModified() bool

IsModified reports whether the contents of f have been modified.

func (*File) WriteTo

func (f *File) WriteTo(w io.Writer) (int64, error)

WriteTo encodes, encrypts, and writes the current contents of f to w. If an error occurs in encoding or encryption, no data are written to w. Writing f clears its modification flag, if set.

type Table

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

A Table is a mapping of string keys to JSON-marshalable values.

func (Table) Clear

func (t Table) Clear()

Clear removes all the keys from t.

func (Table) Delete

func (t Table) Delete(key string) bool

Delete removes key from t and reports whether it was present.

func (Table) Get

func (t Table) Get(key string, val any) bool

Get reports whether t contains a record for key, and if so unmarshals its value into val. As a special case, if val == nil the unmarshal is skipped.

func (Table) Keys

func (t Table) Keys() []string

Keys returns a slice of the keys of t in lexicographic (sorted) order.

func (Table) Len

func (t Table) Len() int

Len reports the number of keys in t.

func (*Table) Rename

func (t *Table) Rename(newName string)

Rename renames t to the specified name.

func (Table) Set

func (t Table) Set(key string, val any) bool

Set adds or updates the value of key in t and reports whether it was new.

Directories

Path Synopsis
cmd
leaf
Program leaf is a command-line interface to read and write LEAF files.
Program leaf is a command-line interface to read and write LEAF files.

Jump to

Keyboard shortcuts

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