diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index b95982e6d2a729..664d254665fcb8 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -450,6 +450,9 @@ bool emberAfOperationalCredentialsClusterAddNOCCallback(app::CommandHandler * co err = Server::GetInstance().GetFabricTable().Store(fabricIndex); VerifyOrExit(err == CHIP_NO_ERROR, nocResponse = ConvertToNOCResponseStatus(err)); + // Notify the secure session of the new fabric. + commandObj->GetExchangeContext()->GetSessionHandle()->AsSecureSession()->NewFabric(commandObj->GetAccessingFabricIndex()); + // We might have a new operational identity, so we should start advertising it right away. app::DnssdServer::Instance().AdvertiseOperational(); diff --git a/src/transport/SecureSession.cpp b/src/transport/SecureSession.cpp index 3a9be04d8912e6..09b2afeb5972a8 100644 --- a/src/transport/SecureSession.cpp +++ b/src/transport/SecureSession.cpp @@ -32,9 +32,9 @@ Access::SubjectDescriptor SecureSession::GetSubjectDescriptor() const } else if (IsPAKEKeyId(mPeerNodeId)) { - subjectDescriptor.authMode = Access::AuthMode::kPase; - subjectDescriptor.subject = mPeerNodeId; - // TODO(#10242): PASE *can* have fabric in some situations + subjectDescriptor.authMode = Access::AuthMode::kPase; + subjectDescriptor.subject = mPeerNodeId; + subjectDescriptor.fabricIndex = mPaseFabric; } else { diff --git a/src/transport/SecureSession.h b/src/transport/SecureSession.h index 05efecc190ae32..a43cf3479bb26f 100644 --- a/src/transport/SecureSession.h +++ b/src/transport/SecureSession.h @@ -114,6 +114,18 @@ class SecureSession : public Session uint16_t GetPeerSessionId() const { return mPeerSessionId; } FabricIndex GetFabricIndex() const { return mFabric; } + // Should only be called for PASE sessions, which start with undefined fabric, + // to place on a newly commissioned fabric after successful + // OperationalCredentialsCluster::AddNOC + CHIP_ERROR NewFabric(FabricIndex fabricIndex) + { + // TODO: should check that secure session type is PASE and current value is undefined + // (i.e. that it's called exactly once in proper circumstances) + // but that's difficult until issue #13711 is addressed + mPaseFabric = fabricIndex; + return CHIP_NO_ERROR; + } + System::Clock::Timestamp GetLastActivityTime() const { return mLastActivityTime; } void MarkActive() { mLastActivityTime = System::SystemClock().GetMonotonicTimestamp(); } @@ -141,6 +153,10 @@ class SecureSession : public Session const uint16_t mPeerSessionId; const FabricIndex mFabric; + // PASE sessions start with undefined fabric, but can be placed on a newly + // commissioned fabric after successful OperationalCredentialsCluster::AddNOC + FabricIndex mPaseFabric = kUndefinedFabricIndex; + PeerAddress mPeerAddress; System::Clock::Timestamp mLastActivityTime; ReliableMessageProtocolConfig mMRPConfig;