ken's passmanager

 

Index

DESCRIPTION
DOWNLOAD
DEPENDENCIES
COMPILATION
SYNOPSIS
OPTIONS SUMMARY
MODES
Add mode
Read mode
Delete mode
Update entry mode
Update database mode
OPENSSL NOTES
OpenSSL Ciphers and Digests
CSPRNG
SECURITY AND DESIGN NOTES
Input Padding
Database Creation and Modification
Authenticated Encryption and Associated Data with User Friendliness
Memory Sanitation
Memory Locking, Core-Dump and Process-Trace Prevention
Clipboard Functionality
EXAMPLES
SEE ALSO
 

DESCRIPTION

passmanager is an ultra simple, but very secure password management program written in C and making use of OpenSSL's Libcrypto API libraries. The passwords can be written, read, updated or deleted from an encrypted database file.

New passwords can be randomly generated when creating or updating account credentials. Passwords can be matched by entry name, and printed/updated/deleted in bulk or individually. All password entries in the database can be updated at once with ease. If the user updated/deleted a password they didn't intend to, the program lists which entries were matched and edited, and provides an automatically produced backup file to restore from. The database password and encryption method can be changed at any time.

The program pays special attention to minimize the amount user passwords are displayed on screen or stored in memory, and allows them to be sent directly to the clipboard (via native X librry calls (default), or xsel binary depending on compilation options), with the password being cleared from the clipboard afterward. Allowing the passwords to be sent directly to the clipboard means adding, updating or retrieving a password can be done without it ever being visible on the screen. Even if a user must display an entry's password to verify it, only that pass can be printed, in order to prevent the entire database being displayed on screen. Authenticated encryption with HMAC protects the database against both data corruption and tampering.

Account credentials are encrypted with 256-bit AES in CTR mode with HMAC-SHA512 for authentication. Using OpenSSL's EVP functions also enables the use of any encryption supported by the EVP interface.

User input is stored in 512 byte buffers padded by cryptographically strong pseudorandom data: One for an entry's name, and the other for that entry's password. This allows very large passwords, as well as long and flexible entry names, which can be comprised of service names and account names, and are best delimited with a colon. The program will print out each buffer delimited as a colon as well, in a list of "entry name : entry pass" format. The format of "entry name" is up to the user.

For example, here the user manually delimits the service and the account name

service : account : password

foobar : foo : passfoo

