Skip to content

Commit 6af5226

Browse files
committedMay 29, 2024
Add ability to add pending fabric at a chosen fabric index
Currently it's only possible to allocate fabric indexes sequentially starting from 1. Sparse fabric tables could be produced by adding & removing fabrics, but not directly. This allow the application to control the assignment of fabric ids directly by providing a function that overrides the next index to use. eg If an application has 3 fabrics, it can recreate the fabric table from scratch while keeping consistent indexes.
1 parent 8c8889b commit 6af5226

File tree

3 files changed

+96
-16
lines changed

3 files changed

+96
-16
lines changed
 

‎src/credentials/FabricTable.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -2124,4 +2124,16 @@ CHIP_ERROR FabricTable::PeekFabricIndexForNextAddition(FabricIndex & outIndex)
21242124
return CHIP_NO_ERROR;
21252125
}
21262126

2127+
CHIP_ERROR FabricTable::SetFabricIndexForNextAddition(FabricIndex fabricIndex)
2128+
{
2129+
VerifyOrReturnError(!mStateFlags.Has(StateFlags::kIsPendingFabricDataPresent), CHIP_ERROR_INCORRECT_STATE);
2130+
VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX);
2131+
2132+
const FabricInfo * fabricInfo = FindFabricWithIndex(fabricIndex);
2133+
VerifyOrReturnError(fabricInfo == nullptr, CHIP_ERROR_FABRIC_EXISTS);
2134+
2135+
mNextAvailableFabricIndex.SetValue(fabricIndex);
2136+
return CHIP_NO_ERROR;
2137+
}
2138+
21272139
} // namespace chip

‎src/credentials/FabricTable.h

+7
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,13 @@ class DLL_EXPORT FabricTable
10031003
*/
10041004
CHIP_ERROR PeekFabricIndexForNextAddition(FabricIndex & outIndex);
10051005

1006+
/**
1007+
* Set the fabric index that will be used fo the next fabric added.
1008+
*
1009+
* Returns an error if the |fabricIndex| is already in use.
1010+
*/
1011+
CHIP_ERROR SetFabricIndexForNextAddition(FabricIndex fabricIndex);
1012+
10061013
private:
10071014
enum class StateFlags : uint16_t
10081015
{

‎src/credentials/tests/TestFabricTable.cpp

+77-16
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ class ScopedFabricTable
7979
chip::Credentials::PersistentStorageOpCertStore mOpCertStore;
8080
};
8181

82+
constexpr FabricId kNode01_01_FabricId = 0xFAB000000000001D;
83+
84+
constexpr FabricId kNode02_01_FabricId = 0xFAB000000000001D;
85+
8286
/**
8387
* Load a single test fabric with with the Root01:ICA01:Node01_01 identity.
8488
*/
@@ -183,6 +187,18 @@ static CHIP_ERROR LoadTestFabric_Node02_01(FabricTable & fabricTable, bool doCom
183187
return err;
184188
}
185189

