diff --git a/src/credentials/BUILD.gn b/src/credentials/BUILD.gn index a62069b3ed55c9..fa9335993eac9c 100644 --- a/src/credentials/BUILD.gn +++ b/src/credentials/BUILD.gn @@ -46,6 +46,7 @@ static_library("credentials") { "${chip_root}/src/lib/asn1", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", + "${chip_root}/src/transport/raw", "${nlassert_root}:nlassert", ] } diff --git a/src/credentials/GroupDataProvider.h b/src/credentials/GroupDataProvider.h index 89363c57074e45..d4bf7092a3302e 100644 --- a/src/credentials/GroupDataProvider.h +++ b/src/credentials/GroupDataProvider.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace chip { namespace Credentials { @@ -198,6 +199,9 @@ class GroupDataProvider // Fabrics virtual CHIP_ERROR RemoveFabric(chip::FabricIndex fabric_index) = 0; + // General + virtual CHIP_ERROR Decrypt(PacketHeader packetHeader, PayloadHeader & payloadHeader, System::PacketBufferHandle && msg) = 0; + // Listener void SetListener(GroupListener * listener) { mListener = listener; }; void RemoveListener() { mListener = nullptr; }; diff --git a/src/credentials/examples/GroupDataProviderExample.cpp b/src/credentials/examples/GroupDataProviderExample.cpp index 0706c52fc55c81..267cbc4607e7a7 100644 --- a/src/credentials/examples/GroupDataProviderExample.cpp +++ b/src/credentials/examples/GroupDataProviderExample.cpp @@ -657,6 +657,13 @@ class StaticGroupsProvider : public GroupDataProvider return CHIP_NO_ERROR; } + CHIP_ERROR Decrypt(PacketHeader packetHeader, PayloadHeader & payloadHeader, System::PacketBufferHandle && msg) override + { + // TODO + + return CHIP_NO_ERROR; + } + private: bool mInitialized = false; Fabric mFabrics[kNumFabrics]; diff --git a/src/transport/SessionManager.cpp b/src/transport/SessionManager.cpp index 3fceaa6eb6b417..5881002bf3b1fd 100644 --- a/src/transport/SessionManager.cpp +++ b/src/transport/SessionManager.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -328,7 +329,14 @@ void SessionManager::OnMessageReceived(const PeerAddress & peerAddress, System:: if (packetHeader.IsEncrypted()) { - SecureMessageDispatch(packetHeader, peerAddress, std::move(msg)); + if (packetHeader.IsGroupSession()) + { + SecureGroupMessageDispatch(packetHeader, peerAddress, std::move(msg)); + } + else + { + SecureUnicastMessageDispatch(packetHeader, peerAddress, std::move(msg)); + } } else { @@ -379,8 +387,8 @@ void SessionManager::MessageDispatch(const PacketHeader & packetHeader, const Tr } } -void SessionManager::SecureMessageDispatch(const PacketHeader & packetHeader, const Transport::PeerAddress & peerAddress, - System::PacketBufferHandle && msg) +void SessionManager::SecureUnicastMessageDispatch(const PacketHeader & packetHeader, const Transport::PeerAddress & peerAddress, + System::PacketBufferHandle && msg) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -493,6 +501,61 @@ void SessionManager::SecureMessageDispatch(const PacketHeader & packetHeader, co } } +void SessionManager::SecureGroupMessageDispatch(const PacketHeader & packetHeader, const Transport::PeerAddress & peerAddress, + System::PacketBufferHandle && msg) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + PayloadHeader payloadHeader; + SessionManagerDelegate::DuplicateMessage isDuplicate = SessionManagerDelegate::DuplicateMessage::No; + // Credentials::GroupDataProvider * groups = Credentials::GetGroupDataProvider(); + + VerifyOrExit(!msg.IsNull(), ChipLogError(Inet, "Secure transport received NULL packet, discarding")); + + // TODO: Handle Group message counter here spec 4.7.3 + // spec 4.5.1.2 for msg counter + + // Trial decryption with GroupDataProvider. TODO: Implement the GroupDataProvider Class + // VerifyOrExit(CHIP_NO_ERROR == groups->DecryptMessage(packetHeader, payloadHeader, msg), + // ChipLogError(Inet, "Secure transport received group message, but failed to decode it, discarding")); + + if (isDuplicate == SessionManagerDelegate::DuplicateMessage::Yes && !payloadHeader.NeedsAck()) + { + ChipLogDetail(Inet, + "Received a duplicate message with MessageCounter:" ChipLogFormatMessageCounter + " on exchange " ChipLogFormatExchangeId, + packetHeader.GetMessageCounter(), ChipLogValueExchangeIdFromSentHeader(payloadHeader)); + if (!payloadHeader.NeedsAck()) + { + // If it's a duplicate message, but doesn't require an ack, let's drop it right here to save CPU + // cycles on further message processing. + ExitNow(err = CHIP_NO_ERROR); + } + } + + if (packetHeader.IsSecureSessionControlMsg()) + { + // TODO: control message counter is not implemented yet + } + else + { + // TODO: Commit Group Message Counter + } + + if (mCB != nullptr) + { + // TODO: Update Session Handle for Group messages. + // SessionHandle session(state->GetPeerNodeId(), state->GetLocalSessionId(), state->GetPeerSessionId(), + // state->GetFabricIndex()); + // mCB->OnMessageReceived(packetHeader, payloadHeader, nullptr, peerAddress, isDuplicate, std::move(msg)); + } + +exit: + if (err != CHIP_NO_ERROR && mCB != nullptr) + { + mCB->OnReceiveError(err, peerAddress); + } +} + void SessionManager::HandleConnectionExpired(const Transport::SecureSession & state) { ChipLogDetail(Inet, "Marking old secure session for device 0x" ChipLogFormatX64 " as expired", diff --git a/src/transport/SessionManager.h b/src/transport/SessionManager.h index 43f6e0adbf1a12..d0d3795b41858a 100644 --- a/src/transport/SessionManager.h +++ b/src/transport/SessionManager.h @@ -313,8 +313,12 @@ class DLL_EXPORT SessionManager : public TransportMgrDelegate */ static void ExpiryTimerCallback(System::Layer * layer, void * param); - void SecureMessageDispatch(const PacketHeader & packetHeader, const Transport::PeerAddress & peerAddress, - System::PacketBufferHandle && msg); + void SecureUnicastMessageDispatch(const PacketHeader & packetHeader, const Transport::PeerAddress & peerAddress, + System::PacketBufferHandle && msg); + + void SecureGroupMessageDispatch(const PacketHeader & packetHeader, const Transport::PeerAddress & peerAddress, + System::PacketBufferHandle && msg); + void MessageDispatch(const PacketHeader & packetHeader, const Transport::PeerAddress & peerAddress, System::PacketBufferHandle && msg);