Re: [gentoo-dev] [PATCH 1/2] sec-keys.eclass: new eclass
Michał Górny writes: > On Wed, 2024-11-27 at 15:30 -0500, Eli Schwartz wrote: >> The current state of verify-sig support is a bit awkward. We rely on >> validating distfiles against a known trusted keyring, but creating the >> known trusted keyring is basically all manual verification. We somehow >> decide an ascii armored key is good enough without any portage >> assistance, then arrange to download it and trust it by Manifest hash. >> How do we know when updating a key is actually safe? >> >> This eclass handles the problem in a manner inspired in part by pacman. >> We require an eclass variable that lists all permitted PGP fingerprints, >> and the eclass is responsible checking that list against the keys we >> will install. It comes with a mechanism for computing SRC_URI for a >> couple of well known locations, or you can append your own in the >> ebuild. > > How about adding a src_test() that would check if the key needs bumping, > i.e. if an online update triggers any meaningful changes? Ooh, I like this idea. We could print a pgpdump diff.
Re: [gentoo-dev] [PATCH 1/2] sec-keys.eclass: new eclass
Eli Schwartz writes: > The current state of verify-sig support is a bit awkward. We rely on > validating distfiles against a known trusted keyring, but creating the > known trusted keyring is basically all manual verification. We somehow > decide an ascii armored key is good enough without any portage > assistance, then arrange to download it and trust it by Manifest hash. > How do we know when updating a key is actually safe? > > This eclass handles the problem in a manner inspired in part by pacman. > We require an eclass variable that lists all permitted PGP fingerprints, > and the eclass is responsible checking that list against the keys we > will install. It comes with a mechanism for computing SRC_URI for a > couple of well known locations, or you can append your own in the > ebuild. > > Key rotations, both expected and malicious, are easily detected by > checking the git log for changes to declared finterprints in a bump. The s/finterprints/fingerprints/ > former can be rationalized in the commit message. So can the latter, but > in most cases those will be rejected during peer review. > > Signed-off-by: Eli Schwartz > --- > eclass/sec-keys.eclass | 150 + > 1 file changed, 150 insertions(+) > create mode 100644 eclass/sec-keys.eclass > I'm actually pleasantly surprised by how elegant this is -- which is no reflection on you, just I sort of assumed the implementation would have to be a bit gnarlier (not sure why). One thing I really want to solve in general is key refreshes, given we have no "src_fetch", users can't opt in to key refreshes even with verify-sig.eclass unless network-sandbox is off, but that's a separate problem. mgorny's suggestion wrt src_test would allow us to even tinderbox needed refreshes which somewhat solves that problem too. I like it. > diff --git a/eclass/sec-keys.eclass b/eclass/sec-keys.eclass > new file mode 100644 > index ..95e1b4a92c0e > --- /dev/null > +++ b/eclass/sec-keys.eclass > @@ -0,0 +1,150 @@ > +# Copyright 2024 Gentoo Authors > +# Distributed under the terms of the GNU General Public License v2 > + > +# @ECLASS: sec-keys.eclass > +# @MAINTAINER: > +# Eli Schwartz > +# @AUTHOR: > +# Eli Schwartz > +# @SUPPORTED_EAPIS: 8 > +# @BLURB: Provides a uniform way of handling ebuilds which package PGP key > material > +# @DESCRIPTION: > +# This eclass provides a streamlined approach to finding suitable source > material > +# for OpenPGP keys used by the verify-sig eclass. Its primary purpose is to > permit > +# developers to easily and securely package new sec-keys/* packages. The > eclass > +# removes the risk of developers accidentally packaging malformed key > material, or > +# neglecting to notice when PGP identities have changed. > +# > +# To use the eclass, define SEC_KEYS_VALIDPGPKEYS to contain the fingerprint > of > +# the key and the short name of the key's owner. > +# > +# @EXAMPLE: > +# Example use: > +# > +# @CODE > +# SEC_KEYS_VALIDPGPKEYS=( > +#'4EC8A4DB7D2E01C00AF36C49E5C587B5E286C65A:jsmith:github' > +# ) Can you expand the example(s) here maybe with some comments in the array to help people see when it might be suitable to use e.g. none with a mix of github? > +# > +# inherit sec-keys > +# @CODE > + > +case ${EAPI} in > + 8) ;; > + *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; > +esac > + > +if [[ ! ${_SEC_KEYS_ECLASS} ]]; then > +_SEC_KEYS_ECLASS=1 > + > +inherit edo > + > +# @ECLASS_VARIABLE: SEC_KEYS_VALIDPGPKEYS > +# @PRE_INHERIT > +# @DEFAULT_UNSET > +# @DESCRIPTION: > +# Mapping of fingerprints, name, and optional location of PGP keys to > include, > +# separated by colons. The allowed values for a location are: > +# > +# - github -- fetch key from github.com/${name}.pgp > +# > +# - openpgp -- fetch key by fingerprint from https://keys.openpgp.org > +# > +# - ubuntu -- fetch key by fingerprint from http://keyserver.ubuntu.com > (the default) > +# > +# - none -- do not add to SRC_URI, the ebuild will provide a custom > download location > +_sec_keys_set_globals() { > + if [[ ${SEC_KEYS_VALIDPGPKEYS[*]} ]]; then > + local key fingerprint name loc locations=() remote > + for key in "${SEC_KEYS_VALIDPGPKEYS[@]}"; do > + fingerprint=${key%%:*} > + name=${key#${fingerprint}:}; name=${name%%:*} > + IFS=: read -r -a locations <<<"${key##*:}" > + [[ ${locations[@]} ]] || locations=(ubuntu) > + for loc in "${locations[@]}"; do > + case ${loc} in > + github) > remote="https://github.com/${name}.gpg";;; > + openpgp) > remote="https://keys.openpgp.org/vks/v1/by-fingerprint/${fingerprint}";;; > + ubuntu) > remote="https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x${fingerprint}";;; > +
Re: [gentoo-dev] [PATCH 1/2] sec-keys.eclass: new eclass
On Wed, 2024-11-27 at 15:30 -0500, Eli Schwartz wrote: > The current state of verify-sig support is a bit awkward. We rely on > validating distfiles against a known trusted keyring, but creating the > known trusted keyring is basically all manual verification. We somehow > decide an ascii armored key is good enough without any portage > assistance, then arrange to download it and trust it by Manifest hash. > How do we know when updating a key is actually safe? > > This eclass handles the problem in a manner inspired in part by pacman. > We require an eclass variable that lists all permitted PGP fingerprints, > and the eclass is responsible checking that list against the keys we > will install. It comes with a mechanism for computing SRC_URI for a > couple of well known locations, or you can append your own in the > ebuild. How about adding a src_test() that would check if the key needs bumping, i.e. if an online update triggers any meaningful changes? -- Best regards, Michał Górny signature.asc Description: This is a digitally signed message part
Re: [gentoo-dev] [PATCH 1/2] sec-keys.eclass: new eclass
On 11/27/24 4:57 PM, Sam James wrote: > Eli Schwartz writes: >> +# @EXAMPLE: >> +# Example use: >> +# >> +# @CODE >> +# SEC_KEYS_VALIDPGPKEYS=( >> +# '4EC8A4DB7D2E01C00AF36C49E5C587B5E286C65A:jsmith:github' >> +# ) > > Can you expand the example(s) here maybe with some comments in the array > to help people see when it might be suitable to use e.g. none with a mix > of github? Sure, good idea. >> +# @FUNCTION: sec-keys_src_compile >> +# @DESCRIPTION: >> +# Default src_compile override that imports all public keys into a keyring, >> +# and validates that they are listed in SEC_KEYS_VALIDPGPKEYS. >> +sec-keys_src_compile() { >> +local -x GNUPGHOME=${WORKDIR}/gnupg >> +mkdir -m700 -p "${GNUPGHOME}" || die > > Is there any value in using gemato's gpg-wrap for this function? I don't think so. The main use case for gemato that I see is it automatically entering a tempdir context based on a keyfile. We need to support multiple keyfiles, including ebuild-specified SRC_URI that may not be ascii-armored and cannot be concatenated together, which means in order to get to a point where gpg-wrap can be used to run one-off commands using a keyfile in which gemato wraps the creation of a keyring... we've basically done all the work we actually wanted to do. >> +local extra_keys=($(comm -23 imported_keys.list allowed_keys.list || >> die)) >> +local missing_keys=($(comm -13 imported_keys.list allowed_keys.list || >> die)) > > Any reason to not readarray this instead? The files each contain a list of words (PGP fingerprint, consisting of characters matching [0-9A-F] and nothing else), with the only whitspace in the file being newline characters. Both readarray and command substitution tokenize this the same. I'm not sure it particularly matters which one to use, but command substitution can be done on one line (local variable=($(command || die)) ) whereas readarray requires two lines (local -a variable; readarray -t varlist < <(command || die) ) and you have to remember to use -t and -a. I don't think readarray provides any functionality we need here. >> +for fingerprint in "${SEC_KEYS_VALIDPGPKEYS[@]%%:*}"; do >> +local uids=() >> +mapfile -t uids < <("${gpg_command[@]}" --list-key >> --with-colons ${fingerprint} | awk -F: '/^uid/{print $10}' || die) >> +edo "${gpg_command[@]}" "${uids[@]/#/--comment=}" --export >> --armor "${fingerprint}" >> ${PN#openpgp-keys-}.asc || die > > No need for the die here. Right, I probably forgot to remove this when I switched to edo. -- Eli Schwartz OpenPGP_signature.asc Description: OpenPGP digital signature
[gentoo-dev] [PATCH] Add 'host' variable to GIT_CRATES to support other host like self-host gitlab or gitea
--- eclass/cargo.eclass | 43 +++ 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass index 95ff317e1f21..aa59d38d8600 100644 --- a/eclass/cargo.eclass +++ b/eclass/cargo.eclass @@ -93,6 +93,10 @@ ECARGO_VENDOR="${ECARGO_HOME}/gentoo" # - optionally: the path to look for Cargo.toml in. # - This will also replace the string "%commit%" with the commit's checksum. # - Defaults to: "${crate}-%commit%" +# - optionally: the git host so it would generate tarball download link. +# - E.g. gitlab +# - It fallbacks to detecting from URL if it's gitlab.com or github.com +# if no host provided. # # Example of a simple definition with no path to Cargo.toml: # @CODE @@ -108,6 +112,13 @@ ECARGO_VENDOR="${ECARGO_HOME}/gentoo" # [rustpython-parser]="https://github.com/RustPython/RustPython;4f38cb68e4a97aeea9eb19673803a0bd5f655383;RustPython-%commit%/compiler/parser"; # ) # @CODE +# +# Example with host defined: +# @CODE +# declare -A GIT_CRATES=( +# [clapper]="https://gitlab.gnome.org/JanGernert/clapper-rs;530b6fd53a60563d8038f7a1d9d735d6dc496adb;clapper-rs-%commit%/libclapper-rs;gitlab"; +# ) +# @CODE # @ECLASS_VARIABLE: CARGO_OPTIONAL # @DEFAULT_UNSET @@ -217,22 +228,38 @@ _cargo_set_crate_uris() { if declare -p GIT_CRATES &>/dev/null; then if [[ $(declare -p GIT_CRATES) == "declare -A"* ]]; then - local crate commit crate_uri crate_dir repo_ext feat_expr + local crate commit crate_uri crate_dir host repo_ext feat_expr for crate in "${!GIT_CRATES[@]}"; do - IFS=';' read -r crate_uri commit crate_dir <<< "${GIT_CRATES[${crate}]}" - - case "${crate_uri}" in - https://github.com/*) + IFS=';' read -r crate_uri commit crate_dir host <<< "${GIT_CRATES[${crate}]}" + + if [[ -z ${host} ]]; then + case "${crate_uri}" in + https://github.com/*) + host="github" + ;; + https://gitlab.com/*) + host="gitlab" + ;; + esac + fi + + case "${host}" in + github) repo_ext=".gh" repo_name="${crate_uri##*/}" crate_uri="${crate_uri%/}/archive/%commit%.tar.gz" ;; - https://gitlab.com/*) + gitlab) repo_ext=".gl" repo_name="${crate_uri##*/}" crate_uri="${crate_uri%/}/-/archive/%commit%/${repo_name}-%commit%.tar.gz" ;; + gitea) + repo_ext=".gt" + repo_name="${crate_uri##*/}" + crate_uri="${crate_uri%/}/archive/%commit%.tar.gz" + ;; *) repo_ext= repo_name="${crate}" @@ -320,11 +347,11 @@ _cargo_gen_git_config() { git_crates_type="$(declare -p GIT_CRATES 2>&-)" if [[ ${git_crates_type} == "declare -A "* ]]; then - local crate commit crate_uri crate_dir + local crate commit crate_uri crate_dir host local -A crate_patches for crate in "${!GIT_CRATES[@]}"; do - IFS=';' read -r crate_uri commit crate_dir <<< "${GIT_CRATES[${crate}]}" + IFS=';' read -r crate_uri commit crate_dir host <<< "${GIT_CRATES[${crate}]}" : "${crate_dir:=${crate}-%commit%}" crate_patches["${crate_uri}"]+="${crate} = { path = \"${WORKDIR}/${crate_dir//%commit%/${commit}}\" };;" done -- 2.45.2
Re: [gentoo-dev] [PATCH] Add 'host' variable to GIT_CRATES to support other host like self-host gitlab or gitea
Hi, associative arrays declared in functions are implicitly local in bash. That means any associative array declared in global ebuild scope needs to be declare global explicitly, as it's not guaranteed not to be sourced within a function by a PM ( e.g. paludis does this ). https://lists.gnu.org/archive/html/bug-bash/2011-08/msg00274.html https://github.com/pkgcore/pkgcheck/issues/628 Paul
[gentoo-dev] [PATCH 1/2] sec-keys.eclass: new eclass
The current state of verify-sig support is a bit awkward. We rely on validating distfiles against a known trusted keyring, but creating the known trusted keyring is basically all manual verification. We somehow decide an ascii armored key is good enough without any portage assistance, then arrange to download it and trust it by Manifest hash. How do we know when updating a key is actually safe? This eclass handles the problem in a manner inspired in part by pacman. We require an eclass variable that lists all permitted PGP fingerprints, and the eclass is responsible checking that list against the keys we will install. It comes with a mechanism for computing SRC_URI for a couple of well known locations, or you can append your own in the ebuild. Key rotations, both expected and malicious, are easily detected by checking the git log for changes to declared finterprints in a bump. The former can be rationalized in the commit message. So can the latter, but in most cases those will be rejected during peer review. Signed-off-by: Eli Schwartz --- eclass/sec-keys.eclass | 150 + 1 file changed, 150 insertions(+) create mode 100644 eclass/sec-keys.eclass diff --git a/eclass/sec-keys.eclass b/eclass/sec-keys.eclass new file mode 100644 index ..95e1b4a92c0e --- /dev/null +++ b/eclass/sec-keys.eclass @@ -0,0 +1,150 @@ +# Copyright 2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: sec-keys.eclass +# @MAINTAINER: +# Eli Schwartz +# @AUTHOR: +# Eli Schwartz +# @SUPPORTED_EAPIS: 8 +# @BLURB: Provides a uniform way of handling ebuilds which package PGP key material +# @DESCRIPTION: +# This eclass provides a streamlined approach to finding suitable source material +# for OpenPGP keys used by the verify-sig eclass. Its primary purpose is to permit +# developers to easily and securely package new sec-keys/* packages. The eclass +# removes the risk of developers accidentally packaging malformed key material, or +# neglecting to notice when PGP identities have changed. +# +# To use the eclass, define SEC_KEYS_VALIDPGPKEYS to contain the fingerprint of +# the key and the short name of the key's owner. +# +# @EXAMPLE: +# Example use: +# +# @CODE +# SEC_KEYS_VALIDPGPKEYS=( +# '4EC8A4DB7D2E01C00AF36C49E5C587B5E286C65A:jsmith:github' +# ) +# +# inherit sec-keys +# @CODE + +case ${EAPI} in + 8) ;; + *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; +esac + +if [[ ! ${_SEC_KEYS_ECLASS} ]]; then +_SEC_KEYS_ECLASS=1 + +inherit edo + +# @ECLASS_VARIABLE: SEC_KEYS_VALIDPGPKEYS +# @PRE_INHERIT +# @DEFAULT_UNSET +# @DESCRIPTION: +# Mapping of fingerprints, name, and optional location of PGP keys to include, +# separated by colons. The allowed values for a location are: +# +# - github -- fetch key from github.com/${name}.pgp +# +# - openpgp -- fetch key by fingerprint from https://keys.openpgp.org +# +# - ubuntu -- fetch key by fingerprint from http://keyserver.ubuntu.com (the default) +# +# - none -- do not add to SRC_URI, the ebuild will provide a custom download location +_sec_keys_set_globals() { + if [[ ${SEC_KEYS_VALIDPGPKEYS[*]} ]]; then + local key fingerprint name loc locations=() remote + for key in "${SEC_KEYS_VALIDPGPKEYS[@]}"; do + fingerprint=${key%%:*} + name=${key#${fingerprint}:}; name=${name%%:*} + IFS=: read -r -a locations <<<"${key##*:}" + [[ ${locations[@]} ]] || locations=(ubuntu) + for loc in "${locations[@]}"; do + case ${loc} in + github) remote="https://github.com/${name}.gpg";;; + openpgp) remote="https://keys.openpgp.org/vks/v1/by-fingerprint/${fingerprint}";;; + ubuntu) remote="https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x${fingerprint}";;; + # provided via manual SRC_URI + none) continue;; + *) die "${ECLASS}: unknown PGP key remote: ${loc}";; + + esac + SRC_URI+=" + ${remote} -> openpgp-keys-${name}-${loc}-${PV}.asc + " + done + done + fi +} +_sec_keys_set_globals +unset -f _sec_keys_set_globals + +BDEPEND="app-crypt/gnupg" +S=${WORKDIR} + +LICENSE="public-domain" +SLOT="0" + + +# @FUNCTION: sec-keys_src_compile +# @DESCRIPTION: +# Default src_compile override that imports all public keys into a keyring, +# and validates that they are listed in SEC_KEYS_VALIDPGPKEYS. +sec-keys_src_compile() { + local -x GNUPGHOME=${WORKDIR}/gnupg + mkdir -m700 -p "${GNUPGHOME}" || die + + pus
[gentoo-dev] [PATCH 2/2] sec-keys/openpgp-keys-gnutls: update to use sec-keys.eclass
Bump EAPI 7 -> 8 as required by eclass. ;) This is a nice demonstration of using the eclass. It showcases some advanced usage, in particular, how to augment a single key within a keyring published on upstream's website with an extended expiration date from the openpgp.org keyserver. The ebuild was previously updated in commit 1061fd37f9491f2601a8b5b6c92ffc3a2f42d7c9 with some explanatory text about why we needed to do that. It wasn't a very good commit (sorry, past self!) because it was kind of inscrutable whether the key "should" have been included. That commit would have instead modified "none" to "openpgp" for daiki, had the eclass existed exactly a year ago. Bug: https://gitlab.com/gnutls/web-pages/-/issues/6 Fixes: 1061fd37f9491f2601a8b5b6c92ffc3a2f42d7c9 Signed-off-by: Eli Schwartz --- sec-keys/openpgp-keys-gnutls/Manifest | 1 + .../openpgp-keys-gnutls-20240415-r1.ebuild| 22 +++ 2 files changed, 23 insertions(+) create mode 100644 sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20240415-r1.ebuild diff --git a/sec-keys/openpgp-keys-gnutls/Manifest b/sec-keys/openpgp-keys-gnutls/Manifest index eb2132f1bf3e..a2a4a26cbb10 100644 --- a/sec-keys/openpgp-keys-gnutls/Manifest +++ b/sec-keys/openpgp-keys-gnutls/Manifest @@ -1,3 +1,4 @@ +DIST openpgp-keys-daiki-openpgp-20240415.asc 7345 BLAKE2B 0a6a0079483320bbd191f3c04a21ac52b159f755518ae7d6e27869b7cda06548bd7772ce5b9def07dece791537cbfb750bd227023f7665cbd860b5ce200fc4d0 SHA512 55af264087eceb244c59bec2aa4c62df3fc0b25ceb13728e7c3fc9042ae2fb990282367e6b46eda7ceb7f267add6dcd8948a887d825c7759cc61c642d6e0a3a7 DIST openpgp-keys-gnutls-20220320-release-keyring.gpg 20850 BLAKE2B 06865e4ac4e69237f7c52f551ce902281f6699bd144cb16c97e81aa1323c99187637c3b62730e700bc1c7f9de4608da55d3a80c8ffc240ee533e42b4707e4fbe SHA512 ebf592298142c7f05d8298a9e42aa4e5579eda54bf3c16f5a97cd22c22f3904a635a20cb1af6587d03b1a58545b925bddb769b098c664a336abce8ec9f10b9d5 DIST openpgp-keys-gnutls-20221017-release-keyring.gpg 26256 BLAKE2B c42024bade07f5e0d189c653a052aaa89803c71c8c3a5653417fb1ae3961c392257b5ef719b9236d291d449490d5dba90ae238b76391933f864458c0805e02e0 SHA512 5c14d83f4f37bd319c652db0d76fc5bb04752fb461bbe853e25b20ffe41d6d14faae6c0bdd0193ac6242975bf1205ce606a9d0082261cc4581fd680abfcdbd4d DIST openpgp-keys-gnutls-20231129-daiki-updated.gpg 7345 BLAKE2B 0a6a0079483320bbd191f3c04a21ac52b159f755518ae7d6e27869b7cda06548bd7772ce5b9def07dece791537cbfb750bd227023f7665cbd860b5ce200fc4d0 SHA512 55af264087eceb244c59bec2aa4c62df3fc0b25ceb13728e7c3fc9042ae2fb990282367e6b46eda7ceb7f267add6dcd8948a887d825c7759cc61c642d6e0a3a7 diff --git a/sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20240415-r1.ebuild b/sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20240415-r1.ebuild new file mode 100644 index ..d98e32a90411 --- /dev/null +++ b/sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20240415-r1.ebuild @@ -0,0 +1,22 @@ +# Copyright 1999-2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +SEC_KEYS_VALIDPGPKEYS=( + 'E987AB7F7E89667776D05B3BB0E9DD20B29F1432:alexander.sosedken:none' + # GnuTLS website has expired key for daiki + '462225C3B46F34879FC8496CD605848ED7E69871:daiki:openpgp' + '1CB27DBC98614B2D5841646D08302DB6A2670428:tim.ruehsen:none' + '5D46CB0F763405A7053556F47A75A648B3F9220C:zfridrich:none' +) + +inherit sec-keys + +DESCRIPTION="OpenPGP keys used by GnuTLS" +HOMEPAGE="https://www.gnutls.org/download.html"; +SRC_URI+=" + https://gnutls.org/gnutls-release-keyring.gpg -> ${P}-release-keyring.gpg +" + +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86" -- 2.45.2
[gentoo-dev] Last rites: sys-boot/woeusb
# Takuya Wakazono (2024-11-27) # Replaced by sys-boot/woeusb-ng, which has more recent upstream # activity and optional GUI support. # Removal on 2024-12-24. sys-boot/woeusb
[gentoo-dev] [PATCH v2 1/2] sec-keys.eclass: new eclass
The current state of verify-sig support is a bit awkward. We rely on validating distfiles against a known trusted keyring, but creating the known trusted keyring is basically all manual verification. We somehow decide an ascii armored key is good enough without any portage assistance, then arrange to download it and trust it by Manifest hash. How do we know when updating a key is actually safe? This eclass handles the problem in a manner inspired in part by pacman. We require an eclass variable that lists all permitted PGP fingerprints, and the eclass is responsible checking that list against the keys we will install. It comes with a mechanism for computing SRC_URI for a couple of well known locations, or you can append your own in the ebuild. Key rotations, both expected and malicious, are easily detected by checking the git log for changes to declared fingerprints in a bump. The former can be rationalized in the commit message. So can the latter, but in most cases those will be rejected during peer review. Signed-off-by: Eli Schwartz --- eclass/sec-keys.eclass | 197 + 1 file changed, 197 insertions(+) create mode 100644 eclass/sec-keys.eclass diff --git a/eclass/sec-keys.eclass b/eclass/sec-keys.eclass new file mode 100644 index ..7ea4d34a8c1c --- /dev/null +++ b/eclass/sec-keys.eclass @@ -0,0 +1,197 @@ +# Copyright 2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: sec-keys.eclass +# @MAINTAINER: +# Eli Schwartz +# @AUTHOR: +# Eli Schwartz +# @SUPPORTED_EAPIS: 8 +# @BLURB: Provides a uniform way of handling ebuilds which package PGP key material +# @DESCRIPTION: +# This eclass provides a streamlined approach to finding suitable source material +# for OpenPGP keys used by the verify-sig eclass. Its primary purpose is to permit +# developers to easily and securely package new sec-keys/* packages. The eclass +# removes the risk of developers accidentally packaging malformed key material, or +# neglecting to notice when PGP identities have changed. +# +# To use the eclass, define SEC_KEYS_VALIDPGPKEYS to contain the fingerprint of +# the key and the short name of the key's owner. +# +# @EXAMPLE: +# Example use: +# +# @CODE +# SEC_KEYS_VALIDPGPKEYS=( +# # implicit Ubuntu +# '3DB7F3CA6C1D90B99FE25B38D4B476A4D175C54F:bjones:' +# '4EC8A4DB7D2E01C00AF36C49E5C587B5E286C65A:jsmith:github,openpgp' +# # key only available on personal website, use manual SRC_URI +# '5FD9B5EC8E3F12D11BA47D50F6D698C6F397D76B:awhite:none' +# ) +# +# inherit sec-keys +# +# SRC_URI+="https://awhite.com/awhite.gpg -> awhite-${PV}.gpg" +# @CODE + +case ${EAPI} in + 8) ;; + *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; +esac + +if [[ ! ${_SEC_KEYS_ECLASS} ]]; then +_SEC_KEYS_ECLASS=1 + +inherit edo + +# @ECLASS_VARIABLE: SEC_KEYS_VALIDPGPKEYS +# @PRE_INHERIT +# @DEFAULT_UNSET +# @DESCRIPTION: +# Mapping of fingerprints, name, and optional location of PGP keys to include, +# separated by colons. The allowed values for a location are: +# +# - gentoo -- fetch key by fingerprint from https://keys.gentoo.org +# +# - github -- fetch key from github.com/${name}.pgp +# +# - openpgp -- fetch key by fingerprint from https://keys.openpgp.org +# +# - ubuntu -- fetch key by fingerprint from http://keyserver.ubuntu.com (the default) +# +# - none -- do not add to SRC_URI, the ebuild will provide a custom download location +_sec_keys_set_globals() { + if [[ ${SEC_KEYS_VALIDPGPKEYS[*]} ]]; then + local key fingerprint name loc locations=() remote + for key in "${SEC_KEYS_VALIDPGPKEYS[@]}"; do + fingerprint=${key%%:*} + name=${key#${fingerprint}:}; name=${name%%:*} + IFS=, read -r -a locations <<<"${key##*:}" + [[ ${locations[@]} ]] || locations=(ubuntu) + for loc in "${locations[@]}"; do + case ${loc} in + gentoo) remote="https://keys.gentoo.org/pks/lookup?op=get&search=0x${fingerprint}";;; + github) remote="https://github.com/${name}.gpg";;; + openpgp) remote="https://keys.openpgp.org/vks/v1/by-fingerprint/${fingerprint}";;; + ubuntu) remote="https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x${fingerprint}";;; + # provided via manual SRC_URI + none) continue;; + *) die "${ECLASS}: unknown PGP key remote: ${loc}";; + + esac + SRC_URI+=" + ${remote} -> openpgp-keys-${name}-${loc}-${PV}.asc + " + done +
[gentoo-dev] [PATCH v2 2/2] sec-keys/openpgp-keys-gnutls: update to use sec-keys.eclass
Bump EAPI 7 -> 8 as required by eclass. ;) This is a nice demonstration of using the eclass. It showcases some advanced usage, in particular, how to augment a single key within a keyring published on upstream's website with an extended expiration date from the openpgp.org keyserver. The ebuild was previously updated in commit 1061fd37f9491f2601a8b5b6c92ffc3a2f42d7c9 with some explanatory text about why we needed to do that. It wasn't a very good commit (sorry, past self!) because it was kind of inscrutable whether the key "should" have been included. That commit would have instead modified "none" to "openpgp" for daiki, had the eclass existed exactly a year ago. Bug: https://gitlab.com/gnutls/web-pages/-/issues/6 Fixes: 1061fd37f9491f2601a8b5b6c92ffc3a2f42d7c9 Signed-off-by: Eli Schwartz --- sec-keys/openpgp-keys-gnutls/Manifest | 1 + .../openpgp-keys-gnutls-20240415-r1.ebuild| 22 +++ 2 files changed, 23 insertions(+) create mode 100644 sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20240415-r1.ebuild diff --git a/sec-keys/openpgp-keys-gnutls/Manifest b/sec-keys/openpgp-keys-gnutls/Manifest index eb2132f1bf3e..a2a4a26cbb10 100644 --- a/sec-keys/openpgp-keys-gnutls/Manifest +++ b/sec-keys/openpgp-keys-gnutls/Manifest @@ -1,3 +1,4 @@ +DIST openpgp-keys-daiki-openpgp-20240415.asc 7345 BLAKE2B 0a6a0079483320bbd191f3c04a21ac52b159f755518ae7d6e27869b7cda06548bd7772ce5b9def07dece791537cbfb750bd227023f7665cbd860b5ce200fc4d0 SHA512 55af264087eceb244c59bec2aa4c62df3fc0b25ceb13728e7c3fc9042ae2fb990282367e6b46eda7ceb7f267add6dcd8948a887d825c7759cc61c642d6e0a3a7 DIST openpgp-keys-gnutls-20220320-release-keyring.gpg 20850 BLAKE2B 06865e4ac4e69237f7c52f551ce902281f6699bd144cb16c97e81aa1323c99187637c3b62730e700bc1c7f9de4608da55d3a80c8ffc240ee533e42b4707e4fbe SHA512 ebf592298142c7f05d8298a9e42aa4e5579eda54bf3c16f5a97cd22c22f3904a635a20cb1af6587d03b1a58545b925bddb769b098c664a336abce8ec9f10b9d5 DIST openpgp-keys-gnutls-20221017-release-keyring.gpg 26256 BLAKE2B c42024bade07f5e0d189c653a052aaa89803c71c8c3a5653417fb1ae3961c392257b5ef719b9236d291d449490d5dba90ae238b76391933f864458c0805e02e0 SHA512 5c14d83f4f37bd319c652db0d76fc5bb04752fb461bbe853e25b20ffe41d6d14faae6c0bdd0193ac6242975bf1205ce606a9d0082261cc4581fd680abfcdbd4d DIST openpgp-keys-gnutls-20231129-daiki-updated.gpg 7345 BLAKE2B 0a6a0079483320bbd191f3c04a21ac52b159f755518ae7d6e27869b7cda06548bd7772ce5b9def07dece791537cbfb750bd227023f7665cbd860b5ce200fc4d0 SHA512 55af264087eceb244c59bec2aa4c62df3fc0b25ceb13728e7c3fc9042ae2fb990282367e6b46eda7ceb7f267add6dcd8948a887d825c7759cc61c642d6e0a3a7 diff --git a/sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20240415-r1.ebuild b/sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20240415-r1.ebuild new file mode 100644 index ..d98e32a90411 --- /dev/null +++ b/sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20240415-r1.ebuild @@ -0,0 +1,22 @@ +# Copyright 1999-2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +SEC_KEYS_VALIDPGPKEYS=( + 'E987AB7F7E89667776D05B3BB0E9DD20B29F1432:alexander.sosedken:none' + # GnuTLS website has expired key for daiki + '462225C3B46F34879FC8496CD605848ED7E69871:daiki:openpgp' + '1CB27DBC98614B2D5841646D08302DB6A2670428:tim.ruehsen:none' + '5D46CB0F763405A7053556F47A75A648B3F9220C:zfridrich:none' +) + +inherit sec-keys + +DESCRIPTION="OpenPGP keys used by GnuTLS" +HOMEPAGE="https://www.gnutls.org/download.html"; +SRC_URI+=" + https://gnutls.org/gnutls-release-keyring.gpg -> ${P}-release-keyring.gpg +" + +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86" -- 2.45.2
[gentoo-dev] [PATCH v2 0/2] sec-keys.eclass
v2 changes: - add src_test - add support for gentoo keyserver - fix small typo in handling multiple sources - remove outdated die based on review Eli Schwartz (2): sec-keys.eclass: new eclass sec-keys/openpgp-keys-gnutls: update to use sec-keys.eclass eclass/sec-keys.eclass| 197 ++ sec-keys/openpgp-keys-gnutls/Manifest | 1 + .../openpgp-keys-gnutls-20240415-r1.ebuild| 22 ++ 3 files changed, 220 insertions(+) create mode 100644 eclass/sec-keys.eclass create mode 100644 sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20240415-r1.ebuild Range-diff against v1: 1: 02c47372ec21 ! 1: 6777dbb541bf sec-keys.eclass: new eclass @@ Commit message ebuild. Key rotations, both expected and malicious, are easily detected by -checking the git log for changes to declared finterprints in a bump. The +checking the git log for changes to declared fingerprints in a bump. The former can be rationalized in the commit message. So can the latter, but in most cases those will be rejected during peer review. @@ eclass/sec-keys.eclass (new) +# +# @CODE +# SEC_KEYS_VALIDPGPKEYS=( -+# '4EC8A4DB7D2E01C00AF36C49E5C587B5E286C65A:jsmith:github' ++# # implicit Ubuntu ++# '3DB7F3CA6C1D90B99FE25B38D4B476A4D175C54F:bjones:' ++# '4EC8A4DB7D2E01C00AF36C49E5C587B5E286C65A:jsmith:github,openpgp' ++# # key only available on personal website, use manual SRC_URI ++# '5FD9B5EC8E3F12D11BA47D50F6D698C6F397D76B:awhite:none' +# ) +# +# inherit sec-keys ++# ++# SRC_URI+="https://awhite.com/awhite.gpg -> awhite-${PV}.gpg" +# @CODE + +case ${EAPI} in @@ eclass/sec-keys.eclass (new) +# Mapping of fingerprints, name, and optional location of PGP keys to include, +# separated by colons. The allowed values for a location are: +# ++# - gentoo -- fetch key by fingerprint from https://keys.gentoo.org ++# +# - github -- fetch key from github.com/${name}.pgp +# +# - openpgp -- fetch key by fingerprint from https://keys.openpgp.org @@ eclass/sec-keys.eclass (new) + for key in "${SEC_KEYS_VALIDPGPKEYS[@]}"; do + fingerprint=${key%%:*} + name=${key#${fingerprint}:}; name=${name%%:*} -+ IFS=: read -r -a locations <<<"${key##*:}" ++ IFS=, read -r -a locations <<<"${key##*:}" + [[ ${locations[@]} ]] || locations=(ubuntu) + for loc in "${locations[@]}"; do + case ${loc} in ++ gentoo) remote="https://keys.gentoo.org/pks/lookup?op=get&search=0x${fingerprint}";;; + github) remote="https://github.com/${name}.gpg";;; + openpgp) remote="https://keys.openpgp.org/vks/v1/by-fingerprint/${fingerprint}";;; + ubuntu) remote="https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x${fingerprint}";;; @@ eclass/sec-keys.eclass (new) +_sec_keys_set_globals +unset -f _sec_keys_set_globals + -+BDEPEND="app-crypt/gnupg" ++IUSE="test" ++PROPERTIES="test_network" ++RESTRICT="test" ++ ++BDEPEND=" ++ app-crypt/gnupg ++ test? ( app-crypt/pgpdump ) ++" +S=${WORKDIR} + +LICENSE="public-domain" @@ eclass/sec-keys.eclass (new) + fi +} + ++ ++sec-keys_src_test() { ++ local -x GNUPGHOME=${WORKDIR}/gnupg ++ local key fingerprint name server ++ local gpg_command=(gpg --export-options export-minimal) ++ ++ for fingerprint in "${SEC_KEYS_VALIDPGPKEYS[@]%%:*}"; do ++ "${gpg_command[@]}" --export "${fingerprint}" | pgpdump > "${fingerprint}.pgpdump" || die ++ done ++ ++ # Best-effort attempt to check for updates. keyservers can and usually do ++ # fail for weird reasons, (such as being unable to import a key without a ++ # uid) as well as normal reasons, like the key being exclusive to a ++ # different keyserver. this isn't a reason to fail src_test. ++ for server in keys.gentoo.org keys.openpgp.org keyserver.ubuntu.com; do ++ gpg --refresh-keys --keyserver "hkps://${server}" ++ done ++ for key in "${SEC_KEYS_VALIDPGPKEYS[@]}"; do ++ if [[ ${key##*:} = *github* ]]; then ++ name=${key#*:}; name=${name%%:*} ++ wget -qO- https://github.com/${name}.gpg | gpg --import || die ++ fi ++ done ++ ++ for fingerprint in "${SEC_KEYS_VALIDPGPKEYS[@]%%:*}"; do ++ "${gpg_command[@]}" --export "${fingerprint}" | pgpdump > "${fingerprint}.pgpdump.new" || die ++ diff -u "${fingerprint}.pgpdump" "${fingerprint}.pgpdump.new" || die "u
Re: [gentoo-dev] [PATCH 1/2] sec-keys.eclass: new eclass
On 11/27/24 4:12 PM, Michał Górny wrote: > On Wed, 2024-11-27 at 15:30 -0500, Eli Schwartz wrote: >> The current state of verify-sig support is a bit awkward. We rely on >> validating distfiles against a known trusted keyring, but creating the >> known trusted keyring is basically all manual verification. We somehow >> decide an ascii armored key is good enough without any portage >> assistance, then arrange to download it and trust it by Manifest hash. >> How do we know when updating a key is actually safe? >> >> This eclass handles the problem in a manner inspired in part by pacman. >> We require an eclass variable that lists all permitted PGP fingerprints, >> and the eclass is responsible checking that list against the keys we >> will install. It comes with a mechanism for computing SRC_URI for a >> couple of well known locations, or you can append your own in the >> ebuild. > > How about adding a src_test() that would check if the key needs bumping, > i.e. if an online update triggers any meaningful changes? This is a really nice suggestion. I used Sam's tip about pgpdump, so that we print a diff after the online update, and fail if diff produces a diff. We use a cleaned and minimized version of the key, so it will only show/trigger on changes to the uid or self-sig packets, which isn't exactly the same as "meaningful changes". For example, running the tests on the gnutls keyring in the second patch, Daiki's key has been updated on Ubuntu with an additional expiry date change for a secondary uid, which may be meaningful in certain senses but we can validate it just fine using the primary uid. -- Eli Schwartz OpenPGP_signature.asc Description: OpenPGP digital signature
Re: [gentoo-dev] New eclass: eapi9-pipestatus.eclass
On 24/11/2024 13.24, Ulrich Müller wrote: This implements a pipestatus command, as discussed in bug 566342 [1] and on IRC. Subject to approval by the council, the command would be added in EAPI 9. Its definition in the Package Manager Specification would be along the lines of: ╓ ║ Tests the shell's pipe status array, i.e. the exit status of the ║ command(s) in the most recently executed foreground pipeline. ║ Returns shell true (0) if all elements are zero, or the last ║ non-zero element otherwise. If called with -v as the first argument, ║ also outputs the pipe status array as a space-separated list. ╙ Thanks again for putting effort into this ulm. When this was discussed in #-qa one initial version of pipestatus() had support for specifying non-zero exit statues as success indication for certain commands in the pipe. The prime example being 'grep' returning 1 if no input matched. One proposed version had support for this, but it was removed in later version and the discussion in #-qa shifted towards how the value of PIPESTATUS can be preserved to be included in a potential error message. I agree that we should drop 'assert' and that dropping it requires a sensible named alternative. And the proposed version of pipestatus() is a functional equivalent alternative. However, I am not sure why the proposed pipestatus() does no longer include support for specifying non-zero exit statuses as success indication. I looked forward to use pipestatus() in texlive-modules.eclass [1], but since the pipe includes a 'grep', which is not uncommon, I can not use what is currently proposed. It seems strange to me to go this far, but then drop the ball on the last meter. Could we please consider re-adding support for this? - Flow 1: https://github.com/gentoo/gentoo/blob/11b21e623fcff8948cbbd33854ffdb2a51b2840b/eclass/texlive-module.eclass#L540-L549 OpenPGP_0x8CAC2A9678548E35.asc Description: OpenPGP public key OpenPGP_signature.asc Description: OpenPGP digital signature
Re: [gentoo-dev] New eclass: eapi9-pipestatus.eclass
On Wed, 2024-11-27 at 11:41 +0100, Florian Schmaus wrote: > I looked forward to use pipestatus() in texlive-modules.eclass [1], but > since the pipe includes a 'grep', which is not uncommon, I can not use > what is currently proposed. Use sed instead. -- Best regards, Michał Górny signature.asc Description: This is a digitally signed message part
Re: [gentoo-dev] New eclass: eapi9-pipestatus.eclass
> On Wed, 27 Nov 2024, Florian Schmaus wrote: >> ╓ >> ║ Tests the shell's pipe status array, i.e. the exit status of the >> ║ command(s) in the most recently executed foreground pipeline. >> ║ Returns shell true (0) if all elements are zero, or the last >> ║ non-zero element otherwise. If called with -v as the first argument, >> ║ also outputs the pipe status array as a space-separated list. >> ╙ > Thanks again for putting effort into this ulm. > When this was discussed in #-qa one initial version of pipestatus() > had support for specifying non-zero exit statues as success indication > for certain commands in the pipe. The prime example being 'grep' > returning 1 if no input matched. > One proposed version had support for this, but it was removed in later > version and the discussion in #-qa shifted towards how the value of > PIPESTATUS can be preserved to be included in a potential error > message. > I agree that we should drop 'assert' and that dropping it requires a > sensible named alternative. And the proposed version of pipestatus() > is a functional equivalent alternative. > However, I am not sure why the proposed pipestatus() does no longer > include support for specifying non-zero exit statuses as success > indication. > I looked forward to use pipestatus() in texlive-modules.eclass [1], > but since the pipe includes a 'grep', which is not uncommon, I can not > use what is currently proposed. > It seems strange to me to go this far, but then drop the ball on the > last meter. > Could we please consider re-adding support for this? I have dropped the feature because feedback in bug 566342 was very negative. The main argument was it would unnecessarily complicate the function, in order to account for a corner case. In the discussion it was suggested to introduce a wrapper instead; this is now bug 945110. Ulrich signature.asc Description: PGP signature