Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses wraparound/overflow in X.509 certificate validity time handling by introducing a custom clock type (ccf::ds::EpochClock) which tracks seconds since epoch, avoiding std::chrono::system_clock’s nanosecond-range limits when parsing externally-sourced cert timestamps.
Changes:
- Add
ccf::ds::EpochClockand switch X.509 time parsing/formatting helpers to use it for parsed time points. - Update verifier APIs and OpenSSL wrappers to accept/use
EpochClock::time_pointfor validity calculations. - Add unit and e2e tests covering long-lived and far-future certificate validity periods.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/js-custom-authorization/custom_authorization.py | Adds e2e coverage for long-lived and far-future cert validity handling. |
| src/crypto/test/crypto.cpp | Adds bounds-focused unit tests and migrates relevant tests to EpochClock. |
| src/crypto/openssl/verifier.h | Updates verifier method signatures to take EpochClock::time_point. |
| src/crypto/openssl/verifier.cpp | Updates implementations to match the new EpochClock-based API. |
| include/ccf/ds/x509_time_fmt.h | Changes parsed time-point type to EpochClock and adds formatting overloads. |
| include/ccf/ds/epoch_clock.h | Introduces the new seconds-based clock abstraction. |
| include/ccf/crypto/verifier.h | Updates public verifier interface to use EpochClock for time-based queries. |
| include/ccf/crypto/openssl/openssl_wrappers.h | Updates Unique_X509_TIME constructor to accept EpochClock::time_point. |
Comments suppressed due to low confidence (1)
src/crypto/openssl/verifier.cpp:216
remaining_seconds()returnssize_tbutduration_cast<seconds>(tp_to - now).count()can be negative for expired certs; converting that tosize_twill underflow to a huge value. Consider clamping at 0 (or returning a signed type) before converting tosize_t.
size_t Verifier_OpenSSL::remaining_seconds(
const ccf::ds::EpochClock::time_point& now) const
{
auto [from, to] = validity_period();
auto tp_to = ccf::ds::time_point_from_string(to);
return std::chrono::duration_cast<std::chrono::seconds>(tp_to - now)
.count() +
1;
achamayou
reviewed
Feb 9, 2026
achamayou
approved these changes
Feb 9, 2026
achamayou
approved these changes
Feb 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spotted some wraparound issues with our time-point parsing code. We use
std::system_clock, which usesint64to store nanoseconds from 1970. As such, the range of representable time points is surprisingly perceivable:This specifically causes problems for certs with Not-Before or Not-After timestamps a few hundred years away - if they're after 2262, they wrap around and we get bugs.
This includes some new tests, in both crypto unit test and e2e cert auth, that exhibit these bugs.
There's also a proposed fix, shifting to trackingsecondsrather thanstd::system_clock::time_points. This has a little more churn on the implementation than I'd like, so I'll also explore just defining our own clock type.We fix this with minimal churn by defining a new clock type -
ccf::ds::EpochClock, tracking seconds rather than nanoseconds. Note that we still usesystem_clockin many places, primarily for::now(). I say that's fine - we can correctly convert betweensystem_clockandEpochClockfor every time withinsystem_clock's bounds, which should include every value returned fromnow(). We only useEpochClockwhen we're consuming cert validity times, that are externally sourced and may well be hundreds of years in the future.