From 247cbcb8c95574b3956d9fac5b4da40b6cc83273 2020-06-29 04:17:56 From: Branko Majic <branko@majic.rs> Date: 2020-06-29 04:17:56 Subject: [PATCH] Check the local public keyring and encrypted files for discrepancies, and re-encrypt the files where there's a mismatch. Resolves issue SCR-1. --- diff --git a/openpgp/gitprotect.sh b/openpgp/gitprotect.sh index f6480c9b7fb133087841e294fa7ffa9801d86ee5..5f149240ae87469e3fb2851a1a81d3f077e05789 100755 --- a/openpgp/gitprotect.sh +++ b/openpgp/gitprotect.sh @@ -225,7 +225,8 @@ temporary GnuPG files. Before proceeding with the commit, verify the changes with: -git status --staged . +git status . +git diff --staged . After you have verfied the changes, commit the changes with (you may specify alternative message): @@ -302,25 +303,42 @@ elif [[ $command = "encrypt" ]]; then # Make sure that we have at least a single recipient. if [[ "${#recipients[@]}" == 0 ]]; then - echo "ERROR: No suitable recipients were found in the keyring." >&2 + echo "ERROR: No suitable recipients were found in the keyring. Did you forget ot add keys?" >&2 exit "$ERR_NORECIPIENTS" fi # Encrypt every file from the decrypted sub-directory. - while read filePath; do - filename=$(basename "$filePath") + while read decryptedFile; do + filename=$(basename "$decryptedFile") + encryptedFile="./${filename}.gpg" checksumFile="decrypted/.${filename}.sha256" + # If the encrypted file is present, fetch list of keys that were used to + # encrypt it, and list of keys in the current keyring so we can compare + # them later on. + if [[ -f $encryptedFile ]]; then + currentFileRecipients=$(gpg2 --status-fd 1 --homedir "$gnupgHome" --quiet --batch --list-only --decrypt "$encryptedFile" | grep ENC_TO | sed -e 's/.*ENC_TO //;s/ .*//' | sort -u) + newFileRecipients=$(echo "${recipients[@]}" | tr ' ' '\n' | sort -u) + fi + + # If an encrypted file exists, and its recipient list is outdated, + # re-encrypt the decrypted file to get the recipients into sync. + if [[ -f $encryptedFile && $currentFileRecipients != $newFileRecipients ]]; then + echo "INFO: Encrypting file '$decryptedFile' due to differing recipients in keyring and current encrypted file." + cat "$decryptedFile" | gpg2 --trust-model always "${gnupgArgs[@]}" \ + --armor "${recipientArgs[@]}" --encrypt > "$encryptedFile" + sha256sum "$decryptedFile" > "$checksumFile" # If the checksum file exists, then verify it. This way we detect if # decrypted file has been changed in any way since it has been # decrypted. We should skip unchanged files. - if [[ -f $checksumFile ]] && sha256sum --quiet -c "$checksumFile" > /dev/null 2>&1; then - echo "INFO: File decrypted/$filename doesn't seem to have been changed. Skipping." + elif [[ -f $checksumFile ]] && sha256sum --quiet -c "$checksumFile" > /dev/null 2>&1; then + echo "INFO: File $decryptedFile doesn't seem to have been changed. Skipping." # The file was changed, so we need to encrypt new version of it. else - cat "$filePath" | gpg2 --trust-model always "${gnupgArgs[@]}" \ - --armor "${recipientArgs[@]}" --encrypt > "${filename}.gpg" - sha256sum "decrypted/$filename" > "decrypted/.${filename}.sha256" + echo "INFO: Encrypting new version of file '$decryptedFile'." + cat "$decryptedFile" | gpg2 --trust-model always "${gnupgArgs[@]}" \ + --armor "${recipientArgs[@]}" --encrypt > "$encryptedFile" + sha256sum "$decryptedFile" > "$checksumFile" fi done < <(find "decrypted/" -maxdepth 1 -type f ! -name '.*.sha256') elif [[ $command = "decrypt" ]]; then