This is a password manager library implementing basic operations on a data structure that can be used to store passwords.
We're still working on the library, so things may change, and there may be BUGS.
An example implementation using Cmdliner is provided in [./app/passmenage_cli.ml].
The binary provides the following sub-commands:
COMMANDS
add
Add an entry to a category.
get
Get an entry from the password file.
init
Initialize a new password file
list
List categories, or entries in a specific category
pretty-print
Pretty-print the state (INCLUDING PASSWORDS)
A manpage is available with ./passmenage_cli.native --help
The internal data structure is a JSON tree:
{ /* encrypted, OCaml struct name: `state` */
configuration:
[ /* list of string tuples, OCaml struct name: `configuration` */
["entry 1", "value 1"],
["entry 2", "value 2"],
],
categories: /* list of associative dictionaries, which may be nested */
[
{ /* OCaml struct name: `category` */
/* each category may optionally be encrypted with a separate key */
name: "category 1",
entries: /* list of associative dictionaries */
[
{ /* OCaml struct name: `entry` */
name: "my github password",
passphrase: "123456",
metadata:
[ /* list of string tuples */
["url", "https://github.com/signin"],
["last_changed", "2017-12-01"],
]
},
],
subcategories: [] /* a list of `category` objects */
},
]
}
The tree is always encrypted when serialized. Each category may be independently encrypted to give the user control over the date loaded in memory during a given session.
The encryption is performed using
Nocrypto's
AES-CCM primitive with a 128-bit MAC
, a random 256-bit key, and a random 104-bit nonce.
New random values for the key and nonce are generated on each
serialization/encryption.
I couldn't find any documentation that references a standardized instance
of AES-CCM in nocrypto
, so there's no telling what actually goes on under
the hood inside this library without reading the source code, which I'm not
smart enough to understand. YOLO.
The random key is encrypted with the
scrypt_enc_buf(maxmem = 1MB, maxtime = 1 second)
primitive from
Tarsnap
(a KDF based on
HMAC-SHA-256
and AES-CTR-256
) using a user-provided passphrase,
and the result is stored in a JSON object:
{ /* OCaml struct name: `encrypted_data` */
kdf: "scrypt...", /* the output from scrypt_enc_buf() */
nonce: "AAAAAA", /* 32-byte random value */
ciphertext: "BBBBBB", /* ciphertext and MAC from AES-CCM */
}
The mli interface specification contains most of the information needed to use the library.
A nice HTML representation can be generated using topkg doc
if you have the
topkg-care
package installed from opam
.
- figure out what breed of AES-CCM nocrypto implements
- add version information to the
state
structure - add version information to the
encrypted_data
structure - ensure key/name uniqueness
- on
configuration
andmetadata
lists - on entries and categories
- consider not exposing raw structs to enforce this invariant
- on
- provide
UPSERT
and similar helper functions to operate on the data