WARNING
This shell script uses parts of OpenSSL/LibreSSL, which are intended for testing purposes only. You may loose your passwords. Use it at your own risk.

Tested on OpenBSD 6.3, 6.4, and 6.5

Manage passwords with openssl(1) and oathtool(1)

pass is a password manager written in shell and powered by openssl(1) and oathtool(1).

Install

# pkg_add oath-toolkit
...
oath-toolkit-2.6.2p0: ok
#

Download and run pass. Assuming ./bin is in PATH.

$ cd bin
$ ftp https://www.romanzolotarev.com/bin/pass
$ chmod +x pass
$ pass
usage: export BASE_DIR=~/.pass
       export PRIVATE_KEY=~/.pass/.key
       export PUBLIC_KEY=~/.pass/.key.pub

       pass init
          | passphrase
          | add        id
          | import     id <pass>
          | show       id
          | export     id <pass>
          | ls        <id>

Initialization

Create a directory for your passwords and generate your key pair. Generate a strong pass phrase. For example, with diceware.

$ pass init
Generating public/private key pair.
New pass phrase:
Confirm:
Generating RSA private key, 2048 bit long modulus
..........................+++
..................+++
e is 65537 (0x10001)
writing RSA key
$ ls -1 ~/.pass
.key
.key.pub
$

As result you get two files in ~/.pass directory. These files are your keys and they are protected with your master pass phrase.

Important! Backup those files, you won’t be able to recover any of your passwords without the private key. Also make sure you remember your pass phrase, there is no way to recover it either.

Change pass phrase

Change the master pass phrase for your private key.

$ pass passphrase
Changing /home/username/.pass/.key pass phrase.
Current pass phrase:
New pass phrase:
Confirm:
Pass phrase changed.
$

Add a password

Add the first password.

Run the following command and enter your master pass phrase, then type-in the password and hit Enter. In the second line type username and in the third line type url. Press Enter and CTRL-D to save the password.

$ pass add github
Pass phrase
Press Enter and CTRL-D to complete.
always mule boots jaguar agnostic singles dalmatian vixen
username: username
url: https://github.com
$

Import a password

Instead of typing your passwords manually you can pipe your favorite password generator right into pass.

$ diceware | pass import twitter
Enter pass phrase for /home/username/.pass/.key:
$

Edit the password

If you want to update your password run:

$ pass edit github
Enter pass phrase for /home/username/.pass/.key:

As soon as you enter the pass phrase pass opens vi with the content of your password file. Let’s enable 2FA at GitHub paste the TOTP seed from GitHub into the password file. For example:

totp: fx33dwhsbw7esrda

When you’re done press ZZ to save and exit vi.

Show the password

To show a password you can run:

$ pass show twitter
pelican mule satchel headband yo-yo lemon luscious older
$

But if a password file has a line staring with totp:, then pass shows one time password in the second line.

$ pass show github
Enter pass phrase for /home/username/.pass/.key:
always mule boots jaguar agnostic singles dalmatian vixen
122635
$

Export the password

If you want to see all lines of your password file, you can use export

$ pass export github
Enter pass phrase for /home/username/.pass/.key:
always mule boots jaguar agnostic singles dalmatian vixen
username: username
url: https://github.com
$

List all passwords

To list all your passwords run:

$ pass ls
github
twitter
$

Files

.pass
|-- .key           - RSA private key protected by pass phrase
|-- .key.pub       - RSA public key
|-- github         - tar archive of two files:
|   |-- github.key - AES key encrypted with RSA public key
|   `-- github.enc - text file encrypted with AES key
|-- github.sig     - signature of tar archive created with
|                    RSA private key
...

Every time you change your password file pass generates tar archive with a new AES key and a new signature. pass verifies the signature every time you show or export the password.

Environment variables

To change path to the working directory or your keys, define environment variables BASE_DIR, PRIVATE_KEY, PUBLIC_KEY. For example:

$ BASE_DIR=~/.pass \
PRIVATE_KEY=~/.pass/.key \
PUBLIC_KEY=~/.pass/.key.pub pass init
...

Completions in Korn shell

If you run pass on OpenBSD you may want to add completions in ksh(1)—its default shell. Add these functions to your ~/.profile:

update_complete_pass() {
  pass_list=$(pass ls)
  set -A complete_pass_edit -- $pass_list
  set -A complete_pass_export -- $pass_list
  set -A complete_pass_show -- $pass_list
}
update_complete_pass
pass_edit() { pass edit "$1"; }
pass_export() { pass export "$1" && update_complete_pass; }
pass_show() { pass show "$1" && update_complete_pass; }

Now open a terminal or source ~/.profile and try pass:

$ pass<Tab>
init  passphrase  add  import  show  export  ls
$ pass

Or most importantly try pass_show:

$ pass_show twit<Tab>
twitch  twitter
$ pass_show twit

See also

diceware, random