From 172775601ee413e6a97bc850ff195a87b6fc7902 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 1 Aug 2023 23:03:46 -0400 Subject: [PATCH] Add utilities for converting CATValues to/from NSSet. (#28453) * Add utilities for converting CATValues to/from NSSet. * Address review comments. * Address more review comments. --- src/darwin/Framework/CHIP/MTRConversion.h | 8 +++ src/darwin/Framework/CHIP/MTRConversion.mm | 61 +++++++++++++++++++ .../Framework/CHIP/MTRDeviceController.mm | 23 ++----- .../CHIP/MTRDeviceControllerStartupParams.mm | 9 +-- .../CHIP/MTROperationalCredentialsDelegate.mm | 6 +- .../Matter.xcodeproj/project.pbxproj | 4 ++ 6 files changed, 81 insertions(+), 30 deletions(-) create mode 100644 src/darwin/Framework/CHIP/MTRConversion.mm diff --git a/src/darwin/Framework/CHIP/MTRConversion.h b/src/darwin/Framework/CHIP/MTRConversion.h index 53225a690e2070..5932ff88bf597b 100644 --- a/src/darwin/Framework/CHIP/MTRConversion.h +++ b/src/darwin/Framework/CHIP/MTRConversion.h @@ -19,6 +19,8 @@ #import +#include +#include #include #include #include @@ -38,4 +40,10 @@ inline NSDate * ChipEpochSecondsAsDate(uint32_t chipEpochSeconds) return [NSDate dateWithTimeIntervalSince1970:(chip::kChipEpochSecondsSinceUnixEpoch + (NSTimeInterval) chipEpochSeconds)]; } +/** + * Utilities for converting between NSSet and chip::CATValues. + */ +CHIP_ERROR SetToCATValues(NSSet * catSet, chip::CATValues & values); +NSSet * CATValuesToSet(const chip::CATValues & values); + NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRConversion.mm b/src/darwin/Framework/CHIP/MTRConversion.mm new file mode 100644 index 00000000000000..77882742dea3e7 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRConversion.mm @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "MTRConversion.h" +#import "MTRLogging_Internal.h" + +#include + +CHIP_ERROR SetToCATValues(NSSet * catSet, chip::CATValues & values) +{ + values = chip::kUndefinedCATs; + + unsigned long long tagCount = catSet.count; + if (tagCount > chip::kMaxSubjectCATAttributeCount) { + MTR_LOG_ERROR("%llu CASE Authenticated Tags cannot be represented in a certificate.", tagCount); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + size_t tagIndex = 0; + for (NSNumber * boxedTag in [catSet.allObjects sortedArrayUsingSelector:@selector(compare:)]) { + auto unboxedTag = boxedTag.unsignedLongLongValue; + if (!chip::CanCastTo(unboxedTag)) { + MTR_LOG_ERROR("0x%llx is not a valid CASE Authenticated Tag value.", unboxedTag); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + auto tag = static_cast(unboxedTag); + if (!chip::IsValidCASEAuthTag(tag)) { + MTR_LOG_ERROR("0x%" PRIx32 " is not a valid CASE Authenticated Tag value.", tag); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + values.values[tagIndex++] = tag; + } + + return CHIP_NO_ERROR; +} + +NSSet * CATValuesToSet(const chip::CATValues & values) +{ + auto * catSet = [[NSMutableSet alloc] initWithCapacity:values.GetNumTagsPresent()]; + for (auto & value : values.values) { + if (value != chip::kUndefinedCAT) { + [catSet addObject:@(value)]; + } + } + return [NSSet setWithSet:catSet]; +} diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 8b34769b09ecea..cf4ab4c068d465 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -22,6 +22,7 @@ #import "MTRCommissionableBrowser.h" #import "MTRCommissionableBrowserResult_Internal.h" #import "MTRCommissioningParameters.h" +#import "MTRConversion.h" #import "MTRDeviceControllerDelegateBridge.h" #import "MTRDeviceControllerFactory_Internal.h" #import "MTRDeviceControllerStartupParams.h" @@ -312,27 +313,11 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams chip::CATValues cats = chip::kUndefinedCATs; if (startupParams.caseAuthenticatedTags != nil) { - unsigned long long tagCount = startupParams.caseAuthenticatedTags.count; - if (tagCount > chip::kMaxSubjectCATAttributeCount) { - MTR_LOG_ERROR("%llu CASE Authenticated Tags cannot be represented in a certificate.", tagCount); + errorCode = SetToCATValues(startupParams.caseAuthenticatedTags, cats); + if (errorCode != CHIP_NO_ERROR) { + // SetToCATValues already handles logging. return; } - - size_t tagIndex = 0; - for (NSNumber * boxedTag in startupParams.caseAuthenticatedTags) { - if (!chip::CanCastTo(boxedTag.unsignedLongLongValue)) { - MTR_LOG_ERROR("0x%llx is not a valid CASE Authenticated Tag value.", boxedTag.unsignedLongLongValue); - return; - } - - auto tag = static_cast(boxedTag.unsignedLongLongValue); - if (!chip::IsValidCASEAuthTag(tag)) { - MTR_LOG_ERROR("0x%" PRIx32 " is not a valid CASE Authenticated Tag value.", tag); - return; - } - - cats.values[tagIndex++] = tag; - } } if (commissionerParams.operationalKeypair != nullptr) { diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm index 771995bf01bc66..ca92c63bf2171b 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.mm @@ -16,6 +16,7 @@ #import "MTRDeviceControllerStartupParams.h" #import "MTRCertificates.h" +#import "MTRConversion.h" #import "MTRDeviceControllerStartupParams_Internal.h" #import "MTRLogging_Internal.h" #import "MTRP256KeypairBridge.h" @@ -302,13 +303,7 @@ - (instancetype)initForExistingFabric:(FabricTable *)fabricTable auto tagCount = cats.GetNumTagsPresent(); if (tagCount > 0) { - auto * catSet = [[NSMutableSet alloc] initWithCapacity:tagCount]; - for (auto & value : cats.values) { - if (value != kUndefinedCAT) { - [catSet addObject:@(value)]; - } - } - self.caseAuthenticatedTags = [NSSet setWithSet:catSet]; + self.caseAuthenticatedTags = CATValuesToSet(cats); } else { self.caseAuthenticatedTags = nil; } diff --git a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm index 7e5282eca51a52..159e772838258c 100644 --- a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm +++ b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm @@ -22,6 +22,7 @@ #import #import "MTRCertificates.h" +#import "MTRConversion.h" #import "MTRDeviceController_Internal.h" #import "MTRLogging_Internal.h" #import "NSDataSpanConversion.h" @@ -469,10 +470,7 @@ uint64_t GetIssuerId(NSNumber * _Nullable providedIssuerId) CATValues cats; if (caseAuthenticatedTags != nil) { - size_t idx = 0; - for (NSNumber * cat in [caseAuthenticatedTags.allObjects sortedArrayUsingSelector:@selector(compare:)]) { - cats.values[idx++] = [cat unsignedIntValue]; - } + ReturnErrorOnFailure(SetToCATValues(caseAuthenticatedTags, cats)); } uint8_t nocBuffer[Controller::kMaxCHIPDERCertLength]; diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index fea8bd9966ac2a..93d491bf23ac1f 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -154,6 +154,7 @@ 51431AF927D2973E008A7943 /* MTRIMDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51431AF827D2973E008A7943 /* MTRIMDispatch.mm */; }; 51431AFB27D29CA4008A7943 /* ota-provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51431AFA27D29CA4008A7943 /* ota-provider.cpp */; }; 5143851E2A65885500EDC8E6 /* MTRSwiftPairingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5143851D2A65885500EDC8E6 /* MTRSwiftPairingTests.swift */; }; + 51565CAE2A79D42100469F18 /* MTRConversion.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51565CAD2A79D42100469F18 /* MTRConversion.mm */; }; 515C1C6F284F9FFB00A48F0C /* MTRFramework.mm in Sources */ = {isa = PBXBuildFile; fileRef = 515C1C6D284F9FFB00A48F0C /* MTRFramework.mm */; }; 515C1C70284F9FFB00A48F0C /* MTRFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 515C1C6E284F9FFB00A48F0C /* MTRFramework.h */; }; 51669AF02913204400F4AA36 /* MTRBackwardsCompatTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 51669AEF2913204400F4AA36 /* MTRBackwardsCompatTests.m */; }; @@ -458,6 +459,7 @@ 51431AFA27D29CA4008A7943 /* ota-provider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "ota-provider.cpp"; path = "clusters/ota-provider/ota-provider.cpp"; sourceTree = ""; }; 5143851C2A65885400EDC8E6 /* MatterTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MatterTests-Bridging-Header.h"; sourceTree = ""; }; 5143851D2A65885500EDC8E6 /* MTRSwiftPairingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTRSwiftPairingTests.swift; sourceTree = ""; }; + 51565CAD2A79D42100469F18 /* MTRConversion.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRConversion.mm; sourceTree = ""; }; 515C1C6D284F9FFB00A48F0C /* MTRFramework.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRFramework.mm; sourceTree = ""; }; 515C1C6E284F9FFB00A48F0C /* MTRFramework.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRFramework.h; sourceTree = ""; }; 51669AEF2913204400F4AA36 /* MTRBackwardsCompatTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTRBackwardsCompatTests.m; sourceTree = ""; }; @@ -1025,6 +1027,7 @@ 51E030FE27EA20D20083DC9C /* MTRControllerAccessControl.h */, 51E030FF27EA20D20083DC9C /* MTRControllerAccessControl.mm */, 3DFCB32B29678C9500332B35 /* MTRConversion.h */, + 51565CAD2A79D42100469F18 /* MTRConversion.mm */, 3CF134A6289D8AD90017A19E /* MTRCSRInfo.h */, 3CF134A8289D8D800017A19E /* MTRCSRInfo.mm */, 3DECCB732934C21B00585AEC /* MTRDefines.h */, @@ -1500,6 +1503,7 @@ 1ED276E226C5812A00547A89 /* MTRCluster.mm in Sources */, B2E0D7B3245B0B5C003C5B48 /* MTRError.mm in Sources */, 51E51FC1282AD37A00FC978D /* MTRDeviceControllerStartupParams.mm in Sources */, + 51565CAE2A79D42100469F18 /* MTRConversion.mm in Sources */, 1ED276E026C57CF000547A89 /* MTRCallbackBridge.mm in Sources */, 517BF3F1282B62B800A8B7DB /* MTRCertificates.mm in Sources */, 5A6FEC9627B5983000F25F42 /* MTRDeviceControllerXPCConnection.mm in Sources */,