LCOV - code coverage report
Current view: top level - transport - SecureSession.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 83 97 85.6 %
Date: 2024-02-15 08:20:41 Functions: 10 10 100.0 %

          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      134968 : void SecureSessionDeleter::Release(SecureSession * entry)
      25             : {
      26      134968 :     entry->mTable.ReleaseSession(entry);
      27      134968 : }
      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      272826 : const char * SecureSession::StateToString(State state) const
      61             : {
      62      272826 :     switch (state)
      63             :     {
      64      135044 :     case State::kEstablishing:
      65      135044 :         return "kEstablishing";
      66             :         break;
      67             : 
      68        2846 :     case State::kActive:
      69        2846 :         return "kActive";
      70             :         break;
      71             : 
      72          17 :     case State::kDefunct:
      73          17 :         return "kDefunct";
      74             :         break;
      75             : 
      76      134919 :     case State::kPendingEviction:
      77      134919 :         return "kPendingEviction";
      78             :         break;
      79             : 
      80           0 :     default:
      81           0 :         return "???";
      82             :         break;
      83             :     }
      84             : }
      85             : 
      86      136371 : void SecureSession::MoveToState(State targetState)
      87             : {
      88      136371 :     if (mState != targetState)
      89             :     {
      90      136371 :         ChipLogProgress(SecureChannel, "SecureSession[%p, LSID:%d]: State change '%s' --> '%s'", this, mLocalSessionId,
      91             :                         StateToString(mState), StateToString(targetState));
      92      136371 :         mState = targetState;
      93             :     }
      94      136371 : }
      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      134919 : void SecureSession::MarkForEviction()
     131             : {
     132      134919 :     ChipLogDetail(Inet, "SecureSession[%p]: MarkForEviction Type:%d LSID:%d", this, to_underlying(mSecureSessionType),
     133             :                   mLocalSessionId);
     134      134919 :     ReferenceCountedHandle<Transport::Session> ref(*this);
     135             : 
     136      134919 :     switch (mState)
     137             :     {
     138      133594 :     case State::kEstablishing:
     139      133594 :         MoveToState(State::kPendingEviction);
     140             :         // Interrupt the pairing
     141      133594 :         NotifySessionReleased();
     142      133594 :         return;
     143             : 
     144        1325 :     case State::kDefunct:
     145             :         FALLTHROUGH;
     146             :     case State::kActive:
     147        1325 :         Release(); // Decrease the ref which is retained at Activate
     148        1325 :         MoveToState(State::kPendingEviction);
     149        1325 :         NotifySessionReleased();
     150        1325 :         return;
     151             : 
     152           0 :     case State::kPendingEviction:
     153             :         // Do nothing
     154           0 :         return;
     155             :     }
     156      134919 : }
     157             : 
     158        6682 : Access::SubjectDescriptor SecureSession::GetSubjectDescriptor() const
     159             : {
     160        6682 :     Access::SubjectDescriptor subjectDescriptor;
     161        6682 :     if (IsOperationalNodeId(mPeerNodeId))
     162             :     {
     163        6682 :         subjectDescriptor.authMode    = Access::AuthMode::kCase;
     164        6682 :         subjectDescriptor.subject     = mPeerNodeId;
     165        6682 :         subjectDescriptor.cats        = mPeerCATs;
     166        6682 :         subjectDescriptor.fabricIndex = GetFabricIndex();
     167             :     }
     168           0 :     else if (IsPAKEKeyId(mPeerNodeId))
     169             :     {
     170             :         // Responder (aka commissionee) gets subject descriptor filled in.
     171             :         // Initiator (aka commissioner) leaves subject descriptor unfilled.
     172           0 :         if (GetCryptoContext().IsResponder())
     173             :         {
     174           0 :             subjectDescriptor.authMode    = Access::AuthMode::kPase;
     175           0 :             subjectDescriptor.subject     = mPeerNodeId;
     176           0 :             subjectDescriptor.fabricIndex = GetFabricIndex();
     177             :         }
     178             :     }
     179             :     else
     180             :     {
     181           0 :         VerifyOrDie(false);
     182             :     }
     183        6682 :     return subjectDescriptor;
     184             : }
     185             : 
     186      760644 : void SecureSession::Retain()
     187             : {
     188             : #if CHIP_CONFIG_SECURE_SESSION_REFCOUNT_LOGGING
     189             :     ChipLogProgress(SecureChannel, "SecureSession[%p]: ++ %d -> %d", this, GetReferenceCount(), GetReferenceCount() + 1);
     190             : #endif
     191             : 
     192      760644 :     ReferenceCounted<SecureSession, SecureSessionDeleter, 0, uint16_t>::Retain();
     193      760644 : }
     194             : 
     195      760521 : void SecureSession::Release()
     196             : {
     197             : #if CHIP_CONFIG_SECURE_SESSION_REFCOUNT_LOGGING
     198             :     ChipLogProgress(SecureChannel, "SecureSession[%p]: -- %d -> %d", this, GetReferenceCount(), GetReferenceCount() - 1);
     199             : #endif
     200             : 
     201      760521 :     ReferenceCounted<SecureSession, SecureSessionDeleter, 0, uint16_t>::Release();
     202      760521 : }
     203             : 
     204          54 : void SecureSession::NewerSessionAvailable(const SessionHandle & session)
     205             : {
     206             :     // Shift to the new session, checks are performed by the the caller SecureSessionTable::NewerSessionAvailable.
     207          54 :     IntrusiveList<SessionHolder>::Iterator iter = mHolders.begin();
     208         100 :     while (iter != mHolders.end())
     209             :     {
     210             :         // The iterator can be invalid once the session holder is migrated to another session. So we store its next value before
     211             :         // notifying the holder.
     212          46 :         IntrusiveList<SessionHolder>::Iterator next = iter;
     213          46 :         ++next;
     214             : 
     215          46 :         iter->ShiftToSession(session);
     216             : 
     217          46 :         iter = next;
     218             :     }
     219          54 : }
     220             : 
     221             : } // namespace Transport
     222             : } // namespace chip

Generated by: LCOV version 1.14