Matter SDK Coverage Report
Current view: top level - app/icd/client - DefaultICDClientStorage.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 93.4 % 301 281
Test Date: 2025-01-17 19:00:11 Functions: 95.7 % 23 22

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2023 Project CHIP Authors
       3              :  *    All rights reserved.
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : #include <app/icd/client/DefaultICDClientStorage.h>
      19              : #include <iterator>
      20              : #include <lib/core/Global.h>
      21              : #include <lib/support/Base64.h>
      22              : #include <lib/support/CodeUtils.h>
      23              : #include <lib/support/DefaultStorageKeyAllocator.h>
      24              : #include <lib/support/SafeInt.h>
      25              : #include <lib/support/logging/CHIPLogging.h>
      26              : #include <limits>
      27              : 
      28              : namespace {
      29              : // FabricIndex is uint8_t, the tlv size with anonymous tag is 1(control bytes) + 1(value) = 2
      30              : constexpr size_t kFabricIndexTlvSize = 2;
      31              : 
      32              : // The array itself has a control byte and an end-of-array marker.
      33              : constexpr size_t kArrayOverHead  = 2;
      34              : constexpr size_t kFabricIndexMax = 255;
      35              : 
      36              : constexpr size_t kMaxFabricListTlvLength = kFabricIndexTlvSize * kFabricIndexMax + kArrayOverHead;
      37              : static_assert(kMaxFabricListTlvLength <= std::numeric_limits<uint16_t>::max(), "Expected size for fabric list TLV is too large!");
      38              : } // namespace
      39              : 
      40              : namespace chip {
      41              : namespace app {
      42           13 : CHIP_ERROR DefaultICDClientStorage::UpdateFabricList(FabricIndex fabricIndex)
      43              : {
      44           17 :     for (auto & fabric_idx : mFabricList)
      45              :     {
      46            4 :         if (fabric_idx == fabricIndex)
      47              :         {
      48            0 :             return CHIP_NO_ERROR;
      49              :         }
      50              :     }
      51              : 
      52           13 :     mFabricList.push_back(fabricIndex);
      53              : 
      54           13 :     return StoreFabricList();
      55              : }
      56              : 
      57           16 : CHIP_ERROR DefaultICDClientStorage::StoreFabricList()
      58              : {
      59           16 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
      60           16 :     size_t counter = mFabricList.size();
      61           16 :     size_t total   = kFabricIndexTlvSize * counter + kArrayOverHead;
      62           16 :     VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY);
      63           16 :     TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total);
      64              : 
      65              :     TLV::TLVType arrayType;
      66           16 :     ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Array, arrayType));
      67           36 :     for (auto & fabric_idx : mFabricList)
      68              :     {
      69           20 :         ReturnErrorOnFailure(writer.Put(TLV::AnonymousTag(), fabric_idx));
      70              :     }
      71           16 :     ReturnErrorOnFailure(writer.EndContainer(arrayType));
      72              : 
      73           16 :     const auto len = writer.GetLengthWritten();
      74           16 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
      75              : 
      76           16 :     ReturnErrorOnFailure(writer.Finalize(backingBuffer));
      77           32 :     return mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName(), backingBuffer.Get(),
      78           16 :                                               static_cast<uint16_t>(len));
      79           16 : }
      80              : 
      81            8 : CHIP_ERROR DefaultICDClientStorage::LoadFabricList()
      82              : {
      83            8 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
      84            8 :     VerifyOrReturnError(backingBuffer.Calloc(kMaxFabricListTlvLength), CHIP_ERROR_NO_MEMORY);
      85            8 :     uint16_t length = kMaxFabricListTlvLength;
      86            8 :     ReturnErrorOnFailure(
      87              :         mpClientInfoStore->SyncGetKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName(), backingBuffer.Get(), length));
      88              : 
      89            0 :     TLV::ScopedBufferTLVReader reader(std::move(backingBuffer), length);
      90            0 :     ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Array, TLV::AnonymousTag()));
      91              :     TLV::TLVType arrayType;
      92            0 :     ReturnErrorOnFailure(reader.EnterContainer(arrayType));
      93              : 
      94            0 :     while ((reader.Next(TLV::kTLVType_UnsignedInteger, TLV::AnonymousTag())) == CHIP_NO_ERROR)
      95              :     {
      96              :         FabricIndex fabricIndex;
      97            0 :         ReturnErrorOnFailure(reader.Get(fabricIndex));
      98            0 :         mFabricList.push_back(fabricIndex);
      99              :     }
     100              : 
     101            0 :     ReturnErrorOnFailure(reader.ExitContainer(arrayType));
     102            0 :     return reader.VerifyEndOfContainer();
     103            8 : }
     104              : 
     105           29 : DefaultICDClientStorage::ICDClientInfoIteratorImpl::ICDClientInfoIteratorImpl(DefaultICDClientStorage & manager) : mManager(manager)
     106              : {
     107           29 :     mFabricListIndex = 0;
     108           29 :     mClientInfoIndex = 0;
     109           29 :     mClientInfoVector.clear();
     110           29 : }
     111              : 
     112            9 : size_t DefaultICDClientStorage::ICDClientInfoIteratorImpl::Count()
     113              : {
     114            9 :     size_t total = 0;
     115           21 :     for (auto & fabric_idx : mManager.mFabricList)
     116              :     {
     117           12 :         size_t count          = 0;
     118           12 :         size_t clientInfoSize = 0;
     119           12 :         if (mManager.LoadCounter(fabric_idx, count, clientInfoSize) != CHIP_NO_ERROR)
     120              :         {
     121            0 :             return 0;
     122              :         };
     123              :         IgnoreUnusedVariable(clientInfoSize);
     124           12 :         total += count;
     125              :     }
     126              : 
     127            9 :     return total;
     128              : }
     129              : 
     130           35 : bool DefaultICDClientStorage::ICDClientInfoIteratorImpl::Next(ICDClientInfo & item)
     131              : {
     132           45 :     for (; mFabricListIndex < mManager.mFabricList.size(); mFabricListIndex++)
     133              :     {
     134           38 :         if (mClientInfoVector.size() == 0)
     135              :         {
     136           29 :             size_t clientInfoSize = 0;
     137           29 :             if (mManager.Load(mManager.mFabricList[mFabricListIndex], mClientInfoVector, clientInfoSize) != CHIP_NO_ERROR)
     138              :             {
     139            0 :                 continue;
     140              :             }
     141              :             IgnoreUnusedVariable(clientInfoSize);
     142              :         }
     143           38 :         if (mClientInfoIndex < mClientInfoVector.size())
     144              :         {
     145           28 :             item = mClientInfoVector[mClientInfoIndex];
     146           28 :             mClientInfoIndex++;
     147           28 :             return true;
     148              :         }
     149           10 :         mClientInfoIndex = 0;
     150           10 :         mClientInfoVector.clear();
     151              :     }
     152              : 
     153            7 :     return false;
     154              : }
     155              : 
     156           29 : void DefaultICDClientStorage::ICDClientInfoIteratorImpl::Release()
     157              : {
     158           29 :     mManager.mICDClientInfoIterators.ReleaseObject(this);
     159           29 : }
     160              : 
     161            8 : CHIP_ERROR DefaultICDClientStorage::Init(PersistentStorageDelegate * clientInfoStore, Crypto::SymmetricKeystore * keyStore)
     162              : {
     163            8 :     VerifyOrReturnError(clientInfoStore != nullptr && keyStore != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     164            8 :     VerifyOrReturnError(mpClientInfoStore == nullptr && mpKeyStore == nullptr, CHIP_ERROR_INCORRECT_STATE);
     165            8 :     mpClientInfoStore = clientInfoStore;
     166            8 :     mpKeyStore        = keyStore;
     167            8 :     CHIP_ERROR err    = LoadFabricList();
     168            8 :     if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     169              :     {
     170            8 :         err = CHIP_NO_ERROR;
     171              :     }
     172            8 :     return err;
     173              : }
     174              : 
     175           29 : DefaultICDClientStorage::ICDClientInfoIterator * DefaultICDClientStorage::IterateICDClientInfo()
     176              : {
     177           29 :     return mICDClientInfoIterators.CreateObject(*this);
     178              : }
     179              : 
     180          103 : CHIP_ERROR DefaultICDClientStorage::LoadCounter(FabricIndex fabricIndex, size_t & count, size_t & clientInfoSize)
     181              : {
     182          103 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
     183          103 :     size_t len = MaxICDCounterSize();
     184          103 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
     185          103 :     VerifyOrReturnError(backingBuffer.Calloc(len), CHIP_ERROR_NO_MEMORY);
     186          103 :     uint16_t length = static_cast<uint16_t>(len);
     187              : 
     188          103 :     CHIP_ERROR err = mpClientInfoStore->SyncGetKeyValue(
     189          206 :         DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName(), backingBuffer.Get(), length);
     190          103 :     if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     191              :     {
     192           24 :         return CHIP_NO_ERROR;
     193              :     }
     194           79 :     ReturnErrorOnFailure(err);
     195              : 
     196           79 :     TLV::ScopedBufferTLVReader reader(std::move(backingBuffer), length);
     197           79 :     ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag()));
     198              :     TLV::TLVType structType;
     199           79 :     ReturnErrorOnFailure(reader.EnterContainer(structType));
     200           79 :     uint32_t tempCount = 0;
     201           79 :     ReturnErrorOnFailure(reader.Next(TLV::ContextTag(CounterTag::kCount)));
     202           79 :     ReturnErrorOnFailure(reader.Get(tempCount));
     203           79 :     count = static_cast<size_t>(tempCount);
     204              : 
     205           79 :     uint32_t tempClientInfoSize = 0;
     206           79 :     ReturnErrorOnFailure(reader.Next(TLV::ContextTag(CounterTag::kSize)));
     207           79 :     ReturnErrorOnFailure(reader.Get(tempClientInfoSize));
     208           79 :     clientInfoSize = static_cast<size_t>(tempClientInfoSize);
     209              : 
     210           79 :     ReturnErrorOnFailure(reader.ExitContainer(structType));
     211           79 :     return reader.VerifyEndOfContainer();
     212          103 : }
     213              : 
     214           61 : CHIP_ERROR DefaultICDClientStorage::Load(FabricIndex fabricIndex, std::vector<ICDClientInfo> & clientInfoVector,
     215              :                                          size_t & clientInfoSize)
     216              : {
     217           61 :     size_t count = 0;
     218           61 :     ReturnErrorOnFailure(LoadCounter(fabricIndex, count, clientInfoSize));
     219           61 :     VerifyOrReturnError(count > 0, CHIP_NO_ERROR);
     220           46 :     size_t len = clientInfoSize * count + kArrayOverHead;
     221           46 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
     222           46 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
     223           46 :     VerifyOrReturnError(backingBuffer.Calloc(len), CHIP_ERROR_NO_MEMORY);
     224           46 :     uint16_t length = static_cast<uint16_t>(len);
     225           46 :     CHIP_ERROR err  = mpClientInfoStore->SyncGetKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricIndex).KeyName(),
     226           46 :                                                          backingBuffer.Get(), length);
     227           46 :     if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     228              :     {
     229            0 :         return CHIP_NO_ERROR;
     230              :     }
     231           46 :     ReturnErrorOnFailure(err);
     232              : 
     233           46 :     TLV::ScopedBufferTLVReader reader(std::move(backingBuffer), length);
     234              : 
     235           46 :     ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Array, TLV::AnonymousTag()));
     236              :     TLV::TLVType arrayType;
     237           46 :     ReturnErrorOnFailure(reader.EnterContainer(arrayType));
     238              : 
     239           97 :     while ((err = reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag())) == CHIP_NO_ERROR)
     240              :     {
     241           51 :         ICDClientInfo clientInfo;
     242              :         TLV::TLVType ICDClientInfoType;
     243              :         NodeId nodeId;
     244              :         NodeId checkInNodeId;
     245              :         FabricIndex fabric;
     246           51 :         ReturnErrorOnFailure(reader.EnterContainer(ICDClientInfoType));
     247              :         // Peer Node ID
     248           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kPeerNodeId)));
     249           51 :         ReturnErrorOnFailure(reader.Get(nodeId));
     250              : 
     251           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kCheckInNodeId)));
     252           51 :         ReturnErrorOnFailure(reader.Get(checkInNodeId));
     253              : 
     254              :         // Fabric Index
     255           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kFabricIndex)));
     256           51 :         ReturnErrorOnFailure(reader.Get(fabric));
     257              : 
     258           51 :         clientInfo.peer_node     = ScopedNodeId(nodeId, fabric);
     259           51 :         clientInfo.check_in_node = ScopedNodeId(checkInNodeId, fabric);
     260              : 
     261              :         // Start ICD Counter
     262           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kStartICDCounter)));
     263           51 :         ReturnErrorOnFailure(reader.Get(clientInfo.start_icd_counter));
     264              : 
     265              :         // Offset
     266           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kOffset)));
     267           51 :         ReturnErrorOnFailure(reader.Get(clientInfo.offset));
     268              : 
     269              :         // MonitoredSubject
     270           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kMonitoredSubject)));
     271           51 :         ReturnErrorOnFailure(reader.Get(clientInfo.monitored_subject));
     272              : 
     273              :         // Aes key handle
     274           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kAesKeyHandle)));
     275           51 :         ByteSpan aesBuf;
     276           51 :         ReturnErrorOnFailure(reader.Get(aesBuf));
     277           51 :         VerifyOrReturnError(aesBuf.size() == sizeof(Crypto::Symmetric128BitsKeyByteArray), CHIP_ERROR_INTERNAL);
     278           51 :         memcpy(clientInfo.aes_key_handle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(), aesBuf.data(),
     279              :                sizeof(Crypto::Symmetric128BitsKeyByteArray));
     280              : 
     281              :         // Hmac key handle
     282           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kHmacKeyHandle)));
     283           51 :         ByteSpan hmacBuf;
     284           51 :         ReturnErrorOnFailure(reader.Get(hmacBuf));
     285           51 :         VerifyOrReturnError(hmacBuf.size() == sizeof(Crypto::Symmetric128BitsKeyByteArray), CHIP_ERROR_INTERNAL);
     286           51 :         memcpy(clientInfo.hmac_key_handle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(), hmacBuf.data(),
     287              :                sizeof(Crypto::Symmetric128BitsKeyByteArray));
     288              : 
     289              :         // ClientType
     290           51 :         ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kClientType)));
     291           51 :         ReturnErrorOnFailure(reader.Get(clientInfo.client_type));
     292              : 
     293           51 :         ReturnErrorOnFailure(reader.ExitContainer(ICDClientInfoType));
     294           51 :         clientInfoVector.push_back(clientInfo);
     295           51 :     }
     296              : 
     297           46 :     if (err != CHIP_END_OF_TLV)
     298              :     {
     299            0 :         return err;
     300              :     }
     301              : 
     302           46 :     ReturnErrorOnFailure(reader.ExitContainer(arrayType));
     303           46 :     return reader.VerifyEndOfContainer();
     304           46 : }
     305              : 
     306           17 : CHIP_ERROR DefaultICDClientStorage::SetKey(ICDClientInfo & clientInfo, const ByteSpan keyData)
     307              : {
     308           17 :     VerifyOrReturnError(keyData.size() == sizeof(Crypto::Symmetric128BitsKeyByteArray), CHIP_ERROR_INVALID_ARGUMENT);
     309              : 
     310              :     Crypto::Symmetric128BitsKeyByteArray keyMaterial;
     311           17 :     memcpy(keyMaterial, keyData.data(), sizeof(Crypto::Symmetric128BitsKeyByteArray));
     312              : 
     313              :     // TODO : Update key lifetime once creaKey method supports it.
     314           17 :     ReturnErrorOnFailure(mpKeyStore->CreateKey(keyMaterial, clientInfo.aes_key_handle));
     315           17 :     CHIP_ERROR err = mpKeyStore->CreateKey(keyMaterial, clientInfo.hmac_key_handle);
     316           17 :     if (err != CHIP_NO_ERROR)
     317              :     {
     318            0 :         mpKeyStore->DestroyKey(clientInfo.aes_key_handle);
     319              :     }
     320           17 :     return err;
     321              : }
     322              : 
     323           13 : void DefaultICDClientStorage::RemoveKey(ICDClientInfo & clientInfo)
     324              : {
     325           13 :     mpKeyStore->DestroyKey(clientInfo.aes_key_handle);
     326           13 :     mpKeyStore->DestroyKey(clientInfo.hmac_key_handle);
     327           13 : }
     328              : 
     329           24 : CHIP_ERROR DefaultICDClientStorage::SerializeToTlv(TLV::TLVWriter & writer, const std::vector<ICDClientInfo> & clientInfoVector)
     330              : {
     331              :     TLV::TLVType arrayType;
     332           24 :     ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Array, arrayType));
     333           50 :     for (auto & clientInfo : clientInfoVector)
     334              :     {
     335              :         TLV::TLVType ICDClientInfoContainerType;
     336           26 :         ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, ICDClientInfoContainerType));
     337           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kPeerNodeId), clientInfo.peer_node.GetNodeId()));
     338           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kCheckInNodeId), clientInfo.check_in_node.GetNodeId()));
     339           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kFabricIndex), clientInfo.peer_node.GetFabricIndex()));
     340           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kStartICDCounter), clientInfo.start_icd_counter));
     341           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kOffset), clientInfo.offset));
     342           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kMonitoredSubject), clientInfo.monitored_subject));
     343           26 :         ByteSpan aesBuf(clientInfo.aes_key_handle.As<Crypto::Symmetric128BitsKeyByteArray>());
     344           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kAesKeyHandle), aesBuf));
     345           26 :         ByteSpan hmacBuf(clientInfo.hmac_key_handle.As<Crypto::Symmetric128BitsKeyByteArray>());
     346           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kHmacKeyHandle), hmacBuf));
     347           26 :         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kClientType), clientInfo.client_type));
     348           26 :         ReturnErrorOnFailure(writer.EndContainer(ICDClientInfoContainerType));
     349              :     }
     350           24 :     return writer.EndContainer(arrayType);
     351              : }
     352              : 
     353           36 : bool DefaultICDClientStorage::FabricExists(FabricIndex fabricIndex)
     354              : {
     355           45 :     for (auto & fabric_idx : mFabricList)
     356              :     {
     357           41 :         if (fabric_idx == fabricIndex)
     358              :         {
     359           32 :             return true;
     360              :         }
     361              :     }
     362            4 :     return false;
     363              : }
     364              : 
     365           24 : CHIP_ERROR DefaultICDClientStorage::StoreEntry(const ICDClientInfo & clientInfo)
     366              : {
     367           24 :     VerifyOrReturnError(FabricExists(clientInfo.peer_node.GetFabricIndex()), CHIP_ERROR_INVALID_FABRIC_INDEX);
     368           21 :     std::vector<ICDClientInfo> clientInfoVector;
     369           21 :     size_t clientInfoSize = MaxICDClientInfoSize();
     370           21 :     ReturnErrorOnFailure(Load(clientInfo.peer_node.GetFabricIndex(), clientInfoVector, clientInfoSize));
     371              : 
     372           24 :     for (auto it = clientInfoVector.begin(); it != clientInfoVector.end(); it++)
     373              :     {
     374            9 :         if (clientInfo.peer_node.GetNodeId() == it->peer_node.GetNodeId())
     375              :         {
     376            6 :             ReturnErrorOnFailure(DecreaseEntryCountForFabric(clientInfo.peer_node.GetFabricIndex()));
     377            6 :             clientInfoVector.erase(it);
     378            6 :             break;
     379              :         }
     380              :     }
     381           21 :     clientInfoVector.push_back(clientInfo);
     382           21 :     size_t total = clientInfoSize * clientInfoVector.size() + kArrayOverHead;
     383           21 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
     384           21 :     VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY);
     385           21 :     TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total);
     386              : 
     387           21 :     ReturnErrorOnFailure(SerializeToTlv(writer, clientInfoVector));
     388              : 
     389           21 :     const auto len = writer.GetLengthWritten();
     390           21 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
     391              : 
     392           21 :     ReturnErrorOnFailure(writer.Finalize(backingBuffer));
     393           21 :     ReturnErrorOnFailure(mpClientInfoStore->SyncSetKeyValue(
     394              :         DefaultStorageKeyAllocator::ICDClientInfoKey(clientInfo.peer_node.GetFabricIndex()).KeyName(), backingBuffer.Get(),
     395              :         static_cast<uint16_t>(len)));
     396              : 
     397           21 :     ReturnErrorOnFailure(IncreaseEntryCountForFabric(clientInfo.peer_node.GetFabricIndex()));
     398           21 :     ChipLogProgress(ICD,
     399              :                     "Store ICD entry successfully with peer nodeId " ChipLogFormatScopedNodeId
     400              :                     " and checkin nodeId " ChipLogFormatScopedNodeId,
     401              :                     ChipLogValueScopedNodeId(clientInfo.peer_node), ChipLogValueScopedNodeId(clientInfo.check_in_node));
     402           21 :     return CHIP_NO_ERROR;
     403           21 : }
     404              : 
     405           21 : CHIP_ERROR DefaultICDClientStorage::IncreaseEntryCountForFabric(FabricIndex fabricIndex)
     406              : {
     407           21 :     return UpdateEntryCountForFabric(fabricIndex, /*increase*/ true);
     408              : }
     409              : 
     410            9 : CHIP_ERROR DefaultICDClientStorage::DecreaseEntryCountForFabric(FabricIndex fabricIndex)
     411              : {
     412            9 :     return UpdateEntryCountForFabric(fabricIndex, /*increase*/ false);
     413              : }
     414              : 
     415           30 : CHIP_ERROR DefaultICDClientStorage::UpdateEntryCountForFabric(FabricIndex fabricIndex, bool increase)
     416              : {
     417           30 :     size_t count          = 0;
     418           30 :     size_t clientInfoSize = MaxICDClientInfoSize();
     419           30 :     ReturnErrorOnFailure(LoadCounter(fabricIndex, count, clientInfoSize));
     420           30 :     if (increase)
     421              :     {
     422           21 :         count++;
     423              :     }
     424              :     else
     425              :     {
     426            9 :         count--;
     427              :     }
     428              : 
     429           30 :     size_t total = MaxICDCounterSize();
     430           30 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
     431           30 :     VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY);
     432           30 :     TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total);
     433              : 
     434              :     TLV::TLVType structType;
     435           30 :     ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, structType));
     436           30 :     ReturnErrorOnFailure(writer.Put(TLV::ContextTag(CounterTag::kCount), static_cast<uint32_t>(count)));
     437           30 :     ReturnErrorOnFailure(writer.Put(TLV::ContextTag(CounterTag::kSize), static_cast<uint32_t>(clientInfoSize)));
     438           30 :     ReturnErrorOnFailure(writer.EndContainer(structType));
     439              : 
     440           30 :     const auto len = writer.GetLengthWritten();
     441           30 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
     442           30 :     ReturnErrorOnFailure(writer.Finalize(backingBuffer));
     443              : 
     444           60 :     return mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName(),
     445           60 :                                               backingBuffer.Get(), static_cast<uint16_t>(len));
     446           30 : }
     447              : 
     448            4 : CHIP_ERROR DefaultICDClientStorage::DeleteEntry(const ScopedNodeId & peerNode)
     449              : {
     450            4 :     VerifyOrReturnError(FabricExists(peerNode.GetFabricIndex()), CHIP_NO_ERROR);
     451            4 :     size_t clientInfoSize = 0;
     452            4 :     std::vector<ICDClientInfo> clientInfoVector;
     453            4 :     ReturnErrorOnFailure(Load(peerNode.GetFabricIndex(), clientInfoVector, clientInfoSize));
     454            4 :     VerifyOrReturnError(clientInfoVector.size() > 0, CHIP_NO_ERROR);
     455              : 
     456            3 :     for (auto it = clientInfoVector.begin(); it != clientInfoVector.end(); it++)
     457              :     {
     458            3 :         if (peerNode.GetNodeId() == it->peer_node.GetNodeId())
     459              :         {
     460            3 :             RemoveKey(*it);
     461            3 :             it = clientInfoVector.erase(it);
     462            3 :             break;
     463              :         }
     464              :     }
     465              : 
     466            3 :     ReturnErrorOnFailure(
     467              :         mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(peerNode.GetFabricIndex()).KeyName()));
     468            3 :     size_t total = clientInfoSize * clientInfoVector.size() + kArrayOverHead;
     469            3 :     Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
     470            3 :     VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY);
     471            3 :     TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total);
     472              : 
     473            3 :     ReturnErrorOnFailure(SerializeToTlv(writer, clientInfoVector));
     474              : 
     475            3 :     const auto len = writer.GetLengthWritten();
     476            3 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
     477              : 
     478            3 :     ReturnErrorOnFailure(writer.Finalize(backingBuffer));
     479            3 :     ReturnErrorOnFailure(
     480              :         mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(peerNode.GetFabricIndex()).KeyName(),
     481              :                                            backingBuffer.Get(), static_cast<uint16_t>(len)));
     482              : 
     483            3 :     ReturnErrorOnFailure(DecreaseEntryCountForFabric(peerNode.GetFabricIndex()));
     484            3 :     ChipLogProgress(ICD, "Remove ICD entry successfully with peer nodeId " ChipLogFormatScopedNodeId,
     485              :                     ChipLogValueScopedNodeId(peerNode));
     486            3 :     return CHIP_NO_ERROR;
     487            4 : }
     488              : 
     489            8 : CHIP_ERROR DefaultICDClientStorage::DeleteAllEntries(FabricIndex fabricIndex)
     490              : {
     491            8 :     VerifyOrReturnError(FabricExists(fabricIndex), CHIP_NO_ERROR);
     492              : 
     493            7 :     size_t clientInfoSize = 0;
     494            7 :     std::vector<ICDClientInfo> clientInfoVector;
     495            7 :     ReturnErrorOnFailure(Load(fabricIndex, clientInfoVector, clientInfoSize));
     496              :     IgnoreUnusedVariable(clientInfoSize);
     497           16 :     for (auto & clientInfo : clientInfoVector)
     498              :     {
     499            9 :         RemoveKey(clientInfo);
     500              :     }
     501            7 :     ReturnErrorOnFailure(
     502              :         mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricIndex).KeyName()));
     503            7 :     ReturnErrorOnFailure(
     504              :         mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName()));
     505              : 
     506            8 :     for (auto fabric = mFabricList.begin(); fabric != mFabricList.end(); fabric++)
     507              :     {
     508            8 :         if (*fabric == fabricIndex)
     509              :         {
     510            7 :             mFabricList.erase(fabric);
     511            7 :             break;
     512              :         }
     513              :     }
     514              : 
     515            7 :     if (mFabricList.size() == 0)
     516              :     {
     517            4 :         return mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName());
     518              :     }
     519              : 
     520            3 :     ReturnErrorOnFailure(StoreFabricList());
     521            3 :     ChipLogProgress(ICD, "Remove all ICD entries successfully for fabric index %u", fabricIndex);
     522            3 :     return CHIP_NO_ERROR;
     523            7 : }
     524              : 
     525           15 : CHIP_ERROR DefaultICDClientStorage::ProcessCheckInPayload(const ByteSpan & payload, ICDClientInfo & clientInfo,
     526              :                                                           Protocols::SecureChannel::CounterType & counter)
     527              : {
     528              :     uint8_t appDataBuffer[kAppDataLength];
     529           15 :     MutableByteSpan appData(appDataBuffer);
     530           15 :     auto * iterator = IterateICDClientInfo();
     531           15 :     VerifyOrReturnError(iterator != nullptr, CHIP_ERROR_NO_MEMORY);
     532           20 :     while (iterator->Next(clientInfo))
     533              :     {
     534           16 :         CHIP_ERROR err = chip::Protocols::SecureChannel::CheckinMessage::ParseCheckinMessagePayload(
     535           16 :             clientInfo.aes_key_handle, clientInfo.hmac_key_handle, payload, counter, appData);
     536           16 :         if (CHIP_NO_ERROR == err)
     537              :         {
     538           11 :             iterator->Release();
     539           11 :             return CHIP_NO_ERROR;
     540              :         }
     541              :     }
     542            4 :     iterator->Release();
     543            4 :     return CHIP_ERROR_NOT_FOUND;
     544              : }
     545              : 
     546            0 : void DefaultICDClientStorage::Shutdown()
     547              : {
     548            0 :     mICDClientInfoIterators.ReleaseAll();
     549            0 :     mpClientInfoStore = nullptr;
     550            0 :     mpKeyStore        = nullptr;
     551            0 :     mFabricList.clear();
     552            0 : }
     553              : 
     554              : } // namespace app
     555              : } // namespace chip
        

Generated by: LCOV version 2.0-1