Login
You're viewing the front-end.social public feed.
  • Feb 2, 2024, 4:29 PM

    @shortridge While working tech support, I got a call on a Monday. Some VPNs which had been working on Friday were no longer working. After a little digging, we found the negotiation was failing due to a certificate validation failure.

    The certificate validation was failing because the system couldn’t check the certificate revocation list (CRL).

    The system couldn’t check the CRL because it was too big. The software doing the validation only allocated 512kB to store the CRL, and it was bigger than that. This is from a private certificate authority, though, and 512kB is a *LOT* of revoked certificates. Shouldn’t be possible for this environment to hit within a human lifespan.

    Turns out the CRL was nearly a megabyte! What gives? We check the certificate authority, and it’s revoking and reissuing every single certificate it has signed once per second.

    The revocations say all the certificates (including the certificate authority’s) are expired. We check the expiration date of the certificate authority, and it’s set to some time in 1910. What? It was around here I started to suspect what had happened.

    The certificate authority isn’t valid before some time in 2037. It was waking up every second, seeing the current date was after the expiration date and reissuing everything. But time is linear, so it doesn’t make sense to reissue an expired certificate with an earlier not-valid-before date, so it reissued all the certs with the same dates and went to sleep. One second later, it woke up and did the whole process over again. But why the clearly invalid dates on the CA?

    The CA operation log was packed with revocations and reissues, but I eventually found the reissues which changed the validity dates of the CA’s certificate. Sure enough, it reissued itself in 2037 and the expiration date was set to 2037 plus ten years, which fell victim to the 2038 limitation. But it’s not 2037, so why did the system think it was?

    The OS running the CA was set to sync with NTP every 120 seconds, and it used a really bad NTP client which blindly set the time to whatever the NTP server gave it. No sanity checking, no drifting. Just get the time, set the time. OS logs showed most of the time, the clock adjustment was a fraction of a second. Then some time on Saturday, there was an adjustment of tens of thousands of seconds forward. The next adjustment was hundreds of thousands of seconds forward. Tens of millions of seconds forward. Eventually it hit billions of seconds backwards, taking the system clock back to 1904 or so. The NTP server was racing forward through the 32-bit timestamp space.

    At some point, the NTP server handed out a date in 2037 which was after the CA’s expiration. It reissued itself as I described above, and a date math bug resulted in a cert which expired before it was valid. So now we have an explanation for the CRL being so huge. On to the NTP server!

    Turns out they had an NTP “appliance” with a radio clock (i.e, a CDMA radio, GPS receiver, etc.). Whoever built it had done so in a really questionable way. It seems it had a faulty internal clock which was very fast. If it lost upstream time for a while, then reacquired it after the internal clock had accumulated a whole extra second, the server didn’t let itself step backwards or extend the duration of a second. The math it used to correct its internal clock somehow resulted in dramatically shortening the duration of a second until it wrapped in 2038 and eventually ended up at the correct time.

    Ultimately found three issues:
    • An OS with an overly-simplistic NTP client
    • A certificate authority with a bad date math system
    • An NTP server with design issues and bad hardware

    Edit: The popularity of this story has me thinking about it some more.

    The 2038 problem happens because when the first bit of a 32-bit value is 1 and you use it as a signed integer, it’s interpreted as a negative number in 2’s complement representation. But C has no protection from treating the same value as signed in some contexts and unsigned in others. If you start with a signed 32-bit integer with the value -1, it is represented in memory as 0xFFFFFFFF. If you then use it as an unsigned integer, it becomes the value 4,294,967,296.

    I bet the NTP box subtracted the internal clock’s seconds from the radio clock’s seconds as signed integers (getting -1 seconds), then treated it as an unsigned integer when figuring out how to adjust the tick rate. It suddenly thought the clock was four billion seconds behind, so it really has to sprint forward to catch up!

    In my experience, the most baffling behavior is almost always caused by very small mistakes. This small mistake would explain the behavior.

    💬 5🔄 448⭐ 635

Replies

  • 💬 1🔄 0⭐ 0
  • Feb 3, 2024, 3:16 AM

    @shortridge Right? It was such a weird sequence of failures.

    Recovery was very painful. Without the VPN connections working, they needed someone to physically go to around a hundred sites and get each one to trust the new CA. It also ended up happening a few times before everything could be fixed.

    💬 0🔄 0⭐ 0
  • 💬 1🔄 0⭐ 0
  • Feb 3, 2024, 5:08 AM

    @dannotdaniel @shortridge At the time, I was the last level of support on a team which was the catch-all for issues which didn’t fall into another team’s specific area of responsibility. We got all the weird problems with random areas of the company’s products which maybe five people worldwide used. We also got all the problems which confounded people at the earlier levels. It was systems programming *and* top-tier sysadmin work rolled into one.

    I miss some aspects of that job, but it was mostly horrible. Every time I catch myself romanticizing it and thinking about going back, I remind myself that while chasing that particular issue, I was paid barely above poverty-level.

    💬 0🔄 0⭐ 0
  • 💬 0🔄 0⭐ 0
  • Feb 3, 2024, 5:26 AM

    @bob_zim @shortridge is it not also a bug to be revoking certificates that are expired? It wouldn't fix the NTP bug or the constant reissuance, but it would keep the CRL small. (And rfx5280 doesn't even have a crl reason code for "already expired", so what reason code was set in the CRL?)

    💬 1🔄 0⭐ 0
  • Feb 3, 2024, 1:30 PM

    @asg @shortridge I don’t remember if I even looked at the CRL itself in great detail. I was focused on the CA operation log. Might have been intended as a security measure on expiration of the CA. Might also have been a bug.

    💬 0🔄 0⭐ 0
  • Feb 3, 2024, 9:33 AM

    @bob_zim @shortridge @xssfox

    reminds me of a new-deployment airgapped site where all the clients had their clocks wrong by ~11h:40s and the customer (who provided the network our gear was on) was not happy. ok, so clients ntp from our server, and our server also has bad time. our server ntps from the site ntp server, which is also wrong. customer claims this is impossible. 11h40s is a really weird error. 11h is the TZ offset, but that shouldn’t turn into an end-user visible local time error. and there’s the 40s on top.

    had enough access to the part of the machine room to see the appliance ntp server, which (being airgapped) pulled time from GPS. but, there were a bunch of SMAs on the back with nothing plugged into ‘em. networking vendor installed the NTP server and forgot to attach the antennas, but set the (utc) time from his watch, hence the almost but not quite exactly TZ-sized error.

    💬 1🔄 2⭐ 0
  • Feb 3, 2024, 1:50 PM

    @rfc6919 @bob_zim @shortridge @xssfox nothing as elaborate as that, but as a gradual student at Rice, our connection to the internet was via a 56kb link from a Fuzzball to UT-Sally.

    Problem #1 was device driver bug, if a packet was an exact match for the buffer size, driver would finish w/ a request for zero bytes, board DMA would decrement till zero, transfer a byte, repeat, clearing entire memory.

    Problem #2 was the day "someone" decided we were best route to seismo.gov. 56kb, recall.

    💬 1🔄 0⭐ 0
  • 💬 0🔄 0⭐ 0