Skip to content

Commit

Permalink
Making structs protected and making Unit Test inherit CASESession
Browse files Browse the repository at this point in the history
  • Loading branch information
Alami-Amine committed Dec 13, 2024
1 parent ca802f1 commit d82be0a
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 115 deletions.
108 changes: 54 additions & 54 deletions src/protocols/secure_channel/CASESession.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,60 +118,6 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
*/
void SetGroupDataProvider(Credentials::GroupDataProvider * groupDataProvider) { mGroupDataProvider = groupDataProvider; }

// This struct only serves as a base struct for EncodeSigma1 and ParseSigma1
struct Sigma1Param
{
ByteSpan initiatorRandom;
uint16_t initiatorSessionId;
ByteSpan destinationId;
bool sessionResumptionRequested = false;
ByteSpan resumptionId;
ByteSpan initiatorResumeMICSpan;
};

struct EncodeSigma1Inputs : Sigma1Param
{
const Crypto::P256PublicKey * pEphPubKey = nullptr;
const ReliableMessageProtocolConfig * initiatorMrpConfig = nullptr;
uint8_t initiatorResume1MIC[Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES];
};

struct ParsedSigma1 : Sigma1Param
{
ByteSpan initiatorEphPubKey;
bool initiatorMrpParamsPresent = false;
};

// Helper Enum for usage in HandleSigma1_and_SendSigma2
enum class Step : uint8_t
{
kNone,
kSendSigma2,
kSendSigma2Resume,
kSendStatusReport
};

Step mNextStep = Step::kNone;

struct EncodeSigma2Inputs
{
uint8_t responderRandom[kSigmaParamRandomNumberSize];
uint16_t responderSessionId;
const Crypto::P256PublicKey * pEphPubKey = nullptr;
Platform::ScopedMemoryBuffer<uint8_t> msg_R2_Encrypted;
size_t encrypted2Length = 0;
const ReliableMessageProtocolConfig * responderMrpConfig;
};

struct EncodeSigma2ResInputs
{
ByteSpan resumptionId;
uint8_t sigma2ResumeMIC[Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES];
MutableByteSpan resumeMICSpan{ sigma2ResumeMIC };
uint16_t responderSessionId;
const ReliableMessageProtocolConfig * responderMrpConfig;
};