gmail : account@gmail.com : (*&*UJD83dh

But any of these are also possible

just a user account : password

foo - bar : foobar : foobar

555 867 5309 : (*&*UJD83dh

With this format and the modes provided, the user can easily and securely manage the contents of the database.

 

DOWNLOAD

GitHub
Automake Tarball
Raw C File

Back To Index  

DEPENDENCIES

OpenSSL development files (1.1.1 or higher)
xsel or X11 (optional for clipboard functions)

Back To Index  

COMPILATION

If you don't want to install the automake package contents, and want to compile the binary alone:

gcc passmanager.c -o passmanager -lcrypto -lX11 -D HAVE_LIBX11

...or if you want to use xsel for clipboard functions, or disable clipboard functions all together...

gcc passmanager.c -o passmanager -lcrypto

Special Note: I would advise against using optimization, because the functions which are used to clear memory of sensitive data may be optimized out.

Back To Index  

SYNOPSIS

passmanager -a entry name | -r entry name | -d entry name | -u entry name | -U [-n new name ] [-p new entry password] [-l random password length] [-c cipher] [-w N,r,p ] [ -P ] [ -C ] [ -O ] [ -s selection ] [ -t seconds or miliseconds ] [-x database password] -f database file

Back To Index  

OPTIONS SUMMARY

Options may have different implications depending on operating mode

-a entry name - Add entry name in Add mode

-r entry name - Lookup entry name in Read mode ('allpasses' will print all passes)

-d entry name - Delete entry name in Delete mode

-u entry name - Update entry name in Update entry mode

-U - Update database mode

-n new name - entry name up to 511 characters (can contain white space or special characters)

-p new entry password - entry password up to 511 characters (don't call to be prompted instead) ('gen' will generate a random password, 'genalpha' will generate a random password with no symbols)

-l random password length - makes 'gen' or 'genalpha' generate a password random password length digits long (defaults to 16 without this option)

-c cipher - Specify 'list' for a list of methods available to OpenSSL. Default: aes-256-ctr.

-H digest - Specify 'list' for a list of methods available to OpenSSL. Default: sha512.

-w N,r,p - Specify scrypt work factors N,r,p (Must be comma separted with no spaces,and N must be a power of 2). Default: 1048576,8,1

-P - In Update entry or Update database mode (-u and -U respectively) this option enables updating the entry password or database password via prompt instead of as command line argument

-C - send entry password directly to clipboard. Clipboard is cleared automatically after pasting, or in 30 seconds if using xsel for clipbord functions.

-t nms or ns - clear password from clipboard in n miliseconds or seconds instead of default 30 seconds.

-O - implies '-t 55ms' to allow only one pasting of password before its cleared

-s selection - use either primary or clipboard X selection (Defaults to 'primary').

-x database password - To supply database password as command-line argument (not reccomended)

-I - Print database information

-f - database file ( must be specified )

-h - Quick usage help

Back To Index  

MODES

 

Add mode

In Add mode the password database is initialized with the first entry, or a new entry is added to an existing password database. The user may specify a cipher and/or digest to use upon initialization of the database.

When adding a new entry, its password can be sent directly to clipboard. This is especially useful for generating new passwords, where 'gen' can be given as the entry password argument and the new randomly generated password will be sent to the clipboard.

Applicable options

-p new entry password - 'gen' will generate a random password, 'genalpha' will generate a random password with no symbols
-l random password length - makes 'gen' or 'genalpha' generate a password random password length digits long (defaults to 16 without this option)
-x database password
-c cipher - Initializes a password database with EVP cipher algorithm 'cipher'
-H digest - Derives keys for ciphers with EVP digest algorithm 'digest'
-C send new entry password to clipboard (useful if randomly generated)
-w N,r,p - Specify scrypt work factors N,r,p.
-t nms or ns - clear password from clipboard in n miliseconds or seconds instead of default 30 seconds.
-O - implies '-t 55ms' to allow only one pasting of password before its cleared
-s selection - use either primary or clipboard X selection (Defaults to 'primary').

Back To Index  

Read mode

In Read mode the password database is searched for an entry with the name entry name for partial or full matches so that entry name of 'app' will find entry names 'apple' and 'appliances'.

Entries can be specifically matched such as "gmail : account1" and "gmail : account2", or both with 'gmail'.

Searching for a specific entry pass can be useful to send the password directly to the clipboard. Note that if multiple entries match your search string, only the first matched entry will be sent to the clipboard.

To display the entire password database, enter 'allpasses' for the entry name argument.

Applicable options

-x database password
-C send entry name password directly to clipboard (useful to avoid displaying passwords on screen)
-t nms or ns - clear password from clipboard in n miliseconds or seconds instead of default 30 seconds.
-O - implies '-t 55ms' to allow only one pasting of password before its cleared
-s selection - use either primary or clipboard X selection (Defaults to 'primary').

Back To Index  

Delete mode

In Delete mode one or more password entries can be deleted. entry name can be partially or fully matched as in Read mode.

Applicable options

-x database password

Back To Index  

Update entry mode

In Update entry mode one or multiple entries are updated. As in Read and Add modes, the entry name will be fully or partially matched.

Both the entry name and password can be updated. The new entry name can be supplied via command line only, but the new password can be received via prompt or as a command line argument ( not recommended ).

As in Add mode, entering 'gen' for the entry password argument will generate a random password. This is especially useful for updating old passwords.

Single new passwords can be sent directly to the clipboard as well. Note that if multiple entries match your search string, only the first matched entry will be updated and sent to the clipboard.

All entries can be updated at once with new randomly generated passwords, if entry name is equal to 'allpasses'

Applicable options

-P updates entry name and entry password, getting new entry password via user input instead of command line (-p)
-p new entry password - update entry name password to new entry password
-l random password length - makes 'gen' or 'genalpha' generate a password random password length digits long (defaults to 16 without this option)
-n new name - update entry name to new name. Without this its assumed you're only changing the password of entry name.
-x database password
-C send new entry password directly to clipboard after updating entry name
-t nms or ns - clear password from clipboard in n miliseconds or seconds instead of default 30 seconds.
-O - implies '-t 55ms' to allow only one pasting of password before its cleared
-s selection - use either primary or clipboard X selection (Defaults to 'primary').

Back To Index  

Update database mode

In Update database mode the password and the underlying OpenSSL encryption of the database can be updated.

If option -c or -H given to update the encryption or digest algorithm ( respectively ) then -P is needed if changing the database password is also desired.

If only option -U is present, then only the password is updated.

The new password can only be received via prompt, and cannot be given on the command line. However the current database password can still be received with the -x option.

Applicable options

-P updates database password. Read via prompt. Cannot be supplied via commandline.
-x database password (the current database password to decrypt/with)
-c cipher - Updates algorithms
-H digest - Update digests used
-w N,r,p - Specify scrypt work factors N,r,p.

 

OPENSSL NOTES

 

OpenSSL Ciphers and Digests

The encryption algorithm used by OpenSSL can be chosen between the ciphers provided by the high-level functions in the evp(3) library. By default the program uses 256-bit AES in CTR mode, using scrypt to derive keys. Authenticated ciphers using GCM or CCM are not supported as the program uses HMAC-SHA512 for authentication. The ability to choose cipher algorithms is primarily added incase different versions of OpenSSL are installed across different machine, thus making different ciphers available. For example, ChaCha20 may not be available on one machine while it is on the other.

Back To Index  

CSPRNG

The EVP library also provides access to OpenSSL's CSPRNG as described in RAND(3). The RAND_bytes(3) function is what fills the buffers with pseudorandomness, generates random passwords, and generates the salt for scrypt.

Back To Index  

SECURITY AND DESIGN NOTES

 

Input Padding

Input buffers will accept any amount of whitespace or special characters up to 511 characters in length. The buffers are padded with pseudo-random data from a Cryptographically Strong Pseudo Random Number Generator (CSPRNG). This was done with more consideration than simply providing ample memory for user input. The extra space being padded with pseudo-random data also helps suppress natural-language frequencies, making frequency analysis of the cipher-text less useful.

Back To Index  

Database Creation and Modification

A password database is created with writeDatabase() when the first password entry is added, or when modifications are made. scrypt uses a randomly generated 256-bit salt and a user-supplied password to derive a 1024-bit master key. This key is split to provide an appropriately sized key for the cipher algorithm selected (surplus bits are discarded), as well as a 512-bit authentication key for HMAC-SHA512. The salt is written as a header along with the cipher name and scrypt work factors, and is also used as an IV in ciphers that require one. openDatabase() is used upon every subsequent reading of the password database to configure these options and check for database integrity, authenticity, and correct password, before any decryption is done. A new salt is generated for scrypt any time a modification is made to the database, so that there is never any key reuse. This makes the use of an IV redudnant, but since its trivial to use the salt as the IV, it's done anyway.

writeDatabase() first writes a header comprised of the salt, the algorithm for encryption, as well as the work factors for scrypt to use. It then writes the resulting cipher-text of the password entries before a keyed hash, a MAC, and a checksum of all the preceding, are signed to it by concatenation and appended as a footer. HMAC-SHA512 is used to generate a keyed hash of the user-supplied database password, that is then signed so that the database password a user supplies can be checked for correctness. HMAC-SHA512 is then used to generate a MAC of the cipher-text and associated data (salt, cipher name, and scrypt work factors), that is then signed to ensure authenticity. SHA512 is then used to hash the header, cipher-text, keyed-hash and MAC, and the checksum is signed to ensure general integrity of the database. All modifications to the database are saved in memory and sent to writeDatabase() to overwrite the previous file.

openDatabase() parses the header for the salt, cipher and scrypt configuration. It then reads in the keyed hash of the password, the MAC of the cipher-text and associated data (salt, cipher name, and scrypt work factors), and the database checksum. A checksum of the database file is then generated and compared to the one it is signed with to check for general integrity of the database in storage. Following that, the keyed hash of the database password the user entered is compared to the keyed hash the database is signed with to determine if the user-supplied password matches the one the database was created with. Finally, the cipher-text data is passed on to the various operating modes that then generate a SHA512 hash with it and the associated data, and compare that to the MAC produced by HMAC-SHA512 that the database was signed with to verify authenticity of the cipher-text and associated data in memory. If the database integrity can't be verified, the user-supplied password is not correct, or the cipher-text and associated data can't be authenticated, the program informs which of these was the case (and possible reasons) and exits. Otherwise, the cipher-text is decrypted and read into memory for processing. If modifications were made, the new data is encrypted, and sent to writeDatabase() to form the new database.

Back To Index  

Authenticated Encryption and Associated Data with User Friendliness

The cipher-text is authenticated in Encrypt-then-MAC composition. If the database fails an integrity check, the password was incorrect, or the cpher-text/associated-data fails authentication, decryption never takes place.

Verifying the integrity of the database file with a checksum means that an actual attack can be detected with very little risk of a false-positive if the integrity check passes but the authenticity check does not. Verifying the authenticity of the cipher-text after it's loaded into memory will also detect tampering (or faulty memory) after it's loaded from disk. The only circumstance in which a false-positive could happen is if the memory that the ciphertext, associated data or MAC was loaded into is faulty and caused corruption after being loaded from disk and passing the integrity test. Otherwise, a passing integrity test, but a failed authenticity test would imply that the checksum was deliberately forged to match the modified cipher-text and/or associated data, indicating an attack on the cipher-text and/or associated data.

The password used when the database was created is hashed with HMAC. Because every modification of the database results in a newly generated salt, every modification will also result in a new keyed hash. Failing the password check will preclude an authenticity check. This isn't intended to add an extra security layer, but rather to be more user-friendly. If the password entered was incorrect, the proper keys for HMAC could not be generated, and so if only the MAC alone were used, it would result in a failed authentication check even if the cipher-text and associated data was authentic but the password was merely mistyped.

Modification of various associated data or the cipher-text and forging the checksum to match will have differing effects (assuming the password's keyed hash is successfully forged as well). If an attacker modifies the salt or scrypt work factors and forges the database checksum to match this modification, it will always result in a password-check failure. This is because modifying the salt or scrypt work factors will produce a different keyed hash than the one signed to the database so it will appear that the password was incorrect (even if it actually was correct). Unless the keyed hash was somehow forged to match the supplied password as well. However, the scrypt work factors and salt are still authenticated by HMAC as associated data, so the MAC would then have to be successfully forged as well for the modification to pass. Likewise, modifying the cipher or digest information will not affect the keyed hash of the database password, but would still fail the authentication test unless the MAC was forged to match the modifications. Finally, if the actual cipher-text itself is modified and the database checksum forged to match the change, both the keyed hash of the password and the MAC would have to be forged for the modification to pass the authenticity test.

This design was chosen to alert the user of a critical issue if they encounter a failed authenticity test, a serious issue if they failed an integrity test, and avoid alarm if they simply mistyped a password.

Back To Index  

Memory Sanitation

OPENSSL_cleanse() is used to ensure sanitation calls aren't optimized away by the compiler.

Back To Index  

Memory Locking, Core-Dump and Process-Trace Prevention

The program will attempt to "lock" all memory, which will prevent it from accidentally being swapped out to disk. It also prevents process tracing, and core dump upon crash. In order to do this, the program needs root priveleges, but drops them after these settings have been made. The executable is installed with the SETUID and SETGID bits and with root as the owner, so the user need not execute it as root or with sudo.

Back To Index  

Clipboard Functionality

Automatically sending passwords to the clipboard is handled by X library calls, or by piping out to a xsel binary installed on the system. The former should be preferred for best security and functionality, but the latter is more portable, and both options can be chosen at compile time with autoconf's configuration script. The 'primary' X selection can be used to paste the password with a middle-click (or both right and left buttons at once), and the 'clipboard' selection can be usd to paste with Ctrl+V or Right-Click->Paste. If text is subsequently highlighted, it will overwrite the 'primary' selection (and thus the password as well).

The internal X library calls offer better security because passwords are cleared from memory at exit and from the 'primary' selection at a specified amount of seconds/miliseconds after pasting; they are also stored in locked-memory to prevent swapping of this data to disk. The countdown does not begin until a password is pasted, and if a password is pasted again, the countdown resets again to faciliatate multiple pastings. A clear time of miliseconds can be used to specify that the password should be cleared from the primary buffer after just one paste. Technically it is a milisecond delay, so a race condition between the password being pasted and cleared may be caused, and the time may need to be set higher if pasting fails; a setting of 55 ms is usually enough, as with option '-O'. If using the 'clipboard' selection, the timer will not be delayed until the password is pasted, but instead will begin to countdown immediately, so the program will enforce use of the 'primary' buffer if a clear time less than 5 seconds is specified.

On the contrary, with piping to an external xsel binary, passwords are not cleared from memory at exit or stored in locked memory, the countdown to clear the password from xsel's selection buffer is began immediately without pasting, and the countdown timer does not reset upon subsequent pastes. However, piping to an xsel binary is far more portable as a user can control where the password is piped to. The program will simply pipe to any binary or shell-script that can be invoked by 'xsel'; this also makes it less secure. If for example, a user is on a system using Wayland instead of X, 'xsel' could be sent to a shell-script to handle the data instead. If the 'primary' selection is used, the program will invoke 'xsel' with no arguments and 'xsel -c' to clear, but if the 'clipboard' selection is specified, it will invoke 'xsel -b' and 'xsel -b -c' to clear.

Back To Index  

EXAMPLES

Initialize a new password database using blowfish encryption, scrypt work factors 1024,8,1 for N, r and p (respectively), and save it to the file 'passwords'. Also randomly generate a password of 32 characters for the new entry, and send that new password to the clipboard, clearing it from memory in 5 seconds

passmanager -a "gmail : myemail@gmail.com" -p gen -c bf-ofb -w 1024,8,1 -l 32 -C -s 5 -f ./passwords

Print a list of available ciphers

passmanager -c list

Can also change password for the database (Will be prompted for input)

passmanager -U -f ./passwords

Or you could do both change the password, the encryption and scrypt work factors in one command

passmanager -U -c aes-256-ctr -w 16384,8,1 -P -f ./passwords

Update the previously added entry name from "gmail : myemail@gmail.com" to "gmail : myemail1@gmail.com" (Note how we're partially matching "gmail", and the need for quotations around the new entry name since it contains whitespace)

passmanager -u gmail -n "gmail : myemail1@gmail.com" -f ./passwords

Add a second gmail account but with the entry password "password"

passmanager -a "gmail : myemail2@gmail.com" -p password -f ./passwords

If you are following these examples sequentially, this is how you would print out your password database, and what it would look like on screen.

passmanager -r allpasses -f ./passwords

gmail : myemail1@gmail.com : Us3[Ag1<lRw9%Vj5>La0{Nh4|Kr8$Te7

gmail : myemail2@gmail.com : password

To update the password for myemail2@gmail.com with a randomly generated 16 character (default) password, and send the newly created password to clipboard

passmanager -u "gmail : myemail2" -p gen -C -f ./passwords

To update the passsword but prompt the user for password

passmanager -u "gmail : myemail2" -P -f ./passwords

Read the new password for myemail2@gmail.com and send it directly to the clipboard

passmanager -r "gmail : myemail2" -C -f ./passwords

Or to just print both gmail passwords on screen ( but no other entry passwords )

passmanager -r gmail -f ./passwords

To delete both of the gmail accounts. (Note no need for quotation marks since we can partially match both entry names before the whitespace portions)

passmanager -d gmail -f ./passwords

To print all passwords in database, and supply the database password as a command-line argument (Perhaps to fill in from some other location besides user input)

passmanager -r allpasses -x password -f ./passwords

To update all passwords in database with a randomly generated passwords

passmanager -u allpasses -p gen -f ./passwords

Back To Index  

SEE ALSO

openssl(1), xsel(1), evp(3), EVP_EncryptInit(3), RAND(3), RAND_bytes(3)

Back To Index