diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-12-19 03:44:03 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-12-21 06:02:14 +0100 |
commit | ff62f87f41557ab7267defab662324927301485a (patch) | |
tree | 5191aedbbbfaab31fd45ab86d015e4160bfbdc70 | |
parent | 2bc437df229865456a77fbb982e187aa69304e98 (diff) |
Add signatures
-rw-r--r-- | man/pass.1 | 7 | ||||
-rwxr-xr-x | src/password-store.sh | 24 |
2 files changed, 31 insertions, 0 deletions
@@ -445,6 +445,13 @@ for more info. The location to look for executable extension files, by default \fIPASSWORD_STORE_DIR/.extensions\fP. .TP +.I PASSWORD_STORE_SIGNING_KEY +If this environment variable is set, then all \fB.gpg-id\fP files and extension files +must be signed using a detached signature using the GPG key specified by the full 40 character +upper-case fingerprint in this variable. If multiple fingerprints are specified, each +separated by a whitespace character, then signatures must match at least one. +The \fBinit\fP command will keep signatures of \fB.gpg-id\fP files up to date. +.TP .I EDITOR The location of the text editor used by \fBedit\fP. .SH SEE ALSO diff --git a/src/password-store.sh b/src/password-store.sh index e68a14e..1c61370 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -49,6 +49,17 @@ die() { echo "$@" >&2 exit 1 } +verify_file() { + [[ -n $PASSWORD_STORE_SIGNING_KEY ]] || return 0 + [[ -f $1.sig ]] || die "Signature for $1 does not exist." + local fingerprints="$(gpg $PASSWORD_STORE_GPG_OPTS --verify --status-fd=1 "$1.sig" "$1" 2>/dev/null | sed -n 's/\[GNUPG:\] VALIDSIG \([A-F0-9]\{40\}\) .* \([A-F0-9]\{40\}\)$/\1\n\2/p')" + local fingerprint found=0 + for fingerprint in $PASSWORD_STORE_SIGNING_KEY; do + [[ $fingerprint =~ ^[A-F0-9]{40}$ ]] || continue + [[ $fingerprints == *$fingerprint* ]] && { found=1; break; } + done + [[ $found -eq 1 ]] || die "Signature for $1 is invalid." +} set_gpg_recipients() { GPG_RECIPIENT_ARGS=( ) GPG_RECIPIENTS=( ) @@ -78,6 +89,8 @@ set_gpg_recipients() { exit 1 fi + verify_file "$current" + local gpg_id while read -r gpg_id; do GPG_RECIPIENT_ARGS+=( "-r" "$gpg_id" ) @@ -291,6 +304,16 @@ cmd_init() { local id_print="$(printf "%s, " "$@")" echo "Password store initialized for ${id_print%, }${id_path:+ ($id_path)}" git_add_file "$gpg_id" "Set GPG id to ${id_print%, }${id_path:+ ($id_path)}." + if [[ -n $PASSWORD_STORE_SIGNING_KEY ]]; then + local signing_keys=( ) key + for key in $PASSWORD_STORE_SIGNING_KEY; do + signing_keys+=( --default-key $key ) + done + gpg "${GPG_OPTS[@]}" "${signing_keys[@]}" --detach-sign "$gpg_id" || die "Could not sign .gpg_id." + key="$(gpg --verify --status-fd=1 "$gpg_id.sig" "$gpg_id" 2>/dev/null | sed -n 's/\[GNUPG:\] VALIDSIG [A-F0-9]\{40\} .* \([A-F0-9]\{40\}\)$/\1/p')" + [[ -n $key ]] || die "Signing of .gpg_id unsuccessful." + git_add_file "$gpg_id.sig" "Signing new GPG id with ${key//[$IFS]/,}." + fi fi reencrypt_path "$PREFIX/$id_path" @@ -578,6 +601,7 @@ cmd_extension() { local extension="$EXTENSIONS/$1.bash" check_sneaky_paths "$extension" if [[ -f $extension && -x $extension ]]; then + verify_file "$extension" shift source "$extension" "$@" else |