]> gitweb.fluxo.info Git - keyringer.git/commitdiff
Fix re-encryption when the secret hass NULL bytes
authorSilvio Rhatto <rhatto@riseup.net>
Fri, 19 Aug 2022 14:17:15 +0000 (11:17 -0300)
committerSilvio Rhatto <rhatto@riseup.net>
Fri, 19 Aug 2022 14:17:15 +0000 (11:17 -0300)
ChangeLog
lib/keyringer/actions/recrypt

index 7b6fae23a53f18c4f5f5e73df1e6773393f59358..0c39eb41cefd3a7b0e49b2a4e109ae8bc8996a3b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2022-08-19 - unreleased - Silvio Rhatto <rhatto@riseup.net>
+
+       Fix re-encryption when the secret hass NULL bytes
+
 2022-06-07 - 0.5.7 - Silvio Rhatto <rhatto@riseup.net>
 
        New upstream URLs
index 0e2f6a09d16de987592976e442b4ec000ecfa217..5542bfcf7f057853b6a38fb3886eb19cfa8cc8d8 100755 (executable)
@@ -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