Page MenuHome GnuPG

Expiration dates after 2107 are reported as wraparound expiration dates
Closed, WontfixPublic


The OpenPGP standard lets users create an expiration date that is greater than 2^32 seconds after the unix epoch, because the expiration date is a 32-bit offset from the creation date.

gpg appears to count the expiration date internally as a 32-bit offset from the unix epoch, which means that

is seen as expiring in 1971, when it should be in February 2108.

Here is a message signed by this key:

gpgv claims EXPKEYSIG and KEYEXPIRED here, despite the future expiration date.



Event Timeline

This is a problem for gpgv and gpg as well. gpg reports:

pub   ed25519 2020-01-28 [SC] [expired: 1971-12-26]
uid           [ expired] Test User <>
werner claimed this task.
werner added a subscriber: werner.

I don't care; encryption won't work for us 6ft under. (This is a protocol problem which someone should address in a couple of decades)

This is not a problem for 2107 (when you and i are 6 feet under). it's a problem well before then for anything that has an expiration date of 2107 or later (as demonstrated by the legitimate example certificate here today).

FWIW, it's not a protocol problem either, the protocol permits expiration dates up to 2242 (although creation dates only up to 2106). other OpenPGP implementations don't have the failure demonstrated with this certificate and message signature.

But ok, i will not ask GnuPG to fix this any longer.

We briefly talked in the OpenPGP WG about the u32 problem and agreed that this is not an issue for 2440bis. The mismatch between creation date and expiration period is one of those minor PGP flaws. PGP-2 even used days to specify the expiration period.

This issue, as well as T4766 has the challenge that there is a disagreement about the usefulness of the use case, as far as I can see.

To me an expiration date that is more than 20 years in the future does not make sense as the conservative estimations
(like the the TR-02102-1 of the BSI, see do not see a way to estimate security of the algorithms
beyond 6-7 years. So no pubkey meant for actual use should have an expiration key beyond 2106. At least I cannot see the use case.

So I can understand the current status as "won't fix", for this technical issue, until on a wider scale the use cases and their importance are discussed. So if this is still import to you @dkg or somebody else, please elaborate on the use case importance on a good place, maybe on the working group or on a public mailinglist.

I agree with you that a certificate with a lengthy expiration is not cryptographically sensible or wise, @bernhard -- i'd never want to produce such a certificate myself.

However, the fun of writing communications tools is that you get to deal with objects that you don't produce yourself. So, how does the tool deal with objects that exceed sensible limits?

If GnuPG wants to impose those sorts of limits in a sensible way, we should have a frank discussion and construct a documented set of constraints that the implementation imposes deliberately. Those limits should not be based on architectural quirks (gpgme actually behaves differently on platforms with a 32-bit ulong than on platforms with a 64-bit ulong) or arbitrary timestamp choices that are unrelated to our current assessment of what reasonable limits are (rejecting an expiration date in Y2107 but accepting an expiration date of Y2105 today in 2020 doesn't make sense).

Obviously, some arbitrary timestamp choices are unavoidable, because they are imposed by the underlying data format -- X.509 can't handle dates after Y9999, and OpenPGP can't handle creation dates after Y2106 or expiration dates after Y2242. Interoperable implementations will all be bound by the limits of the data formats. But they won't be bound by the same arbitrary software choices. So yes: impose sensible limits, but document the choice and its motivation so that interoperable implementations know what to expect.

Furthermore, the action of disabling a feature on an object that falls outside these sensible limits should be something comprehensible and well-motivated, for example:

  • "we are going to ignore expiration dates greater than N years from creation" or
  • "we are going to treat expiration dates greater than N years from creation as N years from creation".

And, if a limit is exceeded, the implementation should produce an understandable warning that the reader can use as feedback to whatever system produces the unwise objects.

The treatment of a certificate with out-of-bounds values should *not* be to silently "wrap around" such that an expiration date explicitly designated as 2107 is instead treated as an expiration date in 1971.

@dkg while I agree with your aim of

impose sensible limits, but document the choice and its motivation so that interoperable implementations know what to expect.

this still is a nice to have feature for an implementation to act with checks, consistency, warnings and explanations if it is fed data that is not coming from a realistic use case.

Okay, this is a more general question of how much code and development efforts should be spend on defensive measures. There is the situation for some implementations that there is too little of these defensive measureas, but the more interesting case is, if there is too much. Think about the situation if much code and effort goes on data which is far outside the intended use case, that is extra code which makes it more heavy with potential more defects and harder to read, then there is the effort that may be missing on more important points which are important for real use cases.

However, this is not the right place to discuss. It is archived, which is good. On the other hand, we do not reach a lot of people in the GnuPG-Dev scene and it is a general topic.

Thanks for your working towards making GnuPG better, it is well appreciated even if we seem to have a different opinion on this particular point. :)