Skip to content

Commit

Permalink
Setup controller by given fabric index without providing NOC chain an…
Browse files Browse the repository at this point in the history
…d update NOC after DeviceController::Init
  • Loading branch information
DejinChen committed Mar 20, 2024
1 parent 43202d9 commit be8b650
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 4 deletions.
74 changes: 70 additions & 4 deletions src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,24 @@ CHIP_ERROR DeviceController::Init(ControllerInitParams params)
mDNSResolver.SetCommissioningDelegate(this);
RegisterDeviceDiscoveryDelegate(params.deviceDiscoveryDelegate);

VerifyOrReturnError(params.operationalCredentialsDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
mOperationalCredentialsDelegate = params.operationalCredentialsDelegate;

mVendorId = params.controllerVendorId;
if (params.operationalKeypair != nullptr || !params.controllerNOC.empty() || !params.controllerRCAC.empty())
{
ReturnErrorOnFailure(InitControllerNOCChain(params));
}
else if (params.fabricIndex.HasValue())
{
VerifyOrReturnError(params.systemState->Fabrics()->FabricCount() > 0, CHIP_ERROR_INVALID_ARGUMENT);
if (params.systemState->Fabrics()->FindFabricWithIndex(params.fabricIndex.Value()) != nullptr)
{
mFabricIndex = params.fabricIndex.Value();
}
else
{
ChipLogError(Controller, "There is no fabric corresponding to the given fabricIndex");
return CHIP_ERROR_INVALID_ARGUMENT;
}
}

mSystemState = params.systemState->Retain();
mState = State::Initialized;
Expand Down Expand Up @@ -305,8 +315,62 @@ CHIP_ERROR DeviceController::InitControllerNOCChain(const ControllerInitParams &
ReturnErrorOnFailure(err);
VerifyOrReturnError(fabricIndex != kUndefinedFabricIndex, CHIP_ERROR_INTERNAL);

mFabricIndex = fabricIndex;
mFabricIndex = fabricIndex;
mAdvertiseIdentity = advertiseOperational;
return CHIP_NO_ERROR;
}

CHIP_ERROR DeviceController::UpdateControllerNOCChain(const ByteSpan & noc, const ByteSpan & icac,
Crypto::P256Keypair * operationalKeypair,
bool operationalKeypairExternalOwned)
{
VerifyOrReturnError(mFabricIndex != kUndefinedFabricIndex, CHIP_ERROR_INTERNAL);
VerifyOrReturnError(mSystemState != nullptr, CHIP_ERROR_INTERNAL);
FabricTable * fabricTable = mSystemState->Fabrics();
CHIP_ERROR err = CHIP_NO_ERROR;
FabricId fabricId;
NodeId nodeId;
CATValues oldCats;
CATValues newCats;
ReturnErrorOnFailure(ExtractNodeIdFabricIdFromOpCert(noc, &nodeId, &fabricId));
ReturnErrorOnFailure(fabricTable->FetchCATs(mFabricIndex, oldCats));
ReturnErrorOnFailure(ExtractCATsFromOpCert(noc, newCats));

bool needCloseSession = true;
if (GetFabricInfo()->GetNodeId() == nodeId && oldCats == newCats)
{
needCloseSession = false;
}

if (operationalKeypair != nullptr)
{
err = fabricTable->UpdatePendingFabricWithProvidedOpKey(mFabricIndex, noc, icac, operationalKeypair,
operationalKeypairExternalOwned, mAdvertiseIdentity);
}
else
{
VerifyOrReturnError(fabricTable->HasOperationalKeyForFabric(mFabricIndex), CHIP_ERROR_KEY_NOT_FOUND);
err = fabricTable->UpdatePendingFabricWithOperationalKeystore(mFabricIndex, noc, icac, mAdvertiseIdentity);
}

if (err == CHIP_NO_ERROR)
{
err = fabricTable->CommitPendingFabricData();
}
else
{
fabricTable->RevertPendingFabricData();
}

ReturnErrorOnFailure(err);
if (needCloseSession)
{
// If the node id or CATs have changed, our existing CASE sessions are no longer valid,
// because the other side will think anything coming over those sessions comes from our
// old node ID, and the new CATs might not satisfy the ACL requirements of the other side.
mSystemState->SessionMgr()->ExpireAllSessionsForFabric(mFabricIndex);
}
ChipLogProgress(Controller, "Controller NOC chain has updated");
return CHIP_NO_ERROR;
}

Expand Down Expand Up @@ -397,6 +461,8 @@ DeviceCommissioner::DeviceCommissioner() :

CHIP_ERROR DeviceCommissioner::Init(CommissionerInitParams params)
{
VerifyOrReturnError(params.operationalCredentialsDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
mOperationalCredentialsDelegate = params.operationalCredentialsDelegate;
ReturnErrorOnFailure(DeviceController::Init(params));

mPairingDelegate = params.pairingDelegate;
Expand Down
23 changes: 23 additions & 0 deletions src/controller/CHIPDeviceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ struct ControllerInitParams
*/
bool removeFromFabricTableOnShutdown = true;

/**
* Specifies whether to utilize the fabric table entry for the given FabricIndex
* for initialization. If provided and neither the operational key pair nor the NOC
* chain are provided, then attempt to locate a fabric corresponding to the given FabricIndex.
*/
chip::Optional<FabricIndex> fabricIndex;

chip::VendorId controllerVendorId;
};

Expand Down Expand Up @@ -351,6 +358,20 @@ class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController
*/
CHIP_ERROR InitControllerNOCChain(const ControllerInitParams & params);

/**
* @brief Update the NOC chain of controller.
*
* @param[in] noc NOC in CHIP certificate format.
* @param[in] icac ICAC in CHIP certificate format. If no icac, an empty ByteSpan should be passed.
* @param[in] externalOperationalKeypair External operational keypair. If null, use keypair in OperationalKeystore.
* @param[in] operationalKeypairExternalOwned If true, external operational keypair must outlive the fabric.
* If false, the keypair is copied and owned in heap of a FabricInfo.
*
* @return CHIP_ERROR CHIP_NO_ERROR on success.
*/
CHIP_ERROR UpdateControllerNOCChain(const ByteSpan & noc, const ByteSpan & icac, Crypto::P256Keypair * operationalKeypair,
bool operationalKeypairExternalOwned);

protected:
enum class State
{
Expand All @@ -374,6 +395,8 @@ class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController

bool mRemoveFromFabricTableOnShutdown = true;

FabricTable::AdvertiseIdentity mAdvertiseIdentity = FabricTable::AdvertiseIdentity::Yes;

// TODO(cecille): Make this configuarable.
static constexpr int kMaxCommissionableNodes = 10;
Dnssd::DiscoveredNodeData mCommissionableNodes[kMaxCommissionableNodes];
Expand Down
4 changes: 4 additions & 0 deletions src/controller/CHIPDeviceControllerFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,10 @@ void DeviceControllerFactory::PopulateInitParams(ControllerInitParams & controll
controllerParams.controllerVendorId = params.controllerVendorId;

controllerParams.enableServerInteractions = params.enableServerInteractions;
if (params.fabricIndex.HasValue())
{
controllerParams.fabricIndex.SetValue(params.fabricIndex.Value());
}
}

void DeviceControllerFactory::ControllerInitialized(const DeviceController & controller)
Expand Down
7 changes: 7 additions & 0 deletions src/controller/CHIPDeviceControllerFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ struct SetupParams
*/
bool removeFromFabricTableOnShutdown = true;

/**
* Specifies whether to utilize the fabric table entry for the given FabricIndex
* for initialization. If provided and neither the operational key pair nor the NOC
* chain are provided, then attempt to locate a fabric corresponding to the given FabricIndex.
*/
chip::Optional<FabricIndex> fabricIndex;

Credentials::DeviceAttestationVerifier * deviceAttestationVerifier = nullptr;
CommissioningDelegate * defaultCommissioner = nullptr;
};
Expand Down

0 comments on commit be8b650

Please sign in to comment.