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>
This commit is contained in:
parent
3aa096a74f
commit
86ec26b2d3
1 changed files with 24 additions and 3 deletions
|
@ -26,6 +26,12 @@ MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
|
||||||
source "$MAKEPKG_LIBRARY/util/message.sh"
|
source "$MAKEPKG_LIBRARY/util/message.sh"
|
||||||
source "$MAKEPKG_LIBRARY/util/pkgbuild.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() {
|
check_pgpsigs() {
|
||||||
(( SKIPPGPCHECK )) && return 0
|
(( SKIPPGPCHECK )) && return 0
|
||||||
! source_has_signatures && return 0
|
! source_has_signatures && return 0
|
||||||
|
@ -35,6 +41,7 @@ check_pgpsigs() {
|
||||||
local netfile proto pubkey success status fingerprint trusted
|
local netfile proto pubkey success status fingerprint trusted
|
||||||
local warnings=0
|
local warnings=0
|
||||||
local errors=0
|
local errors=0
|
||||||
|
local statusfile_raw="$(mktemp)"
|
||||||
local statusfile=$(mktemp)
|
local statusfile=$(mktemp)
|
||||||
local all_sources
|
local all_sources
|
||||||
|
|
||||||
|
@ -103,7 +110,7 @@ check_pgpsigs() {
|
||||||
printf '\n' >&2
|
printf '\n' >&2
|
||||||
done
|
done
|
||||||
|
|
||||||
rm -f "$statusfile"
|
rm -f "$statusfile" "$statusfile_raw"
|
||||||
|
|
||||||
if (( errors )); then
|
if (( errors )); then
|
||||||
error "$(gettext "One or more PGP signatures could not be verified!")"
|
error "$(gettext "One or more PGP signatures could not be verified!")"
|
||||||
|
@ -158,12 +165,19 @@ verify_file_signature() {
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# verify the signature and write metadata to a status file
|
# 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
|
printf '%s\n' "$(gettext "%s is unable to verify the signature.")" "gpg" >&2
|
||||||
errors=1
|
errors=1
|
||||||
return 1
|
return 1
|
||||||
fi
|
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
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,12 +210,19 @@ verify_git_signature() {
|
||||||
printf " %s git repo ... " "${dir##*/}" >&2
|
printf " %s git repo ... " "${dir##*/}" >&2
|
||||||
|
|
||||||
# verify the signature and write metadata to a status file
|
# 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
|
printf '%s\n' "$(gettext "%s is unable to verify the signature.")" "git" >&2
|
||||||
errors=1
|
errors=1
|
||||||
return 1
|
return 1
|
||||||
fi
|
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
|
if ! grep -qs NEWSIG "$statusfile"; then
|
||||||
printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
|
printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
|
||||||
errors=1
|
errors=1
|
||||||
|
|
Loading…
Add table
Reference in a new issue