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

View file

@ -5,9 +5,11 @@
readonly gocrypt_dir=".gocrypt" readonly gocrypt_dir=".gocrypt"
readonly gocrypt_dec_dir="gocrypt" readonly gocrypt_dec_dir="gocrypt"
readonly gocrypt_passwd_file="gocrypt-passwd" readonly gocrypt_passwd_file="gocrypt-passwd"
readonly gocrypt_needs_passphrase_marker=".gocrypt-needs-passphrase"
gocrypt_sys_check() { gocrypt_sys_check() {
which gocryptfs > /dev/null || gocrypt_die "gocryptfs not found in PATH" 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() { gocrypt_env_check() {
@ -30,21 +32,59 @@ gocrypt_die() {
exit 1 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() { 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" [ $# -eq 0 ] || gocrypt_die "Unexpected argument"
gocrypt_sys_check gocrypt_sys_check
if [ -d "$gocrypt_dir" ] || [ -f "$gocrypt_dir" ]; then if [ -d "$gocrypt_dir" ] || [ -f "$gocrypt_dir" ]; then
gocrypt_die "gocrypt plugin already initialized for your password store" gocrypt_die "gocrypt plugin already initialized for your password store"
fi 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 cmd_generate "$gocrypt_passwd_file" 32
local gocrypt_passwd="$(cmd_show "$gocrypt_passwd_file")"
# Initialize gocryptfs # Initialize gocryptfs
mkdir "$gocrypt_dir" 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 # 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 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 # 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 ln -s ../.gpg-id "$gocrypt_dec_dir"/.gpg-id
@ -55,6 +95,7 @@ gocrypt_init() {
echo "gocrypt" >> .gitignore echo "gocrypt" >> .gitignore
cmd_git add .gitignore cmd_git add .gitignore
$needs_passphrase && cmd_git add "$gocrypt_needs_passphrase_marker"
cmd_git add "$gocrypt_dir" cmd_git add "$gocrypt_dir"
cmd_git commit -m "Initialized encrypted storage for gocrypt plugin" cmd_git commit -m "Initialized encrypted storage for gocrypt plugin"
} }
@ -64,7 +105,22 @@ gocrypt_open() {
gocrypt_close_check gocrypt_close_check
mkdir -p "$gocrypt_dec_dir" 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() { gocrypt_close() {
@ -96,7 +152,7 @@ gocrypt_help() {
$PROGRAM gocrypt - hide part of the password store in a subdirectory encrypted with gocryptfs $PROGRAM gocrypt - hide part of the password store in a subdirectory encrypted with gocryptfs
usage usage
$PROGRAM gocrypt init $PROGRAM gocrypt init [-p|--passphrase]
Initialize a encrypted subdirectory at \$PASSWORD_STORE_DIR/$gocrypt_dir. The password used by 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. 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 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 subtree. You can change this manually by mounting (opening) the directory and replacing this
symlink with a custom one. 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 $PROGRAM gocrypt open
Mount the encrypted subdirectory to \$PASSWORD_STORE_DIR/$gocrypt_dec_dir. Mount the encrypted subdirectory to \$PASSWORD_STORE_DIR/$gocrypt_dec_dir.