Skip to content

Commit f2353ad

Browse files
authored
Setup controller by given fabric index without providing NOC chain and update NOC after DeviceController::Init (project-chip#32194)
1 parent c89090c commit f2353ad

4 files changed

+105
-4
lines changed

src/controller/CHIPDeviceController.cpp

+70-4
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,24 @@ CHIP_ERROR DeviceController::Init(ControllerInitParams params)
112112
mDNSResolver.SetCommissioningDelegate(this);
113113
RegisterDeviceDiscoveryDelegate(params.deviceDiscoveryDelegate);
114114

115-
VerifyOrReturnError(params.operationalCredentialsDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
116-
mOperationalCredentialsDelegate = params.operationalCredentialsDelegate;
117-
118115
mVendorId = params.controllerVendorId;
119116
if (params.operationalKeypair != nullptr || !params.controllerNOC.empty() || !params.controllerRCAC.empty())
120117
{
121118
ReturnErrorOnFailure(InitControllerNOCChain(params));
122119
}
120+
else if (params.fabricIndex.HasValue())
121+
{
122+
VerifyOrReturnError(params.systemState->Fabrics()->FabricCount() > 0, CHIP_ERROR_INVALID_ARGUMENT);
123+
if (params.systemState->Fabrics()->FindFabricWithIndex(params.fabricIndex.Value()) != nullptr)
124+
{
125+
mFabricIndex = params.fabricIndex.Value();
126+
}
127+
else
128+
{
129+
ChipLogError(Controller, "There is no fabric corresponding to the given fabricIndex");
130+
return CHIP_ERROR_INVALID_ARGUMENT;
131+
}
132+
}
123133

124134
mSystemState = params.systemState->Retain();
125135
mState = State::Initialized;
@@ -306,8 +316,62 @@ CHIP_ERROR DeviceController::InitControllerNOCChain(const ControllerInitParams &
306316
ReturnErrorOnFailure(err);
307317
VerifyOrReturnError(fabricIndex != kUndefinedFabricIndex, CHIP_ERROR_INTERNAL);
308318

309-
mFabricIndex = fabricIndex;
319+
mFabricIndex = fabricIndex;
320+
mAdvertiseIdentity = advertiseOperational;
321+
return CHIP_NO_ERROR;
322+
}
323+
324+
CHIP_ERROR DeviceController::UpdateControllerNOCChain(const ByteSpan & noc, const ByteSpan & icac,
325+
Crypto::P256Keypair * operationalKeypair,
326+
bool operationalKeypairExternalOwned)
327+
{
328+
VerifyOrReturnError(mFabricIndex != kUndefinedFabricIndex, CHIP_ERROR_INTERNAL);
329+
VerifyOrReturnError(mSystemState != nullptr, CHIP_ERROR_INTERNAL);
330+
FabricTable * fabricTable = mSystemState->Fabrics();
331+
CHIP_ERROR err = CHIP_NO_ERROR;
332+
FabricId fabricId;
333+
NodeId nodeId;
334+
CATValues oldCats;
335+
CATValues newCats;
336+
ReturnErrorOnFailure(ExtractNodeIdFabricIdFromOpCert(noc, &nodeId, &fabricId));
337+
ReturnErrorOnFailure(fabricTable->FetchCATs(mFabricIndex, oldCats));
338+
ReturnErrorOnFailure(ExtractCATsFromOpCert(noc, newCats));
310339

340+
bool needCloseSession = true;
341+
if (GetFabricInfo()->GetNodeId() == nodeId && oldCats == newCats)
342+
{
343+
needCloseSession = false;
344+
}
345+
346+
if (operationalKeypair != nullptr)
347+
{
348+
err = fabricTable->UpdatePendingFabricWithProvidedOpKey(mFabricIndex, noc, icac, operationalKeypair,
349+
operationalKeypairExternalOwned, mAdvertiseIdentity);
350+
}
351+
else
352+
{
353+
VerifyOrReturnError(fabricTable->HasOperationalKeyForFabric(mFabricIndex), CHIP_ERROR_KEY_NOT_FOUND);
354+
err = fabricTable->UpdatePendingFabricWithOperationalKeystore(mFabricIndex, noc, icac, mAdvertiseIdentity);
355+
}
356+
357+
if (err == CHIP_NO_ERROR)
358+
{
359+
err = fabricTable->CommitPendingFabricData();
360+
}
361+
else
362+
{
363+
fabricTable->RevertPendingFabricData();
364+
}
365+
366+
ReturnErrorOnFailure(err);
367+
if (needCloseSession)
368+
{
369+
// If the node id or CATs have changed, our existing CASE sessions are no longer valid,
370+
// because the other side will think anything coming over those sessions comes from our
371+
// old node ID, and the new CATs might not satisfy the ACL requirements of the other side.
372+
mSystemState->SessionMgr()->ExpireAllSessionsForFabric(mFabricIndex);
373+
}
374+
ChipLogProgress(Controller, "Controller NOC chain has updated");
311375
return CHIP_NO_ERROR;
312376
}
313377

@@ -398,6 +462,8 @@ DeviceCommissioner::DeviceCommissioner() :
398462

399463
CHIP_ERROR DeviceCommissioner::Init(CommissionerInitParams params)
400464
{
465+
VerifyOrReturnError(params.operationalCredentialsDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
466+
mOperationalCredentialsDelegate = params.operationalCredentialsDelegate;
401467
ReturnErrorOnFailure(DeviceController::Init(params));
402468

403469
mPairingDelegate = params.pairingDelegate;

src/controller/CHIPDeviceController.h

+24
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,13 @@ struct ControllerInitParams
135135
*/
136136
bool removeFromFabricTableOnShutdown = true;
137137

138+
/**
139+
* Specifies whether to utilize the fabric table entry for the given FabricIndex
140+
* for initialization. If provided and neither the operational key pair nor the NOC
141+
* chain are provided, then attempt to locate a fabric corresponding to the given FabricIndex.
142+
*/
143+
chip::Optional<FabricIndex> fabricIndex;
144+
138145
chip::VendorId controllerVendorId;
139146
};
140147

@@ -350,6 +357,21 @@ class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController
350357
*/
351358
CHIP_ERROR InitControllerNOCChain(const ControllerInitParams & params);
352359

360+
/**
361+
* @brief Update the NOC chain of controller.
362+
*
363+
* @param[in] noc NOC in CHIP certificate format.
364+
* @param[in] icac ICAC in CHIP certificate format. If no icac is present, an empty
365+
* ByteSpan should be passed.
366+
* @param[in] externalOperationalKeypair External operational keypair. If null, use keypair in OperationalKeystore.
367+
* @param[in] operationalKeypairExternalOwned If true, external operational keypair must outlive the fabric.
368+
* If false, the keypair is copied and owned in heap of a FabricInfo.
369+
*
370+
* @return CHIP_ERROR CHIP_NO_ERROR on success.
371+
*/
372+
CHIP_ERROR UpdateControllerNOCChain(const ByteSpan & noc, const ByteSpan & icac, Crypto::P256Keypair * operationalKeypair,
373+
bool operationalKeypairExternalOwned);
374+
353375
protected:
354376
enum class State
355377
{
@@ -373,6 +395,8 @@ class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController
373395

374396
bool mRemoveFromFabricTableOnShutdown = true;
375397

398+
FabricTable::AdvertiseIdentity mAdvertiseIdentity = FabricTable::AdvertiseIdentity::Yes;
399+
376400
// TODO(cecille): Make this configuarable.
377401
static constexpr int kMaxCommissionableNodes = 10;
378402
Dnssd::DiscoveredNodeData mCommissionableNodes[kMaxCommissionableNodes];

src/controller/CHIPDeviceControllerFactory.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,10 @@ void DeviceControllerFactory::PopulateInitParams(ControllerInitParams & controll
310310
controllerParams.controllerVendorId = params.controllerVendorId;
311311

312312
controllerParams.enableServerInteractions = params.enableServerInteractions;
313+
if (params.fabricIndex.HasValue())
314+
{
315+
controllerParams.fabricIndex.SetValue(params.fabricIndex.Value());
316+
}
313317
}
314318

315319
void DeviceControllerFactory::ControllerInitialized(const DeviceController & controller)

src/controller/CHIPDeviceControllerFactory.h

+7
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ struct SetupParams
102102
*/
103103
bool removeFromFabricTableOnShutdown = true;
104104

105+
/**
106+
* Specifies whether to utilize the fabric table entry for the given FabricIndex
107+
* for initialization. If provided and neither the operational key pair nor the NOC
108+
* chain are provided, then attempt to locate a fabric corresponding to the given FabricIndex.
109+
*/
110+
chip::Optional<FabricIndex> fabricIndex;
111+
105112
Credentials::DeviceAttestationVerifier * deviceAttestationVerifier = nullptr;
106113
CommissioningDelegate * defaultCommissioner = nullptr;
107114
};

0 commit comments

Comments
 (0)