Support an extra symmetric passphrase for protecting the crypt subtree

This can help protect against gpg vulnerabilities (e.g. quantum
computing) and/or leakage.
This commit is contained in:
Peter Cai 2022-10-10 16:08:44 -04:00
parent fe28c7e3df
commit f9902f8989
1 changed files with 67 additions and 4 deletions

View File

@ -5,9 +5,11 @@
readonly gocrypt_dir=".gocrypt"
readonly gocrypt_dec_dir="gocrypt"
readonly gocrypt_passwd_file="gocrypt-passwd"
readonly gocrypt_needs_passphrase_marker=".gocrypt-needs-passphrase"
gocrypt_sys_check() {
which gocryptfs > /dev/null || gocrypt_die "gocryptfs not found in PATH"
which perl > /dev/null || gocrypt_die "perl not found in PATH"
}
gocrypt_env_check() {
@ -30,21 +32,59 @@ gocrypt_die() {
exit 1
}
gocrypt_derive_password() {
local data="$1"
local key="$2"
perl <<< "use Digest::SHA qw(hmac_sha256_hex);\$digest=hmac_sha256_hex(\"$data\n\", \"$key\");print(\$digest);"
}
gocrypt_init() {
local needs_passphrase=false
local passphrase=""
while [ $# -gt 0 ]; do
case "$1" in
-p|--passphrase)
needs_passphrase=true
;;
*)
gocrypt_die "Unexpected argument: $1"
;;
esac
shift
done
[ $# -eq 0 ] || gocrypt_die "Unexpected argument"
gocrypt_sys_check
if [ -d "$gocrypt_dir" ] || [ -f "$gocrypt_dir" ]; then
gocrypt_die "gocrypt plugin already initialized for your password store"
fi
if $needs_passphrase; then
echo -n "Enter passphrase: "
read -s passphrase
local passphrase_confirm=""
echo
echo -n "Confirm passphrase: "
read -s passphrase_confirm
echo
[ "$passphrase" == "$passphrase_confirm" ] || gocrypt_die "Passphrase mismatch"
fi
cmd_generate "$gocrypt_passwd_file" 32
local gocrypt_passwd="$(cmd_show "$gocrypt_passwd_file")"
# Initialize gocryptfs
mkdir "$gocrypt_dir"
gocryptfs -passfile /dev/stdin -init "$gocrypt_dir" <<< "$(cmd_show "$gocrypt_passwd_file")"
if $needs_passphrase; then
touch "$gocrypt_needs_passphrase_marker"
gocrypt_passwd="$(gocrypt_derive_password "$gocrypt_passwd" "$passphrase")"
fi
gocryptfs -passfile /dev/stdin -init "$gocrypt_dir" <<< "$gocrypt_passwd" || gocrypt_die "Unable to initialize gocryptfs"
# Mount the gocryptfs subdirectory and initialze what is inside of it
gocrypt_open
_gocrypt_passwd="$gocrypt_passwd" gocrypt_open || gocrypt_die "Cannot open the gocryptfs we just initialized"
touch "$gocrypt_dec_dir"/.pass-gocrypt
# By default, we use the same gpg-id inside, but the user can decide to use a different one later by doing it manually
ln -s ../.gpg-id "$gocrypt_dec_dir"/.gpg-id
@ -55,6 +95,7 @@ gocrypt_init() {
echo "gocrypt" >> .gitignore
cmd_git add .gitignore
$needs_passphrase && cmd_git add "$gocrypt_needs_passphrase_marker"
cmd_git add "$gocrypt_dir"
cmd_git commit -m "Initialized encrypted storage for gocrypt plugin"
}
@ -64,7 +105,22 @@ gocrypt_open() {
gocrypt_close_check
mkdir -p "$gocrypt_dec_dir"
gocryptfs -passfile /dev/stdin "$gocrypt_dir" "$gocrypt_dec_dir" <<< "$(cmd_show "$gocrypt_passwd_file")"
local gocrypt_passwd=""
if [ ! -z "$_gocrypt_passwd" ]; then
gocrypt_passwd="$_gocrypt_passwd"
else
gocrypt_passwd="$(cmd_show "$gocrypt_passwd_file")"
if [ -f "$gocrypt_needs_passphrase_marker" ]; then
local passphrase=""
echo -n "Enter passphrase: "
read -s passphrase
gocrypt_passwd="$(gocrypt_derive_password "$gocrypt_passwd" "$passphrase")"
fi
fi
gocryptfs -passfile /dev/stdin "$gocrypt_dir" "$gocrypt_dec_dir" <<< "$gocrypt_passwd"
}
gocrypt_close() {
@ -96,7 +152,7 @@ gocrypt_help() {
$PROGRAM gocrypt - hide part of the password store in a subdirectory encrypted with gocryptfs
usage
$PROGRAM gocrypt init
$PROGRAM gocrypt init [-p|--passphrase]
Initialize a encrypted subdirectory at \$PASSWORD_STORE_DIR/$gocrypt_dir. The password used by
gocryptfs will be generated by pass and stored at \$PASSWORD_STORE_DIR/$gocrypt_passwd_file.gpg.
The encrypted subdirectory, along with the generated (encrypted) password, will be committed to
@ -106,6 +162,13 @@ usage
subtree. You can change this manually by mounting (opening) the directory and replacing this
symlink with a custom one.
You can optionally use an extra piece of symmetric passphrase to encrypt the subdirectory, by
passing the argument -p or --passphrase when invoking this command to initialize. In this case,
the passphrase you input will be used along with the generated password to derive a new master
password for gocryptfs. This second piece of passphrase will not be stored in the password store,
and you will be asked for it every time you invoke \`$PROGRAM gocrypt open\`. This mode adds an
extra layer of protection in case the gpg-encrypted master password is somehow compromised.
$PROGRAM gocrypt open
Mount the encrypted subdirectory to \$PASSWORD_STORE_DIR/$gocrypt_dec_dir.