SECSTORE(2) SECSTORE(2)
NAME
secstore - fetch data from Plan 9's secure storage service
SYNOPSIS
include "secstore.m";
secstore := load Secstore Secstore->PATH;
Maxfilesize: con 128*1024; # default
init: fn();
privacy: fn(): int;
cansecstore: fn(addr: string, user: string): int;
mkseckey: fn(pass: string): array of byte;
dial: fn(addr: string): ref Sys->Connection;
auth: fn(conn: ref Sys->Connection, user: string, seckey: array of byte):
(string, string);
connect: fn(addr: string, user: string, seckey: array of byte):
(ref Sys->Connection, string, string);
sendpin: fn(conn: ref Sys->Connection, pin: string): int;
files: fn(conn: ref Sys->Connection):
list of (string, int, string, string, array of byte);
getfile: fn(conn: ref Sys->Connection, name: string,
maxsize: int): array of byte;
remove: fn(conn: ref Sys->Connection, file: string): int;
bye: fn(conn: ref Sys->Connection);
mkfilekey: fn(pass: string): array of byte;
decrypt: fn(data: array of byte, filekey: array of byte): array of byte;
erasekey: fn(key: array of byte);
lines: fn(file: array of byte): list of array of byte;
DESCRIPTION
Secstore establishes a secure authenticated connection with
a Plan 9 secstore service (or equivalent, such as Plan 9
from User Space), that can then be used to fetch and decrypt
data files, such as the factotum file containing the initial
keys for an instance of factotum(4). The module's functions
hold the file descriptors for the connection in a
Sys->Connection value, as returned by sys-dial(2). The addr
parameter that gives the network address of the secstore
service is also as defined in sys-dial(2). A nil value
defaults to net!$auth!secstore, for translation in the usual
way by cs(8).
Init must be called before invoking any other operation of
the module.
Privacy ensures the memory of the calling process cannot be
read, for instance by prog(3). It returns zero on success
Page 1 Plan 9 (printed 12/17/25)
SECSTORE(2) SECSTORE(2)
and a negative value on failure.
Cansecstore returns true if a connection can be made to a
secstore at network address addr, and the given user has a
secstore account; it returns false otherwise.
Users authenticate themselves to the service using a secret
key and a special protocol that does not reveal the key
itself to the remote service. The textual secret (eg, pass-
word or pass phrase) is not used directly by the following
functions, but only after transformation by mkseckey, which
hashes it into an array of bytes. That is the key parameter
to the functions.
Dial dials the secstore at network address addr (as defined
by sys-dial(2)) and returns a reference to the resulting
Sys->Connection. It returns nil on an error and sets the
error string.
Auth authenticates a fresh connection as belonging to a
given user of the service. The parameter conn refers to the
Sys->Connection value representing the connection. User
names a user registered with the service. The parameter
seckey is the result of applying mkseckey to the user's
secret. Auth returns a tuple (srvname, diag). Srvname is
the service name configured in the remote host (often simply
secstore). On an error, srvname is nil, and diag is a diag-
nostic. If the remote service has been configured to demand
extra authentication data, then diag contains a demand for
it. Currently the only such value is `needpin'; call
sendpin to provide it to the connection. If sendpin suc-
ceeds, it returns zero, and conn can be used normally; on
error, sendpin returns -1 and the connection cannot be used.
Connect combines the actions of dial and auth: dials the
secstore at addr, and mutually authenticates the server and
the given user using the user's secret key for that service.
It returns a tuple (conn, srvname, diag), where each compo-
nent is as described for dial and auth above. On an error,
conn is nil, and diag contains a diagnostic.
Getfile retrieves the file name from the secure store, and
returns its contents as an array of bytes. Maxsize gives
the largest acceptable file size; if the value is zero or
negative, a large value is used by default. The files
stored on the service are separately encrypted under the
user's secret key. Mkfilekey takes a textual secret key and
returns a hash of it as an array of bytes, suitable for use
as the filekey parameter in subsequent calls to decrypt.
(The filekey is not the same value as the seckey used for
initial authentication, although the secret text is the
same.)
Page 2 Plan 9 (printed 12/17/25)
SECSTORE(2) SECSTORE(2)
Remove deletes the given file from the server. It returns 0
on success and a negative value on error.
Decrypt decrypts the data previously fetched from a file on
the secure store. It uses the filekey produced by mkfilekey
to decrypt the data in place (ie, modifying the contents of
data) and returns a slice of data that excludes any headers
and trailers in the encoding. It returns nil if the file
could not be decrypted (usually because the key value is not
actually the encryption key).
Erasekey clears the bytes of key to zero; it should be
called on every value produced by mkfilekey and mkseckey,
after use, but can also be used on the data arrays returned
by getfile and decrypt.
Lines returns a list of slices of file, representing each
line of file in turn (including newline). Factotum(4) for
instance requires keys to be written to its control file one
at a time.
Bye closes the connection to the secstore.
SOURCE
/appl/lib/secstore.b
DIAGNOSTICS
As well as returning the error values described above, func-
tions set the system error string.
SEE ALSO
crypt(1), factotum(2), factotum(4)
Page 3 Plan 9 (printed 12/17/25)