password-store

Simple password manager using gpg and ordinary unix directories
git clone https://git.zx2c4.com/password-store
Log | Files | Refs | README | LICENSE

t0300-reencryption.sh (4638B)


      1 #!/usr/bin/env bash
      2 
      3 test_description='Reencryption consistency'
      4 cd "$(dirname "$0")"
      5 . ./setup.sh
      6 
      7 INITIAL_PASSWORD="will this password live? a big question indeed..."
      8 
      9 canonicalize_gpg_keys() {
     10 	$GPG --list-keys --with-colons "$@" | sed -n 's/sub:[^:]*:[^:]*:[^:]*:\([^:]*\):[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[a-zA-Z]*e[a-zA-Z]*:.*/\1/p' | LC_ALL=C sort -u
     11 }
     12 gpg_keys_from_encrypted_file() {
     13 	$GPG -v --no-secmem-warning --no-permission-warning --decrypt --list-only --keyid-format long "$1" 2>&1 | grep "public key is" | cut -d ' ' -f 5 | LC_ALL=C sort -u
     14 }
     15 gpg_keys_from_group() {
     16 	local output="$($GPG --list-config --with-colons | sed -n "s/^cfg:group:$1:\\(.*\\)/\\1/p" | head -n 1)"
     17 	local saved_ifs="$IFS"
     18 	IFS=";"
     19 	local keys=( $output )
     20 	IFS="$saved_ifs"
     21 	canonicalize_gpg_keys "${keys[@]}"
     22 }
     23 
     24 test_expect_success 'Setup initial key and git' '
     25 	"$PASS" init $KEY1 && "$PASS" git init
     26 '
     27 
     28 test_expect_success 'Root key encryption' '
     29 	"$PASS" insert -e folder/cred1 <<<"$INITIAL_PASSWORD" &&
     30 	[[ $(canonicalize_gpg_keys "$KEY1") == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/folder/cred1.gpg")" ]]
     31 '
     32 
     33 test_expect_success 'Reencryption root single key' '
     34 	"$PASS" init $KEY2 &&
     35 	[[ $(canonicalize_gpg_keys "$KEY2") == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/folder/cred1.gpg")" ]]
     36 '
     37 
     38 test_expect_success 'Reencryption root multiple key' '
     39 	"$PASS" init $KEY2 $KEY3 $KEY1 &&
     40 	[[ $(canonicalize_gpg_keys $KEY2 $KEY3 $KEY1) == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/folder/cred1.gpg")" ]]
     41 '
     42 
     43 test_expect_success 'Reencryption root multiple key with string' '
     44 	"$PASS" init $KEY2 $KEY3 $KEY1 "pass test key 4" &&
     45 	[[ $(canonicalize_gpg_keys $KEY2 $KEY3 $KEY1 $KEY4) == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/folder/cred1.gpg")" ]]
     46 '
     47 
     48 test_expect_success 'Reencryption root group' '
     49 	"$PASS" init group1 &&
     50 	[[ $(gpg_keys_from_group group1) == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/folder/cred1.gpg")" ]]
     51 '
     52 
     53 test_expect_success 'Reencryption root group with spaces' '
     54 	"$PASS" init "big group" &&
     55 	[[ $(gpg_keys_from_group "big group") == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/folder/cred1.gpg")" ]]
     56 '
     57 
     58 test_expect_success 'Reencryption root group with spaces and other keys' '
     59 	"$PASS" init "big group" $KEY3 $KEY1 $KEY2 &&
     60 	[[ $(canonicalize_gpg_keys $KEY3 $KEY1 $KEY2 $(gpg_keys_from_group "big group")) == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/folder/cred1.gpg")" ]]
     61 '
     62 
     63 test_expect_success 'Reencryption root group and other keys' '
     64 	"$PASS" init group2 $KEY3 $KEY1 $KEY2 &&
     65 	[[ $(canonicalize_gpg_keys $KEY3 $KEY1 $KEY2 $(gpg_keys_from_group group2)) == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/folder/cred1.gpg")" ]]
     66 '
     67 
     68 test_expect_success 'Reencryption root group to identical individual with no file change' '
     69 	oldfile="$SHARNESS_TRASH_DIRECTORY/$RANDOM.$RANDOM.$RANDOM.$RANDOM.$RANDOM" &&
     70 	"$PASS" init group1 &&
     71 	cp "$PASSWORD_STORE_DIR/folder/cred1.gpg" "$oldfile" &&
     72 	"$PASS" init $KEY4 $KEY2 &&
     73 	test_cmp "$PASSWORD_STORE_DIR/folder/cred1.gpg" "$oldfile"
     74 '
     75 
     76 test_expect_success 'Reencryption subfolder multiple keys, copy' '
     77 	"$PASS" init -p anotherfolder $KEY3 $KEY1 &&
     78 	"$PASS" cp folder/cred1 anotherfolder/ &&
     79 	[[ $(canonicalize_gpg_keys $KEY1 $KEY3) == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/anotherfolder/cred1.gpg")" ]]
     80 '
     81 
     82 test_expect_success 'Reencryption subfolder multiple keys, move, deinit' '
     83 	"$PASS" init -p anotherfolder2 $KEY3 $KEY4 $KEY2 &&
     84 	"$PASS" mv -f anotherfolder anotherfolder2/ &&
     85 	[[ $(canonicalize_gpg_keys $KEY1 $KEY3) == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/anotherfolder2/anotherfolder/cred1.gpg")" ]] &&
     86 	"$PASS" init -p anotherfolder2/anotherfolder "" &&
     87 	[[ $(canonicalize_gpg_keys $KEY3 $KEY4 $KEY2) == "$(gpg_keys_from_encrypted_file "$PASSWORD_STORE_DIR/anotherfolder2/anotherfolder/cred1.gpg")" ]]
     88 '
     89 
     90 test_expect_success 'Reencryption skips links' '
     91 	ln -s "$PASSWORD_STORE_DIR/folder/cred1.gpg" "$PASSWORD_STORE_DIR/folder/linked_cred.gpg" &&
     92 	[[ -L $PASSWORD_STORE_DIR/folder/linked_cred.gpg ]] &&
     93 	git add "$PASSWORD_STORE_DIR/folder/linked_cred.gpg" &&
     94 	git commit "$PASSWORD_STORE_DIR/folder/linked_cred.gpg" -m "Added linked cred" &&
     95 	"$PASS" init -p folder $KEY3 &&
     96 	[[ -L $PASSWORD_STORE_DIR/folder/linked_cred.gpg ]]
     97 '
     98 
     99 #TODO: test with more varieties of move and copy!
    100 
    101 test_expect_success 'Password lived through all transformations' '
    102 	[[ $("$PASS" show anotherfolder2/anotherfolder/cred1) == "$INITIAL_PASSWORD" ]]
    103 '
    104 
    105 test_expect_success 'Git picked up all changes throughout' '
    106 	[[ -z $(git status --porcelain 2>&1) ]]
    107 '
    108 
    109 test_done