106 lines
3.9 KiB
Diff
106 lines
3.9 KiB
Diff
From 86ec26b2d33372a4b3bda48f22c4a9f226c3ccce Mon Sep 17 00:00:00 2001
|
|
From: David Runge <dvzrv@archlinux.org>
|
|
Date: Sun, 21 Jan 2024 12:33:04 +0100
|
|
Subject: [PATCH] makepkg: Improve robustness of signature verification by
|
|
limiting terms
|
|
|
|
The output of
|
|
`gpg --quiet --batch --status-fd /dev/stdout --verify <signature_file> <file> 2> /dev/null`
|
|
or
|
|
`git verify-commit --raw <commit> 2>&1`
|
|
may contain binary data, if the signature has been created with an
|
|
OpenPGP implementation, that e.g. makes use of notations.
|
|
If the notation string (see `NOTATION_DATA` in /usr/share/doc/gnupg/
|
|
DETAILS) contains a trailing binary char, this will break signature
|
|
verification, as any following entry (e.g. `VALIDSIG`) will be offset.
|
|
|
|
As we are only making use of a narrow set of terms from the statusfile
|
|
(namely `NEWSIG`, `GOODSIG`, `EXPSIG`, `EXPKEYSIG`, `REVKEYSIG`,
|
|
`BADSIG`, `ERRSIG`, `VALIDSIG`, `TRUST_UNDEFINED`, `TRUST_NEVER`,
|
|
`TRUST_MARGINAL`, `TRUST_FULLY`, `TRUST_ULTIMATE`), we are applying a
|
|
filter, so that only understood terms are written to the file.
|
|
|
|
Signed-off-by: David Runge <dvzrv@archlinux.org>
|
|
---
|
|
.../integrity/verify_signature.sh.in | 27 ++++++++++++++++---
|
|
1 file changed, 24 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/scripts/libmakepkg/integrity/verify_signature.sh.in b/scripts/libmakepkg/integrity/verify_signature.sh.in
|
|
index ca1d5a868..d786a2c39 100644
|
|
--- a/scripts/libmakepkg/integrity/verify_signature.sh.in
|
|
+++ b/scripts/libmakepkg/integrity/verify_signature.sh.in
|
|
@@ -26,6 +26,12 @@ MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
|
|
source "$MAKEPKG_LIBRARY/util/message.sh"
|
|
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
|
|
|
|
+# Filter the contents of a GnuPG statusfile to only contain understood terms to narrow the file's scope and circumvent
|
|
+# the use of terms (e.g. NOTATION_DATA) that may contain unescaped binary data
|
|
+filter_gnupg_statusfile() {
|
|
+ grep -E "(.*SIG| TRUST_.*)"
|
|
+}
|
|
+
|
|
check_pgpsigs() {
|
|
(( SKIPPGPCHECK )) && return 0
|
|
! source_has_signatures && return 0
|
|
@@ -35,6 +41,7 @@ check_pgpsigs() {
|
|
local netfile proto pubkey success status fingerprint trusted
|
|
local warnings=0
|
|
local errors=0
|
|
+ local statusfile_raw="$(mktemp)"
|
|
local statusfile=$(mktemp)
|
|
local all_sources
|
|
|
|
@@ -103,7 +110,7 @@ check_pgpsigs() {
|
|
printf '\n' >&2
|
|
done
|
|
|
|
- rm -f "$statusfile"
|
|
+ rm -f "$statusfile" "$statusfile_raw"
|
|
|
|
if (( errors )); then
|
|
error "$(gettext "One or more PGP signatures could not be verified!")"
|
|
@@ -158,12 +165,19 @@ verify_file_signature() {
|
|
esac
|
|
|
|
# verify the signature and write metadata to a status file
|
|
- if ! $decompress < "$sourcefile" | gpg --quiet --batch --status-file "$statusfile" --verify "$file" - 2> /dev/null; then
|
|
+ if ! $decompress < "$sourcefile" | gpg --quiet --batch --status-file "$statusfile_raw" --verify "$file" - 2> /dev/null; then
|
|
printf '%s\n' "$(gettext "%s is unable to verify the signature.")" "gpg" >&2
|
|
errors=1
|
|
return 1
|
|
fi
|
|
|
|
+ # create a statusfile that contains only understood terms
|
|
+ if ! filter_gnupg_statusfile > "$statusfile" < "$statusfile_raw"; then
|
|
+ printf '%s\n' "$(gettext "unable to extract signature metadata.")" >&2
|
|
+ errors=1
|
|
+ return 1
|
|
+ fi
|
|
+
|
|
return 0
|
|
}
|
|
|
|
@@ -196,12 +210,19 @@ verify_git_signature() {
|
|
printf " %s git repo ... " "${dir##*/}" >&2
|
|
|
|
# verify the signature and write metadata to a status file
|
|
- if ! git -C "$dir" verify-$fragtype --raw "$fragval" > "$statusfile" 2>&1; then
|
|
+ if ! git -C "$dir" verify-$fragtype --raw "$fragval" > "$statusfile_raw" 2>&1; then
|
|
printf '%s\n' "$(gettext "%s is unable to verify the signature.")" "git" >&2
|
|
errors=1
|
|
return 1
|
|
fi
|
|
|
|
+ # create a statusfile that contains only understood terms
|
|
+ if ! filter_gnupg_statusfile > "$statusfile" < "$statusfile_raw"; then
|
|
+ printf '%s\n' "$(gettext "unable to extract signature metadata.")" >&2
|
|
+ errors=1
|
|
+ return 1
|
|
+ fi
|
|
+
|
|
if ! grep -qs NEWSIG "$statusfile"; then
|
|
printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
|
|
errors=1
|
|
--
|
|
GitLab
|
|
|