diff --git a/test/109_accept_encryption.bats b/test/109_accept_encryption.bats index a3c07a7..096c66c 100644 --- a/test/109_accept_encryption.bats +++ b/test/109_accept_encryption.bats @@ -3,11 +3,31 @@ load_fixtures status=;output=; #; populated by bats run() T_PASSWD="ExamplePassword" +T_ARCHIVE_SYMMETRIC="$T_TMP/build_archive.symmetric" +T_ARCHIVE_ASYMMETRIC="$T_TMP/build_archive.asymmetric" +T_KEY_NAME="yadm-test1" +T_KEY_FINGERPRINT="F8BBFC746C58945442349BCEBA54FFD04C599B1A" +T_RECIPIENT_GOOD="[yadm]\n\tgpg-recipient = yadm-test1" +T_RECIPIENT_BAD="[yadm]\n\tgpg-recipient = invalid" +T_RECIPIENT_ASK="[yadm]\n\tgpg-recipient = ASK" + +function import_keys() { + gpg --import "test/test_key" >/dev/null 2>&1 || true + gpg --import-ownertrust < "test/ownertrust.txt" >/dev/null 2>&1 +} + +function remove_keys() { + gpg --batch --yes --delete-secret-keys "$T_KEY_FINGERPRINT" >/dev/null 2>&1 || true + gpg --batch --yes --delete-key "$T_KEY_FINGERPRINT" >/dev/null 2>&1 || true +} setup() { #; start fresh destroy_tmp + #; import test keys + import_keys + #; create a worktree & repo build_repo @@ -27,26 +47,37 @@ setup() { fi ) - #; encrypt YADM_ARCHIVE + #; encrypt YADM_ARCHIVE (symmetric) expect </dev/null set timeout 2; - spawn gpg --yes -c --output "$T_YADM_ARCHIVE" "$T_TMP/build_archive.tar" + spawn gpg --yes -c --output "$T_ARCHIVE_SYMMETRIC" "$T_TMP/build_archive.tar" expect "passphrase:" {send "$T_PASSWD\n"} expect "passphrase:" {send "$T_PASSWD\n"} expect "$" foreach {pid spawnid os_error_flag value} [wait] break EOF + + #; encrypt YADM_ARCHIVE (asymmetric) + gpg --yes --batch -e -r "$T_KEY_NAME" --output "$T_ARCHIVE_ASYMMETRIC" "$T_TMP/build_archive.tar" +} + +teardown() { + remove_keys } function validate_archive() { #; inventory what's in the archive - expect </dev/null - set timeout 2; - spawn bash -c "(gpg -q -d '$T_YADM_ARCHIVE' || echo 1) | tar t | sort > $T_TMP/archive_list" - expect "passphrase:" {send "$T_PASSWD\n"} - expect "$" - foreach {pid spawnid os_error_flag value} [wait] break + if [ "$1" = "symmetric" ]; then + expect </dev/null + set timeout 2; + spawn bash -c "(gpg -q -d '$T_YADM_ARCHIVE' || echo 1) | tar t | sort > $T_TMP/archive_list" + expect "passphrase:" {send "$T_PASSWD\n"} + expect "$" + foreach {pid spawnid os_error_flag value} [wait] break EOF + else + gpg -q -d "$T_YADM_ARCHIVE" || echo 1 | tar t | sort > "$T_TMP/archive_list" + fi #; inventory what is expected in the archive ( @@ -110,9 +141,6 @@ function validate_extraction() { Exit with 1 " - #; remove existing T_YADM_ARCHIVE - rm -f "$T_YADM_ARCHIVE" - #; run encrypt run expect < "$T_YADM_ENCRYPT" #; validate the archive - validate_archive + validate_archive symmetric } @test "Command 'encrypt' (overwrite)" { @@ -213,7 +235,7 @@ EOF Exit with 0 " - #; Explictly create an invalid archive + #; Explicitly create an invalid archive echo "EXISTING ARCHIVE" > "$T_YADM_ARCHIVE" #; run encrypt @@ -232,7 +254,7 @@ EOF [[ "$output" =~ Wrote\ new\ file:.+$T_YADM_ARCHIVE ]] #; validate the archive - validate_archive + validate_archive symmetric } @test "Command 'decrypt' (missing YADM_ARCHIVE)" { @@ -243,10 +265,7 @@ EOF Exit with 1 " - #; remove YADM_ARCHIVE - rm -f "$T_YADM_ARCHIVE" - - #; run encrypt + #; run decrypt run "${T_YADM_Y[@]}" decrypt #; validate status and output @@ -263,7 +282,10 @@ EOF Exit with 1 " - #; run encrypt + #; use the symmetric archive + cp -f "$T_ARCHIVE_SYMMETRIC" "$T_YADM_ARCHIVE" + + #; run decrypt run expect <> "$T_DIR_WORK/$f" done < "$T_TMP/archived_files" - #; run encrypt + #; run decrypt run expect < "$T_YADM_CONFIG" + + #; run encrypt + run "${T_YADM_Y[@]}" encrypt + + #; validate status and output + [ "$status" -eq 1 ] + [[ "$output" =~ invalid\ passphrase ]] + [[ "$output" =~ Unable\ to\ write ]] +} + + +@test "Command 'encrypt' (asymmetric)" { + echo " + When 'encrypt' command is provided, + and YADM_ENCRYPT is present + and yadm.gpg-recipient refers to a valid private key + Create YADM_ARCHIVE + Report the archive created + Archive should be valid + Exit with 0 + " + + #; manually set yadm.gpg-recipient in configuration + make_parents "$T_YADM_CONFIG" + echo -e "$T_RECIPIENT_GOOD" > "$T_YADM_CONFIG" + + #; run encrypt + run "${T_YADM_Y[@]}" encrypt + + #; validate status and output + [ "$status" -eq 0 ] + [[ "$output" =~ Wrote\ new\ file:.+$T_YADM_ARCHIVE ]] + + #; validate the archive + validate_archive asymmetric +} + +@test "Command 'encrypt' (asymmetric, overwrite)" { + echo " + When 'encrypt' command is provided, + and YADM_ENCRYPT is present + and yadm.gpg-recipient refers to a valid private key + and YADM_ARCHIVE already exists + Overwrite YADM_ARCHIVE + Report the archive created + Archive should be valid + Exit with 0 + " + + #; manually set yadm.gpg-recipient in configuration + make_parents "$T_YADM_CONFIG" + echo -e "$T_RECIPIENT_GOOD" > "$T_YADM_CONFIG" + + #; Explicitly create an invalid archive + echo "EXISTING ARCHIVE" > "$T_YADM_ARCHIVE" + + #; run encrypt + run "${T_YADM_Y[@]}" encrypt + + #; validate status and output + [ "$status" -eq 0 ] + [[ "$output" =~ Wrote\ new\ file:.+$T_YADM_ARCHIVE ]] + + #; validate the archive + validate_archive asymmetric +} + +@test "Command 'encrypt' (asymmetric, ask)" { + echo " + When 'encrypt' command is provided, + and YADM_ENCRYPT is present + and yadm.gpg-recipient is set to ASK + Ask for recipient + Create YADM_ARCHIVE + Report the archive created + Archive should be valid + Exit with 0 + " + + #; manually set yadm.gpg-recipient in configuration + make_parents "$T_YADM_CONFIG" + echo -e "$T_RECIPIENT_ASK" > "$T_YADM_CONFIG" + + #; run encrypt + run expect < "$T_YADM_CONFIG" + + #; run decrypt + run "${T_YADM_Y[@]}" decrypt + + #; validate status and output + [ "$status" -eq 1 ] + [[ "$output" =~ does\ not\ exist ]] +} + +@test "Command 'decrypt' (asymmetric, missing key)" { + echo " + When 'decrypt' command is provided, + and yadm.gpg-recipient refers to a valid private key + and YADM_ARCHIVE is present + and the private key is not present + Report problem + Exit with 1 + " + + #; manually set yadm.gpg-recipient in configuration + make_parents "$T_YADM_CONFIG" + echo -e "$T_RECIPIENT_GOOD" > "$T_YADM_CONFIG" + + #; use the asymmetric archive + cp -f "$T_ARCHIVE_ASYMMETRIC" "$T_YADM_ARCHIVE" + + #; remove the private key + remove_keys + + #; run decrypt + run "${T_YADM_Y[@]}" decrypt + + #; validate status and output + [ "$status" -eq 1 ] + [[ "$output" =~ decryption\ failed ]] + [[ "$output" =~ Unable\ to\ extract ]] +} + +@test "Command 'decrypt' -l (asymmetric, missing key)" { + echo " + When 'decrypt' command is provided, + and '-l' is provided, + and yadm.gpg-recipient refers to a valid private key + and YADM_ARCHIVE is present + and the private key is not present + Report problem + Exit with 1 + " + + #; manually set yadm.gpg-recipient in configuration + make_parents "$T_YADM_CONFIG" + echo -e "$T_RECIPIENT_GOOD" > "$T_YADM_CONFIG" + + #; use the asymmetric archive + cp -f "$T_ARCHIVE_ASYMMETRIC" "$T_YADM_ARCHIVE" + + #; remove the private key + remove_keys + + #; run decrypt + run "${T_YADM_Y[@]}" decrypt + + #; validate status and output + [ "$status" -eq 1 ] + [[ "$output" =~ decryption\ failed ]] + [[ "$output" =~ Unable\ to\ extract ]] +} + +@test "Command 'decrypt' (asymmetric)" { + echo " + When 'decrypt' command is provided, + and yadm.gpg-recipient refers to a valid private key + and YADM_ARCHIVE is present + Report the data created + Data should be valid + Exit with 0 + " + + #; manually set yadm.gpg-recipient in configuration + make_parents "$T_YADM_CONFIG" + echo -e "$T_RECIPIENT_GOOD" > "$T_YADM_CONFIG" + + #; use the asymmetric archive + cp -f "$T_ARCHIVE_ASYMMETRIC" "$T_YADM_ARCHIVE" + + #; empty the worktree + rm -rf "$T_DIR_WORK" + mkdir -p "$T_DIR_WORK" + + #; run decrypt + run "${T_YADM_Y[@]}" decrypt + + #; validate status and output + [ "$status" -eq 0 ] + [[ "$output" =~ All\ files\ decrypted ]] + + #; validate the extracted files + validate_extraction +} + +@test "Command 'decrypt' (asymmetric, overwrite)" { + echo " + When 'decrypt' command is provided, + and yadm.gpg-recipient refers to a valid private key + and YADM_ARCHIVE is present + and archived content already exists + Report the data overwritten + Data should be valid + Exit with 0 + " + + #; manually set yadm.gpg-recipient in configuration + make_parents "$T_YADM_CONFIG" + echo -e "$T_RECIPIENT_GOOD" > "$T_YADM_CONFIG" + + #; use the asymmetric archive + cp -f "$T_ARCHIVE_ASYMMETRIC" "$T_YADM_ARCHIVE" + + #; alter the values of the archived files + while IFS= read -r f; do + echo "changed" >> "$T_DIR_WORK/$f" + done < "$T_TMP/archived_files" + + #; run decrypt + run "${T_YADM_Y[@]}" decrypt + + #; validate status and output + [ "$status" -eq 0 ] + [[ "$output" =~ All\ files\ decrypted ]] + + #; validate the extracted files + validate_extraction +} + +@test "Command 'decrypt' -l (asymmetric)" { + echo " + When 'decrypt' command is provided, + and '-l' is provided, + and yadm.gpg-recipient refers to a valid private key + and YADM_ARCHIVE is present + Report the contents of YADM_ARCHIVE + Exit with 0 + " + + #; manually set yadm.gpg-recipient in configuration + make_parents "$T_YADM_CONFIG" + echo -e "$T_RECIPIENT_GOOD" > "$T_YADM_CONFIG" + + #; use the asymmetric archive + cp -f "$T_ARCHIVE_ASYMMETRIC" "$T_YADM_ARCHIVE" + + #; run decrypt + run "${T_YADM_Y[@]}" decrypt -l + + #; validate status + [ "$status" -eq 0 ] + + #; validate every file is listed in output + while IFS= read -r f; do + if [[ ! "$output" =~ $f ]]; then + echo "ERROR: Did not find '$f' in output" + return 1 + fi + done < "$T_TMP/archived_files" + +} diff --git a/test/ownertrust.txt b/test/ownertrust.txt new file mode 100644 index 0000000..9f212c3 --- /dev/null +++ b/test/ownertrust.txt @@ -0,0 +1 @@ +F8BBFC746C58945442349BCEBA54FFD04C599B1A:6: diff --git a/test/test_key b/test/test_key new file mode 100644 index 0000000..14500d5 --- /dev/null +++ b/test/test_key @@ -0,0 +1,57 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: GnuPG v1 + +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 +=2hap +-----END PGP PRIVATE KEY BLOCK-----