190+
const FabricInfo * FindFabric(FabricTable & fabricTable, ByteSpan rootPublicKey, FabricId fabricId)
191+
{
192+
Crypto::P256PublicKey key;
193+
EXPECT_GE(key.Length(), rootPublicKey.size());
194+
if (key.Length() < rootPublicKey.size())
195+
{
196+
return nullptr;
197+
}
198+
memcpy(key.Bytes(), rootPublicKey.data(), rootPublicKey.size());
199+
return fabricTable.FindFabric(key, fabricId);
200+
}
201+
186202
struct TestFabricTable : public ::testing::Test
187203
{
188204

@@ -2281,14 +2297,7 @@ TEST_F(TestFabricTable, TestFabricLookup)
22812297

22822298
// Attempt lookup of the Root01 fabric.
22832299
{
2284-
Crypto::P256PublicKey key;
2285-
EXPECT_GE(key.Length(), TestCerts::sTestCert_Root01_PublicKey.size());
2286-
if (key.Length() < TestCerts::sTestCert_Root01_PublicKey.size())
2287-
{
2288-
return;
2289-
}
2290-
memcpy(key.Bytes(), TestCerts::sTestCert_Root01_PublicKey.data(), TestCerts::sTestCert_Root01_PublicKey.size());
2291-
auto fabricInfo = fabricTable.FindFabric(key, 0xFAB000000000001D);
2300+
auto fabricInfo = FindFabric(fabricTable, TestCerts::sTestCert_Root01_PublicKey, kNode01_01_FabricId);
22922301
ASSERT_NE(fabricInfo, nullptr);
22932302

22942303
EXPECT_EQ(fabricInfo->GetFabricIndex(), 1);
@@ -2297,14 +2306,7 @@ TEST_F(TestFabricTable, TestFabricLookup)
22972306

22982307
// Attempt lookup of the Root02 fabric.
22992308
{
2300-
Crypto::P256PublicKey key;
2301-
EXPECT_GE(key.Length(), TestCerts::sTestCert_Root02_PublicKey.size());
2302-
if (key.Length() < TestCerts::sTestCert_Root02_PublicKey.size())
2303-
{
2304-
return;
2305-
}
2306-
memcpy(key.Bytes(), TestCerts::sTestCert_Root02_PublicKey.data(), TestCerts::sTestCert_Root02_PublicKey.size());
2307-
auto fabricInfo = fabricTable.FindFabric(key, 0xFAB000000000001D);
2309+
auto fabricInfo = FindFabric(fabricTable, TestCerts::sTestCert_Root02_PublicKey, kNode02_01_FabricId);
23082310
ASSERT_NE(fabricInfo, nullptr);
23092311

23102312
EXPECT_EQ(fabricInfo->GetFabricIndex(), 2);
@@ -2317,6 +2319,65 @@ TEST_F(TestFabricTable, TestFabricLookup)
23172319
}
23182320
}
23192321

2322+
TEST_F(TestFabricTable, ShouldFailSetFabricIndexWithInvalidIndex)
2323+
{
2324+
chip::TestPersistentStorageDelegate testStorage;
2325+
ScopedFabricTable fabricTableHolder;
2326+
EXPECT_EQ(fabricTableHolder.Init(&testStorage), CHIP_NO_ERROR);
2327+
FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
2328+
2329+
EXPECT_EQ(fabricTable.SetFabricIndexForNextAddition(kUndefinedFabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX);
2330+
}
2331+
2332+
TEST_F(TestFabricTable, ShouldFailSetFabricIndexWithPendingFabric)
2333+
{
2334+
chip::TestPersistentStorageDelegate testStorage;
2335+
ScopedFabricTable fabricTableHolder;
2336+
EXPECT_EQ(fabricTableHolder.Init(&testStorage), CHIP_NO_ERROR);
2337+
FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
2338+
2339+
EXPECT_EQ(fabricTable.AddNewPendingTrustedRootCert(ByteSpan(TestCerts::sTestCert_Root01_Chip)), CHIP_NO_ERROR);
2340+
2341+
EXPECT_EQ(fabricTable.SetFabricIndexForNextAddition(1), CHIP_ERROR_INCORRECT_STATE);
2342+
}
2343+
2344+
TEST_F(TestFabricTable, ShouldFailSetFabricIndexWhenInUse)
2345+
{
2346+
chip::TestPersistentStorageDelegate testStorage;
2347+
ScopedFabricTable fabricTableHolder;
2348+
EXPECT_EQ(fabricTableHolder.Init(&testStorage), CHIP_NO_ERROR);
2349+
FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
2350+
2351+
EXPECT_EQ(LoadTestFabric_Node01_01(fabricTable, /* doCommit = */ true), CHIP_NO_ERROR);
2352+
EXPECT_EQ(fabricTable.SetFabricIndexForNextAddition(1), CHIP_ERROR_FABRIC_EXISTS);
2353+
}
2354+
2355+
TEST_F(TestFabricTable, ShouldAddFabricAtRequestedIndex)
2356+
{
2357+
chip::TestPersistentStorageDelegate testStorage;
2358+
ScopedFabricTable fabricTableHolder;
2359+
EXPECT_EQ(fabricTableHolder.Init(&testStorage), CHIP_NO_ERROR);
2360+
FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
2361+
2362+
EXPECT_EQ(fabricTable.SetFabricIndexForNextAddition(2), CHIP_NO_ERROR);
2363+
EXPECT_EQ(LoadTestFabric_Node02_01(fabricTable, /* doCommit = */ true), CHIP_NO_ERROR);
2364+
2365+
EXPECT_EQ(fabricTable.SetFabricIndexForNextAddition(1), CHIP_NO_ERROR);
2366+
EXPECT_EQ(LoadTestFabric_Node01_01(fabricTable, /* doCommit = */ true), CHIP_NO_ERROR);
2367+
2368+
{
2369+
auto fabricInfo = FindFabric(fabricTable, TestCerts::sTestCert_Root01_PublicKey, kNode01_01_FabricId);
2370+
ASSERT_NE(fabricInfo, nullptr);
2371+
EXPECT_EQ(fabricInfo->GetFabricIndex(), 1);
2372+
}
2373+
2374+
{
2375+
auto fabricInfo = FindFabric(fabricTable, TestCerts::sTestCert_Root02_PublicKey, kNode02_01_FabricId);
2376+
ASSERT_NE(fabricInfo, nullptr);
2377+
EXPECT_EQ(fabricInfo->GetFabricIndex(), 2);
2378+
}
2379+
}
2380+
23202381
TEST_F(TestFabricTable, TestFetchCATs)
23212382
{
23222383
// Initialize a fabric table.

0 commit comments

Comments
 (0)