Skip to content

Commit 98baa6a

Browse files
authored
Make DecodeMRPParametersIfPresent() and ParseSigma1() methods static + fix for TLV reading corner case (#36956)
* Making DecodeMRPParametersIfPresent self-contained and static and renaming it * Making ParseSigma1 static and not dependent on class state * Making SetRemoteSessionParameters protected * Fix for the following Corner case: if the received TLV-encoded SessionParameters struct has extra TLV elements that were added to the spec, Yet the TLV struct is not terminated with an EndOfContainer Element. In this Case, we should make sure that ExitContainer so that an Error is triggered. * Adding Unit Test for DecodeSessionParametersIfPresent() * Fix CI failure related to using aggregate initializer with C-String * Integrating Comments
1 parent e3bb3e3 commit 98baa6a

7 files changed

+321
-49
lines changed

src/protocols/secure_channel/CASESession.cpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -1097,9 +1097,10 @@ CASESession::NextStep CASESession::HandleSigma1(System::PacketBufferHandle && ms
10971097
ChipLogDetail(SecureChannel, "Peer assigned session key ID %d", parsedSigma1.initiatorSessionId);
10981098
SetPeerSessionId(parsedSigma1.initiatorSessionId);
10991099

1100-
// Set the MRP parameters provided in the Sigma1 message
1101-
if (parsedSigma1.initiatorMrpParamsPresent)
1100+
// Set the Session parameters provided in the Sigma1 message
1101+
if (parsedSigma1.initiatorSessionParamStructPresent)
11021102
{
1103+
SetRemoteSessionParameters(parsedSigma1.initiatorSessionParams);
11031104
mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(
11041105
GetRemoteSessionParameters());
11051106
}
@@ -1436,7 +1437,7 @@ CHIP_ERROR CASESession::HandleSigma2Resume(System::PacketBufferHandle && msg)
14361437

14371438
if (tlvReader.Next() != CHIP_END_OF_TLV)
14381439
{
1439-
SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(4), tlvReader));
1440+
SuccessOrExit(err = DecodeSessionParametersIfPresent(TLV::ContextTag(4), tlvReader, mRemoteSessionParams));
14401441
mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(
14411442
GetRemoteSessionParameters());
14421443
}
@@ -1638,7 +1639,8 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
16381639
// Retrieve responderMRPParams if present
16391640
if (tlvReader.Next() != CHIP_END_OF_TLV)
16401641
{
1641-
SuccessOrExit(err = DecodeMRPParametersIfPresent(AsTlvContextTag(Sigma2Tags::kResponderSessionParams), tlvReader));
1642+
SuccessOrExit(err = DecodeSessionParametersIfPresent(AsTlvContextTag(Sigma2Tags::kResponderSessionParams), tlvReader,
1643+
mRemoteSessionParams));
16421644
mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(
16431645
GetRemoteSessionParameters());
16441646
}
@@ -2324,8 +2326,9 @@ CHIP_ERROR CASESession::ParseSigma1(TLV::ContiguousBufferTLVReader & tlvReader,
23242326
CHIP_ERROR err = tlvReader.Next();
23252327
if (err == CHIP_NO_ERROR && tlvReader.GetTag() == AsTlvContextTag(Sigma1Tags::kInitiatorSessionParams))
23262328
{
2327-
ReturnErrorOnFailure(DecodeMRPParametersIfPresent(AsTlvContextTag(Sigma1Tags::kInitiatorSessionParams), tlvReader));
2328-
outParsedSigma1.initiatorMrpParamsPresent = true;
2329+
ReturnErrorOnFailure(DecodeSessionParametersIfPresent(AsTlvContextTag(Sigma1Tags::kInitiatorSessionParams), tlvReader,
2330+
outParsedSigma1.initiatorSessionParams));
2331+
outParsedSigma1.initiatorSessionParamStructPresent = true;
23292332

23302333
err = tlvReader.Next();
23312334
}

src/protocols/secure_channel/CASESession.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
222222
struct ParsedSigma1 : Sigma1Param
223223
{
224224
ByteSpan initiatorEphPubKey;
225-
bool initiatorMrpParamsPresent = false;
225+
bool initiatorSessionParamStructPresent = false;
226+
SessionParameters initiatorSessionParams;
226227
};
227228

228229
struct EncodeSigma2Inputs
@@ -274,8 +275,10 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
274275
* On success, either the sessionResumptionRequested field will be set to true
275276
* and the resumptionID and initiatorResumeMIC fields will be set to
276277
* valid values, or the sessionResumptionRequested field will be set to false.
278+
*
279+
* @note Calls to this function must always be made with a newly created and fresh ParsedSigma1 parameter.
277280
*/
278-
CHIP_ERROR ParseSigma1(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma1 & parsedMessage);
281+
static CHIP_ERROR ParseSigma1(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma1 & parsedMessage);
279282

280283
/**
281284
* @brief Encodes a Sigma2 message into TLV format and allocates a buffer for it, which is owned by the PacketBufferHandle

src/protocols/secure_channel/PASESession.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ CHIP_ERROR PASESession::HandlePBKDFParamRequest(System::PacketBufferHandle && ms
372372

373373
if (tlvReader.Next() != CHIP_END_OF_TLV)
374374
{
375-
SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(5), tlvReader));
375+
SuccessOrExit(err = DecodeSessionParametersIfPresent(TLV::ContextTag(5), tlvReader, mRemoteSessionParams));
376376
mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(
377377
GetRemoteSessionParameters());
378378
}
@@ -493,7 +493,7 @@ CHIP_ERROR PASESession::HandlePBKDFParamResponse(System::PacketBufferHandle && m
493493
{
494494
if (tlvReader.Next() != CHIP_END_OF_TLV)
495495
{
496-
SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(5), tlvReader));
496+
SuccessOrExit(err = DecodeSessionParametersIfPresent(TLV::ContextTag(5), tlvReader, mRemoteSessionParams));
497497
mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(
498498
GetRemoteSessionParameters());
499499
}
@@ -519,7 +519,7 @@ CHIP_ERROR PASESession::HandlePBKDFParamResponse(System::PacketBufferHandle && m
519519

520520
if (tlvReader.Next() != CHIP_END_OF_TLV)
521521
{
522-
SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(5), tlvReader));
522+
SuccessOrExit(err = DecodeSessionParametersIfPresent(TLV::ContextTag(5), tlvReader, mRemoteSessionParams));
523523
mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(
524524
GetRemoteSessionParameters());
525525
}

src/protocols/secure_channel/PairingSession.cpp

+10-9
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ CHIP_ERROR PairingSession::EncodeSessionParameters(TLV::Tag tag, const ReliableM
144144
return tlvWriter.EndContainer(mrpParamsContainer);
145145
}
146146

147-
CHIP_ERROR PairingSession::DecodeMRPParametersIfPresent(TLV::Tag expectedTag, TLV::ContiguousBufferTLVReader & tlvReader)
147+
CHIP_ERROR PairingSession::DecodeSessionParametersIfPresent(TLV::Tag expectedTag, TLV::ContiguousBufferTLVReader & tlvReader,
148+
SessionParameters & outSessionParameters)
148149
{
149150
CHIP_ERROR err = CHIP_NO_ERROR;
150151

@@ -167,7 +168,7 @@ CHIP_ERROR PairingSession::DecodeMRPParametersIfPresent(TLV::Tag expectedTag, TL
167168
{
168169
uint32_t idleRetransTimeout;
169170
ReturnErrorOnFailure(tlvReader.Get(idleRetransTimeout));
170-
mRemoteSessionParams.SetMRPIdleRetransTimeout(System::Clock::Milliseconds32(idleRetransTimeout));
171+
outSessionParameters.SetMRPIdleRetransTimeout(System::Clock::Milliseconds32(idleRetransTimeout));
171172

172173
// The next element is optional. If it's not present, return CHIP_NO_ERROR.
173174
SuccessOrExit(err = tlvReader.Next());
@@ -177,7 +178,7 @@ CHIP_ERROR PairingSession::DecodeMRPParametersIfPresent(TLV::Tag expectedTag, TL
177178
{
178179
uint32_t activeRetransTimeout;
179180
ReturnErrorOnFailure(tlvReader.Get(activeRetransTimeout));
180-
mRemoteSessionParams.SetMRPActiveRetransTimeout(System::Clock::Milliseconds32(activeRetransTimeout));
181+
outSessionParameters.SetMRPActiveRetransTimeout(System::Clock::Milliseconds32(activeRetransTimeout));
181182

182183
// The next element is optional. If it's not present, return CHIP_NO_ERROR.
183184
SuccessOrExit(err = tlvReader.Next());
@@ -187,7 +188,7 @@ CHIP_ERROR PairingSession::DecodeMRPParametersIfPresent(TLV::Tag expectedTag, TL
187188
{
188189
uint16_t activeThresholdTime;
189190
ReturnErrorOnFailure(tlvReader.Get(activeThresholdTime));
190-
mRemoteSessionParams.SetMRPActiveThresholdTime(System::Clock::Milliseconds16(activeThresholdTime));
191+
outSessionParameters.SetMRPActiveThresholdTime(System::Clock::Milliseconds16(activeThresholdTime));
191192

192193
// The next element is optional. If it's not present, return CHIP_NO_ERROR.
193194
SuccessOrExit(err = tlvReader.Next());
@@ -197,7 +198,7 @@ CHIP_ERROR PairingSession::DecodeMRPParametersIfPresent(TLV::Tag expectedTag, TL
197198
{
198199
uint16_t dataModelRevision;
199200
ReturnErrorOnFailure(tlvReader.Get(dataModelRevision));
200-
mRemoteSessionParams.SetDataModelRevision(dataModelRevision);
201+
outSessionParameters.SetDataModelRevision(dataModelRevision);
201202

202203
// The next element is optional. If it's not present, return CHIP_NO_ERROR.
203204
SuccessOrExit(err = tlvReader.Next());
@@ -207,7 +208,7 @@ CHIP_ERROR PairingSession::DecodeMRPParametersIfPresent(TLV::Tag expectedTag, TL
207208
{
208209
uint16_t interactionModelRevision;
209210
ReturnErrorOnFailure(tlvReader.Get(interactionModelRevision));
210-
mRemoteSessionParams.SetInteractionModelRevision(interactionModelRevision);
211+
outSessionParameters.SetInteractionModelRevision(interactionModelRevision);
211212

212213
// The next element is optional. If it's not present, return CHIP_NO_ERROR.
213214
SuccessOrExit(err = tlvReader.Next());
@@ -217,7 +218,7 @@ CHIP_ERROR PairingSession::DecodeMRPParametersIfPresent(TLV::Tag expectedTag, TL
217218
{
218219
uint32_t specificationVersion;
219220
ReturnErrorOnFailure(tlvReader.Get(specificationVersion));
220-
mRemoteSessionParams.SetSpecificationVersion(specificationVersion);
221+
outSessionParameters.SetSpecificationVersion(specificationVersion);
221222

222223
// The next element is optional. If it's not present, return CHIP_NO_ERROR.
223224
SuccessOrExit(err = tlvReader.Next());
@@ -227,15 +228,15 @@ CHIP_ERROR PairingSession::DecodeMRPParametersIfPresent(TLV::Tag expectedTag, TL
227228
{
228229
uint16_t maxPathsPerInvoke;
229230
ReturnErrorOnFailure(tlvReader.Get(maxPathsPerInvoke));
230-
mRemoteSessionParams.SetMaxPathsPerInvoke(maxPathsPerInvoke);
231+
outSessionParameters.SetMaxPathsPerInvoke(maxPathsPerInvoke);
231232

232233
// The next element is optional. If it's not present, return CHIP_NO_ERROR.
233234
SuccessOrExit(err = tlvReader.Next());
234235
}
235236

236237
// Future proofing - Don't error out if there are other tags
237238
exit:
238-
if (err == CHIP_END_OF_TLV)
239+
if (err == CHIP_END_OF_TLV || err == CHIP_NO_ERROR)
239240
{
240241
return tlvReader.ExitContainer(containerType);
241242
}

src/protocols/secure_channel/PairingSession.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ class DLL_EXPORT PairingSession : public SessionDelegate
129129
void DiscardExchange(); // Clear our reference to our exchange context pointer so that it can close itself at some later time.
130130

131131
void SetPeerSessionId(uint16_t id) { mPeerSessionId.SetValue(id); }
132+
133+
void SetRemoteSessionParameters(const SessionParameters & sessionParams) { mRemoteSessionParams = sessionParams; }
134+
132135
virtual void OnSuccessStatusReport() {}
133136

134137
// Handle a failure StatusReport message from the server. protocolData will
@@ -207,16 +210,17 @@ class DLL_EXPORT PairingSession : public SessionDelegate
207210
}
208211

209212
/**
210-
* Try to decode the current element (pointed by the TLV reader) as MRP parameters.
211-
* If the MRP parameters are found, mRemoteSessionParams is updated with the devoded values.
213+
* Try to decode the current element (pointed by the TLV reader) as Session parameters (which include MRP parameters).
214+
* If the Session parameters are found, outparam sessionParameters is updated with the decoded values.
212215
*
213-
* MRP parameters are optional. So, if the TLV reader is not pointing to the MRP parameters,
216+
* Session parameters are optional. So, if the TLV reader is not pointing to the Session parameters,
214217
* the function is a noop.
215218
*
216219
* If the parameters are present, but TLV reader fails to correctly parse it, the function will
217220
* return the corresponding error.
218221
*/
219-
CHIP_ERROR DecodeMRPParametersIfPresent(TLV::Tag expectedTag, TLV::ContiguousBufferTLVReader & tlvReader);
222+
static CHIP_ERROR DecodeSessionParametersIfPresent(TLV::Tag expectedTag, TLV::ContiguousBufferTLVReader & tlvReader,
223+
SessionParameters & sessionParameters);
220224

221225
bool IsSessionEstablishmentInProgress();
222226

src/protocols/secure_channel/tests/TestCASESession.cpp

+4-7
Original file line numberDiff line numberDiff line change
@@ -760,10 +760,9 @@ static CHIP_ERROR EncodeSigma1Helper(MutableByteSpan & buf)
760760
\
761761
TLV::ContiguousBufferTLVReader reader; \
762762
reader.Init(buf); \
763-
CASESessionAccess session; \
764763
CASESessionAccess::ParsedSigma1 parsedSigma1; \
765764
\
766-
EXPECT_EQ(session.ParseSigma1(reader, parsedSigma1) == CHIP_NO_ERROR, params::kExpectSuccess); \
765+
EXPECT_EQ(CASESessionAccess::ParseSigma1(reader, parsedSigma1) == CHIP_NO_ERROR, params::kExpectSuccess); \
767766
if (params::kExpectSuccess) \
768767
{ \
769768
EXPECT_EQ(parsedSigma1.sessionResumptionRequested, \
@@ -936,10 +935,9 @@ TEST_F(TestCASESession, EncodeSigma1Test)
936935
System::PacketBufferTLVReader tlvReader;
937936
tlvReader.Init(std::move(msg1));
938937

939-
CASESessionAccess session;
940938
CASESessionAccess::ParsedSigma1 parsedMessage;
941939

942-
EXPECT_EQ(CHIP_NO_ERROR, session.ParseSigma1(tlvReader, parsedMessage));
940+
EXPECT_EQ(CHIP_NO_ERROR, CASESessionAccess::ParseSigma1(tlvReader, parsedMessage));
943941

944942
// compare parsed values with original values
945943
EXPECT_TRUE(parsedMessage.initiatorRandom.data_equal(encodeParams.initiatorRandom));
@@ -970,10 +968,9 @@ TEST_F(TestCASESession, EncodeSigma1Test)
970968
System::PacketBufferTLVReader tlvReader;
971969
tlvReader.Init(std::move(msg2));
972970

973-
CASESessionAccess session;
974971
CASESessionAccess::ParsedSigma1 parsedMessage;
975972

976-
EXPECT_EQ(CHIP_NO_ERROR, session.ParseSigma1(tlvReader, parsedMessage));
973+
EXPECT_EQ(CHIP_NO_ERROR, CASESessionAccess::ParseSigma1(tlvReader, parsedMessage));
977974

978975
// RoundTrip
979976
EXPECT_TRUE(parsedMessage.initiatorRandom.data_equal(encodeParams.initiatorRandom));
@@ -984,7 +981,7 @@ TEST_F(TestCASESession, EncodeSigma1Test)
984981

985982
EXPECT_TRUE(parsedMessage.resumptionId.data_equal(encodeParams.resumptionId));
986983
EXPECT_TRUE(parsedMessage.initiatorResumeMIC.data_equal(encodeParams.initiatorResumeMIC));
987-
EXPECT_TRUE(parsedMessage.initiatorMrpParamsPresent);
984+
EXPECT_TRUE(parsedMessage.sessionResumptionRequested);
988985
}
989986
// Release EphemeralKeyPair
990987
gDeviceOperationalKeystore.ReleaseEphemeralKeypair(ephemeralKey);

0 commit comments

Comments
 (0)