SECSTORE(2)                                           SECSTORE(2)

     NAME
          secstore - fetch data from Plan 9's secure storage service

     SYNOPSIS
          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;

     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
          Dial->Connection value, as returned by dial(2). The addr
          parameter that gives the network address of the secstore
          service is also as defined in 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.

     Page 1                       Plan 9            (printed 12/22/24)

     SECSTORE(2)                                           SECSTORE(2)

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

     Page 2                       Plan 9            (printed 12/22/24)

     SECSTORE(2)                                           SECSTORE(2)

          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 nega-
          tive 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 ver-
          sion 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.

     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), secstore(1), factotum(2), factotum(4)

     Page 3                       Plan 9            (printed 12/22/24)