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


Reply via email to