Skip to content

Commit

Permalink
Add an attestation challenge to MTROperationalCredentialsClusterAttes…
Browse files Browse the repository at this point in the history
…tationResponseParams. (#28586)

Not public API, for now, but is needed to make sense of the data returned by
this response command.
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Sep 25, 2023
1 parent cf29a85 commit 2845874
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 1 deletion.
37 changes: 36 additions & 1 deletion src/darwin/Framework/CHIP/MTRCallbackBridgeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@
#import "MTRBaseDevice_Internal.h"
#import "MTRDeviceController_Internal.h"
#import "MTRError_Internal.h"
#import "NSDataSpanConversion.h"
#import "zap-generated/MTRBaseClusters.h"
#import "zap-generated/MTRCommandPayloads_Internal.h"

#include <app-common/zap-generated/cluster-objects.h>
#include <app/data-model/NullObject.h>
#include <messaging/ExchangeMgr.h>
#include <platform/CHIPDeviceLayer.h>
#include <transport/Session.h>

#include <type_traits>

NS_ASSUME_NONNULL_BEGIN

/**
Expand Down Expand Up @@ -147,7 +152,23 @@ using MTRActionBlockT = CHIP_ERROR (^)(chip::Messaging::ExchangeManager & exchan
template <typename SuccessCallback>
using MTRLocalActionBlockT = CHIP_ERROR (^)(SuccessCallback successCb, MTRErrorCallback failureCb);

template <class T> class MTRCallbackBridge : public MTRCallbackBridgeBase {
class NoAttestationChallenge {
};

class HaveAttestationChallenge {
protected:
NSData * mAttestationChallenge;
};

namespace detail {
using AttestationResponseCallback
= void (*)(void *, const chip::app::Clusters::OperationalCredentials::Commands::AttestationResponse::DecodableType &);
} // namespace detail

template <class T>
class MTRCallbackBridge : public MTRCallbackBridgeBase,
protected std::conditional<std::is_same_v<T, detail::AttestationResponseCallback>,
HaveAttestationChallenge, NoAttestationChallenge>::type {
public:
using MTRActionBlock = MTRActionBlockT<T>;
using MTRLocalActionBlock = MTRLocalActionBlockT<T>;
Expand Down Expand Up @@ -232,6 +253,10 @@ template <class T> class MTRCallbackBridge : public MTRCallbackBridgeBase {
return;
}

if constexpr (HaveAttestationChallenge()) {
this->mAttestationChallenge = AsData(session.Value()->AsSecureSession()->GetCryptoContext().GetAttestationChallenge());
}

CHIP_ERROR err = action(*exchangeManager, session.Value(), mSuccess, mFailure, this);
if (err != CHIP_NO_ERROR) {
ChipLogError(Controller, "Failure performing action. C++-mangled success callback type: '%s', error: %s",
Expand All @@ -252,7 +277,17 @@ template <class T> class MTRCallbackBridge : public MTRCallbackBridgeBase {

static void DispatchFailure(void * context, NSError * error) { DispatchCallbackResult(context, error, nil); }

template <typename ResponseType> static void SetAttestationChallengeIfNeeded(void * context, ResponseType * _Nonnull response)
{
if constexpr (HaveAttestationChallenge()) {
auto * self = static_cast<MTRCallbackBridge *>(context);
response.attestationChallenge = self->mAttestationChallenge;
}
}

private:
static constexpr bool HaveAttestationChallenge() { return std::is_same_v<T, detail::AttestationResponseCallback>; }

static void DispatchCallbackResult(void * context, NSError * _Nullable error, id _Nullable value)
{
MTRCallbackBridge * callbackBridge = static_cast<MTRCallbackBridge *>(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

NS_ASSUME_NONNULL_BEGIN

@interface MTROperationalCredentialsClusterAttestationResponseParams ()
@property (nonatomic, strong) NSData * attestationChallenge;
@end

{{#zcl_clusters}}
{{#zcl_commands}}
{{! We only need to generate conversion functions for the server-generated commands }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ void MTR{{> @partial-block}}Bridge::OnSuccessFn(void * context
OnFailureFn(context, err);
return;
}
SetAttestationChallengeIfNeeded(context, response);
DispatchSuccess(context, response);
{{else if (isStrEqual partial-type "CommandStatus")}}
DispatchSuccess(context, nil);
Expand Down
Loading

0 comments on commit 2845874

Please sign in to comment.