Skip to content

Commit

Permalink
Fix APIs involved in the MTROperationalCredentialsDelegate.
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
bzbarsky-apple committed Dec 3, 2022
1 parent 21245f4 commit aaa7585
Show file tree
Hide file tree
Showing 13 changed files with 435 additions and 193 deletions.
30 changes: 30 additions & 0 deletions src/darwin/Framework/CHIP/MTRAttestationInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,36 @@ NS_ASSUME_NONNULL_BEGIN
* Represents information relating to product attestation.
*
*/
@interface MTRAttestationInfo : NSObject

@property (nonatomic, copy, readonly) NSData * challenge;

@property (nonatomic, copy, readonly) NSData * nonce;

@property (nonatomic, copy, readonly) NSData * elements;

@property (nonatomic, copy, readonly) NSData * elementsSignature;

@property (nonatomic, copy, readonly) NSData * dac;

@property (nonatomic, copy, readonly) NSData * pai;

@property (nonatomic, copy, readonly) NSData * certificationDeclaration;

@property (nonatomic, copy, readonly) NSData * firmwareInfo;

- (instancetype)initWithChallenge:(NSData *)challenge
nonce:(NSData *)nonce
elements:(NSData *)elements
elementsSignature:(NSData *)elementsSignature
dac:(NSData *)dac
pai:(NSData *)pai
certificationDeclaration:(NSData *)certificationDeclaration
firmwareInfo:(NSData *)firmwareInfo;

@end

MTR_NEWLY_DEPRECATED("Please use MTRAttestationInfo")
@interface AttestationInfo : NSObject

@property (nonatomic, copy) NSData * challenge;
Expand Down
26 changes: 26 additions & 0 deletions src/darwin/Framework/CHIP/MTRAttestationInfo.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,32 @@

NS_ASSUME_NONNULL_BEGIN

@implementation MTRAttestationInfo : NSObject

- (instancetype)initWithChallenge:(NSData *)challenge
nonce:(NSData *)nonce
elements:(NSData *)elements
elementsSignature:(NSData *)elementsSignature
dac:(NSData *)dac
pai:(NSData *)pai
certificationDeclaration:(NSData *)certificationDeclaration
firmwareInfo:(NSData *)firmwareInfo
{
if (self = [super init]) {
_challenge = challenge;
_nonce = nonce;
_elements = elements;
_elementsSignature = elementsSignature;
_dac = dac;
_pai = pai;
_certificationDeclaration = certificationDeclaration;
_firmwareInfo = firmwareInfo;
}
return self;
}

@end

@implementation AttestationInfo : NSObject

- (instancetype)initWithChallenge:(NSData *)challenge
Expand Down
24 changes: 23 additions & 1 deletion src/darwin/Framework/CHIP/MTRCSRInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,31 @@
NS_ASSUME_NONNULL_BEGIN

/**
* Represents information relating to NOC CSR.
* Represents information relating to a certificate signing request for a Matter
* operational certificate. The entire TLV nocsr-elements structure, including
* any vendor-specific data, is included, as well as the parsed-out CSR and
* CSRNonce fields from that structure.
*
* The AttestationSignature from the CSRResponse command is also included. This
* signs a concatenation of csrElements and the attestationChallenge found in
* MTRAttestationInfo.
*/
MTR_NEWLY_AVAILABLE
@interface MTROperationalCSRInfo : NSObject

@property (nonatomic, copy, readonly) NSData * csr;
@property (nonatomic, copy, readonly) NSData * csrNonce;
@property (nonatomic, copy, readonly) NSData * csrElements;
@property (nonatomic, copy, readonly) NSData * attestationSignature;

- (instancetype)initWithCSR:(NSData *)csr
csrNonce:(NSData *)csrNonce
csrElements:(NSData *)csrElements
attestationSignature:(NSData *)attestationSignature;

@end

MTR_NEWLY_DEPRECATED("Please use MTROperationalCSRInfo")
@interface CSRInfo : NSObject

@property (nonatomic, copy) NSData * nonce;
Expand Down
17 changes: 17 additions & 0 deletions src/darwin/Framework/CHIP/MTRCSRInfo.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@

NS_ASSUME_NONNULL_BEGIN

@implementation MTROperationalCSRInfo : NSObject

- (instancetype)initWithCSR:(NSData *)csr
csrNonce:(NSData *)csrNonce
csrElements:(NSData *)csrElements
attestationSignature:(NSData *)attestationSignature;
{
if (self = [super init]) {
_csr = csr;
_csrNonce = csrNonce;
_csrElements = csrElements;
_attestationSignature = attestationSignature;
}
return self;
}
@end

@implementation CSRInfo : NSObject

- (instancetype)initWithNonce:(NSData *)nonce
Expand Down
35 changes: 26 additions & 9 deletions src/darwin/Framework/CHIP/MTRDeviceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

#import <Foundation/Foundation.h>

#import <Matter/MTRNOCChainIssuer.h>
#import <Matter/MTROperationalCertificateIssuer.h>

@class MTRBaseDevice;

