gpgme_signature_t relies on `unsigned long` for signature creation and expiration times
Closed, WontfixPublic

Description

the C specification only requires that long be at least 32 bits wide.

On a platform where unsigned long is a 32-bit integer, this cannot represent values larger than 2106-02-07 06:28:16 UTC. This means that (for example) a signature due to expire 87 years from today will be unrepresentable on such a platform (or, perhaps more troublingly, will appear to have an expiration date in the past).

I have no examples of such a signature to point to today, but 32 bit platforms have proved remarkably persistent, and some might still be relevant at a time when they could plausibly encounter a 2106 expiration date.

I'm not sure of the right way to fix this, since fixing it properly will likely be both an API and an ABI change in GPGME.

For the OpenPGP engine for GPGME, this is irrelevant for creation times, because they are bound to 4 byte unsigned integers in the first place. But it is still relevant for expiration time markers: both Key Expiration Time and Signature Expiration Time subpackets are *offsets* from their corresponding creation time subpackets. So the computed expiration value can surpass 2^32 seconds since the epoch.

For the CMS engine for GPGME, this is relevant because CMS "validAfter" and "validBefore" times are typically represented as a GeneralizedTime object, which can represent up to the year 9999.

I can create objects that have values in the relevant time regions if having a test case would help to resolve the matter.

dkg created this task.Dec 4 2019, 3:52 AM
werner closed this task as Wontfix.Dec 4 2019, 8:51 AM
werner claimed this task.
werner added a subscriber: werner.

We will run into all kind of problems after 2038 on 32 bit boxes. 2106 is nothing to care about.

dkg added a comment.Dec 4 2019, 4:42 PM

The most plausible fix to the Y2K38 problem on 32-bit machines is to simply move to a 64-bit time_t at the same time as any other major system-wide ABI break. However, if that ABI break doesn't also change the size of long to more than 32 bits, GPGME will remain unfixed in spite of any architectural correction.

Furthermore, the trouble with expiration dates is that we will run into the problems well before we hit the overflow time. In particular, expiration dates set in the distant future may wrap around to a low value, making them invalid even though we are not even close to the overflow time.

In other words, this is not a problem that is going to hit in 2106 or 2038. It is going to hit at any time before then for people using GPGME on selected platforms, depending on the choice of expiration dates made by other people (who may not share the same platform choices, and so may not notice the breakage).

dkg added a comment.Dec 6 2019, 10:31 PM

fwiw, ensuring that overflow for either field results in ULONG_MAX (rather than wrapping around) would go a long way toward this problem being something that we can reasonably put off for another 50 years.

dkg reopened this task as Open.Jan 28 2020, 11:43 PM

I'm reopening this because i think users of these 32-bit platforms are going to run into issues before 2038 happens. Certs could appear expired before they are actually expired, for example, because of the wraparound time.

All the 32-bit platforms in debian are failing a simple test that i wrote to check this situation.

dkg added a comment.Jan 28 2020, 11:45 PM

I don't mind a workaround that avoids an ABI/API fix as long as it defers actual failures until 2038.

For example, verifying that overflow in creation or expiration times should result in ULONG_MAX would be a fine workaround.

dkg added a comment.Jan 29 2020, 12:35 AM
-----BEGIN PGP PUBLIC KEY BLOCK-----

xjMEXjDE0hYJKwYBBAHaRw8BAQdAqsnZTGgZJ9AXtkh6B1J5mUkyGVk23H0p6dj1
mqnjZ6bNHFRlc3QgVXNlciA8dGVzdEBleGFtcGxlLmNvbT7CigQTFggAMgUCXjDE
0gIbAQUJpWB/rQIVCAIXgAIZAQIeARYhBBMAmwFhhdPRleVAtvo53XnrTpdPAAoJ
EPo53XnrTpdP454A/AmeHjQPQ5j7AT18qaoJZiD2UYoS5Vz20TXI5fpFnfuiAP9O
rXXPJs6rmF/mIFYDxhx3w5auq7ZlxNxjaSK0eRZhDA==
=HjDI
-----END PGP PUBLIC KEY BLOCK-----

The OpenPGP certificate above should expire at the end of 2107.

dkg added a comment.Jan 29 2020, 12:38 AM
-----BEGIN PGP PRIVATE KEY BLOCK-----

xVgEXjDE0hYJKwYBBAHaRw8BAQdAqsnZTGgZJ9AXtkh6B1J5mUkyGVk23H0p6dj1
mqnjZ6YAAQCiziuw2X9WxZ7VHsdFD/W99AVw3tRGe2BsZTdpN81INRBLzRxUZXN0
IFVzZXIgPHRlc3RAZXhhbXBsZS5jb20+wooEExYIADIFAl4wxNICGwEFCaVgf60C
FQgCF4ACGQECHgEWIQQTAJsBYYXT0ZXlQLb6Od15606XTwAKCRD6Od15606XT+Oe
APwJnh40D0OY+wE9fKmqCWYg9lGKEuVc9tE1yOX6RZ37ogD/Tq11zybOq5hf5iBW
A8Ycd8OWrqu2ZcTcY2kitHkWYQw=
=Snqi
-----END PGP PRIVATE KEY BLOCK-----

This should contain the corresponding secret key material. You can try verifying certifications made with this key.

dkg added a comment.EditedJan 29 2020, 1:01 AM

It looks like at least for OpenPGP, the layer below GPGME is also broken for expiration dates in this time window (see T4826)

dkg closed this task as Wontfix.Jan 29 2020, 3:44 PM

Changing back to wontfix given the wontfix resolution of T4826

bernhard added a subscriber: bernhard.

Just added a comment to T4826 how to move forward, if this is still interesting for parties. Right now (from my point of view) a pubkey with an expiration date beyond 2106 is not a sensible key configuration, so the use to motivate a chance in this area would need to be argumented better.