alitheg opened a new issue, #1416: URL: https://github.com/apache/tooling-trusted-releases/issues/1416
<div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">FINDING-001: Expired signing keys accepted during signature verification; OpenPGP revocation handling not explicit or tested</h4><a id="user-content-finding-001-expired-signing-keys-accepted-during-signature-verification-openpgp-revocation-handling-not-explicit-or-tested" class="anchor" aria-label="Permalink: FINDING-001: Expired signing keys accepted during signature verification; OpenPGP revocation handling not explicit or tested" href="https://github.com/apache/tooling-runbooks/blob/main/ASVS/reports/mythos/tooling-trusted-releases/tooling-trusted-releases-2026-07-14-2626a23/consolidated.md#finding-001-expired-signing-keys-accepted-during-signature-verification-openpgp-revocation-handling-not-explicit-or-tested"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"></svg></a></div> <markdown-accessiblity-table data-catalyst=""> Attribute | Value -- | -- Severity | 🔴 Critical ASVS Level(s) | L2, L3 CWE | — ASVS Sections | 11.6.1, 4.1.5 Files | atr/tasks/checks/signature.py, atr/storage/writers/keys.py, atr/get/keys.py Source Reports | 11.6.1.md, 4.1.5.md Related | — </markdown-accessiblity-table> <p dir="auto"><strong>Description:</strong></p> <p dir="auto">ATR computes and persists key expiration as a first-class security attribute (<code>_key_expires_at</code> via <code>_effective_key_expiration_self_signature</code> in <code>atr/storage/writers/keys.py</code>, stored in <code>PublicSigningKey.expires</code>; <code>atr/get/keys.py::details</code> renders an 'Expired' danger badge from this field). However, the signature-verification path (<code>atr/tasks/checks/signature.py::_check_core_logic</code>) loads full <code>PublicSigningKey</code> rows — including <code>expires</code> — and never consults it. The <code>where</code> clause filters only on committee membership and <code>deleted IS NULL</code>; there is no <code>expires</code> filter, and <code>_check_core_logic_verify_signature</code> calls <code>signature.verify_file(candidate_key, artifact_path)</code> with no expiry check on the key or on the signature creation time relative to key validity. An expired key — precisely the class of keys most likely to have lapsed operational protection or been deliberately expired after suspected compromise — verifies identically to a valid key, yielding 'Signature verified successfully'. Data flow: attacker-held expired key (committee-linked, not soft-deleted) → detached <code>.asc</code> uploaded with tampered artifact → <code>check()</code> → <code>_check_core_logic</code> (no expiry filter) → <code>verify_file</code> succeeds. Impact: forged signatures on release artifacts pass the committee signature check, so the primary supply-chain assurance ('this artifact was signed by a currently valid committee key') is false. Additionally, it is unverified whether the <code>openpgp</code> library evaluates OpenPGP revocation self-signatures during <code>verify_file</code>; the embedded test key in <code>tests/unit/test_keys_writer.py</code> is titled 'Demonstrating Revoker Trouble (DO NOT USE)' yet no test asserts rejection of a revoked or expired key at verification time.</p> <p dir="auto"><strong>Remediation:</strong></p> <p dir="auto">In <code>_check_core_logic</code>, after loading keys, filter out expired keys: <code>db_public_keys = [key for key in db_public_keys if (key.expires is None) or (key.expires > datetime.datetime.now(datetime.UTC))]</code>. Better: also check the signature creation time against key validity — reject if <code>key.expires is not None and signature_info.creation_time > key.expires</code>. Additionally, verify (and document with a test) whether the <code>openpgp</code> library evaluates OpenPGP revocation self-signatures during <code>verify_file</code>; if it does not, revocation certificates present in imported key blocks must be evaluated explicitly. Add regression tests using the already-embedded expiring test key.</p> -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
