blob: c390f99096bb03db929bc729c1a217da045365f5 [file] [log] [blame]
/*
*
* 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.
*/
#include "MessagingContext.h"
#include "system/SystemClock.h"
#include <credentials/tests/CHIPCert_unit_test_vectors.h>
#include <lib/core/ErrorStr.h>
#include <lib/support/CodeUtils.h>
#include <messaging/ReliableMessageMgr.h>
#include <protocols/secure_channel/Constants.h>
namespace chip {
namespace Test {
using namespace TestCerts;
CHIP_ERROR MessagingContext::Init(TransportMgrBase * transport, IOContext * ioContext)
{
VerifyOrReturnError(mpData->mInitialized == false, CHIP_ERROR_INTERNAL);
mpData->mInitialized = true;
mpData->mIOContext = ioContext;
mpData->mTransport = transport;
ReturnErrorOnFailure(PlatformMemoryUser::Init());
// Make sure the storage is clean, so we will not reuse any stale data.
mpData->mStorage.ClearStorage();
ReturnErrorOnFailure(mpData->mOpKeyStore.Init(&mpData->mStorage));
ReturnErrorOnFailure(mpData->mOpCertStore.Init(&mpData->mStorage));
chip::FabricTable::InitParams initParams;
initParams.storage = &mpData->mStorage;
initParams.operationalKeystore = &mpData->mOpKeyStore;
initParams.opCertStore = &mpData->mOpCertStore;
ReturnErrorOnFailure(mpData->mFabricTable.Init(initParams));
ReturnErrorOnFailure(mpData->mSessionManager.Init(&GetSystemLayer(), transport, &mpData->mMessageCounterManager,
&mpData->mStorage, &mpData->mFabricTable, mpData->mSessionKeystore));
ReturnErrorOnFailure(mpData->mExchangeManager.Init(&mpData->mSessionManager));
ReturnErrorOnFailure(mpData->mMessageCounterManager.Init(&mpData->mExchangeManager));
if (mpData->mInitializeNodes)
{
ReturnErrorOnFailure(CreateAliceFabric());
ReturnErrorOnFailure(CreateBobFabric());
ReturnErrorOnFailure(CreateSessionBobToAlice());
ReturnErrorOnFailure(CreateSessionAliceToBob());
ReturnErrorOnFailure(CreateSessionBobToFriends());
ReturnErrorOnFailure(CreatePASESessionCharlieToDavid());
ReturnErrorOnFailure(CreatePASESessionDavidToCharlie());
}
// Set the additional MRP backoff to zero so that it does not affect the test execution time.
Messaging::ReliableMessageMgr::SetAdditionalMRPBackoffTime(MakeOptional(System::Clock::kZero));
return CHIP_NO_ERROR;
}
// Shutdown all layers, finalize operations
void MessagingContext::Shutdown()
{
VerifyOrDie(mpData->mInitialized);
mpData->mInitialized = false;
mpData->mMessageCounterManager.Shutdown();
mpData->mExchangeManager.Shutdown();
mpData->mSessionManager.Shutdown();
mpData->mFabricTable.Shutdown();
mpData->mOpCertStore.Finish();
mpData->mOpKeyStore.Finish();
// Reset the default additional MRP backoff.
Messaging::ReliableMessageMgr::SetAdditionalMRPBackoffTime(NullOptional);
}
CHIP_ERROR MessagingContext::InitFromExisting(const MessagingContext & existing)
{
return Init(existing.mpData->mTransport, existing.mpData->mIOContext);
}
void MessagingContext::ShutdownAndRestoreExisting(MessagingContext & existing)
{
Shutdown();
// Point the transport back to the original session manager, since we had
// pointed it to ours.
existing.mpData->mTransport->SetSessionManager(&existing.GetSecureSessionManager());
}
using namespace System::Clock::Literals;
constexpr chip::System::Clock::Timeout MessagingContext::kResponsiveIdleRetransTimeout;
constexpr chip::System::Clock::Timeout MessagingContext::kResponsiveActiveRetransTimeout;
void MessagingContext::SetMRPMode(MRPMode mode)
{
if (mode == MRPMode::kDefault)
{
mpData->mSessionBobToAlice->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig());
mpData->mSessionAliceToBob->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig());
mpData->mSessionCharlieToDavid->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig());
mpData->mSessionDavidToCharlie->AsSecureSession()->SetRemoteSessionParameters(GetDefaultMRPConfig());
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
ClearLocalMRPConfigOverride();
#else
//
// A test is calling this function assuming the overrides above are going to work
// when in fact, they won't because the compile flag is not set correctly.
//
VerifyOrDie(false);
#endif
}
else
{
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
OverrideLocalMRPConfig(MessagingContext::kResponsiveIdleRetransTimeout, MessagingContext::kResponsiveActiveRetransTimeout);
#else
//
// A test is calling this function assuming the overrides above are going to work
// when in fact, they won't because the compile flag is not set correctly.
//
VerifyOrDie(false);
#endif
mpData->mSessionBobToAlice->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig(
MessagingContext::kResponsiveIdleRetransTimeout, MessagingContext::kResponsiveActiveRetransTimeout));
mpData->mSessionAliceToBob->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig(
MessagingContext::kResponsiveIdleRetransTimeout, MessagingContext::kResponsiveActiveRetransTimeout));
mpData->mSessionCharlieToDavid->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig(
MessagingContext::kResponsiveIdleRetransTimeout, MessagingContext::kResponsiveActiveRetransTimeout));
mpData->mSessionDavidToCharlie->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig(
MessagingContext::kResponsiveIdleRetransTimeout, MessagingContext::kResponsiveActiveRetransTimeout));
}
}
CHIP_ERROR MessagingContext::CreateAliceFabric()
{
return mpData->mFabricTable.AddNewFabricForTestIgnoringCollisions(GetRootACertAsset().mCert, GetIAA1CertAsset().mCert,
GetNodeA1CertAsset().mCert, GetNodeA1CertAsset().mKey,
&mpData->mAliceFabricIndex);
}
CHIP_ERROR MessagingContext::CreateBobFabric()
{
return mpData->mFabricTable.AddNewFabricForTestIgnoringCollisions(GetRootACertAsset().mCert, GetIAA1CertAsset().mCert,
GetNodeA2CertAsset().mCert, GetNodeA2CertAsset().mKey,
&mpData->mBobFabricIndex);
}
CHIP_ERROR MessagingContext::CreateSessionBobToAlice()
{
return mpData->mSessionManager.InjectPaseSessionWithTestKey(mpData->mSessionBobToAlice, kBobKeyId,
GetAliceFabric()->GetNodeId(), kAliceKeyId, mpData->mBobFabricIndex,
mpData->mAliceAddress, CryptoContext::SessionRole::kInitiator);
}
CHIP_ERROR MessagingContext::CreateCASESessionBobToAlice()
{
return mpData->mSessionManager.InjectCaseSessionWithTestKey(
mpData->mSessionBobToAlice, kBobKeyId, kAliceKeyId, GetBobFabric()->GetNodeId(), GetAliceFabric()->GetNodeId(),
mpData->mBobFabricIndex, mpData->mAliceAddress, CryptoContext::SessionRole::kInitiator);
}
CHIP_ERROR MessagingContext::CreateCASESessionBobToAlice(const CATValues & cats)
{
return mpData->mSessionManager.InjectCaseSessionWithTestKey(
mpData->mSessionBobToAlice, kBobKeyId, kAliceKeyId, GetBobFabric()->GetNodeId(), GetAliceFabric()->GetNodeId(),
mpData->mBobFabricIndex, mpData->mAliceAddress, CryptoContext::SessionRole::kInitiator, cats);
}
CHIP_ERROR MessagingContext::CreateSessionAliceToBob()
{
return mpData->mSessionManager.InjectPaseSessionWithTestKey(mpData->mSessionAliceToBob, kAliceKeyId,
GetBobFabric()->GetNodeId(), kBobKeyId, mpData->mAliceFabricIndex,
mpData->mBobAddress, CryptoContext::SessionRole::kResponder);
}
CHIP_ERROR MessagingContext::CreateCASESessionAliceToBob()
{
return mpData->mSessionManager.InjectCaseSessionWithTestKey(
mpData->mSessionAliceToBob, kAliceKeyId, kBobKeyId, GetAliceFabric()->GetNodeId(), GetBobFabric()->GetNodeId(),
mpData->mAliceFabricIndex, mpData->mBobAddress, CryptoContext::SessionRole::kResponder);
}
CHIP_ERROR MessagingContext::CreateCASESessionAliceToBob(const CATValues & cats)
{
return mpData->mSessionManager.InjectCaseSessionWithTestKey(
mpData->mSessionAliceToBob, kAliceKeyId, kBobKeyId, GetAliceFabric()->GetNodeId(), GetBobFabric()->GetNodeId(),
mpData->mAliceFabricIndex, mpData->mBobAddress, CryptoContext::SessionRole::kResponder, cats);
}
CHIP_ERROR MessagingContext::CreatePASESessionCharlieToDavid()
{
return mpData->mSessionManager.InjectPaseSessionWithTestKey(mpData->mSessionCharlieToDavid, kCharlieKeyId, 0xdeadbeef,
kDavidKeyId, kUndefinedFabricIndex, mpData->mDavidAddress,
CryptoContext::SessionRole::kInitiator);
}
CHIP_ERROR MessagingContext::CreatePASESessionDavidToCharlie()
{
return mpData->mSessionManager.InjectPaseSessionWithTestKey(mpData->mSessionDavidToCharlie, kDavidKeyId, 0xcafe, kCharlieKeyId,
kUndefinedFabricIndex, mpData->mCharlieAddress,
CryptoContext::SessionRole::kResponder);
}
CHIP_ERROR MessagingContext::CreateSessionBobToFriends()
{
mpData->mSessionBobToFriends.Emplace(GetFriendsGroupId(), mpData->mBobFabricIndex);
return CHIP_NO_ERROR;
}
SessionHandle MessagingContext::GetSessionBobToAlice()
{
auto sessionHandle = mpData->mSessionBobToAlice.Get();
return std::move(sessionHandle.Value());
}
SessionHandle MessagingContext::GetSessionAliceToBob()
{
auto sessionHandle = mpData->mSessionAliceToBob.Get();
return std::move(sessionHandle.Value());
}
SessionHandle MessagingContext::GetSessionCharlieToDavid()
{
auto sessionHandle = mpData->mSessionCharlieToDavid.Get();
return std::move(sessionHandle.Value());
}
SessionHandle MessagingContext::GetSessionDavidToCharlie()
{
auto sessionHandle = mpData->mSessionDavidToCharlie.Get();
return std::move(sessionHandle.Value());
}
SessionHandle MessagingContext::GetSessionBobToFriends()
{
return SessionHandle(mpData->mSessionBobToFriends.Value());
}
void MessagingContext::ExpireSessionBobToAlice()
{
if (mpData->mSessionBobToAlice)
{
mpData->mSessionBobToAlice.Get().Value()->AsSecureSession()->MarkForEviction();
}
}
void MessagingContext::ExpireSessionAliceToBob()
{
if (mpData->mSessionAliceToBob)
{
mpData->mSessionAliceToBob.Get().Value()->AsSecureSession()->MarkForEviction();
}
}
void MessagingContext::ExpireSessionBobToFriends()
{
mpData->mSessionBobToFriends.ClearValue();
}
Messaging::ExchangeContext * MessagingContext::NewUnauthenticatedExchangeToAlice(Messaging::ExchangeDelegate * delegate)
{
return mpData->mExchangeManager.NewContext(
mpData->mSessionManager
.CreateUnauthenticatedSession(mpData->mAliceAddress, GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig()))
.Value(),
delegate);
}
Messaging::ExchangeContext * MessagingContext::NewUnauthenticatedExchangeToBob(Messaging::ExchangeDelegate * delegate)
{
return mpData->mExchangeManager.NewContext(
mpData->mSessionManager
.CreateUnauthenticatedSession(mpData->mBobAddress, GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig()))
.Value(),
delegate);
}
Messaging::ExchangeContext * MessagingContext::NewExchangeToAlice(Messaging::ExchangeDelegate * delegate, bool isInitiator)
{
return mpData->mExchangeManager.NewContext(GetSessionBobToAlice(), delegate, isInitiator);
}
Messaging::ExchangeContext * MessagingContext::NewExchangeToBob(Messaging::ExchangeDelegate * delegate, bool isInitiator)
{
return mpData->mExchangeManager.NewContext(GetSessionAliceToBob(), delegate, isInitiator);
}
LoopbackTransportManager * LoopbackMessagingContext::spLoopbackTransportManager = nullptr;
UDPTransportManager * UDPMessagingContext::spUDPTransportManager = nullptr;
void MessageCapturer::OnMessageReceived(const PacketHeader & packetHeader, const PayloadHeader & payloadHeader,
const SessionHandle & session, DuplicateMessage isDuplicate,
System::PacketBufferHandle && msgBuf)
{
if (mCaptureStandaloneAcks || !payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::StandaloneAck))
{
mCapturedMessages.emplace_back(Message{ packetHeader, payloadHeader, isDuplicate, msgBuf.CloneData() });
}
mOriginalDelegate.OnMessageReceived(packetHeader, payloadHeader, session, isDuplicate, std::move(msgBuf));
}
} // namespace Test
} // namespace chip