Matter SDK Coverage Report
Current view: top level - protocols/secure_channel - SimpleSessionResumptionStorage.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 98.3 % 118 116
Test Date: 2025-01-17 19:00:11 Functions: 100.0 % 10 10

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2022 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              : /**
      19              :  *    @file
      20              :  *      This file defines the CHIP CASE Session object that provides
      21              :  *      APIs for constructing a secure session using a certificate from the device's
      22              :  *      operational credentials.
      23              :  */
      24              : 
      25              : #include <protocols/secure_channel/SimpleSessionResumptionStorage.h>
      26              : 
      27              : #include <lib/support/Base64.h>
      28              : #include <lib/support/SafeInt.h>
      29              : 
      30              : namespace chip {
      31              : 
      32              : constexpr TLV::Tag SimpleSessionResumptionStorage::kFabricIndexTag;
      33              : constexpr TLV::Tag SimpleSessionResumptionStorage::kPeerNodeIdTag;
      34              : constexpr TLV::Tag SimpleSessionResumptionStorage::kResumptionIdTag;
      35              : constexpr TLV::Tag SimpleSessionResumptionStorage::kSharedSecretTag;
      36              : constexpr TLV::Tag SimpleSessionResumptionStorage::kCATTag;
      37              : 
      38          879 : StorageKeyName SimpleSessionResumptionStorage::GetStorageKey(const ScopedNodeId & node)
      39              : {
      40          879 :     return DefaultStorageKeyAllocator::FabricSession(node.GetFabricIndex(), node.GetNodeId());
      41              : }
      42              : 
      43          683 : StorageKeyName SimpleSessionResumptionStorage::GetStorageKey(ConstResumptionIdView resumptionId)
      44              : {
      45              :     char resumptionIdBase64[BASE64_ENCODED_LEN(resumptionId.size()) + 1];
      46          683 :     auto len                = Base64Encode(resumptionId.data(), resumptionId.size(), resumptionIdBase64);
      47          683 :     resumptionIdBase64[len] = '\0';
      48          683 :     return DefaultStorageKeyAllocator::SessionResumption(resumptionIdBase64);
      49              : }
      50              : 
      51          218 : CHIP_ERROR SimpleSessionResumptionStorage::SaveIndex(const SessionIndex & index)
      52              : {
      53              :     std::array<uint8_t, MaxIndexSize()> buf;
      54          218 :     TLV::TLVWriter writer;
      55          218 :     writer.Init(buf);
      56              : 
      57              :     TLV::TLVType arrayType;
      58          218 :     ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Array, arrayType));
      59              : 
      60         5340 :     for (size_t i = 0; i < index.mSize; ++i)
      61              :     {
      62              :         TLV::TLVType innerType;
      63         5122 :         ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, innerType));
      64         5122 :         ReturnErrorOnFailure(writer.Put(kFabricIndexTag, index.mNodes[i].GetFabricIndex()));
      65         5122 :         ReturnErrorOnFailure(writer.Put(kPeerNodeIdTag, index.mNodes[i].GetNodeId()));
      66         5122 :         ReturnErrorOnFailure(writer.EndContainer(innerType));
      67              :     }
      68              : 
      69          218 :     ReturnErrorOnFailure(writer.EndContainer(arrayType));
      70              : 
      71          218 :     const auto len = writer.GetLengthWritten();
      72          218 :     VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
      73              : 
      74          218 :     ReturnErrorOnFailure(mStorage->SyncSetKeyValue(DefaultStorageKeyAllocator::SessionResumptionIndex().KeyName(), buf.data(),
      75              :                                                    static_cast<uint16_t>(len)));
      76              : 
      77          218 :     return CHIP_NO_ERROR;
      78              : }
      79              : 
      80          278 : CHIP_ERROR SimpleSessionResumptionStorage::LoadIndex(SessionIndex & index)
      81              : {
      82              :     std::array<uint8_t, MaxIndexSize()> buf;
      83          278 :     uint16_t len = static_cast<uint16_t>(buf.size());
      84              : 
      85          278 :     if (mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::SessionResumptionIndex().KeyName(), buf.data(), len) != CHIP_NO_ERROR)
      86              :     {
      87            5 :         index.mSize = 0;
      88            5 :         return CHIP_NO_ERROR;
      89              :     }
      90              : 
      91          273 :     TLV::ContiguousBufferTLVReader reader;
      92          273 :     reader.Init(buf.data(), len);
      93              : 
      94          273 :     ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Array, TLV::AnonymousTag()));
      95              :     TLV::TLVType arrayType;
      96          273 :     ReturnErrorOnFailure(reader.EnterContainer(arrayType));
      97              : 
      98          273 :     size_t count = 0;
      99              :     CHIP_ERROR err;
     100         5569 :     while ((err = reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag())) == CHIP_NO_ERROR)
     101              :     {
     102         5296 :         if (count >= ArraySize(index.mNodes))
     103              :         {
     104            0 :             return CHIP_ERROR_NO_MEMORY;
     105              :         }
     106              : 
     107              :         TLV::TLVType containerType;
     108         5296 :         ReturnErrorOnFailure(reader.EnterContainer(containerType));
     109              : 
     110              :         FabricIndex fabricIndex;
     111         5296 :         ReturnErrorOnFailure(reader.Next(kFabricIndexTag));
     112         5296 :         ReturnErrorOnFailure(reader.Get(fabricIndex));
     113              : 
     114              :         NodeId peerNodeId;
     115         5296 :         ReturnErrorOnFailure(reader.Next(kPeerNodeIdTag));
     116         5296 :         ReturnErrorOnFailure(reader.Get(peerNodeId));
     117              : 
     118         5296 :         index.mNodes[count++] = ScopedNodeId(peerNodeId, fabricIndex);
     119              : 
     120         5296 :         ReturnErrorOnFailure(reader.ExitContainer(containerType));
     121              :     }
     122              : 
     123          273 :     if (err != CHIP_END_OF_TLV)
     124              :     {
     125            0 :         return err;
     126              :     }
     127              : 
     128          273 :     ReturnErrorOnFailure(reader.ExitContainer(arrayType));
     129          273 :     ReturnErrorOnFailure(reader.VerifyEndOfContainer());
     130              : 
     131          273 :     index.mSize = count;
     132              : 
     133          273 :     return CHIP_NO_ERROR;
     134              : }
     135              : 
     136          207 : CHIP_ERROR SimpleSessionResumptionStorage::SaveLink(ConstResumptionIdView resumptionId, const ScopedNodeId & node)
     137              : {
     138              :     // Save a link from resumptionId to node, in key: /g/s/<resumptionId>
     139              :     std::array<uint8_t, MaxScopedNodeIdSize()> buf;
     140          207 :     TLV::TLVWriter writer;
     141          207 :     writer.Init(buf);
     142              : 
     143              :     TLV::TLVType outerType;
     144          207 :     ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerType));
     145          207 :     ReturnErrorOnFailure(writer.Put(kFabricIndexTag, node.GetFabricIndex()));
     146          207 :     ReturnErrorOnFailure(writer.Put(kPeerNodeIdTag, node.GetNodeId()));
     147          207 :     ReturnErrorOnFailure(writer.EndContainer(outerType));
     148              : 
     149          207 :     const auto len = writer.GetLengthWritten();
     150          207 :     VerifyOrDie(CanCastTo<uint16_t>(len));
     151              : 
     152          207 :     ReturnErrorOnFailure(mStorage->SyncSetKeyValue(GetStorageKey(resumptionId).KeyName(), buf.data(), static_cast<uint16_t>(len)));
     153          207 :     return CHIP_NO_ERROR;
     154              : }
     155              : 
     156          163 : CHIP_ERROR SimpleSessionResumptionStorage::LoadLink(ConstResumptionIdView resumptionId, ScopedNodeId & node)
     157              : {
     158              :     std::array<uint8_t, MaxScopedNodeIdSize()> buf;
     159          163 :     uint16_t len = static_cast<uint16_t>(buf.size());
     160              : 
     161          163 :     ReturnErrorOnFailure(mStorage->SyncGetKeyValue(GetStorageKey(resumptionId).KeyName(), buf.data(), len));
     162              : 
     163           56 :     TLV::ContiguousBufferTLVReader reader;
     164           56 :     reader.Init(buf.data(), len);
     165              : 
     166           56 :     ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag()));
     167              :     TLV::TLVType containerType;
     168           56 :     ReturnErrorOnFailure(reader.EnterContainer(containerType));
     169              : 
     170              :     FabricIndex fabricIndex;
     171           56 :     ReturnErrorOnFailure(reader.Next(kFabricIndexTag));
     172           56 :     ReturnErrorOnFailure(reader.Get(fabricIndex));
     173              : 
     174              :     NodeId peerNodeId;
     175           56 :     ReturnErrorOnFailure(reader.Next(kPeerNodeIdTag));
     176           56 :     ReturnErrorOnFailure(reader.Get(peerNodeId));
     177              : 
     178           56 :     ReturnErrorOnFailure(reader.ExitContainer(containerType));
     179           56 :     ReturnErrorOnFailure(reader.VerifyEndOfContainer());
     180              : 
     181           56 :     node = ScopedNodeId(peerNodeId, fabricIndex);
     182              : 
     183           56 :     return CHIP_NO_ERROR;
     184              : }
     185              : 
     186          159 : CHIP_ERROR SimpleSessionResumptionStorage::DeleteLink(ConstResumptionIdView resumptionId)
     187              : {
     188          159 :     ReturnErrorOnFailure(mStorage->SyncDeleteKeyValue(GetStorageKey(resumptionId).KeyName()));
     189          159 :     return CHIP_NO_ERROR;
     190              : }
     191              : 
     192          207 : CHIP_ERROR SimpleSessionResumptionStorage::SaveState(const ScopedNodeId & node, ConstResumptionIdView resumptionId,
     193              :                                                      const Crypto::P256ECDHDerivedSecret & sharedSecret, const CATValues & peerCATs)
     194              : {
     195              :     // Save session state into key: /f/<fabricIndex>/s/<nodeId>
     196              :     std::array<uint8_t, MaxStateSize()> buf;
     197          207 :     TLV::TLVWriter writer;
     198          207 :     writer.Init(buf);
     199              : 
     200              :     TLV::TLVType outerType;
     201          207 :     ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerType));
     202              : 
     203          207 :     ReturnErrorOnFailure(writer.Put(kResumptionIdTag, resumptionId));
     204              : 
     205          207 :     ReturnErrorOnFailure(writer.Put(kSharedSecretTag, ByteSpan(sharedSecret.ConstBytes(), sharedSecret.Length())));
     206              : 
     207              :     CATValues::Serialized cat;
     208          207 :     peerCATs.Serialize(cat);
     209          207 :     ReturnErrorOnFailure(writer.Put(kCATTag, ByteSpan(cat)));
     210              : 
     211          207 :     ReturnErrorOnFailure(writer.EndContainer(outerType));
     212              : 
     213          207 :     const auto len = writer.GetLengthWritten();
     214          207 :     VerifyOrDie(CanCastTo<uint16_t>(len));
     215              : 
     216          207 :     ReturnErrorOnFailure(mStorage->SyncSetKeyValue(GetStorageKey(node).KeyName(), buf.data(), static_cast<uint16_t>(len)));
     217          207 :     return CHIP_NO_ERROR;
     218              : }
     219              : 
     220          472 : CHIP_ERROR SimpleSessionResumptionStorage::LoadState(const ScopedNodeId & node, ResumptionIdStorage & resumptionId,
     221              :                                                      Crypto::P256ECDHDerivedSecret & sharedSecret, CATValues & peerCATs)
     222              : {
     223              :     std::array<uint8_t, MaxStateSize()> buf;
     224          472 :     uint16_t len = static_cast<uint16_t>(buf.size());
     225              : 
     226          472 :     ReturnErrorOnFailure(mStorage->SyncGetKeyValue(GetStorageKey(node).KeyName(), buf.data(), len));
     227              : 
     228          317 :     TLV::ContiguousBufferTLVReader reader;
     229          317 :     reader.Init(buf.data(), len);
     230              : 
     231          317 :     ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag()));
     232              :     TLV::TLVType containerType;
     233          317 :     ReturnErrorOnFailure(reader.EnterContainer(containerType));
     234              : 
     235          317 :     ByteSpan resumptionIdSpan;
     236          317 :     ReturnErrorOnFailure(reader.Next(kResumptionIdTag));
     237          317 :     ReturnErrorOnFailure(reader.Get(resumptionIdSpan));
     238          317 :     VerifyOrReturnError(resumptionIdSpan.size() == resumptionId.size(), CHIP_ERROR_KEY_NOT_FOUND);
     239          317 :     std::copy(resumptionIdSpan.begin(), resumptionIdSpan.end(), resumptionId.begin());
     240              : 
     241          317 :     ByteSpan sharedSecretSpan;
     242          317 :     ReturnErrorOnFailure(reader.Next(kSharedSecretTag));
     243          317 :     ReturnErrorOnFailure(reader.Get(sharedSecretSpan));
     244          317 :     VerifyOrReturnError(sharedSecretSpan.size() <= sharedSecret.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL);
     245          317 :     ::memcpy(sharedSecret.Bytes(), sharedSecretSpan.data(), sharedSecretSpan.size());
     246          317 :     sharedSecret.SetLength(sharedSecretSpan.size());
     247              : 
     248          317 :     ByteSpan catSpan;
     249          317 :     ReturnErrorOnFailure(reader.Next(kCATTag));
     250          317 :     ReturnErrorOnFailure(reader.Get(catSpan));
     251              :     CATValues::Serialized cat;
     252          317 :     VerifyOrReturnError(sizeof(cat) == catSpan.size(), CHIP_ERROR_INVALID_TLV_ELEMENT);
     253          317 :     ::memcpy(cat, catSpan.data(), catSpan.size());
     254          317 :     peerCATs.Deserialize(cat);
     255              : 
     256          317 :     ReturnErrorOnFailure(reader.ExitContainer(containerType));
     257          317 :     ReturnErrorOnFailure(reader.VerifyEndOfContainer());
     258              : 
     259          317 :     return CHIP_NO_ERROR;
     260              : }
     261              : 
     262          101 : CHIP_ERROR SimpleSessionResumptionStorage::DeleteState(const ScopedNodeId & node)
     263              : {
     264          101 :     ReturnErrorOnFailure(mStorage->SyncDeleteKeyValue(GetStorageKey(node).KeyName()));
     265          101 :     return CHIP_NO_ERROR;
     266              : }
     267              : 
     268              : } // namespace chip
        

Generated by: LCOV version 2.0-1