Matter SDK Coverage Report
Current view: top level - transport - SecureSession.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 84.8 % 105 89
Test Date: 2025-01-17 19:00:11 Functions: 100.0 % 11 11

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2021 Project CHIP Authors
       3              :  *
       4              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       5              :  *    you may not use this file except in compliance with the License.
       6              :  *    You may obtain a copy of the License at
       7              :  *
       8              :  *        http://www.apache.org/licenses/LICENSE-2.0
       9              :  *
      10              :  *    Unless required by applicable law or agreed to in writing, software
      11              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      12              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13              :  *    See the License for the specific language governing permissions and
      14              :  *    limitations under the License.
      15              :  */
      16              : 
      17              : #include <access/AuthMode.h>
      18              : #include <transport/SecureSession.h>
      19              : #include <transport/SecureSessionTable.h>
      20              : 
      21              : namespace chip {
      22              : namespace Transport {
      23              : 
      24       135111 : void SecureSessionDeleter::Release(SecureSession * entry)
      25              : {
      26       135111 :     entry->mTable.ReleaseSession(entry);
      27       135111 : }
      28              : 
      29          110 : void SecureSession::Activate(const ScopedNodeId & localNode, const ScopedNodeId & peerNode, CATValues peerCATs,
      30              :                              uint16_t peerSessionId, const SessionParameters & sessionParameters)
      31              : {
      32          110 :     VerifyOrDie(mState == State::kEstablishing);
      33          110 :     VerifyOrDie(peerNode.GetFabricIndex() == localNode.GetFabricIndex());
      34              : 
      35              :     // PASE sessions must always start unassociated with a Fabric!
      36          110 :     VerifyOrDie(!((mSecureSessionType == Type::kPASE) && (peerNode.GetFabricIndex() != kUndefinedFabricIndex)));
      37              :     // CASE sessions must always start "associated" a given Fabric!
      38          110 :     VerifyOrDie(!((mSecureSessionType == Type::kCASE) && (peerNode.GetFabricIndex() == kUndefinedFabricIndex)));
      39              :     // CASE sessions can only be activated against operational node IDs!
      40          110 :     VerifyOrDie(!((mSecureSessionType == Type::kCASE) &&
      41              :                   (!IsOperationalNodeId(peerNode.GetNodeId()) || !IsOperationalNodeId(localNode.GetNodeId()))));
      42              : 
      43          110 :     mPeerNodeId          = peerNode.GetNodeId();
      44          110 :     mLocalNodeId         = localNode.GetNodeId();
      45          110 :     mPeerCATs            = peerCATs;
      46          110 :     mPeerSessionId       = peerSessionId;
      47          110 :     mRemoteSessionParams = sessionParameters;
      48          110 :     SetFabricIndex(peerNode.GetFabricIndex());
      49          110 :     MarkActiveRx(); // Initialize SessionTimestamp and ActiveTimestamp per spec.
      50              : 
      51          110 :     Retain(); // This ref is released inside MarkForEviction
      52          110 :     MoveToState(State::kActive);
      53              : 
      54          110 :     if (mSecureSessionType == Type::kCASE)
      55          100 :         mTable.NewerSessionAvailable(this);
      56              : 
      57          110 :     ChipLogDetail(Inet, "SecureSession[%p]: Activated - Type:%d LSID:%d", this, to_underlying(mSecureSessionType), mLocalSessionId);
      58          110 : }
      59              : 
      60       273404 : const char * SecureSession::StateToString(State state) const
      61              : {
      62       273404 :     switch (state)
      63              :     {
      64       135187 :     case State::kEstablishing:
      65       135187 :         return "kEstablishing";
      66              :         break;
      67              : 
      68         3138 :     case State::kActive:
      69         3138 :         return "kActive";
      70              :         break;
      71              : 
      72           17 :     case State::kDefunct:
      73           17 :         return "kDefunct";
      74              :         break;
      75              : 
      76       135062 :     case State::kPendingEviction:
      77       135062 :         return "kPendingEviction";
      78              :         break;
      79              : 
      80            0 :     default:
      81            0 :         return "???";
      82              :         break;
      83              :     }
      84              : }
      85              : 
      86       136660 : void SecureSession::MoveToState(State targetState)
      87              : {
      88       136660 :     if (mState != targetState)
      89              :     {
      90       136660 :         ChipLogProgress(SecureChannel, "SecureSession[%p, LSID:%d]: State change '%s' --> '%s'", this, mLocalSessionId,
      91              :                         StateToString(mState), StateToString(targetState));
      92       136660 :         mState = targetState;
      93              :     }
      94       136660 : }
      95              : 
      96            5 : void SecureSession::MarkAsDefunct()
      97              : {
      98            5 :     ChipLogDetail(Inet, "SecureSession[%p]: MarkAsDefunct Type:%d LSID:%d", this, to_underlying(mSecureSessionType),
      99              :                   mLocalSessionId);
     100            5 :     ReferenceCountedHandle<Transport::Session> ref(*this);
     101              : 
     102            5 :     switch (mState)
     103              :     {
     104            0 :     case State::kEstablishing:
     105              :         //
     106              :         // A session can only be marked as defunct from the state of Active.
     107              :         //
     108            0 :         VerifyOrDie(false);
     109              :         return;
     110              : 
     111            4 :     case State::kActive:
     112            4 :         MoveToState(State::kDefunct);
     113            4 :         return;
     114              : 
     115            0 :     case State::kDefunct:
     116              :         //
     117              :         // Do nothing
     118              :         //
     119            0 :         return;
     120              : 
     121            1 :     case State::kPendingEviction:
     122              :         //
     123              :         // Once a session is headed for eviction, we CANNOT bring it back to either being active or defunct. Let's just
     124              :         // do nothing and return.
     125              :         //
     126            1 :         return;
     127              :     }
     128            5 : }
     129              : 
     130       135062 : void SecureSession::MarkForEviction()
     131              : {
     132       135062 :     ChipLogDetail(Inet, "SecureSession[%p]: MarkForEviction Type:%d LSID:%d", this, to_underlying(mSecureSessionType),
     133              :                   mLocalSessionId);
     134       135062 :     ReferenceCountedHandle<Transport::Session> ref(*this);
     135              : 
     136       135062 :     switch (mState)
     137              :     {
     138       133591 :     case State::kEstablishing:
     139       133591 :         MoveToState(State::kPendingEviction);
     140              :         // Interrupt the pairing
     141       133591 :         NotifySessionReleased();
     142       133591 :         return;
     143              : 
     144         1471 :     case State::kDefunct:
     145              :         FALLTHROUGH;
     146              :     case State::kActive:
     147         1471 :         Release(); // Decrease the ref which is retained at Activate
     148         1471 :         MoveToState(State::kPendingEviction);
     149         1471 :         NotifySessionReleased();
     150         1471 :         return;
     151              : 
     152            0 :     case State::kPendingEviction:
     153              :         // Do nothing
     154            0 :         return;
     155              :     }
     156       135062 : }
     157              : 
     158         7484 : Access::SubjectDescriptor SecureSession::GetSubjectDescriptor() const
     159              : {
     160         7484 :     Access::SubjectDescriptor subjectDescriptor;
     161         7484 :     if (IsOperationalNodeId(mPeerNodeId))
     162              :     {
     163         7484 :         subjectDescriptor.authMode        = Access::AuthMode::kCase;
     164         7484 :         subjectDescriptor.subject         = mPeerNodeId;
     165         7484 :         subjectDescriptor.cats            = mPeerCATs;
     166         7484 :         subjectDescriptor.fabricIndex     = GetFabricIndex();
     167         7484 :         subjectDescriptor.isCommissioning = IsCommissioningSession();
     168              :     }
     169            0 :     else if (IsPAKEKeyId(mPeerNodeId))
     170              :     {
     171              :         // Responder (aka commissionee) gets subject descriptor filled in.
     172              :         // Initiator (aka commissioner) leaves subject descriptor unfilled.
     173            0 :         if (GetCryptoContext().IsResponder())
     174              :         {
     175            0 :             subjectDescriptor.authMode        = Access::AuthMode::kPase;
     176            0 :             subjectDescriptor.subject         = mPeerNodeId;
     177            0 :             subjectDescriptor.fabricIndex     = GetFabricIndex();
     178            0 :             subjectDescriptor.isCommissioning = IsCommissioningSession();
     179              :         }
     180              :     }
     181              :     else
     182              :     {
     183            0 :         VerifyOrDie(false);
     184              :     }
     185         7484 :     return subjectDescriptor;
     186              : }
     187              : 
     188         7484 : bool SecureSession::IsCommissioningSession() const
     189              : {
     190              :     // PASE session is always a commissioning session.
     191         7484 :     if (IsPASESession())
     192              :     {
     193         7477 :         return true;
     194              :     }
     195              : 
     196              :     // CASE session is a commissioning session if it was marked as such.
     197              :     // The SessionManager is what keeps track.
     198            7 :     if (IsCASESession() && mIsCaseCommissioningSession)
     199              :     {
     200            0 :         return true;
     201              :     }
     202              : 
     203            7 :     return false;
     204              : }
     205              : 
     206       764336 : void SecureSession::Retain()
     207              : {
     208              : #if CHIP_CONFIG_SECURE_SESSION_REFCOUNT_LOGGING
     209              :     ChipLogProgress(SecureChannel, "SecureSession[%p]: ++ %d -> %d", this, GetReferenceCount(), GetReferenceCount() + 1);
     210              : #endif
     211              : 
     212       764336 :     ReferenceCounted<SecureSession, SecureSessionDeleter, 0, uint16_t>::Retain();
     213       764336 : }
     214              : 
     215       764213 : void SecureSession::Release()
     216              : {
     217              : #if CHIP_CONFIG_SECURE_SESSION_REFCOUNT_LOGGING
     218              :     ChipLogProgress(SecureChannel, "SecureSession[%p]: -- %d -> %d", this, GetReferenceCount(), GetReferenceCount() - 1);
     219              : #endif
     220              : 
     221       764213 :     ReferenceCounted<SecureSession, SecureSessionDeleter, 0, uint16_t>::Release();
     222       764213 : }
     223              : 
     224           54 : void SecureSession::NewerSessionAvailable(const SessionHandle & session)
     225              : {
     226              :     // Shift to the new session, checks are performed by the the caller SecureSessionTable::NewerSessionAvailable.
     227           54 :     IntrusiveList<SessionHolder>::Iterator iter = mHolders.begin();
     228          100 :     while (iter != mHolders.end())
     229              :     {
     230              :         // The iterator can be invalid once the session holder is migrated to another session. So we store its next value before
     231              :         // notifying the holder.
     232           46 :         IntrusiveList<SessionHolder>::Iterator next = iter;
     233           46 :         ++next;
     234              : 
     235           46 :         iter->ShiftToSession(session);
     236              : 
     237           46 :         iter = next;
     238              :     }
     239           54 : }
     240              : 
     241              : } // namespace Transport
     242              : } // namespace chip
        

Generated by: LCOV version 2.0-1