From 6fc4beb89d2988e2e839a5f63e58929691354ffc Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 12 Dec 2022 16:39:04 -0500 Subject: [PATCH] Fix APIs involved in the MTROperationalCredentialsDelegate. (#23893) * Fix APIs involved in the MTROperationalCredentialsDelegate. * Rename CSRInfo to MTROperationalCSRInfo * Rename the properties of MTROperationalCSRInfo to match the spec more closely. * Rename AttestationInfo to MTRAttestationInfo. * Fix naming of the API on MTRDeviceController to follow conventions better, document the API more clearly, and have it return errors as needed. * Rename MTRNOCChainIssuer to MTROperationalCertificateIssuer * Change signature of the one method on MTROperationalCertificateIssuer to have better naming, take a controller, and name the completion block "completion". * Change the completion signature on MTROperationalCertificateIssuer to allow the external certificate issuer to return an error (e.g. if its device attestation checks failed). * Don't ask the external issuer for the IPK, since we should already have that anyway (from our controller init). * Allow the external issuer to return nil for the intermediate certificate, to indicate that there isn't one. * Make sure that all our access to mOnNOCCompletionCallback happens on the Matter queue, so we don't have thread races on that member. * Make all the dispatch we do as part of the credential-issuing process async. * Introduce backwards-compat shims for all the API changes for now. Fixes https://github.com/project-chip/connectedhomeip/issues/23439 * Address review comment. * Address review comments. --- .../Framework/CHIP/MTRAttestationInfo.h | 59 ++++++ .../Framework/CHIP/MTRAttestationInfo.mm | 26 +++ src/darwin/Framework/CHIP/MTRCSRInfo.h | 40 +++- src/darwin/Framework/CHIP/MTRCSRInfo.mm | 17 ++ src/darwin/Framework/CHIP/MTRDefines.h | 2 + .../Framework/CHIP/MTRDeviceController.h | 19 +- .../Framework/CHIP/MTRDeviceController.mm | 100 +++++++++- .../CHIP/MTRDeviceControllerStartupParams.h | 34 +++- src/darwin/Framework/CHIP/MTRNOCChainIssuer.h | 53 ------ .../CHIP/MTROperationalCertificateIssuer.h | 91 +++++++++ .../CHIP/MTROperationalCertificateIssuer.mm | 37 ++++ .../CHIP/MTROperationalCredentialsDelegate.h | 45 ++--- .../CHIP/MTROperationalCredentialsDelegate.mm | 180 +++++++++--------- src/darwin/Framework/CHIP/Matter.h | 2 +- .../Matter.xcodeproj/project.pbxproj | 12 +- 15 files changed, 513 insertions(+), 204 deletions(-) delete mode 100644 src/darwin/Framework/CHIP/MTRNOCChainIssuer.h create mode 100644 src/darwin/Framework/CHIP/MTROperationalCertificateIssuer.h create mode 100644 src/darwin/Framework/CHIP/MTROperationalCertificateIssuer.mm diff --git a/src/darwin/Framework/CHIP/MTRAttestationInfo.h b/src/darwin/Framework/CHIP/MTRAttestationInfo.h index a31c181b0daebd..74c89241d518cc 100644 --- a/src/darwin/Framework/CHIP/MTRAttestationInfo.h +++ b/src/darwin/Framework/CHIP/MTRAttestationInfo.h @@ -17,12 +17,71 @@ #import +#import +#import + NS_ASSUME_NONNULL_BEGIN /** * Represents information relating to product attestation. * */ +MTR_NEWLY_AVAILABLE +@interface MTRAttestationInfo : NSObject + +/** + * The attestation challenge from the secure session. + */ +@property (nonatomic, copy, readonly) NSData * challenge; +/** + * The attestation nonce from the AttestationRequest command. + */ +@property (nonatomic, copy, readonly) NSData * nonce; +/** + * The TLV-encoded attestation_elements_message that was used to find the + * certificationDeclaration and firmwareInfo. + */ +@property (nonatomic, copy, readonly) MTRTLVBytes elementsTLV; +/** + * A signature, using the device attestation private key of the device that sent + * the attestation information, over the concatenation of elementsTLV and the + * attestation challenge from the secure session. + */ +@property (nonatomic, copy, readonly) NSData * elementsSignature; +/** + * The device attestation certificate for the device. This can be used to + * verify signatures created with the device attestation private key. + */ +@property (nonatomic, copy, readonly) MTRCertificateDERBytes deviceAttestationCertificate; +/** + * The product attestation intermediate certificate that can be used to verify + * the authenticity of the device attestation certificate. + */ +@property (nonatomic, copy, readonly) MTRCertificateDERBytes productAttestationIntermediateCertificate; +/** + * The certification declaration of the device. This is a DER-encoded string + * representing a CMS-formatted certification declaration. + */ +@property (nonatomic, copy, readonly) NSData * certificationDeclaration; +/* + * Firmware information, if any, provided in the elementsTLV. The encoding of + * this is not currently specified, but if present this must match the + * Distributed Compliance Ledger entry for the device. + */ +@property (nonatomic, copy, readonly, nullable) NSData * firmwareInfo; + +- (instancetype)initWithChallenge:(NSData *)challenge + nonce:(NSData *)nonce + elementsTLV:(MTRTLVBytes)elementsTLV + elementsSignature:(NSData *)elementsSignature + deviceAttestationCertificate:(MTRCertificateDERBytes)deviceAttestationCertificate + productAttestationIntermediateCertificate:(MTRCertificateDERBytes)processAttestationIntermediateCertificate + certificationDeclaration:(NSData *)certificationDeclaration + firmwareInfo:(NSData *)firmwareInfo; + +@end + +MTR_NEWLY_DEPRECATED("Please use MTRAttestationInfo") @interface AttestationInfo : NSObject @property (nonatomic, copy) NSData * challenge; diff --git a/src/darwin/Framework/CHIP/MTRAttestationInfo.mm b/src/darwin/Framework/CHIP/MTRAttestationInfo.mm index 93b9483cce6fe0..7edfc38b114763 100644 --- a/src/darwin/Framework/CHIP/MTRAttestationInfo.mm +++ b/src/darwin/Framework/CHIP/MTRAttestationInfo.mm @@ -19,6 +19,32 @@ NS_ASSUME_NONNULL_BEGIN +@implementation MTRAttestationInfo : NSObject + +- (instancetype)initWithChallenge:(NSData *)challenge + nonce:(NSData *)nonce + elementsTLV:(MTRTLVBytes)elementsTLV + elementsSignature:(NSData *)elementsSignature + deviceAttestationCertificate:(MTRCertificateDERBytes)deviceAttestationCertificate + productAttestationIntermediateCertificate:(MTRCertificateDERBytes)productAttestationIntermediateCertificate + certificationDeclaration:(NSData *)certificationDeclaration + firmwareInfo:(NSData *)firmwareInfo +{ + if (self = [super init]) { + _challenge = challenge; + _nonce = nonce; + _elementsTLV = elementsTLV; + _elementsSignature = elementsSignature; + _deviceAttestationCertificate = deviceAttestationCertificate; + _productAttestationIntermediateCertificate = productAttestationIntermediateCertificate; + _certificationDeclaration = certificationDeclaration; + _firmwareInfo = firmwareInfo; + } + return self; +} + +@end + @implementation AttestationInfo : NSObject - (instancetype)initWithChallenge:(NSData *)challenge diff --git a/src/darwin/Framework/CHIP/MTRCSRInfo.h b/src/darwin/Framework/CHIP/MTRCSRInfo.h index 8971bfd6fbd294..f90c108e239c88 100644 --- a/src/darwin/Framework/CHIP/MTRCSRInfo.h +++ b/src/darwin/Framework/CHIP/MTRCSRInfo.h @@ -17,12 +17,50 @@ #import +#import + +typedef NSData * MTRCSRDERBytes; + NS_ASSUME_NONNULL_BEGIN /** - * Represents information relating to NOC CSR. + * Represents information relating to a certificate signing request for a Matter + * operational certificate. + */ +MTR_NEWLY_AVAILABLE +@interface MTROperationalCSRInfo : NSObject + +/** + * DER-encoded certificate signing request. + */ +@property (nonatomic, copy, readonly) MTRCSRDERBytes csr; +/** + * The nonce provided in the original CSRRequest command hat led to this CSR + * being created. + */ +@property (nonatomic, copy, readonly) NSData * csrNonce; +/** + * TLV-encoded nocsr-elements structure. This includes the "csr" and "csrNonce" + * fields, and can include additional vendor-specific information. + */ +@property (nonatomic, copy, readonly) MTRTLVBytes csrElementsTLV; +/** + * A signature, using the device attestation private key of the device that + * created the CSR, over the concatenation of csrElementsTLV and the attestation + * challenge from the secure session. * + * The attestation challenge is available in MTRAttestionInfo. */ +@property (nonatomic, copy, readonly) NSData * attestationSignature; + +- (instancetype)initWithCSR:(MTRCSRDERBytes)csr + csrNonce:(NSData *)csrNonce + csrElementsTLV:(MTRTLVBytes)csrElementsTLV + attestationSignature:(NSData *)attestationSignature; + +@end + +MTR_NEWLY_DEPRECATED("Please use MTROperationalCSRInfo") @interface CSRInfo : NSObject @property (nonatomic, copy) NSData * nonce; diff --git a/src/darwin/Framework/CHIP/MTRCSRInfo.mm b/src/darwin/Framework/CHIP/MTRCSRInfo.mm index 676aa1ed36e5b4..d8a77fba5e941a 100644 --- a/src/darwin/Framework/CHIP/MTRCSRInfo.mm +++ b/src/darwin/Framework/CHIP/MTRCSRInfo.mm @@ -19,6 +19,23 @@ NS_ASSUME_NONNULL_BEGIN +@implementation MTROperationalCSRInfo : NSObject + +- (instancetype)initWithCSR:(MTRCSRDERBytes)csr + csrNonce:(NSData *)csrNonce + csrElementsTLV:(MTRTLVBytes)csrElementsTLV + attestationSignature:(NSData *)attestationSignature; +{ + if (self = [super init]) { + _csr = csr; + _csrNonce = csrNonce; + _csrElementsTLV = csrElementsTLV; + _attestationSignature = attestationSignature; + } + return self; +} +@end + @implementation CSRInfo : NSObject - (instancetype)initWithNonce:(NSData *)nonce diff --git a/src/darwin/Framework/CHIP/MTRDefines.h b/src/darwin/Framework/CHIP/MTRDefines.h index 0751dda4011c77..80bfaaf5ff875b 100644 --- a/src/darwin/Framework/CHIP/MTRDefines.h +++ b/src/darwin/Framework/CHIP/MTRDefines.h @@ -24,3 +24,5 @@ #else #define MTR_EXTERN extern MTR_EXPORT #endif + +typedef NSData * MTRTLVBytes; diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.h b/src/darwin/Framework/CHIP/MTRDeviceController.h index 5bff3ebb76aaae..866c1999620052 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController.h @@ -17,7 +17,7 @@ #import -#import +#import @class MTRBaseDevice; @@ -127,20 +127,6 @@ typedef void (^MTRDeviceConnectionCallback)(MTRBaseDevice * _Nullable device, NS */ - (void)setDeviceControllerDelegate:(id)delegate queue:(dispatch_queue_t)queue MTR_NEWLY_AVAILABLE; -/** - * Sets this MTRDeviceController to use the given issuer for issuing operational certs. By default, the MTRDeviceController uses an - * internal issuer. - * - * When a nocChainIssuer is set, the device commissioner will delegate verification to the chip::Credentials::PartialDACVerifier so - * that DAC chain and CD validation can be performed by custom code triggered by MTRNOCChainIssuer.onNOCChainGenerationNeeded(). - * Otherwise, the device commissioner uses the chip::Credentials::DefaultDACVerifier - * - * @param[in] nocChainIssuer the NOC Chain issuer to use for issuer operational certs - * - * @param[in] queue The queue on which the callbacks will be delivered - */ -- (void)setNocChainIssuer:(id)nocChainIssuer queue:(dispatch_queue_t)queue; - /** * Return the attestation challenge for the secure session of the device being commissioned. * @@ -231,6 +217,9 @@ typedef void (^MTRDeviceConnectionCallback)(MTRBaseDevice * _Nullable device, NS - (void)setPairingDelegate:(id)delegate queue:(dispatch_queue_t)queue MTR_NEWLY_DEPRECATED("Please use setDeviceControllerDelegate:"); +- (void)setNocChainIssuer:(id)nocChainIssuer + queue:(dispatch_queue_t)queue + MTR_NEWLY_DEPRECATED("Please set the operationalCertificateIssuer in the MTRDeviceControllerStartupParams instead."); @end NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 38abb49b1439f2..066d32774f0aed 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -115,7 +115,7 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory queue:(dis return nil; } - _operationalCredentialsDelegate = new MTROperationalCredentialsDelegate(); + _operationalCredentialsDelegate = new MTROperationalCredentialsDelegate(self); if ([self checkForInitError:(_operationalCredentialsDelegate != nullptr) logMsg:kErrorOperationalCredentialsInit]) { return nil; } @@ -347,9 +347,21 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams if (commissionerInitialized == NO) { [self cleanupAfterStartup]; + return NO; + } + + // TODO: Once setNocChainIssuer no longer needs to be supported, + // we can just move the internals of + // setOperationalCertificateIssuer into the sync-dispatched block + // above. + if (![self setOperationalCertificateIssuer:startupParams.operationalCertificateIssuer + queue:startupParams.operationalCertificateIssuerQueue]) { + MTR_LOG_ERROR("operationalCertificateIssuer and operationalCertificateIssuerQueue must both be nil or both be non-nil"); + [self cleanupAfterStartup]; + return NO; } - return commissionerInitialized; + return YES; } - (NSNumber *)controllerNodeID @@ -568,20 +580,31 @@ - (void)setDeviceControllerDelegate:(id)delegate qu }); } -- (void)setNocChainIssuer:(id)nocChainIssuer queue:(dispatch_queue_t)queue +- (BOOL)setOperationalCertificateIssuer:(nullable id)operationalCertificateIssuer + queue:(nullable dispatch_queue_t)queue { - VerifyOrReturn([self checkIsRunning]); + if ((operationalCertificateIssuer != nil && queue == nil) || (operationalCertificateIssuer == nil && queue != nil)) { + return NO; + } + + VerifyOrReturnValue([self checkIsRunning], NO); + __block BOOL success = NO; dispatch_sync(_chipWorkQueue, ^{ VerifyOrReturn([self checkIsRunning]); - if (nocChainIssuer != nil) { - self->_operationalCredentialsDelegate->SetNocChainIssuer(nocChainIssuer, queue); + if (operationalCertificateIssuer != nil) { + self->_operationalCredentialsDelegate->SetOperationalCertificateIssuer(operationalCertificateIssuer, queue); self->_cppCommissioner->SetDeviceAttestationVerifier(_partialDACVerifier); } else { - self->_cppCommissioner->SetDeviceAttestationVerifier(chip::Credentials::GetDeviceAttestationVerifier()); + // TODO: Once we are not supporting setNocChainIssuer this + // branch can just go away. + self->_cppCommissioner->SetDeviceAttestationVerifier(_factory.deviceAttestationVerifier); } + success = YES; }); + + return success; } + (nullable NSData *)computePASEVerifierForSetupPasscode:(NSNumber *)setupPasscode @@ -902,6 +925,64 @@ - (void)onPairingDeleted:(NSError * _Nullable)error @end +/** + * Shim to allow us to treat an MTRNOCChainIssuer as an + * MTROperationalCertificateIssuer. + */ +@interface MTROperationalCertificateChainIssuerShim : NSObject +@property (nonatomic, readonly) id nocChainIssuer; +- (instancetype)initWithIssuer:(id)nocChainIssuer; +@end + +@implementation MTROperationalCertificateChainIssuerShim +- (instancetype)initWithIssuer:(id)nocChainIssuer +{ + if (self = [super init]) { + _nocChainIssuer = nocChainIssuer; + } + return self; +} + +- (void)issueOperationalCertificateForRequest:(MTROperationalCSRInfo *)csrInfo + attestationInfo:(MTRAttestationInfo *)attestationInfo + controller:(MTRDeviceController *)controller + completion:(MTROperationalCertificateIssuedHandler)completion +{ + CSRInfo * oldCSRInfo = [[CSRInfo alloc] initWithNonce:csrInfo.csrNonce + elements:csrInfo.csrElementsTLV + elementsSignature:csrInfo.attestationSignature + csr:csrInfo.csr]; + NSData * _Nullable firmwareInfo = attestationInfo.firmwareInfo; + if (firmwareInfo == nil) { + firmwareInfo = [NSData data]; + } + AttestationInfo * oldAttestationInfo = + [[AttestationInfo alloc] initWithChallenge:attestationInfo.challenge + nonce:attestationInfo.nonce + elements:attestationInfo.elementsTLV + elementsSignature:attestationInfo.elementsSignature + dac:attestationInfo.deviceAttestationCertificate + pai:attestationInfo.productAttestationIntermediateCertificate + certificationDeclaration:attestationInfo.certificationDeclaration + firmwareInfo:firmwareInfo]; + [self.nocChainIssuer + onNOCChainGenerationNeeded:oldCSRInfo + attestationInfo:oldAttestationInfo + onNOCChainGenerationComplete:^(NSData * operationalCertificate, NSData * intermediateCertificate, NSData * rootCertificate, + NSData * _Nullable ipk, NSNumber * _Nullable adminSubject, NSError * __autoreleasing * error) { + auto * info = [[MTROperationalCertificateInfo alloc] initWithOperationalCertificate:operationalCertificate + intermediateCertificate:intermediateCertificate + rootCertificate:rootCertificate + adminSubject:adminSubject]; + completion(info, nil); + if (error != nil) { + *error = nil; + } + }]; +} + +@end + @implementation MTRDeviceController (Deprecated) - (NSNumber *)controllerNodeId @@ -1125,4 +1206,9 @@ - (void)setPairingDelegate:(id)delegate queue:(dispatc [self setDeviceControllerDelegate:delegateShim queue:queue]; } +- (void)setNocChainIssuer:(id)nocChainIssuer queue:(dispatch_queue_t)queue +{ + [self setOperationalCertificateIssuer:[[MTROperationalCertificateChainIssuerShim alloc] initWithIssuer:nocChainIssuer] + queue:queue]; +} @end diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.h b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.h index 8ff5775ed71279..36090b9766dd44 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerStartupParams.h @@ -17,6 +17,7 @@ #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -27,11 +28,11 @@ NS_ASSUME_NONNULL_BEGIN * Keypair used to sign operational certificates. This is the root CA keypair * if not using an intermediate CA, the intermediate CA's keypair otherwise. * - * Allowed to be nil if this controller will not be issuing operational - * certificates. In that case, the MTRDeviceControllerStartupParams object must - * be initialized using + * Allowed to be nil if this controller will not be issuing internally-generated + * operational certificates. In that case, the MTRDeviceControllerStartupParams + * object must be initialized using * initWithIPK:operationalKeypair:operationalCertificate:intermediateCertificate:rootCertificate: - * (to provide the operational credentials for the controller itself). + * (to provide the operational credentials for t2he controller itself). */ @property (nonatomic, copy, readonly, nullable) id nocSigner; /** @@ -187,6 +188,31 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, strong, nullable) id operationalKeypair; +/** + * The certificate issuer delegate to use for issuing operational certificates + * when commmissioning devices. Allowed to be nil if this controller either + * does not issue operational certificates at all or internally generates the + * certificates to be issued. In the latter case, nocSigner must not be nil. + * + * When this property is non-nill, all device attestation checks that require + * some sort of trust anchors are delegated to the operationalCertificateIssuer. + * Specifically, the following device attestation checks are not performed and + * must be done by the operationalCertificateIssuer: + * + * (1) Make sure the PAA is valid and approved by CSA. + * (2) VID-scoped PAA check: if the PAA is VID scoped, then its VID must match the DAC VID. + * (3) cert chain check: verify PAI is signed by PAA, and DAC is signed by PAI. + * (4) PAA subject key id extraction: the PAA subject key must match the PAA key referenced in the PAI. + * (5) CD signature check: make sure a valid CSA CD key is used to sign the CD. + */ +@property (nonatomic, strong, nullable) id operationalCertificateIssuer MTR_NEWLY_AVAILABLE; + +/** + * The dispatch queue on which operationalCertificateIssuer should be called. + * Allowed to be nil if and only if operationalCertificateIssuer is nil. + */ +@property (nonatomic, strong, nullable) dispatch_queue_t operationalCertificateIssuerQueue MTR_NEWLY_AVAILABLE; + - (instancetype)init NS_UNAVAILABLE; /** diff --git a/src/darwin/Framework/CHIP/MTRNOCChainIssuer.h b/src/darwin/Framework/CHIP/MTRNOCChainIssuer.h deleted file mode 100644 index 7c1eb03e37c1b7..00000000000000 --- a/src/darwin/Framework/CHIP/MTRNOCChainIssuer.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * - * Copyright (c) 2022 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 - -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -typedef void (^MTRNOCChainGenerationCompleteHandler)(NSData * operationalCertificate, NSData * intermediateCertificate, - NSData * rootCertificate, NSData * _Nullable ipk, NSNumber * _Nullable adminSubject, NSError * __autoreleasing * error); - -@protocol MTRNOCChainIssuer -@required - -/** - * @brief When a MTRNOCChainIssuer is set for the MTRDeviceController, then onNOCChainGenerationNeeded will be - * called when the NOC CSR needs to be signed. This allows for custom credentials issuer - * implementations, for example, when a proprietary cloud API will perform the CSR signing. - - * The commissioning workflow will stop upon the onNOCChainGenerationNeeded callback and - * resume once onNOCChainGenerationComplete is called - - * The following fields MUST be passed to onNOCChainGenerationComplete with non-nil values: - * rootCertificate, intermediateCertificate, operationalCertificate. - * If ipk and adminSubject are passed, then they will be used in - * the AddNOC command sent to the commissionee. If they are not passed, then the values - * provided in the MTRDeviceController initialization will be used. - * - * All csr and attestation fields are provided to allow for custom attestestation checks. - */ -- (void)onNOCChainGenerationNeeded:(CSRInfo *)csrInfo - attestationInfo:(AttestationInfo *)attestationInfo - onNOCChainGenerationComplete:(MTRNOCChainGenerationCompleteHandler)onNOCChainGenerationComplete; - -@end - -NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTROperationalCertificateIssuer.h b/src/darwin/Framework/CHIP/MTROperationalCertificateIssuer.h new file mode 100644 index 00000000000000..84566e20dbee14 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTROperationalCertificateIssuer.h @@ -0,0 +1,91 @@ +/** + * + * Copyright (c) 2022 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 + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@class MTRDeviceController; + +/** + * A representation of the operation certificate info for a node. + * + * A nil intermediateCertificate means there is no intermediate. + * + * adminSubject is passed to the device as part of the AddNOC command. A nil + * adminSubject means the node id of the relevant MTRDeviceController will be + * used. + */ +MTR_NEWLY_AVAILABLE +@interface MTROperationalCertificateInfo : NSObject +@property (nonatomic, copy) MTRCertificateDERBytes operationalCertificate; +@property (nonatomic, copy, nullable) MTRCertificateDERBytes intermediateCertificate; +@property (nonatomic, copy) MTRCertificateDERBytes rootCertificate; +@property (nonatomic, copy, nullable) NSNumber * adminSubject; + +- (instancetype)initWithOperationalCertificate:(MTRCertificateDERBytes)operationalCertificate + intermediateCertificate:(nullable MTRCertificateDERBytes)intermediateCertificate + rootCertificate:(MTRCertificateDERBytes)rootCertificate + adminSubject:(nullable NSNumber *)adminSubject; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; +@end + +typedef void (^MTROperationalCertificateIssuedHandler)(MTROperationalCertificateInfo * _Nullable info, NSError * _Nullable error); + +MTR_NEWLY_AVAILABLE +@protocol MTROperationalCertificateIssuer +@required + +/** + * @brief When an MTROperationalCertificateIssuer is set for an + * MTRDeviceController, it will be used to issue operational certificates as + * needed during commissioning. + * + * Commissioning will pause when + * issueOperationalCertificateForRequest:attestationInfo:completion: is called, + * and resume when the completion is invoked with a non-nil + * MTROperationalCertificateInfo. When the completion is invoked with an error, + * commissioning will fail. + */ +- (void)issueOperationalCertificateForRequest:(MTROperationalCSRInfo *)csrInfo + attestationInfo:(MTRAttestationInfo *)attestationInfo + controller:(MTRDeviceController *)controller + completion:(MTROperationalCertificateIssuedHandler)completion; + +@end + +MTR_NEWLY_DEPRECATED("Please use MTROperationalCertificateIssuedHandler") +typedef void (^MTRNOCChainGenerationCompleteHandler)(NSData * operationalCertificate, NSData * intermediateCertificate, + NSData * rootCertificate, NSData * _Nullable ipk, NSNumber * _Nullable adminSubject, NSError * __autoreleasing * error); + +MTR_NEWLY_DEPRECATED("Please use MTROperationalCertificateIssuer") +@protocol MTRNOCChainIssuer +@required + +- (void)onNOCChainGenerationNeeded:(CSRInfo *)csrInfo + attestationInfo:(AttestationInfo *)attestationInfo + onNOCChainGenerationComplete:(MTRNOCChainGenerationCompleteHandler)onNOCChainGenerationComplete; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTROperationalCertificateIssuer.mm b/src/darwin/Framework/CHIP/MTROperationalCertificateIssuer.mm new file mode 100644 index 00000000000000..21ee514e8b242b --- /dev/null +++ b/src/darwin/Framework/CHIP/MTROperationalCertificateIssuer.mm @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2022 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 + +#import "MTROperationalCertificateIssuer.h" + +@implementation MTROperationalCertificateInfo + +- (instancetype)initWithOperationalCertificate:(MTRCertificateDERBytes)operationalCertificate + intermediateCertificate:(nullable MTRCertificateDERBytes)intermediateCertificate + rootCertificate:(MTRCertificateDERBytes)rootCertificate + adminSubject:(nullable NSNumber *)adminSubject +{ + if (self = [super init]) { + _operationalCertificate = operationalCertificate; + _intermediateCertificate = intermediateCertificate; + _rootCertificate = rootCertificate; + _adminSubject = adminSubject; + } + return self; +} + +@end diff --git a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h index b6427512f31106..e0e34130aa5a8e 100644 --- a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h +++ b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h @@ -20,9 +20,10 @@ #import #import +#import "MTRDeviceController.h" #import "MTRError_Internal.h" #import "MTRKeypair.h" -#import "MTRNOCChainIssuer.h" +#import "MTROperationalCertificateIssuer.h" #import "MTRP256KeypairBridge.h" #import "MTRPersistentStorageDelegateBridge.h" @@ -37,6 +38,7 @@ class MTROperationalCredentialsDelegate : public chip::Controller::OperationalCr public: using ChipP256KeypairPtr = chip::Crypto::P256Keypair *; + MTROperationalCredentialsDelegate(MTRDeviceController * deviceController); ~MTROperationalCredentialsDelegate() {} CHIP_ERROR Init(MTRPersistentStorageDelegateBridge * storage, ChipP256KeypairPtr nocSigner, NSData * ipk, NSData * rootCert, @@ -69,15 +71,13 @@ class MTROperationalCredentialsDelegate : public chip::Controller::OperationalCr void setChipWorkQueue(dispatch_queue_t chipWorkQueue) { mChipWorkQueue = chipWorkQueue; } - void SetNocChainIssuer(id nocChainIssuer, dispatch_queue_t nocChainIssuerQueue) + void SetOperationalCertificateIssuer( + id operationalCertificateIssuer, dispatch_queue_t operationalCertificateIssuerQueue) { - mNocChainIssuer = nocChainIssuer; - mNocChainIssuerQueue = nocChainIssuerQueue; + mOperationalCertificateIssuer = operationalCertificateIssuer; + mOperationalCertificateIssuerQueue = operationalCertificateIssuerQueue; } - CHIP_ERROR NOCChainGenerated(CHIP_ERROR status, const chip::ByteSpan & noc, const chip::ByteSpan & icac, - const chip::ByteSpan & rcac, chip::Optional ipk, chip::Optional adminSubject); - CHIP_ERROR GenerateNOC(chip::NodeId nodeId, chip::FabricId fabricId, const chip::CATValues & cats, const chip::Crypto::P256PublicKey & pubkey, chip::MutableByteSpan & noc); @@ -120,22 +120,12 @@ class MTROperationalCredentialsDelegate : public chip::Controller::OperationalCr chip::FabricId fabricId, const chip::CATValues & cats, const chip::Crypto::P256PublicKey & pubkey, chip::MutableByteSpan & noc); - /** - * When a NOCChainIssuer is set, then onNOCChainGenerationNeeded will be called when the NOC CSR needs to be - * signed. This allows for custom credentials issuer implementations, for example, when a proprietary cloud API will perform the - * CSR signing. The commissioning workflow will stop upon the onNOCChainGenerationNeeded callback and resume once - * onNOCChainGenerationComplete is called. - * - * Caller must pass a non-nil value for the rootCertificate, intermediateCertificate, operationalCertificate - * If ipk and adminSubject are non nil, then they will be used in the AddNOC command sent to the commissionee. If they are not - * populated, then the values provided in the MTRDeviceController initialization will be used. - */ - void onNOCChainGenerationComplete(NSData * operationalCertificate, NSData * intermediateCertificate, NSData * rootCertificate, - NSData * _Nullable ipk, NSNumber * _Nullable adminSubject, NSError * __autoreleasing * error); - - void setNSError(CHIP_ERROR err, NSError * __autoreleasing * outError); - - CHIP_ERROR CallbackGenerateNOCChain(const chip::ByteSpan & csrElements, const chip::ByteSpan & csrNonce, + // Called asynchronously in response to the MTROperationalCertificateIssuer + // calling the completion we passed it when asking it to generate a NOC + // chain. + void ExternalNOCChainGenerated(MTROperationalCertificateInfo * _Nullable info, NSError * _Nullable error); + + CHIP_ERROR ExternalGenerateNOCChain(const chip::ByteSpan & csrElements, const chip::ByteSpan & csrNonce, const chip::ByteSpan & attestationSignature, const chip::ByteSpan & attestationChallenge, const chip::ByteSpan & DAC, const chip::ByteSpan & PAI, chip::Callback::Callback * onCompletion); @@ -162,11 +152,12 @@ class MTROperationalCredentialsDelegate : public chip::Controller::OperationalCr NSData * _Nullable mRootCert; NSData * _Nullable mIntermediateCert; - chip::Controller::DeviceCommissioner * mCppCommissioner = nullptr; - id _Nullable mNocChainIssuer; - dispatch_queue_t _Nullable mNocChainIssuerQueue; + MTRDeviceController * __weak mWeakController; + chip::Controller::DeviceCommissioner * _Nullable mCppCommissioner = nullptr; + id _Nullable mOperationalCertificateIssuer; + dispatch_queue_t _Nullable mOperationalCertificateIssuerQueue; dispatch_queue_t _Nullable mChipWorkQueue; - chip::Callback::Callback * mOnNOCCompletionCallback = nullptr; + chip::Callback::Callback * _Nullable mOnNOCCompletionCallback = nullptr; }; NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm index ba11b3c947a479..40e2fd3f8028a4 100644 --- a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm +++ b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm @@ -35,12 +35,18 @@ #include #include #include +#include using namespace chip; using namespace TLV; using namespace Credentials; using namespace Crypto; +MTROperationalCredentialsDelegate::MTROperationalCredentialsDelegate(MTRDeviceController * deviceController) + : mWeakController(deviceController) +{ +} + CHIP_ERROR MTROperationalCredentialsDelegate::Init(MTRPersistentStorageDelegateBridge * storage, ChipP256KeypairPtr nocSigner, NSData * ipk, NSData * rootCert, NSData * _Nullable icaCert) { @@ -113,39 +119,29 @@ return NewNodeOperationalX509Cert(noc_request, pubkey, signingKeypair, noc); } -CHIP_ERROR MTROperationalCredentialsDelegate::NOCChainGenerated(CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac, - const ByteSpan & rcac, Optional ipk, Optional adminSubject) -{ - ReturnErrorCodeIf(mOnNOCCompletionCallback == nullptr, CHIP_ERROR_INCORRECT_STATE); - - Callback::Callback * onCompletion = mOnNOCCompletionCallback; - mOnNOCCompletionCallback = nullptr; - - // Call-back into commissioner with the generated data. - dispatch_sync(mChipWorkQueue, ^{ - onCompletion->mCall(onCompletion->mContext, status, noc, icac, rcac, ipk, adminSubject); - }); - - return CHIP_NO_ERROR; -} - CHIP_ERROR MTROperationalCredentialsDelegate::GenerateNOCChain(const chip::ByteSpan & csrElements, const chip::ByteSpan & csrNonce, const chip::ByteSpan & attestationSignature, const chip::ByteSpan & attestationChallenge, const chip::ByteSpan & DAC, const chip::ByteSpan & PAI, chip::Callback::Callback * onCompletion) { - if (mNocChainIssuer != nil) { - return CallbackGenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, DAC, PAI, onCompletion); + if (mOperationalCertificateIssuer != nil) { + return ExternalGenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, DAC, PAI, onCompletion); } else { return LocalGenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, DAC, PAI, onCompletion); } } -CHIP_ERROR MTROperationalCredentialsDelegate::CallbackGenerateNOCChain(const chip::ByteSpan & csrElements, +CHIP_ERROR MTROperationalCredentialsDelegate::ExternalGenerateNOCChain(const chip::ByteSpan & csrElements, const chip::ByteSpan & csrNonce, const chip::ByteSpan & csrElementsSignature, const chip::ByteSpan & attestationChallenge, const chip::ByteSpan & DAC, const chip::ByteSpan & PAI, chip::Callback::Callback * onCompletion) { + assertChipStackLockedByCurrentThread(); + VerifyOrReturnError(mCppCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE); + + MTRDeviceController * strongController = mWeakController; + VerifyOrReturnError(strongController != nil, CHIP_ERROR_INCORRECT_STATE); + mOnNOCCompletionCallback = onCompletion; TLVReader reader; @@ -166,10 +162,10 @@ reader.Get(csr); reader.ExitContainer(containerType); - CSRInfo * csrInfo = [[CSRInfo alloc] initWithNonce:AsData(csrNonce) - elements:AsData(csrElements) - elementsSignature:AsData(csrElementsSignature) - csr:AsData(csr)]; + auto * csrInfo = [[MTROperationalCSRInfo alloc] initWithCSR:AsData(csr) + csrNonce:AsData(csrNonce) + csrElementsTLV:AsData(csrElements) + attestationSignature:AsData(csrElementsSignature)]; chip::ByteSpan certificationDeclarationSpan; chip::ByteSpan attestationNonceSpan; @@ -187,90 +183,90 @@ chip::Credentials::DeconstructAttestationElements(commissioningParameters.Value().GetAttestationElements().Value(), certificationDeclarationSpan, attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan, vendorReserved)); - AttestationInfo * attestationInfo = - [[AttestationInfo alloc] initWithChallenge:AsData(attestationChallenge) - nonce:AsData(commissioningParameters.Value().GetAttestationNonce().Value()) - elements:AsData(commissioningParameters.Value().GetAttestationElements().Value()) - elementsSignature:AsData(commissioningParameters.Value().GetAttestationSignature().Value()) - dac:AsData(DAC) - pai:AsData(PAI) - certificationDeclaration:AsData(certificationDeclarationSpan) - firmwareInfo:AsData(firmwareInfoSpan)]; - - dispatch_sync(mNocChainIssuerQueue, ^{ - [mNocChainIssuer onNOCChainGenerationNeeded:csrInfo - attestationInfo:attestationInfo - onNOCChainGenerationComplete:^void(NSData * operationalCertificate, NSData * intermediateCertificate, - NSData * rootCertificate, NSData * ipk, NSNumber * adminSubject, NSError * __autoreleasing * error) { - onNOCChainGenerationComplete( - operationalCertificate, intermediateCertificate, rootCertificate, ipk, adminSubject, error); - }]; + NSData * firmwareInfo = nil; + if (!firmwareInfoSpan.empty()) { + firmwareInfo = AsData(firmwareInfoSpan); + } + MTRAttestationInfo * attestationInfo = + [[MTRAttestationInfo alloc] initWithChallenge:AsData(attestationChallenge) + nonce:AsData(commissioningParameters.Value().GetAttestationNonce().Value()) + elementsTLV:AsData(commissioningParameters.Value().GetAttestationElements().Value()) + elementsSignature:AsData(commissioningParameters.Value().GetAttestationSignature().Value()) + deviceAttestationCertificate:AsData(DAC) + productAttestationIntermediateCertificate:AsData(PAI) + certificationDeclaration:AsData(certificationDeclarationSpan) + firmwareInfo:firmwareInfo]; + + MTRDeviceController * __weak weakController = mWeakController; + dispatch_async(mOperationalCertificateIssuerQueue, ^{ + [mOperationalCertificateIssuer + issueOperationalCertificateForRequest:csrInfo + attestationInfo:attestationInfo + controller:strongController + completion:^(MTROperationalCertificateInfo * _Nullable info, NSError * _Nullable error) { + MTRDeviceController * strongController = weakController; + if (strongController == nil || !strongController.isRunning) { + // No longer safe to touch "this" + return; + } + this->ExternalNOCChainGenerated(info, error); + }]; }); return CHIP_NO_ERROR; } -void MTROperationalCredentialsDelegate::setNSError(CHIP_ERROR err, NSError * __autoreleasing * outError) +void MTROperationalCredentialsDelegate::ExternalNOCChainGenerated( + MTROperationalCertificateInfo * _Nullable info, NSError * _Nullable error) { - if (outError) { - *outError = [MTRError errorForCHIPErrorCode:err]; - } -} + MTRDeviceController * __weak weakController = mWeakController; + dispatch_async(mChipWorkQueue, ^{ + MTRDeviceController * strongController = weakController; + if (strongController == nil || !strongController.isRunning) { + // No longer safe to touch "this" + return; + } -void MTROperationalCredentialsDelegate::onNOCChainGenerationComplete(NSData * operationalCertificate, - NSData * intermediateCertificate, NSData * rootCertificate, NSData * _Nullable ipk, NSNumber * _Nullable adminSubject, - NSError * __autoreleasing * error) -{ - if (operationalCertificate == nil || intermediateCertificate == nil || rootCertificate == nil) { - setNSError(CHIP_ERROR_INVALID_ARGUMENT, error); - return; - } + if (mOnNOCCompletionCallback == nullptr) { + return; + } - if (mCppCommissioner == nullptr) { - setNSError(CHIP_ERROR_INCORRECT_STATE, error); - return; - } + auto * onCompletion = mOnNOCCompletionCallback; + mOnNOCCompletionCallback = nullptr; - __block chip::Optional commissioningParameters; - dispatch_sync(mChipWorkQueue, ^{ - commissioningParameters = mCppCommissioner->GetCommissioningParameters(); - }); - if (!commissioningParameters.HasValue()) { - setNSError(CHIP_ERROR_INCORRECT_STATE, error); - return; - } + if (mCppCommissioner == nullptr) { + // Quite unexpected, since we checked that our controller is running already. + return; + } - chip::Optional ipkOptional; - uint8_t ipkValue[chip::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES]; - chip::Crypto::AesCcm128KeySpan ipkTempSpan(ipkValue); - if (ipk != nil) { - if ([ipk length] != sizeof(ipkValue)) { - setNSError(CHIP_ERROR_INCORRECT_STATE, error); + if (info == nil) { + onCompletion->mCall(onCompletion->mContext, [MTRError errorToCHIPErrorCode:error], ByteSpan(), ByteSpan(), ByteSpan(), + NullOptional, NullOptional); return; } - memcpy(&ipkValue[0], [ipk bytes], [ipk length]); - ipkOptional.SetValue(ipkTempSpan); - } else if (commissioningParameters.Value().GetIpk().HasValue()) { - ipkOptional.SetValue(commissioningParameters.Value().GetIpk().Value()); - } - chip::Optional adminSubjectOptional; - if (adminSubject != nil) { - adminSubjectOptional.SetValue(adminSubject.unsignedLongLongValue); - } else { - adminSubjectOptional = commissioningParameters.Value().GetAdminSubject(); - } + auto commissioningParameters = mCppCommissioner->GetCommissioningParameters(); + if (!commissioningParameters.HasValue()) { + return; + } - // This could potentially be done as an async operation as a future optimization. But it ultimately calls - // DeviceCommissioner::OnDeviceNOCChainGeneration which sends the AddNoc message to the target. The call returns without - // blocking as it is. - CHIP_ERROR err = NOCChainGenerated(CHIP_NO_ERROR, AsByteSpan(operationalCertificate), AsByteSpan(intermediateCertificate), - AsByteSpan(rootCertificate), ipkOptional, adminSubjectOptional); + AesCcm128KeySpan ipk = commissioningParameters.Value().GetIpk().ValueOr(GetIPK()); - if (err != CHIP_NO_ERROR) { - MTR_LOG_ERROR("Failed to SetNocChain for the device: %" CHIP_ERROR_FORMAT, err.Format()); - setNSError(CHIP_ERROR_INCORRECT_STATE, error); - } + Optional adminSubject; + if (info.adminSubject != nil) { + adminSubject.SetValue(info.adminSubject.unsignedLongLongValue); + } else { + adminSubject = commissioningParameters.Value().GetAdminSubject(); + } + + ByteSpan intermediateCertificate; + if (info.intermediateCertificate != nil) { + intermediateCertificate = AsByteSpan(info.intermediateCertificate); + } + + onCompletion->mCall(onCompletion->mContext, CHIP_NO_ERROR, AsByteSpan(info.operationalCertificate), intermediateCertificate, + AsByteSpan(info.rootCertificate), MakeOptional(ipk), adminSubject); + }); } CHIP_ERROR MTROperationalCredentialsDelegate::LocalGenerateNOCChain(const chip::ByteSpan & csrElements, diff --git a/src/darwin/Framework/CHIP/Matter.h b/src/darwin/Framework/CHIP/Matter.h index 179c28424581ba..b5c699e20c695f 100644 --- a/src/darwin/Framework/CHIP/Matter.h +++ b/src/darwin/Framework/CHIP/Matter.h @@ -49,10 +49,10 @@ #import #import #import -#import #import #import #import +#import #import #import #import diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index af1f6c339433e5..7a419bdbf3aa36 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -36,12 +36,13 @@ 3CF134A9289D8D800017A19E /* MTRCSRInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CF134A8289D8D800017A19E /* MTRCSRInfo.mm */; }; 3CF134AB289D8DF70017A19E /* MTRAttestationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CF134AA289D8DF70017A19E /* MTRAttestationInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3CF134AD289D8E570017A19E /* MTRAttestationInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CF134AC289D8E570017A19E /* MTRAttestationInfo.mm */; }; - 3CF134AF289D90FF0017A19E /* MTRNOCChainIssuer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CF134AE289D90FF0017A19E /* MTRNOCChainIssuer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3CF134AF289D90FF0017A19E /* MTROperationalCertificateIssuer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CF134AE289D90FF0017A19E /* MTROperationalCertificateIssuer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3D69868529383096007314E7 /* com.csa.matter.plist in Copy Logging Preferences */ = {isa = PBXBuildFile; fileRef = 3D69868029382EF4007314E7 /* com.csa.matter.plist */; }; 3DECCB6E29347D2D00585AEC /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DECCB6D29347D2C00585AEC /* Security.framework */; }; 3DECCB702934AECD00585AEC /* MTRLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DECCB6F2934AC1C00585AEC /* MTRLogging.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3DECCB722934AFE200585AEC /* MTRLogging.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3DECCB712934AFE200585AEC /* MTRLogging.mm */; }; 3DECCB742934C21B00585AEC /* MTRDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DECCB732934C21B00585AEC /* MTRDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 51029DF6293AA6100087AFB0 /* MTROperationalCertificateIssuer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51029DF5293AA6100087AFB0 /* MTROperationalCertificateIssuer.mm */; }; 5112F606287CD2C100B827E7 /* privilege-storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5112F605287CD2C100B827E7 /* privilege-storage.cpp */; }; 511913FB28C100EF009235E9 /* MTRBaseSubscriptionCallback.mm in Sources */ = {isa = PBXBuildFile; fileRef = 511913F928C100EF009235E9 /* MTRBaseSubscriptionCallback.mm */; }; 511913FC28C100EF009235E9 /* MTRBaseSubscriptionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 511913FA28C100EF009235E9 /* MTRBaseSubscriptionCallback.h */; }; @@ -196,12 +197,13 @@ 3CF134A8289D8D800017A19E /* MTRCSRInfo.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRCSRInfo.mm; sourceTree = ""; }; 3CF134AA289D8DF70017A19E /* MTRAttestationInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRAttestationInfo.h; sourceTree = ""; }; 3CF134AC289D8E570017A19E /* MTRAttestationInfo.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRAttestationInfo.mm; sourceTree = ""; }; - 3CF134AE289D90FF0017A19E /* MTRNOCChainIssuer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRNOCChainIssuer.h; sourceTree = ""; }; + 3CF134AE289D90FF0017A19E /* MTROperationalCertificateIssuer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTROperationalCertificateIssuer.h; sourceTree = ""; }; 3D69868029382EF4007314E7 /* com.csa.matter.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.csa.matter.plist; sourceTree = ""; }; 3DECCB6D29347D2C00585AEC /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; 3DECCB6F2934AC1C00585AEC /* MTRLogging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRLogging.h; sourceTree = ""; }; 3DECCB712934AFE200585AEC /* MTRLogging.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRLogging.mm; sourceTree = ""; }; 3DECCB732934C21B00585AEC /* MTRDefines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDefines.h; sourceTree = ""; }; + 51029DF5293AA6100087AFB0 /* MTROperationalCertificateIssuer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTROperationalCertificateIssuer.mm; sourceTree = ""; }; 5112F605287CD2C100B827E7 /* privilege-storage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "privilege-storage.cpp"; path = "../../../app/util/privilege-storage.cpp"; sourceTree = ""; }; 511913F928C100EF009235E9 /* MTRBaseSubscriptionCallback.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRBaseSubscriptionCallback.mm; sourceTree = ""; }; 511913FA28C100EF009235E9 /* MTRBaseSubscriptionCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRBaseSubscriptionCallback.h; sourceTree = ""; }; @@ -497,10 +499,11 @@ 3CF134A8289D8D800017A19E /* MTRCSRInfo.mm */, 3CF134AA289D8DF70017A19E /* MTRAttestationInfo.h */, 3CF134AC289D8E570017A19E /* MTRAttestationInfo.mm */, - 3CF134AE289D90FF0017A19E /* MTRNOCChainIssuer.h */, + 3CF134AE289D90FF0017A19E /* MTROperationalCertificateIssuer.h */, 511913FA28C100EF009235E9 /* MTRBaseSubscriptionCallback.h */, 511913F928C100EF009235E9 /* MTRBaseSubscriptionCallback.mm */, 51E4D120291D0EB400C8C535 /* MTRBaseClustersCpp_Internal.h */, + 51029DF5293AA6100087AFB0 /* MTROperationalCertificateIssuer.mm */, ); path = CHIP; sourceTree = ""; @@ -572,7 +575,7 @@ 991DC0842475F45400C13860 /* MTRDeviceController.h in Headers */, AF1CB86E2874B03B00865A96 /* MTROTAProviderDelegate.h in Headers */, 754F3DF427FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h in Headers */, - 3CF134AF289D90FF0017A19E /* MTRNOCChainIssuer.h in Headers */, + 3CF134AF289D90FF0017A19E /* MTROperationalCertificateIssuer.h in Headers */, 3CF134AB289D8DF70017A19E /* MTRAttestationInfo.h in Headers */, B2E0D7B2245B0B5C003C5B48 /* MTRManualSetupPayloadParser.h in Headers */, 3CF134A7289D8ADA0017A19E /* MTRCSRInfo.h in Headers */, @@ -742,6 +745,7 @@ 2CB7163C252E8A7C0026E2BB /* MTRDeviceControllerDelegateBridge.mm in Sources */, 997DED162695343400975E97 /* MTRThreadOperationalDataset.mm in Sources */, 515C1C6F284F9FFB00A48F0C /* MTRFramework.mm in Sources */, + 51029DF6293AA6100087AFB0 /* MTROperationalCertificateIssuer.mm in Sources */, 27A53C1827FBC6920053F131 /* MTRAttestationTrustStoreBridge.mm in Sources */, 998F287126D56940001846C6 /* MTRP256KeypairBridge.mm in Sources */, 5136661428067D550025EDAE /* MTRDeviceControllerFactory.mm in Sources */,