From 64b05ac4fc49694b072a4d450b328548089e33eb Mon Sep 17 00:00:00 2001 From: Alexey Igrychev Date: Tue, 27 Apr 2021 01:39:13 +0100 Subject: [PATCH] Fix gpg signature generation for tag and simplify signed data - Use tag object ID instead of head commit as git note object ID - Use note object ID as signed data --- bin/git-signatures | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/bin/git-signatures b/bin/git-signatures index 9acf5ad..558fb0d 100755 --- a/bin/git-signatures +++ b/bin/git-signatures @@ -215,20 +215,8 @@ path_check() { return 0 } -default_base() { - # are we signing the genesis commit? - git rev-parse HEAD^ 1>/dev/null 2>&1 - if [ "$?" -eq 128 ]; then - echo "4b825dc642cb6eb9a060e54bf8d69288fbee4904"; - else - echo "HEAD^" - fi -} - sig_subject() { - git -c diff.indentHeuristic=false diff-tree -p "$1"..HEAD \ - | git patch-id --stable \ - | cut -d' ' -f1 + printf "%s" "$(git show-ref "$1" -s)" } sig_parse(){ @@ -267,19 +255,18 @@ sig_parse(){ sig_decode() { local sig="$1" - local base="$2" + local ref="$2" gpg --verify --trustdb-name="$trust_db" --status-fd=1 \ <(printf '%s' "$sig" | openssl base64 -d -A) \ - <(sig_subject "$base") 2>/dev/null + <(sig_subject "$ref") 2>/dev/null } get_sigs() { local ref="$1" - local base="$2" while IFS='' read -r line; do # shellcheck disable=SC2005 # TODO: Figure out some other way to do this - echo "$(sig_parse "$(sig_decode "$line" "$base")")" + echo "$(sig_parse "$(sig_decode "$line" "$ref")")" done < <(git notes --ref signatures show "$ref" | grep -v "^$") } @@ -300,19 +287,15 @@ cmd_add() { [ "$#" -gt 2 ] && usage add && exit 1 ref=${1:-HEAD} - base=${2:-$(default_base)} key=${key_id:-$(git config user.signingKey)} gpg --list-secret-keys "$key" &> /dev/null || { error "invalid_private_key" "$key"; exit 1; } - # check for HEAD equal to base - [ "$(git rev-parse "$base")" == "$(git rev-parse HEAD)" ] && echo "error: cannot sign empty diff" && exit 1 - - sig_subject "$base" \ + sig_subject "$ref" \ | gpg --detach-sign --local-user "$key" \ | openssl base64 -A \ - | git notes --ref signatures append --file=- + | git notes --ref signatures append --file=- "$ref" TAG_TARGET=$(git rev-parse refs/notes/signatures 2>/dev/null) && git tag -f latest-signature "$TAG_TARGET" @@ -329,9 +312,7 @@ cmd_show() { -t|--trust-db) trust_db="$2"; shift 2;; --) shift; break ;; esac done - [ "$#" -gt 2 ] && usage show && exit 1 ref=${1:-HEAD} - base=${2:-$(default_base)} if [ "$raw" -ne 1 ]; then printf " %-16s | %-10s | %-9s | %-28s | %-50s \\n" \ "Public Key ID" "Status" "Trust" "Date" "Signer Name" @@ -343,7 +324,7 @@ cmd_show() { IFS="|" read -d '' -ra sig < <(echo -n "$sig_parsed") printf " %-16s | %-10s | %-9s | %28s | %-50s\\n" \ "${sig[0]}" "${sig[1]}" "${sig[2]}" "${sig[3]}" "${sig[4]}" - done < <(get_sigs "$ref" "$base") + done < <(get_sigs "$ref") } cmd_verify() { @@ -358,9 +339,8 @@ cmd_verify() { esac done [ "$#" -gt 2 ] && usage verify && exit 1 ref=${1:-HEAD} - base=${2:-$(default_base)} valid_count=$( \ - cmd_show --raw --trust-db="$trust_db" "$ref" "$base" \ + cmd_show --raw --trust-db="$trust_db" "$ref" \ | grep "ULTIMATE" \ | awk -F"|" '{ print $1 }' \ | uniq \