Skip to content
This repository has been archived by the owner on Feb 16, 2022. It is now read-only.

Commit

Permalink
Fix gpg signature generation for tag and simplify signed data
Browse files Browse the repository at this point in the history
- Use tag object ID instead of head commit as git note object ID
- Use note object ID as signed data
  • Loading branch information
alexey-igrychev committed May 4, 2021
1 parent 979f207 commit 64b05ac
Showing 1 changed file with 8 additions and 28 deletions.
36 changes: 8 additions & 28 deletions bin/git-signatures
Original file line number Diff line number Diff line change
Expand Up @@ -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(){
Expand Down Expand Up @@ -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 "^$")
}

Expand All @@ -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"

Expand All @@ -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"
Expand All @@ -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() {
Expand All @@ -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 \
Expand Down

0 comments on commit 64b05ac

Please sign in to comment.