Bug 2532553
| Summary: | Consider proper handling of expired signing keys in openpgpverify | ||
|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | Ben Beasley <code> |
| Component: | openpgpverify | Assignee: | Jakub Jelen <jjelen> |
| Status: | CLOSED NOTABUG | QA Contact: | |
| Severity: | medium | Docs Contact: | |
| Priority: | unspecified | ||
| Version: | rawhide | CC: | decathorpe, jjelen, mjg |
| Target Milestone: | --- | ||
| Target Release: | --- | ||
| Hardware: | Unspecified | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | --- | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2026-10-09 13:19:47 UTC | Type: | --- |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
| Bug Depends On: | |||
| Bug Blocks: | 2523619 | ||
|
Description
Ben Beasley
2026-09-12 09:56:47 UTC
I *think* the intention is to consider signatures "valid" as long as the key was not expired at the time when the signature was made ... not sure why it doesn't work that way currently, it might be a bug or require passing some flag to sqv. Apparently, the openpgp standard considers those signatures invalid. The reasoning given is that signature time stamps are not cryptographically secured, so someone getting hold of an expired key can create signatures which appear to have been made before the expiration date. From a quick check: sqv has a `--time` option to set a reference time, that is for checking "was the signature valid at time x"? One could use that with a good defult (per release? Last commit date?) or inspect the signature first for its creation time and use that plus epsilon. From my reading, the sequoia already checks expiry at the time the signature was made. That means for the cases where it fails are just the ones where the signature was made with expired key or the key expiration was extended, but the keyring was not updated in the dist git (or published).
From what I see cairo-1.18.0.tar.xz was released in 2023, while the key (as available in the keyserver and dist git) expired in 2022. It might be the owner extended the expiry date, but never published the updated key anywhere, which is something that needs to be communicated with the key owner. Blindly trusting any signature made after the key expired does not sounds to me like sane solution (even though gnupg might have done that for some reason).
You can see this for example in radvd package, that recently changed to openpgpverify. The primary key in the keyring expired on 2026-07-11T19:00:04Z, but the signature was made at 2026-05-25 21:14:09:
```
$ sq inspect robbat2.gpg
...
Bad Signatures: 7, use --dump-bad-signatures to list
OpenPGP Certificate.
Fingerprint: 7D0B3CEBE9B85B1F825BCECFEE05E6F6A48F6136
Invalid: The primary key is not live: Expired on 2026-07-11T19:00:04Z
Public-key algo: RSA
Public-key size: 4096 bits
Creation time: 2015-08-08 23:04:11 UTC
Expiration time: 2026-07-11 19:00:04 UTC (creation time + 10years 11months 2days 11h 46m 17s)
Key flags: certification
...
$ sq packet dump radvd-2.21.tar.xz.asc
Signature Packet, old CTB, 687 bytes
Version: 4
Type: Binary
Pk algo: RSA
Hash algo: SHA512
Hashed area:
Issuer Fingerprint: BDEBB6A52F156FDF3168D91119395F23C58826C4
Signature creation time: 2026-05-25 21:14:09 UTC
Notation: manu: 2,2.5+1.11,2,2
Notation: issuer-fpr.fifthhorseman.net: BDEBB6A52F156FDF3168D91119395F23C58826C4
Unhashed area:
Issuer: 19395F23C58826C4
Digest prefix: 18B3
Level: 0 (signature over data)
```
This means the openpgpverify works just ok in this case (and it will work forever. Or as long as the algorithm will be considered secure):
```
$ fedpkg prep
...
+ /usr/libexec/openpgpverify --keyring=/home/jjelen/devel/fedora/radvd/robbat2.gpg --signature=/home/jjelen/devel/fedora/radvd/radvd-2.21.tar.xz.asc --data=/home/jjelen/devel/fedora/radvd/radvd-2.21.tar.xz
7D0B3CEBE9B85B1F825BCECFEE05E6F6A48F6136
1 of 1 signatures are valid (threshold is: 1).
```
(In reply to Jakub Jelen from comment #3) > From my reading, the sequoia already checks expiry at the time the signature > was made. That means for the cases where it fails are just the ones where > the signature was made with expired key or the key expiration was extended, > but the keyring was not updated in the dist git (or published). > > From what I see cairo-1.18.0.tar.xz was released in 2023, while the key (as > available in the keyserver and dist git) expired in 2022. It might be the > owner extended the expiry date, but never published the updated key > anywhere, which is something that needs to be communicated with the key > owner. Blindly trusting any signature made after the key expired does not > sounds to me like sane solution (even though gnupg might have done that for > some reason). > > You can see this for example in radvd package, that recently changed to > openpgpverify. The primary key in the keyring expired on > 2026-07-11T19:00:04Z, but the signature was made at 2026-05-25 21:14:09: > > […] > > This means the openpgpverify works just ok in this case (and it will work > forever. Or as long as the algorithm will be considered secure): > > […] Thank you. This seems to be good and correct analysis, and it looks like I missed the fact that the signing key was already expired at the time it was used to sign the release. The behavior you’ve demonstrated with radvd is what I expect: once a key has been successfully used to verify a particular source file, it won’t stop working simply due to the passage of time. For cairomm1.16, I think the correct action will be to simply stop trying to verify the signature, make a note that this is due to upstream signing with an expired key at the time of release, and raise the issue with upstream. Sadly, the latest release 1.18.1 earlier this year was still signed with a key that expired in 2022. (In reply to Jakub Jelen from comment #3) > From my reading, the sequoia already checks expiry at the time the signature > was made. That means for the cases where it fails are just the ones where > the signature was made with expired key or the key expiration was extended, > but the keyring was not updated in the dist git (or published). > > From what I see cairo-1.18.0.tar.xz was released in 2023, while the key (as > available in the keyserver and dist git) expired in 2022. It might be the > owner extended the expiry date, but never published the updated key > anywhere, which is something that needs to be communicated with the key > owner. Blindly trusting any signature made after the key expired does not > sounds to me like sane solution (even though gnupg might have done that for > some reason). > > You can see this for example in radvd package, that recently changed to > openpgpverify. The primary key in the keyring expired on > 2026-07-11T19:00:04Z, but the signature was made at 2026-05-25 21:14:09: > > ``` > $ sq inspect robbat2.gpg > ... > Bad Signatures: 7, use --dump-bad-signatures to list > OpenPGP Certificate. > > Fingerprint: 7D0B3CEBE9B85B1F825BCECFEE05E6F6A48F6136 > Invalid: The primary key is not live: Expired on > 2026-07-11T19:00:04Z > Public-key algo: RSA > Public-key size: 4096 bits > Creation time: 2015-08-08 23:04:11 UTC > Expiration time: 2026-07-11 19:00:04 UTC (creation time + 10years 11months > 2days 11h 46m 17s) > Key flags: certification > ... > $ sq packet dump radvd-2.21.tar.xz.asc > Signature Packet, old CTB, 687 bytes > Version: 4 > Type: Binary > Pk algo: RSA > Hash algo: SHA512 > Hashed area: > Issuer Fingerprint: BDEBB6A52F156FDF3168D91119395F23C58826C4 > Signature creation time: 2026-05-25 21:14:09 UTC > Notation: manu: 2,2.5+1.11,2,2 > Notation: issuer-fpr.fifthhorseman.net: > BDEBB6A52F156FDF3168D91119395F23C58826C4 > Unhashed area: > Issuer: 19395F23C58826C4 > Digest prefix: 18B3 > Level: 0 (signature over data) > > ``` > > This means the openpgpverify works just ok in this case (and it will work > forever. Or as long as the algorithm will be considered secure): > ``` How does "bad Signatures" and "invalid" show that here is no problem? That is what I described: sequoia intentionally considers them invalid. > $ fedpkg prep > ... > + /usr/libexec/openpgpverify > --keyring=/home/jjelen/devel/fedora/radvd/robbat2.gpg > --signature=/home/jjelen/devel/fedora/radvd/radvd-2.21.tar.xz.asc > --data=/home/jjelen/devel/fedora/radvd/radvd-2.21.tar.xz > 7D0B3CEBE9B85B1F825BCECFEE05E6F6A48F6136 > 1 of 1 signatures are valid (threshold is: 1). > ``` I don't know what in fedpkg prep makes the signature valid here. Something in the macro? A date that is set by fedpkg? An flag passed to sqv? sequoia behaviour changed (in our package or upstream)? I mean, it's good that it works, but it should work for a good reason. > How does "bad Signatures" and "invalid" show that here is no problem? That is what I described: sequoia intentionally considers them invalid. The keyring contains several keys including some ancient crypto and expired ones. I listed the one that says "invalid" and that is the primary key for the signing key that signed this package (excluded from the previous code): ``` Subkey: BDEBB6A52F156FDF3168D91119395F23C58826C4 Invalid: The certificate is not live: The primary key is not live, because Expired on 2026-07-11T19:00:04Z Public-key algo: RSA Public-key size: 4096 bits Creation time: 2015-08-08 23:05:35 UTC Expiration time: 2026-07-11 19:00:01 UTC (creation time + 10years 11months 2days 11h 44m 50s) Key flags: signing ``` The "invalid" here means that its not valid for signing new data, I think. Verification of historic data is different thing. > I don't know what in fedpkg prep makes the signature valid here. Something in the macro? A date that is set by fedpkg? An flag passed to sqv? sequoia behaviour changed (in our package or upstream)? Nothing in fedpkg/openpgpverify. It verifies with pure sqv: ``` $ sqv --keyring robbat2.gpg radvd-2.21.tar.xz --signature-file radvd-2.21.tar.xz.asc -v 7D0B3CEBE9B85B1F825BCECFEE05E6F6A48F6136 1 of 1 signatures are valid (threshold is: 1). ``` This is mostly Sequoia interpretation of the RFC 9580 (and RFC 4880 before it) and I find it quite sensible approach. The RFC really describes the data format and leaves the exact verification algorithm to the implementations. |