[pacman-dev] [PATCH] pacman-key: just accept one file to verify, and enforce detached sigs
Simply pass options on to gpg the same way gpg uses them -- no looping through and checking lots of signatures. This prevents a situation where the signature file to be verified is manipulated to contain a complete signature which is valid, but not a detached signature for the file you are actually trying to verify. gpg does not offer an option to verify many files at once by naming each signature/file pair, and there's no reason for us to do so either, since it would be quite tiresome to do so. Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- scripts/pacman-key.sh.in | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 0f1630a9..0573e92f 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -486,18 +486,19 @@ refresh_keys() { } verify_sig() { - local ret=0 - for sig; do - msg "Checking %s..." "$sig" - if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then - error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig" - return 1 - fi - if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then - error "$(gettext "The signature identified by %s could not be verified.")" "$sig" - ret=1 - fi - done + local ret=0 sig=$1 file=$2 + if [[ -z $file ]]; then + file=${sig%.*} + fi + msg "Checking %s..." "$sig" + if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then + error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig" + exit 1 + fi + if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" "$file" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then + error "$(gettext "The signature identified by %s could not be verified.")" "$sig" + ret=1 + fi exit $ret } -- 2.17.0
On 30/05/18 03:00, Eli Schwartz wrote:
Simply pass options on to gpg the same way gpg uses them -- no looping through and checking lots of signatures.
This prevents a situation where the signature file to be verified is manipulated to contain a complete signature which is valid, but not a detached signature for the file you are actually trying to verify.
gpg does not offer an option to verify many files at once by naming each signature/file pair, and there's no reason for us to do so either, since it would be quite tiresome to do so.
Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- scripts/pacman-key.sh.in | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 0f1630a9..0573e92f 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -486,18 +486,19 @@ refresh_keys() { }
verify_sig() { - local ret=0 - for sig; do - msg "Checking %s..." "$sig" - if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then - error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig" - return 1 - fi - if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then - error "$(gettext "The signature identified by %s could not be verified.")" "$sig" - ret=1 - fi - done + local ret=0 sig=$1 file=$2 + if [[ -z $file ]]; then + file=${sig%.*} + fi
Opinions on if we should we do this? All pacman's infrastructure assumes detached signatures, but this is a difference from how gpg does things when only one argument is given.
+ msg "Checking %s..." "$sig" + if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then + error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig" + exit 1 + fi + if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" "$file" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then + error "$(gettext "The signature identified by %s could not be verified.")" "$sig" + ret=1 + fi exit $ret }
On 30/5/18 3:00 am, Eli Schwartz wrote:
Simply pass options on to gpg the same way gpg uses them -- no looping through and checking lots of signatures.
This prevents a situation where the signature file to be verified is manipulated to contain a complete signature which is valid, but not a detached signature for the file you are actually trying to verify.
gpg does not offer an option to verify many files at once by naming each signature/file pair, and there's no reason for us to do so either, since it would be quite tiresome to do so.
Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- scripts/pacman-key.sh.in | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 0f1630a9..0573e92f 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -486,18 +486,19 @@ refresh_keys() { }
verify_sig() { - local ret=0 - for sig; do - msg "Checking %s..." "$sig" - if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then - error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig" - return 1 - fi - if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then - error "$(gettext "The signature identified by %s could not be verified.")" "$sig" - ret=1 - fi - done + local ret=0 sig=$1 file=$2 + if [[ -z $file ]]; then + file=${sig%.*} + fi
Only do this if $file exists. Otherwise we can assume it is an embedded signature.
+ msg "Checking %s..." "$sig"
Can we add a (detached) at the end here if $file exists? Also, docs will need updated.
+ if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then + error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig" + exit 1 + fi + if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" "$file" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then + error "$(gettext "The signature identified by %s could not be verified.")" "$sig" + ret=1 + fi exit $ret }
Simply pass options on to gpg the same way gpg uses them -- no looping through and checking lots of signatures. This prevents a situation where the signature file to be verified is manipulated to contain an embedded signature which is valid, but not a detached signature for the file you are actually trying to verify. gpg does not offer an option to verify many files at once by naming each signature/file pair, and there's no reason for us to do so either, since it would be quite tiresome to do so. In the event that there is no signature/file pair specified to pacman-key itself, - preserve gpg's behavior, *if* the matching file does not exist, by - assuming the signature is an embedded signature - deviate from gpg's behavior, by - offering a security warning about which one is happening - when there is an embedded signature *and* a matching detached file, assume the latter is desired Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- v2: based on feedback, rework the verification logic to fall back on GnuPG defaults, but only when we cannot find the data file. Explicitly tell the user which mode we're using. Add the missing documentation on the change. ... fallback mode is sort of ugly, but we need to know when not to pass any second file at all -- not even ''. doc/pacman-key.8.asciidoc | 8 +++++++- scripts/pacman-key.sh.in | 31 +++++++++++++++++++------------ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/doc/pacman-key.8.asciidoc b/doc/pacman-key.8.asciidoc index f0b5ac08..e32fe5d8 100644 --- a/doc/pacman-key.8.asciidoc +++ b/doc/pacman-key.8.asciidoc @@ -97,7 +97,13 @@ Operations Displays the program version. *-v, \--verify*:: - Verify the file(s) specified by the signature(s). + Assume that the first argument is a signature and verify it. If a second + argument is provided, it is the file to be verified. ++ +With only one argument given, assume that the signature is a detached +signature, and look for a matching data file to verify by stripping the file +extension. If no matching data file is found, fall back on GnuPG semantics and +attempt to verify a file with an embedded signature. Options diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 66336e9a..b05754e5 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -485,18 +485,25 @@ refresh_keys() { } verify_sig() { - local ret=0 - for sig; do - msg "Checking %s..." "$sig" - if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then - error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig" - return 1 - fi - if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then - error "$(gettext "The signature identified by %s could not be verified.")" "$sig" - ret=1 - fi - done + local ret=0 sig=$1 file=$2 + if [[ -z $file && -f ${sig%.*} ]]; then + file=${sig%.*} + fi + if [[ -n $file ]]; then + local files=("$sig" "$file") + msg "Checking %s... (detached)" "$sig" + else + local files=("$sig") + msg "Checking %s... (embedded)" "$sig" + fi + if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then + error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig" + exit 1 + fi + if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "${files[@]}" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then + error "$(gettext "The signature identified by %s could not be verified.")" "$sig" + ret=1 + fi exit $ret } -- 2.19.1
participants (2)
-
Allan McRae
-
Eli Schwartz