From e7915eaa69ec5fcdd07c7ca891f4afd19c272aa3 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 13 Jul 2022 07:05:50 -0400 Subject: [PATCH] Fix validity times on certificates issued by the Darwin framework. (#20637) The Darwin framework was using the current timezone, not UTC, when determining the Matter epoch time corresponding to a given offset from now. This caused the epoch times it computed to be off by the offset from UTC. In timezones ahead of UTC, this could easily lead to certificates with mNotBeforeTime set to a value larger than the current UTC time, which would then cause those certificates to be considered not-yet-valid. Fixes https://github.com/project-chip/connectedhomeip/issues/20302 --- src/credentials/CHIPCert.cpp | 6 ++++++ .../Framework/CHIP/MTROperationalCredentialsDelegate.mm | 4 +--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/credentials/CHIPCert.cpp b/src/credentials/CHIPCert.cpp index 7f11430cd2a634..8dd1a9797d13ed 100644 --- a/src/credentials/CHIPCert.cpp +++ b/src/credentials/CHIPCert.cpp @@ -384,11 +384,15 @@ CHIP_ERROR ChipCertificateSet::ValidateCert(const ChipCertificateData * cert, Va { if (context.mEffectiveTime.Get().count() < cert->mNotBeforeTime) { + ChipLogDetail(SecureChannel, "Certificate's mNotBeforeTime (%" PRIu32 ") is after current time (%" PRIu32 ")", + cert->mNotBeforeTime, context.mEffectiveTime.Get().count()); validityResult = CertificateValidityResult::kNotYetValid; } else if (cert->mNotAfterTime != kNullCertTime && context.mEffectiveTime.Get().count() > cert->mNotAfterTime) { + ChipLogDetail(SecureChannel, "Certificate's mNotAfterTime (%" PRIu32 ") is before current time (%" PRIu32 ")", + cert->mNotAfterTime, context.mEffectiveTime.Get().count()); validityResult = CertificateValidityResult::kExpired; } else @@ -407,6 +411,8 @@ CHIP_ERROR ChipCertificateSet::ValidateCert(const ChipCertificateData * cert, Va // certificate in question is expired. Check for this. if (cert->mNotAfterTime != 0 && context.mEffectiveTime.Get().count() > cert->mNotAfterTime) { + ChipLogDetail(SecureChannel, "Certificate's mNotAfterTime (%" PRIu32 ") is before last known good time (%" PRIu32 ")", + cert->mNotAfterTime, context.mEffectiveTime.Get().count()); validityResult = CertificateValidityResult::kExpiredAtLastKnownGoodTime; } else diff --git a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm index 8b703e4b317b9b..3688c9a08f7433 100644 --- a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm +++ b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm @@ -172,10 +172,8 @@ bool MTROperationalCredentialsDelegate::ToChipEpochTime(uint32_t offset, uint32_t & epoch) { NSDate * date = [NSDate dateWithTimeIntervalSinceNow:offset]; - unsigned units = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute - | NSCalendarUnitSecond; NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; - NSDateComponents * components = [calendar components:units fromDate:date]; + NSDateComponents * components = [calendar componentsInTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0] fromDate:date]; uint16_t year = static_cast([components year]); uint8_t month = static_cast([components month]);