v3 changes: - rename "none" to "manual" - method is now required, rather than defaulting to ubuntu - move creation of exported key files to src_compile; this fixes test-fail-continue, and makes src_install simpler. - documentation/formatting nits
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 (3): sec-keys.eclass: new eclass sec-keys/openpgp-keys-gnutls: update to use sec-keys.eclass sec-keys/openpgp-keys-gnutls: add 20250704 eclass/sec-keys.eclass | 202 ++++++++++++++++++ sec-keys/openpgp-keys-gnutls/Manifest | 4 + .../openpgp-keys-gnutls-20240415-r1.ebuild | 22 ++ .../openpgp-keys-gnutls-20250704.ebuild | 22 ++ 4 files changed, 250 insertions(+) create mode 100644 eclass/sec-keys.eclass create mode 100644 sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20240415-r1.ebuild create mode 100644 sec-keys/openpgp-keys-gnutls/openpgp-keys-gnutls-20250704.ebuild Range-diff against v2: 1: de9448ce1b38 ! 1: e4f5ce60806c sec-keys.eclass: new eclass @@ Commit message ## eclass/sec-keys.eclass (new) ## @@ -+# Copyright 2024 Gentoo Authors ++# Copyright 2024-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: sec-keys.eclass @@ eclass/sec-keys.eclass (new) +# @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. ++# 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. ++# 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:' ++# '3DB7F3CA6C1D90B99FE25B38D4B476A4D175C54F:bjones:ubuntu' +# '4EC8A4DB7D2E01C00AF36C49E5C587B5E286C65A:jsmith:github,openpgp' +# # key only available on personal website, use manual SRC_URI -+# '5FD9B5EC8E3F12D11BA47D50F6D698C6F397D76B:awhite:none' ++# '5FD9B5EC8E3F12D11BA47D50F6D698C6F397D76B:awhite:manual' +# ) +# +# inherit sec-keys @@ eclass/sec-keys.eclass (new) +# @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: ++# Mapping of fingerprints, name, and optional locations 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 +# @@ eclass/sec-keys.eclass (new) +# +# - openpgp -- fetch key by fingerprint from https://keys.openpgp.org +# -+# - ubuntu -- fetch key by fingerprint from http://keyserver.ubuntu.com (the default) ++# - ubuntu -- fetch key by fingerprint from http://keyserver.ubuntu.com +# -+# - none -- do not add to SRC_URI, the ebuild will provide a custom download location ++# - manual -- 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 ++ 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[@]} ]] || die "${ECLASS}: ${name}: PGP key remote is mandatory" ++ 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 ++ manual) continue;; ++ *) die "${ECLASS}: unknown PGP key remote: ${loc}";; ++ esac ++ SRC_URI+=" ++ ${remote} -> openpgp-keys-${name}-${loc}-${PV}.asc ++ " + done -+ fi ++ done +} +_sec_keys_set_globals +unset -f _sec_keys_set_globals + ++S=${WORKDIR} ++ ++LICENSE="public-domain" ++SLOT="0" ++ +IUSE="test" +PROPERTIES="test_network" -+RESTRICT="test" ++RESTRICT="!test? ( test )" + +BDEPEND=" + app-crypt/gnupg + test? ( app-crypt/pgpdump ) +" -+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. ++# Default src_compile override that: ++# ++# - imports all public keys into a keyring ++# ++# - validates that they are listed in SEC_KEYS_VALIDPGPKEYS ++# ++# - minifies and exports them back into a unified keyfile +sec-keys_src_compile() { + local -x GNUPGHOME=${WORKDIR}/gnupg ++ local fingerprint ++ local gpg_command=(gpg --export-options export-minimal) ++ + mkdir -m700 -p "${GNUPGHOME}" || die ++ cat <<- EOF > "${GNUPGHOME}"/gpg.conf || die ++ no-secmem-warning ++ EOF + + pushd "${DISTDIR}" >/dev/null || die + gpg --import ${A} || die @@ eclass/sec-keys.eclass (new) + imported_keys+=("${line[9]}") + found=1 + fi -+ done < <(gpg --batch --list-keys --keyid-format=long --with-colons || die) ++ done < <(gpg --batch --list-keys --with-colons || die) + + printf '%s\n' "${imported_keys[@]}" | sort > imported_keys.list || die + printf '%s\n' "${SEC_KEYS_VALIDPGPKEYS[@]%%:*}" | sort > allowed_keys.list || die @@ eclass/sec-keys.eclass (new) + local missing_keys=($(comm -13 imported_keys.list allowed_keys.list || die)) + + if [[ ${#extra_keys[@]} != 0 ]]; then -+ die "too many keys found. Suspicious keys: ${extra_keys[@]}" ++ die "Too many keys found. Suspicious keys: ${extra_keys[@]}" + fi + if [[ ${#missing_keys[@]} != 0 ]]; then -+ die "too few keys found. Unavailable keys: ${missing_keys[@]}" ++ die "Too few keys found. Unavailable keys: ${missing_keys[@]}" + fi -+} + ++ 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}" > "${fingerprint}.asc" ++ cat ${fingerprint}.asc >> ${PN#openpgp-keys-}.asc || die ++ done ++} + +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. ++ # 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 @@ eclass/sec-keys.eclass (new) + done + + for fingerprint in "${SEC_KEYS_VALIDPGPKEYS[@]%%:*}"; do ++ pgpdump "${fingerprint}.asc" > "${fingerprint}.pgpdump" || die + "${gpg_command[@]}" --export "${fingerprint}" | pgpdump > "${fingerprint}.pgpdump.new" || die + diff -u "${fingerprint}.pgpdump" "${fingerprint}.pgpdump.new" || die "updates available for PGP key: ${fingerprint}" + done @@ eclass/sec-keys.eclass (new) + +# @FUNCTION: sec-keys_src_install +# @DESCRIPTION: -+# Default src_install override that minifies and exports all PGP public keys -+# into an ascii-armored keyfile installed to the standard /usr/share/openpgp-keys. ++# Default src_install override that installs an ascii-armored keyfile ++# installed to the standard /usr/share/openpgp-keys. +sec-keys_src_install() { -+ local -x GNUPGHOME=${WORKDIR}/gnupg -+ local fingerprint -+ local gpg_command=(gpg --no-permission-warning --export-options export-minimal) -+ -+ 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 -+ done -+ + insinto /usr/share/openpgp-keys + doins ${PN#openpgp-keys-}.asc +} 2: b3257b4d5284 = 2: 7404d7abf297 sec-keys/openpgp-keys-gnutls: update to use sec-keys.eclass -: ------------ > 3: 6a8d7edc9b92 sec-keys/openpgp-keys-gnutls: add 20250704 -- 2.49.1