include "dial.m"; 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 Dial->Connection; auth: fn(conn: ref Dial->Connection, user: string, seckey: array of byte): (string, string); connect: fn(addr: string, user: string, seckey: array of byte): (ref Dial->Connection, string, string); sendpin: fn(conn: ref Dial->Connection, pin: string): int; files: fn(conn: ref Dial->Connection): list of (string, int, string, string, array of byte); getfile: fn(conn: ref Dial->Connection, name: string, maxsize: int): array of byte; putfile: fn(conn: ref Dial->Connection, name: string, data: array of byte): int; remove: fn(conn: ref Dial->Connection, file: string): int; bye: fn(conn: ref Dial->Connection); mkfilekey: fn(pass: string): array of byte; decrypt: fn(data: array of byte, filekey: array of byte): array of byte; encrypt: 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;
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 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, password 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 dial(2)) and returns a reference to the resulting Dial->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 Dial->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 diagnostic. 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 succeeds, 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 component 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.)
Putfile writes data under file name to the secure store, overwriting a possibly existing file by that name. Data should already be encrypted. The caller can arrange this by calling encrypt. Putfile returns 0 on success and a negative value on error.
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).
Encrypt does the opposite of decrypt. Given plain data and filekey produced by mkfilekey, it returns an encrypted version of data, including headers and trailers. This data is suitable for writing to the secure store with putfile.
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.
|SECSTORE(2 )||Rev: Tue Mar 31 02:42:39 GMT 2015|