Bug 2532553

Summary: Consider proper handling of expired signing keys in openpgpverify
Product: [Fedora] Fedora Reporter: Ben Beasley <code>
Component: openpgpverifyAssignee: Jakub Jelen <jjelen>
Status: CLOSED NOTABUG QA Contact:
Severity: medium Docs Contact:
Priority: unspecified    
Version: rawhideCC: 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 tried migrating the cairomm1.16 package from gpgverify to openpgpverify following the current guidelines at https://docs.fedoraproject.org/en-US/packaging-guidelines/#_verifying_signatures, but %{openpgpverify} failed because the signing key had expired:

Signing key on 6CB445A816504714AA4962579EBA155FCC12D2C0 is bad:
           The primary key is not live
  because: Expired on 2022-09-08T14:11:17Z
0 of 1 signatures are valid (threshold is: 1).
openpgpverify: Signature verification failed.

The same signature is accepted by %{gpgverify}.

Now, it’s very easy to say that we should not accept expired keys for source signature verification: after all, that’s the purpose of expiration. The problem is that this means every source RPM that verifies its sources becomes a ticking FTBFS time-bomb: it will break at some point no matter what, even though nothing has changed about the inputs.

Worse, keys often expire on timelines shorter than Fedora release cycles, and certainly shorter than RHEL/EPEL lifecycles. Furthermore, the projects that sign source archives in the first place tend to be the ones that are highly mature and slow-moving. In these projects, the latest release will often be old enough that the key used to sign it has already expired.

It’s worth pointing out that packages randomly starting to FTBFS in stable releases is a real headache, and that in most cases the only fix will be to disable signature verification entirely. Asking upstreams to regularly re-sign old releases with new keys is not likely to get very far, and having to repeatedly modify downstream packaging in stable branches is a lot to ask of downstream package maintainers in any case.

Please consider whether the %{openpgpverify} macro should (if feasible) skip checking for signing key expiry, or perhaps (again, if feasible) implement some middle ground like only refusing signing keys that expired before the source archive’s mtime.

Reproducible: Always

Comment 1 Fabio Valentini 2026-09-12 10:01:32 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.

Comment 2 Michael J Gruber 2026-09-12 13:41:59 UTC
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.

Comment 3 Jakub Jelen 2026-10-08 13:15:13 UTC
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).
```

Comment 4 Ben Beasley 2026-10-09 13:19:47 UTC
(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.

Comment 5 Michael J Gruber 2026-10-09 14:46:14 UTC
(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.

Comment 6 Jakub Jelen 2026-10-12 11:03:18 UTC
> 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.