summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSilvio Rhatto <rhatto@riseup.net>2022-08-19 11:17:15 -0300
committerSilvio Rhatto <rhatto@riseup.net>2022-08-19 11:17:15 -0300
commitaac16ab2cbd31d783f98a1ffe814a363886f74f4 (patch)
tree74fd569eda0cee5ef26530d010340114c60710c6 /lib
parenta3c913dec62cb098b3234bfaec22492ba8979119 (diff)
downloadkeyringer-aac16ab2cbd31d783f98a1ffe814a363886f74f4.tar.gz
keyringer-aac16ab2cbd31d783f98a1ffe814a363886f74f4.tar.bz2
Fix re-encryption when the secret hass NULL bytes
Diffstat (limited to 'lib')
-rwxr-xr-xlib/keyringer/actions/recrypt59
1 files changed, 48 insertions, 11 deletions
diff --git a/lib/keyringer/actions/recrypt b/lib/keyringer/actions/recrypt
index 0e2f6a0..5542bfc 100755
--- a/lib/keyringer/actions/recrypt
+++ b/lib/keyringer/actions/recrypt
@@ -9,33 +9,66 @@ source "$LIB" readwrite $* || exit 1
# Recrypt a single secret
function keyringer_recrypt {
-
# Get file
keyringer_get_file "$1"
# Set recipients file
keyringer_set_recipients "$FILE"
- # Decrypt
- decrypted="$($GPG --use-agent -d "$KEYDIR/$FILE")"
+ # Verbosity
+ echo "Processing $FILE..."
- if [ "$?" != "0" ]; then
- echo "Decryption error on $1."
- exit 1
- fi
+ # Recrypt in stages. This approach will fail for secrets that have NULL bytes, since
+ # bash can't hold those as variables.
+ #
+ # In that case, it would lead to the following warning:
+ #
+ # lib/keyringer/actions/recrypt: line 20: warning: command substitution: ignored null byte in input
+ #
+ # See https://stackoverflow.com/a/42493691
+ #
+ ## Decrypt
+ #decrypted="$($GPG --use-agent -d "$KEYDIR/$FILE")"
+
+ #if [ "$?" != "0" ]; then
+ # echo "Decryption error on $1."
+ # exit 1
+ #fi
+
+ ## Recrypt
+ #recrypted="`echo "$decrypted" | $GPG --use-agent --armor -e -s $(keyringer_recipients "$RECIPIENTS_FILE")`"
+
+ #if [ "$?" != "0" ]; then
+ # echo "Recryption error on $1."
+ # exit 1
+ #fi
- # Recrypt
- recrypted="`echo "$decrypted" | $GPG --use-agent --armor -e -s $(keyringer_recipients "$RECIPIENTS_FILE")`"
+ #unset decrypted
+ #echo "$recrypted" > "$KEYDIR/$FILE"
+
+ # As we can't use variables as the secret material can contain NULL bytes, we
+ # use a temporary file instead
+ set -o pipefail
+ mkdir -p -m 700 "$TMPWORK/`dirname $FILE`"
+ $GPG --use-agent -d "$KEYDIR/$FILE" | $GPG --use-agent --armor -e -s $(keyringer_recipients "$RECIPIENTS_FILE") -o "$TMPWORK/$FILE.recrypted"
if [ "$?" != "0" ]; then
echo "Recryption error on $1."
+
+ if [ -e "$TMPWORK/$FILE.recrypted" ]; then
+ keyringer_shred "$TMPWORK/$FILE.recrypted"
+ fi
+
exit 1
fi
- unset decrypted
- echo "$recrypted" > "$KEYDIR/$FILE"
+ # Move the re-encrypted secret only if there was no error
+ mv "$TMPWORK/$FILE.recrypted" "$KEYDIR/$FILE"
}
+# Set a tmp file
+keyringer_set_tmpfile recrypt -d
+
# Syntax check and dispatcher
if [ ! -z "$2" ]; then
keyringer_recrypt $2
@@ -46,3 +79,7 @@ else
fi
done
fi
+
+# Cleanup
+rm -rf "$TMPWORK"
+trap - EXIT