Expand Down Expand Up @@ -118,18 +118,33 @@ typedef void (^MTRDeviceConnectionCallback)(MTRBaseDevice * _Nullable device, NS
- (void)setDeviceControllerDelegate:(id<MTRDeviceControllerDelegate>)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.
* Sets this MTRDeviceController to use the given issuer for issuing operational
* certificates. By default, the MTRDeviceController uses an internal issuer
* using the signing provided when it was created.
*
* 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
* Both arguments must be nil (to stop using an external operational certificate
* issuer) or both must be non-nil.
*
* @param[in] nocChainIssuer the NOC Chain issuer to use for issuer operational certs
* When using an external operational certificate issuer, all device attestation
* checks that require some sort of trust anchors are delegated to the external
* certificate issuer. Specifically, the following device attestation checks
* are not performed and must be done by the operationalCertificateIssuer:
*
* @param[in] queue The queue on which the callbacks will be delivered
* (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.
*
* @param[in] operationalCertificateIssuer the operationalCertificateIssuer to
* use for issuing operational certs
*
* @param[in] queue The queue on which the calls into the
* operationalCertificateIssuer will happen.
*/
- (void)setNocChainIssuer:(id<MTRNOCChainIssuer>)nocChainIssuer queue:(dispatch_queue_t)queue;
- (BOOL)setOperationalCertificateIssuer:(nullable id<MTROperationalCertificateIssuer>)operationalCertificateIssuer
queue:(nullable dispatch_queue_t)queue
error:(NSError * __autoreleasing *)error MTR_NEWLY_AVAILABLE;

/**
* Return the attestation challenge for the secure session of the device being commissioned.
Expand Down Expand Up @@ -221,6 +236,8 @@ typedef void (^MTRDeviceConnectionCallback)(MTRBaseDevice * _Nullable device, NS
- (void)setPairingDelegate:(id<MTRDevicePairingDelegate>)delegate
queue:(dispatch_queue_t)queue MTR_NEWLY_DEPRECATED("Please use setDeviceControllerDelegate:");

- (void)setNocChainIssuer:(id<MTRNOCChainIssuer>)nocChainIssuer
queue:(dispatch_queue_t)queue MTR_NEWLY_DEPRECATED("Please use setOperationalCertificateIssuer");
@end

NS_ASSUME_NONNULL_END
84 changes: 78 additions & 6 deletions src/darwin/Framework/CHIP/MTRDeviceController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,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;
}
Expand Down Expand Up @@ -548,20 +548,33 @@ - (void)setDeviceControllerDelegate:(id<MTRDeviceControllerDelegate>)delegate qu
});
}

- (void)setNocChainIssuer:(id<MTRNOCChainIssuer>)nocChainIssuer queue:(dispatch_queue_t)queue
- (BOOL)setOperationalCertificateIssuer:(nullable id<MTROperationalCertificateIssuer>)operationalCertificateIssuer
queue:(nullable dispatch_queue_t)queue
error:(NSError * __autoreleasing *)error
{
VerifyOrReturn([self checkIsRunning]);
if ((operationalCertificateIssuer != nil && queue == nil) || (operationalCertificateIssuer == nil && queue != nil)) {
if (error) {
*error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT];
}
return NO;
}

VerifyOrReturnValue([self checkIsRunning:error], NO);

__block BOOL success = NO;
dispatch_sync(_chipWorkQueue, ^{
VerifyOrReturn([self checkIsRunning]);
VerifyOrReturn([self checkIsRunning:error]);

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());
}
success = YES;
});

return success;
}

+ (nullable NSData *)computePASEVerifierForSetupPasscode:(NSNumber *)setupPasscode
Expand Down Expand Up @@ -882,6 +895,59 @@ - (void)onPairingDeleted:(NSError * _Nullable)error

@end

/**
* Shim to allow us to treat an MTRNOCChainIssuer as an
* MTROperationalCertificateIssuer.
*/
@interface MTROperationalCertificateChainIssuerShim : NSObject <MTROperationalCertificateIssuer>
@property (nonatomic, readonly) id<MTRNOCChainIssuer> nocChainIssuer;
- (instancetype)initWithIssuer:(id<MTRNOCChainIssuer>)nocChainIssuer;
@end

@implementation MTROperationalCertificateChainIssuerShim
- (instancetype)initWithIssuer:(id<MTRNOCChainIssuer>)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.csrElements
elementsSignature:csrInfo.attestationSignature
csr:csrInfo.csr];
AttestationInfo * oldAttestationInfo = [[AttestationInfo alloc] initWithChallenge:attestationInfo.challenge
nonce:attestationInfo.nonce
elements:attestationInfo.elements
elementsSignature:attestationInfo.elementsSignature
dac:attestationInfo.dac
pai:attestationInfo.pai
certificationDeclaration:attestationInfo.certificationDeclaration
firmwareInfo:attestationInfo.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 infoWithOperationalCertificate:operationalCertificate
intermediateCertificate:intermediateCertificate
rootCertificate:rootCertificate
adminSubject:adminSubject];
completion(info, nil);
if (error != nil) {
*error = nil;
}
}];
}

@end

@implementation MTRDeviceController (Deprecated)

- (NSNumber *)controllerNodeId
Expand Down Expand Up @@ -1105,4 +1171,10 @@ - (void)setPairingDelegate:(id<MTRDevicePairingDelegate>)delegate queue:(dispatc
[self setDeviceControllerDelegate:delegateShim queue:queue];
}

- (void)setNocChainIssuer:(id<MTRNOCChainIssuer>)nocChainIssuer queue:(dispatch_queue_t)queue
{
[self setOperationalCertificateIssuer:[[MTROperationalCertificateChainIssuerShim alloc] initWithIssuer:nocChainIssuer]
queue:queue
error:nil];
}
@end
53 changes: 0 additions & 53 deletions src/darwin/Framework/CHIP/MTRNOCChainIssuer.h

This file was deleted.

Loading

0 comments on commit aaa7585

Please sign in to comment.