From 80d5dd01a3e281240498b65e18cff0e80d8ce1f1 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Tue, 2 Feb 2021 21:08:36 -0800 Subject: [PATCH 1/3] Implement Message Counter Synchronization Protocol (MCSP) part --- src/messaging/BUILD.gn | 2 + src/messaging/ExchangeContext.h | 13 + src/messaging/ExchangeMgr.cpp | 15 +- src/messaging/ExchangeMgr.h | 4 + src/messaging/ReliableMessageMgr.cpp | 1 + src/messaging/SecureChannelMgr.cpp | 270 +++++++++++++++++ src/messaging/SecureChannelMgr.h | 78 +++++ src/messaging/tests/BUILD.gn | 2 + src/messaging/tests/TestMessagingLayer.h | 1 + src/messaging/tests/TestSecureChannelMgr.cpp | 272 ++++++++++++++++++ .../tests/TestSecureChannelMgrDriver.cpp | 35 +++ src/transport/SecureSessionMgr.h | 3 + 12 files changed, 693 insertions(+), 3 deletions(-) create mode 100644 src/messaging/SecureChannelMgr.cpp create mode 100644 src/messaging/SecureChannelMgr.h create mode 100644 src/messaging/tests/TestSecureChannelMgr.cpp create mode 100644 src/messaging/tests/TestSecureChannelMgrDriver.cpp diff --git a/src/messaging/BUILD.gn b/src/messaging/BUILD.gn index e3ef612a761296..8fa8a87df8da85 100644 --- a/src/messaging/BUILD.gn +++ b/src/messaging/BUILD.gn @@ -32,6 +32,8 @@ static_library("messaging") { "ReliableMessageMgr.cpp", "ReliableMessageMgr.h", "ReliableMessageProtocolConfig.h", + "SecureChannelMgr.cpp", + "SecureChannelMgr.h", ] cflags = [ "-Wconversion" ] diff --git a/src/messaging/ExchangeContext.h b/src/messaging/ExchangeContext.h index 9f14609c5caa20..d749fdd91e1337 100644 --- a/src/messaging/ExchangeContext.h +++ b/src/messaging/ExchangeContext.h @@ -34,6 +34,9 @@ #include namespace chip { + +constexpr uint16_t kMsgCounterChallengeSize = 8; // The size of the message counter synchronization request message. + namespace Messaging { class ExchangeManager; @@ -164,6 +167,12 @@ class DLL_EXPORT ExchangeContext : public ReferenceCounted mFlags; // Internal state flags /** diff --git a/src/messaging/ExchangeMgr.cpp b/src/messaging/ExchangeMgr.cpp index 76bd6dca62d234..199ffe769589e5 100644 --- a/src/messaging/ExchangeMgr.cpp +++ b/src/messaging/ExchangeMgr.cpp @@ -66,8 +66,9 @@ ExchangeManager::ExchangeManager() : mReliableMessageMgr(mContextPool) CHIP_ERROR ExchangeManager::Init(SecureSessionMgr * sessionMgr) { - if (mState != State::kState_NotInitialized) - return CHIP_ERROR_INCORRECT_STATE; + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(mState == State::kState_NotInitialized, err = CHIP_ERROR_INCORRECT_STATE); mSessionMgr = sessionMgr; @@ -82,14 +83,22 @@ CHIP_ERROR ExchangeManager::Init(SecureSessionMgr * sessionMgr) mReliableMessageMgr.Init(sessionMgr->SystemLayer(), sessionMgr); + err = mSecureChannelMgr.Init(this); + SuccessOrExit(err); + mState = State::kState_Initialized; - return CHIP_NO_ERROR; +exit: + return err; } CHIP_ERROR ExchangeManager::Shutdown() { +<<<<<<< HEAD mReliableMessageMgr.Shutdown(); +======= + mSecureChannelMgr.Shutdown(); +>>>>>>> Implement Message Counter Synchronization Protocol (MCSP) part if (mSessionMgr != nullptr) { diff --git a/src/messaging/ExchangeMgr.h b/src/messaging/ExchangeMgr.h index 4b17d7b81f5088..e375a8a34532ad 100644 --- a/src/messaging/ExchangeMgr.h +++ b/src/messaging/ExchangeMgr.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -177,6 +178,8 @@ class DLL_EXPORT ExchangeManager : public SecureSessionMgrDelegate ReliableMessageMgr * GetReliableMessageMgr() { return &mReliableMessageMgr; }; + SecureChannel::SecureChannelMgr * GetSecureChannelMgr() { return &mSecureChannelMgr; }; + size_t GetContextsInUse() const { return mContextsInUse; } private: @@ -197,6 +200,7 @@ class DLL_EXPORT ExchangeManager : public SecureSessionMgrDelegate State mState; SecureSessionMgr * mSessionMgr; ReliableMessageMgr mReliableMessageMgr; + SecureChannel::SecureChannelMgr mSecureChannelMgr; std::array mContextPool; size_t mContextsInUse; diff --git a/src/messaging/ReliableMessageMgr.cpp b/src/messaging/ReliableMessageMgr.cpp index 05fd0d6253658a..79281154ecfc58 100644 --- a/src/messaging/ReliableMessageMgr.cpp +++ b/src/messaging/ReliableMessageMgr.cpp @@ -25,6 +25,7 @@ #include +#include #include #include #include diff --git a/src/messaging/SecureChannelMgr.cpp b/src/messaging/SecureChannelMgr.cpp new file mode 100644 index 00000000000000..28a3cf0452eb94 --- /dev/null +++ b/src/messaging/SecureChannelMgr.cpp @@ -0,0 +1,270 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements the CHIP Secure Channel protocol. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace SecureChannel { + +SecureChannelMgr::SecureChannelMgr() +{ + mExchangeMgr = nullptr; +} + +CHIP_ERROR SecureChannelMgr::Init(Messaging::ExchangeManager * exchangeMgr) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(exchangeMgr != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + mExchangeMgr = exchangeMgr; + + // Register to receive unsolicited Secure Channel Request messages from the exchange manager. + err = mExchangeMgr->RegisterUnsolicitedMessageHandlerForProtocol(Protocols::kProtocol_SecureChannel, this); + + SuccessOrExit(err); + +exit: + return err; +} + +void SecureChannelMgr::Shutdown() +{ + if (mExchangeMgr != nullptr) + { + mExchangeMgr->UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::kProtocol_SecureChannel); + mExchangeMgr = nullptr; + } +} + +void SecureChannelMgr::OnMessageReceived(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, + const PayloadHeader & payloadHeader, System::PacketBufferHandle msgBuf) +{ + if (payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::MsgCounterSyncReq)) + { + HandleMsgCounterSyncReq(ec, packetHeader, std::move(msgBuf)); + } + else if (payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::MsgCounterSyncRsp)) + { + HandleMsgCounterSyncResp(ec, packetHeader, std::move(msgBuf)); + } +} + +void SecureChannelMgr::OnResponseTimeout(Messaging::ExchangeContext * ec) +{ + // Close the exchange if MsgCounterSyncRsp is not received before kMsgCounterSyncTimeout. + if (ec != nullptr) + ec->Close(); +} + +// Create and initialize new exchange for the message counter synchronization request/response messages. +CHIP_ERROR SecureChannelMgr::NewMsgCounterSyncExchange(SecureSessionHandle session, Messaging::ExchangeContext *& ec) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Message counter synchronization protocol is only applicable for application group keys. + VerifyOrExit(ChipKeyId::IsAppGroupKey(session.GetPeerKeyId()), err = CHIP_ERROR_INVALID_ARGUMENT); + + // Create new exchange context. + ec = mExchangeMgr->NewContext(session, this); + VerifyOrExit(ec != nullptr, err = CHIP_ERROR_NO_MEMORY); + +exit: + return err; +} + +CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncReq(SecureSessionHandle session) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + Messaging::ExchangeContext * ec = nullptr; + System::PacketBufferHandle msgBuf; + Messaging::SendFlags sendFlags; + uint8_t challenge[kMsgCounterChallengeSize]; + + // Create and initialize new exchange. + err = NewMsgCounterSyncExchange(session, ec); + SuccessOrExit(err); + + // Allocate a buffer for the null message. + msgBuf = System::PacketBufferHandle::New(kMsgCounterChallengeSize); + VerifyOrExit(!msgBuf.IsNull(), err = CHIP_ERROR_NO_MEMORY); + + // Generate a 64-bit random number to uniquely identify the request. + err = DRBG_get_bytes(challenge, kMsgCounterChallengeSize); + SuccessOrExit(err); + + // Store generated Challenge value to ExchangeContext to resolve synchronization response. + ec->SetChallenge(challenge); + + memcpy(msgBuf->Start(), challenge, kMsgCounterChallengeSize); + msgBuf->SetDataLength(kMsgCounterChallengeSize); + + // TODO:(#4641) We shall also set the C flag in the packet header, this will be used for message protection later. + sendFlags.Set(Messaging::SendMessageFlags::kNoAutoRequestAck, true).Set(Messaging::SendMessageFlags::kExpectResponse, true); + + // Arm a timer to enforce that a MsgCounterSyncRsp is received before kMsgCounterSyncTimeout. + ec->SetResponseTimeout(kMsgCounterSyncTimeout); + + // Send the message counter synchronization request in a Secure Channel Protocol::MsgCounterSyncReq message. + err = ec->SendMessage(Protocols::SecureChannel::MsgType::MsgCounterSyncReq, std::move(msgBuf), sendFlags); + SuccessOrExit(err); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(ExchangeManager, "Failed to send message counter synchronization request with error:%s", ErrorStr(err)); + } + + return err; +} + +CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncResp(Messaging::ExchangeContext * ec, SecureSessionHandle session) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + Transport::PeerConnectionState * state = nullptr; + System::PacketBufferHandle msgBuf; + uint8_t * msg = nullptr; + + state = mExchangeMgr->GetSessionMgr()->GetPeerConnectionState(session); + VerifyOrExit(state != nullptr, err = CHIP_ERROR_NOT_CONNECTED); + + // Allocate new buffer. + msgBuf = System::PacketBufferHandle::New(kMsgCounterSyncRespMsgSize); + VerifyOrExit(!msgBuf.IsNull(), err = CHIP_ERROR_NO_MEMORY); + + msg = msgBuf->Start(); + + // Let's construct the message using BufBound + { + Encoding::LittleEndian::BufferWriter bbuf(msg, kMsgCounterSyncRespMsgSize); + + // Write the message id (counter) field. + bbuf.Put32(state->GetSendMessageIndex()); + + // Fill in the random value + bbuf.Put(ec->GetChallenge(), kMsgCounterChallengeSize); + + VerifyOrExit(bbuf.Fit(), err = CHIP_ERROR_NO_MEMORY); + } + + // Set message length. + msgBuf->SetDataLength(kMsgCounterSyncRespMsgSize); + + // Send message counter synchronization response message. + err = ec->SendMessage(Protocols::SecureChannel::MsgType::MsgCounterSyncRsp, std::move(msgBuf), + Messaging::SendFlags(Messaging::SendMessageFlags::kNoAutoRequestAck)); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(ExchangeManager, "Failed to send message counter synchronization response with error:%s", ErrorStr(err)); + } + + return err; +} + +void SecureChannelMgr::HandleMsgCounterSyncReq(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, + System::PacketBufferHandle msgBuf) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + const uint8_t * req = msgBuf->Start(); + size_t reqlen = msgBuf->DataLength(); + + ChipLogDetail(ExchangeManager, "Received MsgCounterSyncReq request"); + + VerifyOrExit(packetHeader.GetSourceNodeId().HasValue(), err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(ChipKeyId::IsAppGroupKey(packetHeader.GetEncryptionKeyID()), err = CHIP_ERROR_WRONG_KEY_TYPE); + VerifyOrExit(req != nullptr, err = CHIP_ERROR_MESSAGE_INCOMPLETE); + VerifyOrExit(reqlen == kMsgCounterChallengeSize, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + + // Store the 64-bit value sent in the Challenge filed of the MsgCounterSyncReq. + ec->SetChallenge(req); + + // Respond with MsgCounterSyncResp + err = SendMsgCounterSyncResp(ec, { packetHeader.GetSourceNodeId().Value(), packetHeader.GetEncryptionKeyID() }); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(ExchangeManager, "Failed to handle MsgCounterSyncReq message with error:%s", ErrorStr(err)); + } + + if (ec != nullptr) + ec->Close(); + + return; +} + +void SecureChannelMgr::HandleMsgCounterSyncResp(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, + System::PacketBufferHandle msgBuf) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + uint32_t syncCounter = 0; + uint8_t challenge[kMsgCounterChallengeSize]; + + const uint8_t * resp = msgBuf->Start(); + size_t resplen = msgBuf->DataLength(); + + ChipLogDetail(ExchangeManager, "Received MsgCounterSyncResp response"); + + VerifyOrExit(msgBuf->DataLength() == kMsgCounterSyncRespMsgSize, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + VerifyOrExit(ChipKeyId::IsAppGroupKey(packetHeader.GetEncryptionKeyID()), err = CHIP_ERROR_WRONG_KEY_TYPE); + + // Store the 64-bit value sent in the Challenge filed of the MsgCounterSyncReq. + VerifyOrExit(resp != nullptr, err = CHIP_ERROR_MESSAGE_INCOMPLETE); + VerifyOrExit(resplen == kMsgCounterSyncRespMsgSize, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + + syncCounter = chip::Encoding::LittleEndian::Read32(resp); + memcpy(challenge, resp, kMsgCounterChallengeSize); + + // Verify that the response field matches the expected Challenge field for the exchange. + VerifyOrExit(memcmp(ec->GetChallenge(), challenge, kMsgCounterChallengeSize) == 0, err = CHIP_ERROR_INVALID_SIGNATURE); + + // ToDo:(#4628)Initialize/synchronize peer's message counter to FabricState. + VerifyOrExit(syncCounter != 0, err = CHIP_ERROR_READ_FAILED); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(ExchangeManager, "Failed to handle MsgCounterSyncResp message with error:%s", ErrorStr(err)); + } + + if (ec != nullptr) + ec->Close(); + + return; +} + +} // namespace SecureChannel +} // namespace chip diff --git a/src/messaging/SecureChannelMgr.h b/src/messaging/SecureChannelMgr.h new file mode 100644 index 00000000000000..7d7b6640c2724e --- /dev/null +++ b/src/messaging/SecureChannelMgr.h @@ -0,0 +1,78 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file + * This file defines types and objects for CHIP Secure Channel protocol. + * + */ + +#pragma once + +#include + +namespace chip { +namespace SecureChannel { + +constexpr uint16_t kMsgCounterSyncRespMsgSize = 12; // The size of the message counter synchronization response message. +constexpr uint32_t kMsgCounterSyncTimeout = 500; // The amount of time(in milliseconds) which a peer is given to respond + // to a message counter synchronization request. + +class ExchangeManager; + +class SecureChannelMgr : public Messaging::ExchangeDelegate +{ +public: + SecureChannelMgr(); + + CHIP_ERROR Init(Messaging::ExchangeManager * exchangeMgr); + void Shutdown(); + + /** + * Send peer message counter synchronization request. + * This function is called while processing a message encrypted with an application key from a peer whose message counter is not + * synchronized. This message is sent on a newly created exchange, which is closed immediately after. + * + * @param[in] session The secure session handle of the received message. + * + * @retval #CHIP_ERROR_NO_MEMORY If memory could not be allocated for the new + * exchange context or new message buffer. + * @retval #CHIP_NO_ERROR On success. + * + */ + CHIP_ERROR SendMsgCounterSyncReq(SecureSessionHandle session); + +private: + Messaging::ExchangeManager * mExchangeMgr; // [READ ONLY] Associated Exchange Manager object. + + CHIP_ERROR NewMsgCounterSyncExchange(SecureSessionHandle session, Messaging::ExchangeContext *& ec); + + CHIP_ERROR SendMsgCounterSyncResp(Messaging::ExchangeContext * ec, SecureSessionHandle session); + + void HandleMsgCounterSyncReq(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, + System::PacketBufferHandle msgBuf); + + void HandleMsgCounterSyncResp(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, + System::PacketBufferHandle msgBuf); + + void OnMessageReceived(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, const PayloadHeader & payloadHeader, + System::PacketBufferHandle payload) override; + + void OnResponseTimeout(Messaging::ExchangeContext * ec) override; +}; + +} // namespace SecureChannel +} // namespace chip diff --git a/src/messaging/tests/BUILD.gn b/src/messaging/tests/BUILD.gn index 5e72204ad35d7f..bc6d76bc4bb663 100644 --- a/src/messaging/tests/BUILD.gn +++ b/src/messaging/tests/BUILD.gn @@ -28,6 +28,7 @@ chip_test_suite("tests") { "TestExchangeMgr.cpp", "TestMessagingLayer.h", "TestReliableMessageProtocol.cpp", + "TestSecureChannelMgr.cpp", ] cflags = [ "-Wconversion" ] @@ -46,6 +47,7 @@ chip_test_suite("tests") { tests = [ "TestExchangeMgr", + "TestSecureChannelMgr", "TestReliableMessageProtocol", ] } diff --git a/src/messaging/tests/TestMessagingLayer.h b/src/messaging/tests/TestMessagingLayer.h index 7bdcef314c4c0b..bf50d519b5ced8 100644 --- a/src/messaging/tests/TestMessagingLayer.h +++ b/src/messaging/tests/TestMessagingLayer.h @@ -29,6 +29,7 @@ extern "C" { #endif int TestExchangeMgr(void); +int TestSecureChannelMgr(void); int TestReliableMessageProtocol(void); #ifdef __cplusplus diff --git a/src/messaging/tests/TestSecureChannelMgr.cpp b/src/messaging/tests/TestSecureChannelMgr.cpp new file mode 100644 index 00000000000000..641cbc491853dc --- /dev/null +++ b/src/messaging/tests/TestSecureChannelMgr.cpp @@ -0,0 +1,272 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements unit tests for the SecureChannelMgr implementation. + */ + +#include "TestMessagingLayer.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace { + +using namespace chip; +using namespace chip::Inet; +using namespace chip::Transport; +using namespace chip::Messaging; +using namespace chip::Protocols; + +using TestContext = chip::Test::MessagingContext; + +TestContext sContext; + +constexpr NodeId kSourceNodeId = 123654; +constexpr NodeId kDestinationNodeId = 111222333; +constexpr chip::NodeId kTestPeerGroupKeyId = 0x4000; +constexpr chip::NodeId kTestLocalGroupKeyId = 0x5000; + +class LoopbackTransport : public Transport::Base +{ +public: + /// Transports are required to have a constructor that takes exactly one argument + CHIP_ERROR Init(const char * unused) { return CHIP_NO_ERROR; } + + CHIP_ERROR SendMessage(const PacketHeader & header, const PeerAddress & address, System::PacketBufferHandle msgBuf) override + { + // We need to change the peerKeyId to local Key Id to be received by itself. + PacketHeader tmpHeader = header; + + tmpHeader.SetEncryptionKeyID(kTestLocalGroupKeyId); + HandleMessageReceived(tmpHeader, address, std::move(msgBuf)); + + return CHIP_NO_ERROR; + } + + bool CanSendToPeer(const PeerAddress & address) override { return true; } +}; + +class TestExchangeMgr : public SecureSessionMgrDelegate +{ +public: + void OnMessageReceived(const PacketHeader & header, const PayloadHeader & payloadHeader, SecureSessionHandle session, + System::PacketBufferHandle msgBuf, SecureSessionMgr * mgr) override + { + NL_TEST_ASSERT(mSuite, header.GetSourceNodeId() == Optional::Value(kSourceNodeId)); + NL_TEST_ASSERT(mSuite, header.GetDestinationNodeId() == Optional::Value(kDestinationNodeId)); + NL_TEST_ASSERT(mSuite, msgBuf->DataLength() == kMsgCounterChallengeSize); + + ReceiveHandlerCallCount++; + } + + void OnNewConnection(SecureSessionHandle session, SecureSessionMgr * mgr) override {} + + void OnConnectionExpired(SecureSessionHandle session, SecureSessionMgr * mgr) override {} + + nlTestSuite * mSuite = nullptr; + int ReceiveHandlerCallCount = 0; +}; + +class MockAppDelegate : public ExchangeDelegate +{ +public: + void OnMessageReceived(ExchangeContext * ec, const PacketHeader & packetHeader, const PayloadHeader & payloadHeader, + System::PacketBufferHandle msgBuf) override + { + IsOnMessageReceivedCalled = true; + + NL_TEST_ASSERT(mSuite, payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::MsgCounterSyncReq)); + NL_TEST_ASSERT(mSuite, packetHeader.GetSourceNodeId() == Optional::Value(kSourceNodeId)); + NL_TEST_ASSERT(mSuite, packetHeader.GetDestinationNodeId() == Optional::Value(kDestinationNodeId)); + NL_TEST_ASSERT(mSuite, msgBuf->DataLength() == kMsgCounterChallengeSize); + } + + void OnResponseTimeout(ExchangeContext * ec) override {} + + nlTestSuite * mSuite = nullptr; + bool IsOnMessageReceivedCalled = false; +}; + +TransportMgr gTransportMgr; + +void CheckSendMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext) +{ + TestContext & ctx = *reinterpret_cast(inContext); + + ctx.GetInetLayer().SystemLayer()->Init(nullptr); + + IPAddress addr; + IPAddress::FromString("127.0.0.1", addr); + + CHIP_ERROR err = CHIP_NO_ERROR; + TestExchangeMgr testExchangeMgr; + + testExchangeMgr.mSuite = inSuite; + ctx.GetSecureSessionManager().SetDelegate(&testExchangeMgr); + + chip::SecureChannel::SecureChannelMgr * sm = ctx.GetExchangeManager().GetSecureChannelMgr(); + NL_TEST_ASSERT(inSuite, sm != nullptr); + + Optional peer(Transport::PeerAddress::UDP(addr, CHIP_PORT)); + + SecurePairingUsingTestSecret pairingLocalToPeer(Optional::Value(kDestinationNodeId), kTestPeerGroupKeyId, + kTestLocalGroupKeyId); + + err = ctx.GetSecureSessionManager().NewPairing(peer, kDestinationNodeId, &pairingLocalToPeer, 0); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + SecurePairingUsingTestSecret pairingPeerToLocal(Optional::Value(kSourceNodeId), kTestLocalGroupKeyId, + kTestPeerGroupKeyId); + + err = ctx.GetSecureSessionManager().NewPairing(peer, kSourceNodeId, &pairingPeerToLocal, 1); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + SecureSessionHandle session(kDestinationNodeId, 0x4000); + + // Should be able to send a message to itself by just calling send. + testExchangeMgr.ReceiveHandlerCallCount = 0; + + err = sm->SendMsgCounterSyncReq(session); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, testExchangeMgr.ReceiveHandlerCallCount == 1); +} + +void CheckReceiveMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext) +{ + TestContext & ctx = *reinterpret_cast(inContext); + + ctx.GetInetLayer().SystemLayer()->Init(nullptr); + + IPAddress addr; + IPAddress::FromString("127.0.0.1", addr); + + CHIP_ERROR err = CHIP_NO_ERROR; + MockAppDelegate mockAppDelegate; + + mockAppDelegate.mSuite = inSuite; + + chip::SecureChannel::SecureChannelMgr * sm = ctx.GetExchangeManager().GetSecureChannelMgr(); + NL_TEST_ASSERT(inSuite, sm != nullptr); + + // Register to receive unsolicited Secure Channel Request messages from the exchange manager. + err = + ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(Protocols::kProtocol_SecureChannel, &mockAppDelegate); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + Optional peer(Transport::PeerAddress::UDP(addr, CHIP_PORT)); + + SecurePairingUsingTestSecret pairingLocalToPeer(Optional::Value(kDestinationNodeId), kTestPeerGroupKeyId, + kTestLocalGroupKeyId); + + err = ctx.GetSecureSessionManager().NewPairing(peer, kDestinationNodeId, &pairingLocalToPeer, 0); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + SecurePairingUsingTestSecret pairingPeerToLocal(Optional::Value(kSourceNodeId), kTestLocalGroupKeyId, + kTestPeerGroupKeyId); + + err = ctx.GetSecureSessionManager().NewPairing(peer, kSourceNodeId, &pairingPeerToLocal, 1); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + SecureSessionHandle session(kDestinationNodeId, 0x4000); + + err = sm->SendMsgCounterSyncReq(session); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, mockAppDelegate.IsOnMessageReceivedCalled == true); +} + +// Test Suite + +/** + * Test Suite that lists all the test functions. + */ +// clang-format off +const nlTest sTests[] = +{ + NL_TEST_DEF("Test SecureChannelMgr::ReceiveMsgCounterSyncReq", CheckReceiveMsgCounterSyncReq), + NL_TEST_DEF("Test SecureChannelMgr::SendMsgCounterSyncReq", CheckSendMsgCounterSyncReq), + NL_TEST_SENTINEL() +}; +// clang-format on + +int Initialize(void * aContext); +int Finalize(void * aContext); + +// clang-format off +nlTestSuite sSuite = +{ + "Test-SecureChannelMgr", + &sTests[0], + Initialize, + Finalize +}; +// clang-format on + +/** + * Initialize the test suite. + */ +int Initialize(void * aContext) +{ + CHIP_ERROR err = gTransportMgr.Init("LOOPBACK"); + if (err != CHIP_NO_ERROR) + return FAILURE; + + err = reinterpret_cast(aContext)->Init(&sSuite, &gTransportMgr); + return (err == CHIP_NO_ERROR) ? SUCCESS : FAILURE; +} + +/** + * Finalize the test suite. + */ +int Finalize(void * aContext) +{ + CHIP_ERROR err = reinterpret_cast(aContext)->Shutdown(); + return (err == CHIP_NO_ERROR) ? SUCCESS : FAILURE; +} + +} // namespace + +/** + * Main + */ +int TestSecureChannelMgr() +{ + // Run test suit against one context + nlTestRunner(&sSuite, &sContext); + + return (nlTestRunnerStats(&sSuite)); +} diff --git a/src/messaging/tests/TestSecureChannelMgrDriver.cpp b/src/messaging/tests/TestSecureChannelMgrDriver.cpp new file mode 100644 index 00000000000000..e637457efc025f --- /dev/null +++ b/src/messaging/tests/TestSecureChannelMgrDriver.cpp @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements a standalone/native program executable + * test driver for the SecureChannelMgr tests. + * + */ + +#include "TestMessagingLayer.h" + +#include + +int main() +{ + // Generate machine-readable, comma-separated value (CSV) output. + nlTestSetOutputStyle(OUTPUT_CSV); + + return (TestSecureChannelMgr()); +} diff --git a/src/transport/SecureSessionMgr.h b/src/transport/SecureSessionMgr.h index 0f1d9c9a7b2597..5224a945f77fde 100644 --- a/src/transport/SecureSessionMgr.h +++ b/src/transport/SecureSessionMgr.h @@ -62,6 +62,9 @@ class SecureSessionHandle return mPeerNodeId == that.mPeerNodeId && mPeerKeyId == that.mPeerKeyId && mAdmin == that.mAdmin; } + NodeId GetPeerNodeId() const { return mPeerNodeId; } + uint16_t GetPeerKeyId() const { return mPeerKeyId; } + private: friend class SecureSessionMgr; NodeId mPeerNodeId; From 7892d91074abb7c37315fcba1bca6464e3b907f9 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Mon, 8 Feb 2021 12:29:48 -0800 Subject: [PATCH 2/3] Address review comments. --- src/messaging/ExchangeContext.h | 6 +- src/messaging/ExchangeMgr.h | 4 +- src/messaging/SecureChannelMgr.cpp | 64 ++++++++++---------- src/messaging/SecureChannelMgr.h | 18 +++--- src/messaging/tests/TestSecureChannelMgr.cpp | 4 +- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/messaging/ExchangeContext.h b/src/messaging/ExchangeContext.h index d749fdd91e1337..340a902916d952 100644 --- a/src/messaging/ExchangeContext.h +++ b/src/messaging/ExchangeContext.h @@ -167,9 +167,9 @@ class DLL_EXPORT ExchangeContext : public ReferenceCounted mFlags; // Internal state flags diff --git a/src/messaging/ExchangeMgr.h b/src/messaging/ExchangeMgr.h index e375a8a34532ad..b62427e2f4537c 100644 --- a/src/messaging/ExchangeMgr.h +++ b/src/messaging/ExchangeMgr.h @@ -178,7 +178,7 @@ class DLL_EXPORT ExchangeManager : public SecureSessionMgrDelegate ReliableMessageMgr * GetReliableMessageMgr() { return &mReliableMessageMgr; }; - SecureChannel::SecureChannelMgr * GetSecureChannelMgr() { return &mSecureChannelMgr; }; + Protocols::SecureChannel::SecureChannelMgr * GetSecureChannelMgr() { return &mSecureChannelMgr; }; size_t GetContextsInUse() const { return mContextsInUse; } @@ -200,7 +200,7 @@ class DLL_EXPORT ExchangeManager : public SecureSessionMgrDelegate State mState; SecureSessionMgr * mSessionMgr; ReliableMessageMgr mReliableMessageMgr; - SecureChannel::SecureChannelMgr mSecureChannelMgr; + Protocols::SecureChannel::SecureChannelMgr mSecureChannelMgr; std::array mContextPool; size_t mContextsInUse; diff --git a/src/messaging/SecureChannelMgr.cpp b/src/messaging/SecureChannelMgr.cpp index 28a3cf0452eb94..e2be22ae970657 100644 --- a/src/messaging/SecureChannelMgr.cpp +++ b/src/messaging/SecureChannelMgr.cpp @@ -34,13 +34,9 @@ #include namespace chip { +namespace Protocols { namespace SecureChannel { -SecureChannelMgr::SecureChannelMgr() -{ - mExchangeMgr = nullptr; -} - CHIP_ERROR SecureChannelMgr::Init(Messaging::ExchangeManager * exchangeMgr) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -66,28 +62,28 @@ void SecureChannelMgr::Shutdown() } } -void SecureChannelMgr::OnMessageReceived(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, +void SecureChannelMgr::OnMessageReceived(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, const PayloadHeader & payloadHeader, System::PacketBufferHandle msgBuf) { if (payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::MsgCounterSyncReq)) { - HandleMsgCounterSyncReq(ec, packetHeader, std::move(msgBuf)); + HandleMsgCounterSyncReq(exchangeContext, packetHeader, std::move(msgBuf)); } else if (payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::MsgCounterSyncRsp)) { - HandleMsgCounterSyncResp(ec, packetHeader, std::move(msgBuf)); + HandleMsgCounterSyncResp(exchangeContext, packetHeader, std::move(msgBuf)); } } -void SecureChannelMgr::OnResponseTimeout(Messaging::ExchangeContext * ec) +void SecureChannelMgr::OnResponseTimeout(Messaging::ExchangeContext * exchangeContext) { // Close the exchange if MsgCounterSyncRsp is not received before kMsgCounterSyncTimeout. - if (ec != nullptr) - ec->Close(); + if (exchangeContext != nullptr) + exchangeContext->Close(); } // Create and initialize new exchange for the message counter synchronization request/response messages. -CHIP_ERROR SecureChannelMgr::NewMsgCounterSyncExchange(SecureSessionHandle session, Messaging::ExchangeContext *& ec) +CHIP_ERROR SecureChannelMgr::NewMsgCounterSyncExchange(SecureSessionHandle session, Messaging::ExchangeContext *& exchangeContext) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -95,8 +91,8 @@ CHIP_ERROR SecureChannelMgr::NewMsgCounterSyncExchange(SecureSessionHandle sessi VerifyOrExit(ChipKeyId::IsAppGroupKey(session.GetPeerKeyId()), err = CHIP_ERROR_INVALID_ARGUMENT); // Create new exchange context. - ec = mExchangeMgr->NewContext(session, this); - VerifyOrExit(ec != nullptr, err = CHIP_ERROR_NO_MEMORY); + exchangeContext = mExchangeMgr->NewContext(session, this); + VerifyOrExit(exchangeContext != nullptr, err = CHIP_ERROR_NO_MEMORY); exit: return err; @@ -104,14 +100,14 @@ CHIP_ERROR SecureChannelMgr::NewMsgCounterSyncExchange(SecureSessionHandle sessi CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncReq(SecureSessionHandle session) { - CHIP_ERROR err = CHIP_NO_ERROR; - Messaging::ExchangeContext * ec = nullptr; + CHIP_ERROR err = CHIP_NO_ERROR; + Messaging::ExchangeContext * exchangeContext = nullptr; System::PacketBufferHandle msgBuf; Messaging::SendFlags sendFlags; uint8_t challenge[kMsgCounterChallengeSize]; // Create and initialize new exchange. - err = NewMsgCounterSyncExchange(session, ec); + err = NewMsgCounterSyncExchange(session, exchangeContext); SuccessOrExit(err); // Allocate a buffer for the null message. @@ -123,7 +119,7 @@ CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncReq(SecureSessionHandle session) SuccessOrExit(err); // Store generated Challenge value to ExchangeContext to resolve synchronization response. - ec->SetChallenge(challenge); + exchangeContext->SetChallenge(challenge); memcpy(msgBuf->Start(), challenge, kMsgCounterChallengeSize); msgBuf->SetDataLength(kMsgCounterChallengeSize); @@ -132,10 +128,10 @@ CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncReq(SecureSessionHandle session) sendFlags.Set(Messaging::SendMessageFlags::kNoAutoRequestAck, true).Set(Messaging::SendMessageFlags::kExpectResponse, true); // Arm a timer to enforce that a MsgCounterSyncRsp is received before kMsgCounterSyncTimeout. - ec->SetResponseTimeout(kMsgCounterSyncTimeout); + exchangeContext->SetResponseTimeout(kMsgCounterSyncTimeout); // Send the message counter synchronization request in a Secure Channel Protocol::MsgCounterSyncReq message. - err = ec->SendMessage(Protocols::SecureChannel::MsgType::MsgCounterSyncReq, std::move(msgBuf), sendFlags); + err = exchangeContext->SendMessage(Protocols::SecureChannel::MsgType::MsgCounterSyncReq, std::move(msgBuf), sendFlags); SuccessOrExit(err); exit: @@ -147,7 +143,7 @@ CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncReq(SecureSessionHandle session) return err; } -CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncResp(Messaging::ExchangeContext * ec, SecureSessionHandle session) +CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncResp(Messaging::ExchangeContext * exchangeContext, SecureSessionHandle session) { CHIP_ERROR err = CHIP_NO_ERROR; Transport::PeerConnectionState * state = nullptr; @@ -171,7 +167,7 @@ CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncResp(Messaging::ExchangeContext * bbuf.Put32(state->GetSendMessageIndex()); // Fill in the random value - bbuf.Put(ec->GetChallenge(), kMsgCounterChallengeSize); + bbuf.Put(exchangeContext->GetChallenge(), kMsgCounterChallengeSize); VerifyOrExit(bbuf.Fit(), err = CHIP_ERROR_NO_MEMORY); } @@ -180,8 +176,8 @@ CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncResp(Messaging::ExchangeContext * msgBuf->SetDataLength(kMsgCounterSyncRespMsgSize); // Send message counter synchronization response message. - err = ec->SendMessage(Protocols::SecureChannel::MsgType::MsgCounterSyncRsp, std::move(msgBuf), - Messaging::SendFlags(Messaging::SendMessageFlags::kNoAutoRequestAck)); + err = exchangeContext->SendMessage(Protocols::SecureChannel::MsgType::MsgCounterSyncRsp, std::move(msgBuf), + Messaging::SendFlags(Messaging::SendMessageFlags::kNoAutoRequestAck)); exit: if (err != CHIP_NO_ERROR) @@ -192,7 +188,7 @@ CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncResp(Messaging::ExchangeContext * return err; } -void SecureChannelMgr::HandleMsgCounterSyncReq(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, +void SecureChannelMgr::HandleMsgCounterSyncReq(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, System::PacketBufferHandle msgBuf) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -208,10 +204,10 @@ void SecureChannelMgr::HandleMsgCounterSyncReq(Messaging::ExchangeContext * ec, VerifyOrExit(reqlen == kMsgCounterChallengeSize, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); // Store the 64-bit value sent in the Challenge filed of the MsgCounterSyncReq. - ec->SetChallenge(req); + exchangeContext->SetChallenge(req); // Respond with MsgCounterSyncResp - err = SendMsgCounterSyncResp(ec, { packetHeader.GetSourceNodeId().Value(), packetHeader.GetEncryptionKeyID() }); + err = SendMsgCounterSyncResp(exchangeContext, { packetHeader.GetSourceNodeId().Value(), packetHeader.GetEncryptionKeyID() }); exit: if (err != CHIP_NO_ERROR) @@ -219,13 +215,13 @@ void SecureChannelMgr::HandleMsgCounterSyncReq(Messaging::ExchangeContext * ec, ChipLogError(ExchangeManager, "Failed to handle MsgCounterSyncReq message with error:%s", ErrorStr(err)); } - if (ec != nullptr) - ec->Close(); + if (exchangeContext != nullptr) + exchangeContext->Close(); return; } -void SecureChannelMgr::HandleMsgCounterSyncResp(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, +void SecureChannelMgr::HandleMsgCounterSyncResp(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, System::PacketBufferHandle msgBuf) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -249,7 +245,8 @@ void SecureChannelMgr::HandleMsgCounterSyncResp(Messaging::ExchangeContext * ec, memcpy(challenge, resp, kMsgCounterChallengeSize); // Verify that the response field matches the expected Challenge field for the exchange. - VerifyOrExit(memcmp(ec->GetChallenge(), challenge, kMsgCounterChallengeSize) == 0, err = CHIP_ERROR_INVALID_SIGNATURE); + VerifyOrExit(memcmp(exchangeContext->GetChallenge(), challenge, kMsgCounterChallengeSize) == 0, + err = CHIP_ERROR_INVALID_SIGNATURE); // ToDo:(#4628)Initialize/synchronize peer's message counter to FabricState. VerifyOrExit(syncCounter != 0, err = CHIP_ERROR_READ_FAILED); @@ -260,11 +257,12 @@ void SecureChannelMgr::HandleMsgCounterSyncResp(Messaging::ExchangeContext * ec, ChipLogError(ExchangeManager, "Failed to handle MsgCounterSyncResp message with error:%s", ErrorStr(err)); } - if (ec != nullptr) - ec->Close(); + if (exchangeContext != nullptr) + exchangeContext->Close(); return; } } // namespace SecureChannel +} // namespace Protocols } // namespace chip diff --git a/src/messaging/SecureChannelMgr.h b/src/messaging/SecureChannelMgr.h index 7d7b6640c2724e..194c332ae7b7af 100644 --- a/src/messaging/SecureChannelMgr.h +++ b/src/messaging/SecureChannelMgr.h @@ -25,6 +25,7 @@ #include namespace chip { +namespace Protocols { namespace SecureChannel { constexpr uint16_t kMsgCounterSyncRespMsgSize = 12; // The size of the message counter synchronization response message. @@ -36,7 +37,7 @@ class ExchangeManager; class SecureChannelMgr : public Messaging::ExchangeDelegate { public: - SecureChannelMgr(); + SecureChannelMgr() : mExchangeMgr(nullptr) {} CHIP_ERROR Init(Messaging::ExchangeManager * exchangeMgr); void Shutdown(); @@ -58,21 +59,22 @@ class SecureChannelMgr : public Messaging::ExchangeDelegate private: Messaging::ExchangeManager * mExchangeMgr; // [READ ONLY] Associated Exchange Manager object. - CHIP_ERROR NewMsgCounterSyncExchange(SecureSessionHandle session, Messaging::ExchangeContext *& ec); + CHIP_ERROR NewMsgCounterSyncExchange(SecureSessionHandle session, Messaging::ExchangeContext *& exchangeContext); - CHIP_ERROR SendMsgCounterSyncResp(Messaging::ExchangeContext * ec, SecureSessionHandle session); + CHIP_ERROR SendMsgCounterSyncResp(Messaging::ExchangeContext * exchangeContext, SecureSessionHandle session); - void HandleMsgCounterSyncReq(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, + void HandleMsgCounterSyncReq(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, System::PacketBufferHandle msgBuf); - void HandleMsgCounterSyncResp(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, + void HandleMsgCounterSyncResp(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, System::PacketBufferHandle msgBuf); - void OnMessageReceived(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader, const PayloadHeader & payloadHeader, - System::PacketBufferHandle payload) override; + void OnMessageReceived(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, + const PayloadHeader & payloadHeader, System::PacketBufferHandle payload) override; - void OnResponseTimeout(Messaging::ExchangeContext * ec) override; + void OnResponseTimeout(Messaging::ExchangeContext * exchangeContext) override; }; } // namespace SecureChannel +} // namespace Protocols } // namespace chip diff --git a/src/messaging/tests/TestSecureChannelMgr.cpp b/src/messaging/tests/TestSecureChannelMgr.cpp index 641cbc491853dc..ce9f237e98bff7 100644 --- a/src/messaging/tests/TestSecureChannelMgr.cpp +++ b/src/messaging/tests/TestSecureChannelMgr.cpp @@ -139,7 +139,7 @@ void CheckSendMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext) testExchangeMgr.mSuite = inSuite; ctx.GetSecureSessionManager().SetDelegate(&testExchangeMgr); - chip::SecureChannel::SecureChannelMgr * sm = ctx.GetExchangeManager().GetSecureChannelMgr(); + chip::Protocols::SecureChannel::SecureChannelMgr * sm = ctx.GetExchangeManager().GetSecureChannelMgr(); NL_TEST_ASSERT(inSuite, sm != nullptr); Optional peer(Transport::PeerAddress::UDP(addr, CHIP_PORT)); @@ -180,7 +180,7 @@ void CheckReceiveMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext) mockAppDelegate.mSuite = inSuite; - chip::SecureChannel::SecureChannelMgr * sm = ctx.GetExchangeManager().GetSecureChannelMgr(); + chip::Protocols::SecureChannel::SecureChannelMgr * sm = ctx.GetExchangeManager().GetSecureChannelMgr(); NL_TEST_ASSERT(inSuite, sm != nullptr); // Register to receive unsolicited Secure Channel Request messages from the exchange manager. From 2428bc8bd86d6ad14d0fdac56b2da0fa2b8098d7 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Thu, 11 Feb 2021 11:25:26 -0800 Subject: [PATCH 3/3] Rename SecureChannelMgr to MessageCounterSyncMgr --- src/messaging/BUILD.gn | 4 +- src/messaging/ExchangeMgr.cpp | 13 ++--- src/messaging/ExchangeMgr.h | 6 +-- ...eChannelMgr.cpp => MessageCounterSync.cpp} | 48 +++++++++---------- ...ecureChannelMgr.h => MessageCounterSync.h} | 12 ++--- src/messaging/ReliableMessageMgr.cpp | 1 - src/messaging/tests/BUILD.gn | 4 +- ...lMgr.cpp => TestMessageCounterSyncMgr.cpp} | 18 +++---- ...pp => TestMessageCounterSyncMgrDriver.cpp} | 2 +- src/messaging/tests/TestMessagingLayer.h | 2 +- 10 files changed, 50 insertions(+), 60 deletions(-) rename src/messaging/{SecureChannelMgr.cpp => MessageCounterSync.cpp} (81%) rename src/messaging/{SecureChannelMgr.h => MessageCounterSync.h} (92%) rename src/messaging/tests/{TestSecureChannelMgr.cpp => TestMessageCounterSyncMgr.cpp} (92%) rename src/messaging/tests/{TestSecureChannelMgrDriver.cpp => TestMessageCounterSyncMgrDriver.cpp} (95%) diff --git a/src/messaging/BUILD.gn b/src/messaging/BUILD.gn index 8fa8a87df8da85..766354d0a4ba70 100644 --- a/src/messaging/BUILD.gn +++ b/src/messaging/BUILD.gn @@ -27,13 +27,13 @@ static_library("messaging") { "ExchangeMgr.cpp", "ExchangeMgr.h", "Flags.h", + "MessageCounterSync.cpp", + "MessageCounterSync.h", "ReliableMessageContext.cpp", "ReliableMessageContext.h", "ReliableMessageMgr.cpp", "ReliableMessageMgr.h", "ReliableMessageProtocolConfig.h", - "SecureChannelMgr.cpp", - "SecureChannelMgr.h", ] cflags = [ "-Wconversion" ] diff --git a/src/messaging/ExchangeMgr.cpp b/src/messaging/ExchangeMgr.cpp index 199ffe769589e5..54f27b66e8ea14 100644 --- a/src/messaging/ExchangeMgr.cpp +++ b/src/messaging/ExchangeMgr.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include using namespace chip::Encoding; @@ -68,7 +69,7 @@ CHIP_ERROR ExchangeManager::Init(SecureSessionMgr * sessionMgr) { CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrExit(mState == State::kState_NotInitialized, err = CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mState == State::kState_NotInitialized, err = CHIP_ERROR_INCORRECT_STATE); mSessionMgr = sessionMgr; @@ -83,22 +84,18 @@ CHIP_ERROR ExchangeManager::Init(SecureSessionMgr * sessionMgr) mReliableMessageMgr.Init(sessionMgr->SystemLayer(), sessionMgr); - err = mSecureChannelMgr.Init(this); - SuccessOrExit(err); + err = mMessageCounterSyncMgr.Init(this); + ReturnErrorOnFailure(err); mState = State::kState_Initialized; -exit: return err; } CHIP_ERROR ExchangeManager::Shutdown() { -<<<<<<< HEAD + mMessageCounterSyncMgr.Shutdown(); mReliableMessageMgr.Shutdown(); -======= - mSecureChannelMgr.Shutdown(); ->>>>>>> Implement Message Counter Synchronization Protocol (MCSP) part if (mSessionMgr != nullptr) { diff --git a/src/messaging/ExchangeMgr.h b/src/messaging/ExchangeMgr.h index b62427e2f4537c..7ab119c1235720 100644 --- a/src/messaging/ExchangeMgr.h +++ b/src/messaging/ExchangeMgr.h @@ -27,8 +27,8 @@ #include #include +#include #include -#include #include #include @@ -178,7 +178,7 @@ class DLL_EXPORT ExchangeManager : public SecureSessionMgrDelegate ReliableMessageMgr * GetReliableMessageMgr() { return &mReliableMessageMgr; }; - Protocols::SecureChannel::SecureChannelMgr * GetSecureChannelMgr() { return &mSecureChannelMgr; }; + MessageCounterSyncMgr * GetMessageCounterSyncMgr() { return &mMessageCounterSyncMgr; }; size_t GetContextsInUse() const { return mContextsInUse; } @@ -200,7 +200,7 @@ class DLL_EXPORT ExchangeManager : public SecureSessionMgrDelegate State mState; SecureSessionMgr * mSessionMgr; ReliableMessageMgr mReliableMessageMgr; - Protocols::SecureChannel::SecureChannelMgr mSecureChannelMgr; + MessageCounterSyncMgr mMessageCounterSyncMgr; std::array mContextPool; size_t mContextsInUse; diff --git a/src/messaging/SecureChannelMgr.cpp b/src/messaging/MessageCounterSync.cpp similarity index 81% rename from src/messaging/SecureChannelMgr.cpp rename to src/messaging/MessageCounterSync.cpp index e2be22ae970657..829c49b85a9e82 100644 --- a/src/messaging/SecureChannelMgr.cpp +++ b/src/messaging/MessageCounterSync.cpp @@ -27,33 +27,32 @@ #include #include #include -#include +#include #include #include #include +#include #include namespace chip { -namespace Protocols { -namespace SecureChannel { +namespace Messaging { -CHIP_ERROR SecureChannelMgr::Init(Messaging::ExchangeManager * exchangeMgr) +CHIP_ERROR MessageCounterSyncMgr::Init(Messaging::ExchangeManager * exchangeMgr) { CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrExit(exchangeMgr != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(exchangeMgr != nullptr, err = CHIP_ERROR_INCORRECT_STATE); mExchangeMgr = exchangeMgr; // Register to receive unsolicited Secure Channel Request messages from the exchange manager. err = mExchangeMgr->RegisterUnsolicitedMessageHandlerForProtocol(Protocols::kProtocol_SecureChannel, this); - SuccessOrExit(err); + ReturnErrorOnFailure(err); -exit: return err; } -void SecureChannelMgr::Shutdown() +void MessageCounterSyncMgr::Shutdown() { if (mExchangeMgr != nullptr) { @@ -62,8 +61,8 @@ void SecureChannelMgr::Shutdown() } } -void SecureChannelMgr::OnMessageReceived(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, - const PayloadHeader & payloadHeader, System::PacketBufferHandle msgBuf) +void MessageCounterSyncMgr::OnMessageReceived(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, + const PayloadHeader & payloadHeader, System::PacketBufferHandle msgBuf) { if (payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::MsgCounterSyncReq)) { @@ -75,7 +74,7 @@ void SecureChannelMgr::OnMessageReceived(Messaging::ExchangeContext * exchangeCo } } -void SecureChannelMgr::OnResponseTimeout(Messaging::ExchangeContext * exchangeContext) +void MessageCounterSyncMgr::OnResponseTimeout(Messaging::ExchangeContext * exchangeContext) { // Close the exchange if MsgCounterSyncRsp is not received before kMsgCounterSyncTimeout. if (exchangeContext != nullptr) @@ -83,22 +82,22 @@ void SecureChannelMgr::OnResponseTimeout(Messaging::ExchangeContext * exchangeCo } // Create and initialize new exchange for the message counter synchronization request/response messages. -CHIP_ERROR SecureChannelMgr::NewMsgCounterSyncExchange(SecureSessionHandle session, Messaging::ExchangeContext *& exchangeContext) +CHIP_ERROR MessageCounterSyncMgr::NewMsgCounterSyncExchange(SecureSessionHandle session, + Messaging::ExchangeContext *& exchangeContext) { CHIP_ERROR err = CHIP_NO_ERROR; // Message counter synchronization protocol is only applicable for application group keys. - VerifyOrExit(ChipKeyId::IsAppGroupKey(session.GetPeerKeyId()), err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(ChipKeyId::IsAppGroupKey(session.GetPeerKeyId()), err = CHIP_ERROR_INVALID_ARGUMENT); // Create new exchange context. exchangeContext = mExchangeMgr->NewContext(session, this); - VerifyOrExit(exchangeContext != nullptr, err = CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(exchangeContext != nullptr, err = CHIP_ERROR_NO_MEMORY); -exit: return err; } -CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncReq(SecureSessionHandle session) +CHIP_ERROR MessageCounterSyncMgr::SendMsgCounterSyncReq(SecureSessionHandle session) { CHIP_ERROR err = CHIP_NO_ERROR; Messaging::ExchangeContext * exchangeContext = nullptr; @@ -111,7 +110,7 @@ CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncReq(SecureSessionHandle session) SuccessOrExit(err); // Allocate a buffer for the null message. - msgBuf = System::PacketBufferHandle::New(kMsgCounterChallengeSize); + msgBuf = MessagePacketBuffer::New(kMsgCounterChallengeSize); VerifyOrExit(!msgBuf.IsNull(), err = CHIP_ERROR_NO_MEMORY); // Generate a 64-bit random number to uniquely identify the request. @@ -143,7 +142,7 @@ CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncReq(SecureSessionHandle session) return err; } -CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncResp(Messaging::ExchangeContext * exchangeContext, SecureSessionHandle session) +CHIP_ERROR MessageCounterSyncMgr::SendMsgCounterSyncResp(Messaging::ExchangeContext * exchangeContext, SecureSessionHandle session) { CHIP_ERROR err = CHIP_NO_ERROR; Transport::PeerConnectionState * state = nullptr; @@ -188,8 +187,8 @@ CHIP_ERROR SecureChannelMgr::SendMsgCounterSyncResp(Messaging::ExchangeContext * return err; } -void SecureChannelMgr::HandleMsgCounterSyncReq(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, - System::PacketBufferHandle msgBuf) +void MessageCounterSyncMgr::HandleMsgCounterSyncReq(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, + System::PacketBufferHandle msgBuf) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -207,7 +206,7 @@ void SecureChannelMgr::HandleMsgCounterSyncReq(Messaging::ExchangeContext * exch exchangeContext->SetChallenge(req); // Respond with MsgCounterSyncResp - err = SendMsgCounterSyncResp(exchangeContext, { packetHeader.GetSourceNodeId().Value(), packetHeader.GetEncryptionKeyID() }); + err = SendMsgCounterSyncResp(exchangeContext, { packetHeader.GetSourceNodeId().Value(), packetHeader.GetEncryptionKeyID(), 0 }); exit: if (err != CHIP_NO_ERROR) @@ -221,8 +220,8 @@ void SecureChannelMgr::HandleMsgCounterSyncReq(Messaging::ExchangeContext * exch return; } -void SecureChannelMgr::HandleMsgCounterSyncResp(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader, - System::PacketBufferHandle msgBuf) +void MessageCounterSyncMgr::HandleMsgCounterSyncResp(Messaging::ExchangeContext * exchangeContext, + const PacketHeader & packetHeader, System::PacketBufferHandle msgBuf) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -263,6 +262,5 @@ void SecureChannelMgr::HandleMsgCounterSyncResp(Messaging::ExchangeContext * exc return; } -} // namespace SecureChannel -} // namespace Protocols +} // namespace Messaging } // namespace chip diff --git a/src/messaging/SecureChannelMgr.h b/src/messaging/MessageCounterSync.h similarity index 92% rename from src/messaging/SecureChannelMgr.h rename to src/messaging/MessageCounterSync.h index 194c332ae7b7af..efcae568110019 100644 --- a/src/messaging/SecureChannelMgr.h +++ b/src/messaging/MessageCounterSync.h @@ -22,11 +22,8 @@ #pragma once -#include - namespace chip { -namespace Protocols { -namespace SecureChannel { +namespace Messaging { constexpr uint16_t kMsgCounterSyncRespMsgSize = 12; // The size of the message counter synchronization response message. constexpr uint32_t kMsgCounterSyncTimeout = 500; // The amount of time(in milliseconds) which a peer is given to respond @@ -34,10 +31,10 @@ constexpr uint32_t kMsgCounterSyncTimeout = 500; // The amount of time(in mi class ExchangeManager; -class SecureChannelMgr : public Messaging::ExchangeDelegate +class MessageCounterSyncMgr : public Messaging::ExchangeDelegate { public: - SecureChannelMgr() : mExchangeMgr(nullptr) {} + MessageCounterSyncMgr() : mExchangeMgr(nullptr) {} CHIP_ERROR Init(Messaging::ExchangeManager * exchangeMgr); void Shutdown(); @@ -75,6 +72,5 @@ class SecureChannelMgr : public Messaging::ExchangeDelegate void OnResponseTimeout(Messaging::ExchangeContext * exchangeContext) override; }; -} // namespace SecureChannel -} // namespace Protocols +} // namespace Messaging } // namespace chip diff --git a/src/messaging/ReliableMessageMgr.cpp b/src/messaging/ReliableMessageMgr.cpp index 79281154ecfc58..05fd0d6253658a 100644 --- a/src/messaging/ReliableMessageMgr.cpp +++ b/src/messaging/ReliableMessageMgr.cpp @@ -25,7 +25,6 @@ #include -#include #include #include #include diff --git a/src/messaging/tests/BUILD.gn b/src/messaging/tests/BUILD.gn index bc6d76bc4bb663..b8975653459c95 100644 --- a/src/messaging/tests/BUILD.gn +++ b/src/messaging/tests/BUILD.gn @@ -26,9 +26,9 @@ chip_test_suite("tests") { "MessagingContext.cpp", "MessagingContext.h", "TestExchangeMgr.cpp", + "TestMessageCounterSyncMgr.cpp", "TestMessagingLayer.h", "TestReliableMessageProtocol.cpp", - "TestSecureChannelMgr.cpp", ] cflags = [ "-Wconversion" ] @@ -47,7 +47,7 @@ chip_test_suite("tests") { tests = [ "TestExchangeMgr", - "TestSecureChannelMgr", + "TestMessageCounterSyncMgr", "TestReliableMessageProtocol", ] } diff --git a/src/messaging/tests/TestSecureChannelMgr.cpp b/src/messaging/tests/TestMessageCounterSyncMgr.cpp similarity index 92% rename from src/messaging/tests/TestSecureChannelMgr.cpp rename to src/messaging/tests/TestMessageCounterSyncMgr.cpp index ce9f237e98bff7..3301dbdbf5cd3a 100644 --- a/src/messaging/tests/TestSecureChannelMgr.cpp +++ b/src/messaging/tests/TestMessageCounterSyncMgr.cpp @@ -18,7 +18,7 @@ /** * @file - * This file implements unit tests for the SecureChannelMgr implementation. + * This file implements unit tests for the MessageCounterSyncMgr implementation. */ #include "TestMessagingLayer.h" @@ -139,7 +139,7 @@ void CheckSendMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext) testExchangeMgr.mSuite = inSuite; ctx.GetSecureSessionManager().SetDelegate(&testExchangeMgr); - chip::Protocols::SecureChannel::SecureChannelMgr * sm = ctx.GetExchangeManager().GetSecureChannelMgr(); + MessageCounterSyncMgr * sm = ctx.GetExchangeManager().GetMessageCounterSyncMgr(); NL_TEST_ASSERT(inSuite, sm != nullptr); Optional peer(Transport::PeerAddress::UDP(addr, CHIP_PORT)); @@ -156,7 +156,7 @@ void CheckSendMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext) err = ctx.GetSecureSessionManager().NewPairing(peer, kSourceNodeId, &pairingPeerToLocal, 1); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - SecureSessionHandle session(kDestinationNodeId, 0x4000); + SecureSessionHandle session(kDestinationNodeId, 0x4000, 0); // Should be able to send a message to itself by just calling send. testExchangeMgr.ReceiveHandlerCallCount = 0; @@ -180,7 +180,7 @@ void CheckReceiveMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext) mockAppDelegate.mSuite = inSuite; - chip::Protocols::SecureChannel::SecureChannelMgr * sm = ctx.GetExchangeManager().GetSecureChannelMgr(); + MessageCounterSyncMgr * sm = ctx.GetExchangeManager().GetMessageCounterSyncMgr(); NL_TEST_ASSERT(inSuite, sm != nullptr); // Register to receive unsolicited Secure Channel Request messages from the exchange manager. @@ -202,7 +202,7 @@ void CheckReceiveMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext) err = ctx.GetSecureSessionManager().NewPairing(peer, kSourceNodeId, &pairingPeerToLocal, 1); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - SecureSessionHandle session(kDestinationNodeId, 0x4000); + SecureSessionHandle session(kDestinationNodeId, 0x4000, 0); err = sm->SendMsgCounterSyncReq(session); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); @@ -217,8 +217,8 @@ void CheckReceiveMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext) // clang-format off const nlTest sTests[] = { - NL_TEST_DEF("Test SecureChannelMgr::ReceiveMsgCounterSyncReq", CheckReceiveMsgCounterSyncReq), - NL_TEST_DEF("Test SecureChannelMgr::SendMsgCounterSyncReq", CheckSendMsgCounterSyncReq), + NL_TEST_DEF("Test MessageCounterSyncMgr::ReceiveMsgCounterSyncReq", CheckReceiveMsgCounterSyncReq), + NL_TEST_DEF("Test MessageCounterSyncMgr::SendMsgCounterSyncReq", CheckSendMsgCounterSyncReq), NL_TEST_SENTINEL() }; // clang-format on @@ -229,7 +229,7 @@ int Finalize(void * aContext); // clang-format off nlTestSuite sSuite = { - "Test-SecureChannelMgr", + "Test-MessageCounterSyncMgr", &sTests[0], Initialize, Finalize @@ -263,7 +263,7 @@ int Finalize(void * aContext) /** * Main */ -int TestSecureChannelMgr() +int TestMessageCounterSyncMgr() { // Run test suit against one context nlTestRunner(&sSuite, &sContext); diff --git a/src/messaging/tests/TestSecureChannelMgrDriver.cpp b/src/messaging/tests/TestMessageCounterSyncMgrDriver.cpp similarity index 95% rename from src/messaging/tests/TestSecureChannelMgrDriver.cpp rename to src/messaging/tests/TestMessageCounterSyncMgrDriver.cpp index e637457efc025f..0bf0a9aa49c677 100644 --- a/src/messaging/tests/TestSecureChannelMgrDriver.cpp +++ b/src/messaging/tests/TestMessageCounterSyncMgrDriver.cpp @@ -31,5 +31,5 @@ int main() // Generate machine-readable, comma-separated value (CSV) output. nlTestSetOutputStyle(OUTPUT_CSV); - return (TestSecureChannelMgr()); + return (TestMessageCounterSyncMgr()); } diff --git a/src/messaging/tests/TestMessagingLayer.h b/src/messaging/tests/TestMessagingLayer.h index bf50d519b5ced8..fbab413701831b 100644 --- a/src/messaging/tests/TestMessagingLayer.h +++ b/src/messaging/tests/TestMessagingLayer.h @@ -29,7 +29,7 @@ extern "C" { #endif int TestExchangeMgr(void); -int TestSecureChannelMgr(void); +int TestMessageCounterSyncMgr(void); int TestReliableMessageProtocol(void); #ifdef __cplusplus