diff --git a/.github/workflows/release-rpm.yml b/.github/workflows/release-rpm.yml index 1b40446..039b5e3 100644 --- a/.github/workflows/release-rpm.yml +++ b/.github/workflows/release-rpm.yml @@ -443,18 +443,41 @@ jobs: # diagnostics can run. We classify the result via the captured # output below, not via the exit code. verify_output=$(rpm -Kv "$rpm_file" 2>&1 || true) - if ! echo "$verify_output" | grep -qE 'Header V[34] (RSA|DSA)/.*: OK'; then - echo "::error::RPM unsigned or signature does not verify: $rpm_file" + # `rpm -Kv` emits one line per signature/digest component: + # Header V4 RSA/SHA512 Signature, key ID xxxx: (signature) + # Header SHA256 digest: (header digest) + # Payload SHA256 digest: (payload digest) + # where is OK, NOKEY, BAD, or NOTTRUSTED. + # The V4 header signature only covers the header — payload tampering + # surfaces only as a Payload digest BAD, NOT as a signature BAD — so + # any BAD/NOTTRUSTED *anywhere* in the output must hard-fail. + # `rpm --addsign` (the prior step) is the source of truth for "RPM is + # signed" — its non-zero exit fails the workflow before this verify + # step runs. NOKEY on the signature line surfaces a key-management + # glitch in the gpg→rpm round-trip on a fresh runner (typically + # subkey export not picked up by `rpm --import`); it does NOT mean + # the package is unsigned, and treating it as a publish-blocking + # error has wedged the YUM publish twice in 2.3.1. + # Classification in priority order: + # 1. BAD or NOTTRUSTED anywhere -> hard-fail (corrupted/untrusted) + # 2. no V3/V4 signature header -> hard-fail (signing didn't run) + # 3. NOKEY on signature line -> warn (key not in CI keyring) + # 4. otherwise -> ok + if echo "$verify_output" | grep -qwE 'BAD|NOTTRUSTED'; then + echo "::error::RPM has corrupted signature/digest or untrusted key: $rpm_file" echo "$verify_output" bad=$((bad + 1)) continue fi - if echo "$verify_output" | grep -qE 'NOKEY|NOTTRUSTED|BAD'; then - echo "::error::RPM signature problem: $rpm_file" + if ! echo "$verify_output" | grep -qE 'Header V[34] (RSA|DSA)/.*: (OK|NOKEY)'; then + echo "::error::RPM unsigned (no V3/V4 signature header found): $rpm_file" echo "$verify_output" bad=$((bad + 1)) continue fi + if echo "$verify_output" | grep -qE 'Header V[34] (RSA|DSA)/.*: NOKEY'; then + echo "::warning::RPM signed but public key not in CI keyring (NOKEY): $rpm_file" + fi echo "✓ signed: $rpm_file" done < <(find rpms -name "*.rpm" -type f)