/**
* @brief
* Derive a secure session from the established session. The API will return error if called before session is established.
Expand Down Expand Up @@ -245,6 +191,60 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
bool InvokeBackgroundWorkWatchdog();

protected:
// Helper Enum for usage in HandleSigma1_and_SendSigma2
enum class Step : uint8_t
{
kNone,
kSendSigma2,
kSendSigma2Resume,
kSendStatusReport
};

Step mNextStep = Step::kNone;

// This struct only serves as a base struct for EncodeSigma1 and ParseSigma1
struct Sigma1Param
{
ByteSpan initiatorRandom;
uint16_t initiatorSessionId;
ByteSpan destinationId;
bool sessionResumptionRequested = false;
ByteSpan resumptionId;
ByteSpan initiatorResumeMICSpan;
};

struct EncodeSigma1Inputs : Sigma1Param
{
const Crypto::P256PublicKey * pEphPubKey = nullptr;
const ReliableMessageProtocolConfig * initiatorMrpConfig = nullptr;
uint8_t initiatorResume1MIC[Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES];
};

struct ParsedSigma1 : Sigma1Param
{
ByteSpan initiatorEphPubKey;
bool initiatorMrpParamsPresent = false;
};

struct EncodeSigma2Inputs
{
uint8_t responderRandom[kSigmaParamRandomNumberSize];
uint16_t responderSessionId;
const Crypto::P256PublicKey * pEphPubKey = nullptr;
Platform::ScopedMemoryBuffer<uint8_t> msg_R2_Encrypted;
size_t encrypted2Length = 0;
const ReliableMessageProtocolConfig * responderMrpConfig;
};

struct EncodeSigma2ResInputs
{
ByteSpan resumptionId;
uint8_t sigma2ResumeMIC[Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES];
MutableByteSpan resumeMICSpan{ sigma2ResumeMIC };
uint16_t responderSessionId;
const ReliableMessageProtocolConfig * responderMrpConfig;
};

/**
* @brief Encodes a Sigma1 message into TLV format and allocates a buffer for it within the provided PacketBufferHandle.
*
Expand Down
92 changes: 31 additions & 61 deletions src/protocols/secure_channel/tests/TestCASESession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ using namespace chip::Crypto;
namespace chip {
class TestCASESecurePairingDelegate;

class TestCASESession : public Test::LoopbackMessagingContext
class TestCASESession : public Test::LoopbackMessagingContext, public CASESession
{
public:
// Performs shared setup for all tests in the test suite
Expand All @@ -80,32 +80,6 @@ class TestCASESession : public Test::LoopbackMessagingContext
void SimulateUpdateNOCInvalidatePendingEstablishment();
};

// CASESession Wrapper to Test the protected Functions
class CASESessionWrapper : public CASESession
{
public:
CHIP_ERROR ParseSigma1Access(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma1 & outParam)
{
return ParseSigma1(tlvReader, outParam);
}

CHIP_ERROR EncodeSigma1Access(System::PacketBufferHandle & outMsg, EncodeSigma1Inputs & inParam)
{
return EncodeSigma1(outMsg, inParam);
}

CHIP_ERROR EncodeSigma2Access(System::PacketBufferHandle & outMsg, EncodeSigma2Inputs & inParam)

{
return EncodeSigma2(outMsg, inParam);
}

CHIP_ERROR EncodeSigma2ResumeAccess(System::PacketBufferHandle & outMsg, EncodeSigma2ResInputs & inParam)
{
return EncodeSigma2Resume(outMsg, inParam);
}
};

void TestCASESession::ServiceEvents()
{
// Takes a few rounds of this because handling IO messages may schedule work,
Expand Down Expand Up @@ -771,10 +745,9 @@ static CHIP_ERROR EncodeSigma1Helper(MutableByteSpan & buf)
\
TLV::ContiguousBufferTLVReader reader; \
reader.Init(buf); \
CASESessionWrapper::ParsedSigma1 parsedSigma1; \
CASESessionWrapper session; \
ParsedSigma1 parsedSigma1; \
\
EXPECT_EQ(session.ParseSigma1Access(reader, parsedSigma1) == CHIP_NO_ERROR, params::expectSuccess); \
EXPECT_EQ(ParseSigma1(reader, parsedSigma1) == CHIP_NO_ERROR, params::expectSuccess); \
if (params::expectSuccess) \
{ \
EXPECT_EQ(parsedSigma1.sessionResumptionRequested, \
Expand Down Expand Up @@ -896,8 +869,7 @@ TEST_F(TestCASESession, Sigma1ParsingTest)
TEST_F(TestCASESession, EncodeSigma1Test)
{
System::PacketBufferHandle msg;
CASESessionWrapper session;
CASESessionWrapper::EncodeSigma1Inputs encodeParams;
CASESession::EncodeSigma1Inputs encodeParams;

uint8_t random[32];
EXPECT_EQ(chip::Crypto::DRBG_get_bytes(&random[0], 32), CHIP_NO_ERROR);
Expand All @@ -910,47 +882,47 @@ TEST_F(TestCASESession, EncodeSigma1Test)
encodeParams.initiatorMrpConfig = &MRPConfig;

// EncodeSigma1 should fail when there is no public key
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, session.EncodeSigma1Access(msg, encodeParams));
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, EncodeSigma1(msg, encodeParams));

Crypto::P256Keypair * EphemeralKey = gDeviceOperationalKeystore.AllocateEphemeralKeypairForCASE();
ASSERT_NE(EphemeralKey, nullptr);
EXPECT_EQ(CHIP_NO_ERROR, EphemeralKey->Initialize(ECPKeyTarget::ECDH));
encodeParams.pEphPubKey = &EphemeralKey->Pubkey();

// Succeed when Public Key is provided
EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma1Access(msg, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma1(msg, encodeParams));

// Free the PacketBuffer
msg = nullptr;

// EncodeSigma1 should fail when MRP config is missing
encodeParams.initiatorMrpConfig = nullptr;
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, session.EncodeSigma1Access(msg, encodeParams));
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, EncodeSigma1(msg, encodeParams));

// Free the PacketBuffer
msg = nullptr;

// Succeed when MRP Config is provided
encodeParams.initiatorMrpConfig = &MRPConfig;
EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma1Access(msg, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma1(msg, encodeParams));

{
System::PacketBufferHandle nonEmptyMsg = System::PacketBufferHandle::New(100);

// EncodeSigma1 should fail when the packetBufferHandle passed to it is not empty
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, session.EncodeSigma1Access(nonEmptyMsg, encodeParams));
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, EncodeSigma1(nonEmptyMsg, encodeParams));
}

{
System::PacketBufferHandle msg1;
System::PacketBufferTLVReader tlvReader;
CASESessionWrapper::ParsedSigma1 parseParams;
CASESession::ParsedSigma1 parseParams;

// Round Trip Test: Encode Sigma1, Parse it then verify parsed values
EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma1Access(msg1, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma1(msg1, encodeParams));

tlvReader.Init(std::move(msg1));
EXPECT_EQ(CHIP_NO_ERROR, session.ParseSigma1Access(tlvReader, parseParams));
EXPECT_EQ(CHIP_NO_ERROR, ParseSigma1(tlvReader, parseParams));

// compare parsed values with original values
EXPECT_TRUE(parseParams.initiatorRandom.data_equal(encodeParams.initiatorRandom));
Expand All @@ -963,7 +935,7 @@ TEST_F(TestCASESession, EncodeSigma1Test)
{
System::PacketBufferHandle msg2;
System::PacketBufferTLVReader tlvReader;
CASESessionWrapper::ParsedSigma1 parseParams;
CASESession::ParsedSigma1 parseParams;

// Round Trip Test: Sigma1 with Session Resumption
// Encode Sigma1 with Resumption, parse it and and verify with original values
Expand All @@ -977,12 +949,12 @@ TEST_F(TestCASESession, EncodeSigma1Test)
encodeParams.initiatorResumeMICSpan = ByteSpan(encodeParams.initiatorResume1MIC);
encodeParams.sessionResumptionRequested = true;

EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma1Access(msg2, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma1(msg2, encodeParams));

// Encode and Parse Round Trip Test
tlvReader.Init(std::move(msg2));

EXPECT_EQ(CHIP_NO_ERROR, session.ParseSigma1Access(tlvReader, parseParams));
EXPECT_EQ(CHIP_NO_ERROR, ParseSigma1(tlvReader, parseParams));

// RoundTrip
EXPECT_TRUE(parseParams.initiatorRandom.data_equal(encodeParams.initiatorRandom));
Expand All @@ -1002,8 +974,7 @@ TEST_F(TestCASESession, EncodeSigma1Test)
TEST_F(TestCASESession, EncodeSigma2Test)
{
System::PacketBufferHandle msg;
CASESessionWrapper session;
CASESessionWrapper::EncodeSigma2Inputs encodeParams;
CASESession::EncodeSigma2Inputs encodeParams;
constexpr uint8_t kEncrypted2datalen = 100U;

EXPECT_EQ(chip::Crypto::DRBG_get_bytes(&encodeParams.responderRandom[0], sizeof(encodeParams.responderRandom)), CHIP_NO_ERROR);
Expand All @@ -1023,50 +994,50 @@ TEST_F(TestCASESession, EncodeSigma2Test)
ReliableMessageProtocolConfig MRPConfig = GetDefaultMRPConfig();
encodeParams.responderMrpConfig = &MRPConfig;

EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma2Access(msg, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma2(msg, encodeParams));
// free Buffer owned by PacketBufferHandle
msg = nullptr;

{
System::PacketBufferHandle nonEmptyMsg = System::PacketBufferHandle::New(100);

// EncodeSigma2 should fail when the packetBufferHandle passed to it is not empty
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, session.EncodeSigma2Access(nonEmptyMsg, encodeParams));
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, EncodeSigma2(nonEmptyMsg, encodeParams));
}

// EncodeSigma2 should fail when there is no public key
encodeParams.pEphPubKey = nullptr;
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, session.EncodeSigma2Access(msg, encodeParams));
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, EncodeSigma2(msg, encodeParams));

encodeParams.pEphPubKey = &EphemeralKey->Pubkey();
EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma2Access(msg, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma2(msg, encodeParams));
msg = nullptr;

// EncodeSigma2 should fail when TBEData2Encrypted is not allocated
encodeParams.msg_R2_Encrypted.Free();

EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, session.EncodeSigma2Access(msg, encodeParams));
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, EncodeSigma2(msg, encodeParams));

encodeParams.msg_R2_Encrypted.Alloc(encodeParams.encrypted2Length);

EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma2Access(msg, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma2(msg, encodeParams));
msg = nullptr;

// EncodeSigma2 should fail when the encrypted2Length is not set
encodeParams.encrypted2Length = 0;
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, session.EncodeSigma2Access(msg, encodeParams));
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, EncodeSigma2(msg, encodeParams));

// Set encrypted2Length again
encodeParams.encrypted2Length = kEncrypted2datalen + CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;

// EncodeSigma2 should fail when MRP config is missing
encodeParams.responderMrpConfig = nullptr;
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, session.EncodeSigma2Access(msg, encodeParams));
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, EncodeSigma2(msg, encodeParams));
msg = nullptr;

// Succeed when MRP Config is provided
encodeParams.responderMrpConfig = &MRPConfig;
EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma2Access(msg, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma2(msg, encodeParams));

// Release EphemeralKeyPair
gDeviceOperationalKeystore.ReleaseEphemeralKeypair(EphemeralKey);
Expand All @@ -1075,36 +1046,35 @@ TEST_F(TestCASESession, EncodeSigma2Test)
TEST_F(TestCASESession, EncodeSigma2ResumeTest)
{
System::PacketBufferHandle msg;
CASESessionWrapper session;
CASESessionWrapper::EncodeSigma2ResInputs encodeParams;
CASESession::EncodeSigma2ResInputs encodeParams;

encodeParams.responderSessionId = 7315;

// responder Session Parameters
ReliableMessageProtocolConfig MRPConfig = GetDefaultMRPConfig();
encodeParams.responderMrpConfig = &MRPConfig;

EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma2ResumeAccess(msg, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma2Resume(msg, encodeParams));
// Free buffer owned by msg
msg = nullptr;

{
System::PacketBufferHandle nonEmptyMsg = System::PacketBufferHandle::New(100);

// EncodeSigma2Resume should fail when the packetBufferHandle passed to it is not empty
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, session.EncodeSigma2ResumeAccess(nonEmptyMsg, encodeParams));
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, EncodeSigma2Resume(nonEmptyMsg, encodeParams));
}

EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma2ResumeAccess(msg, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma2Resume(msg, encodeParams));
msg = nullptr;

// EncodeSigma2Resume should fail when MRP config is missing
encodeParams.responderMrpConfig = nullptr;
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, session.EncodeSigma2ResumeAccess(msg, encodeParams));
EXPECT_EQ(CHIP_ERROR_INCORRECT_STATE, EncodeSigma2Resume(msg, encodeParams));

// Succeed when MRP Config is provided
encodeParams.responderMrpConfig = &MRPConfig;
EXPECT_EQ(CHIP_NO_ERROR, session.EncodeSigma2ResumeAccess(msg, encodeParams));
EXPECT_EQ(CHIP_NO_ERROR, EncodeSigma2Resume(msg, encodeParams));
}

struct SessionResumptionTestStorage : SessionResumptionStorage
Expand Down

0 comments on commit d82be0a

Please sign in to comment.