From 107257535a92ec1147093bd84a6b50b95eca01ee Mon Sep 17 00:00:00 2001 From: Bill Waters <65681039+billwatersiii@users.noreply.github.com> Date: Wed, 8 Dec 2021 08:15:34 -0800 Subject: [PATCH] Send/Extract optional MRP parameters in CASE messages (#12705) * Send optional MRP parameters in CASE messages * test case update * fixed restyle issues --- src/protocols/secure_channel/CASESession.cpp | 36 +++++++++++++++---- src/protocols/secure_channel/CASESession.h | 20 ++++++----- .../secure_channel/tests/TestCASESession.cpp | 5 +-- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index 6ff1dec6e48c9e..cde2d4f333a0f3 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include namespace chip { @@ -193,12 +194,14 @@ CHIP_ERROR CASESession::Init(uint16_t localSessionId, SessionEstablishmentDelega } CHIP_ERROR -CASESession::ListenForSessionEstablishment(uint16_t localSessionId, FabricTable * fabrics, SessionEstablishmentDelegate * delegate) +CASESession::ListenForSessionEstablishment(uint16_t localSessionId, FabricTable * fabrics, SessionEstablishmentDelegate * delegate, + Optional mrpConfig) { VerifyOrReturnError(fabrics != nullptr, CHIP_ERROR_INVALID_ARGUMENT); ReturnErrorOnFailure(Init(localSessionId, delegate)); - mFabricsTable = fabrics; + mFabricsTable = fabrics; + mLocalMRPConfig = mrpConfig; mCASESessionEstablished = false; @@ -209,7 +212,7 @@ CASESession::ListenForSessionEstablishment(uint16_t localSessionId, FabricTable CHIP_ERROR CASESession::EstablishSession(const Transport::PeerAddress peerAddress, FabricInfo * fabric, NodeId peerNodeId, uint16_t localSessionId, ExchangeContext * exchangeCtxt, - SessionEstablishmentDelegate * delegate) + SessionEstablishmentDelegate * delegate, Optional mrpConfig) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -227,7 +230,8 @@ CHIP_ERROR CASESession::EstablishSession(const Transport::PeerAddress peerAddres // been initialized SuccessOrExit(err); - mFabricInfo = fabric; + mFabricInfo = fabric; + mLocalMRPConfig = mrpConfig; mExchangeCtxt->SetResponseTimeout(kSigma_Response_Timeout); SetPeerAddress(peerAddress); @@ -328,6 +332,12 @@ CHIP_ERROR CASESession::SendSigma1() ReturnErrorOnFailure( tlvWriter.PutBytes(TLV::ContextTag(4), mEphemeralKey.Pubkey(), static_cast(mEphemeralKey.Pubkey().Length()))); + if (mLocalMRPConfig.HasValue()) + { + ChipLogDetail(SecureChannel, "Including MRP parameters"); + ReturnErrorOnFailure(EncodeMRPParameters(TLV::ContextTag(5), mLocalMRPConfig.Value(), tlvWriter)); + } + // If CASE session was previously established using the current state information, let's fill in the session resumption // information in the the Sigma1 request. It'll speed up the session establishment process if the peer can resume the old // session, since no certificate chains will have to be verified. @@ -478,7 +488,11 @@ CHIP_ERROR CASESession::SendSigma2Resume(const ByteSpan & initiatorRandom) ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), GetLocalSessionId())); - // TODO: Add support for optional MRP parameters + if (mLocalMRPConfig.HasValue()) + { + ChipLogDetail(SecureChannel, "Including MRP parameters"); + ReturnErrorOnFailure(EncodeMRPParameters(TLV::ContextTag(4), mLocalMRPConfig.Value(), tlvWriter)); + } ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriter.Finalize(&msg_R2_resume)); @@ -606,6 +620,11 @@ CHIP_ERROR CASESession::SendSigma2() tlvWriterMsg2.PutBytes(TLV::ContextTag(3), mEphemeralKey.Pubkey(), static_cast(mEphemeralKey.Pubkey().Length()))); ReturnErrorOnFailure(tlvWriterMsg2.PutBytes(TLV::ContextTag(4), msg_R2_Encrypted.Get(), static_cast(msg_r2_signed_enc_len + CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES))); + if (mLocalMRPConfig.HasValue()) + { + ChipLogDetail(SecureChannel, "Including MRP parameters"); + ReturnErrorOnFailure(EncodeMRPParameters(TLV::ContextTag(5), mLocalMRPConfig.Value(), tlvWriter)); + } ReturnErrorOnFailure(tlvWriterMsg2.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriterMsg2.Finalize(&msg_R2)); @@ -661,6 +680,8 @@ CHIP_ERROR CASESession::HandleSigma2Resume(System::PacketBufferHandle && msg) VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); SuccessOrExit(err = tlvReader.Get(responderSessionId)); + SuccessOrExit(err = DecodeMRPParametersIfPresent(tlvReader)); + ChipLogDetail(SecureChannel, "Peer assigned session session ID %d", responderSessionId); SetPeerSessionId(responderSessionId); @@ -830,6 +851,9 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg) SuccessOrExit(err = ExtractCATsFromOpCert(responderNOC, peerCATs)); SetPeerCATs(peerCATs); + // Retrieve responderMRPParams if present + SuccessOrExit(err = DecodeMRPParametersIfPresent(tlvReader)); + exit: if (err != CHIP_NO_ERROR) { @@ -1354,7 +1378,7 @@ CHIP_ERROR CASESession::ParseSigma1(TLV::ContiguousBufferTLVReader & tlvReader, CHIP_ERROR err = tlvReader.Next(); if (err == CHIP_NO_ERROR && tlvReader.GetTag() == ContextTag(kInitiatorMRPParamsTag)) { - // We don't handle this yet; just move on. + ReturnErrorOnFailure(DecodeMRPParametersIfPresent(tlvReader)); err = tlvReader.Next(); } diff --git a/src/protocols/secure_channel/CASESession.h b/src/protocols/secure_channel/CASESession.h index f2eb5b8ab7b678..1bc451f2a48ed5 100644 --- a/src/protocols/secure_channel/CASESession.h +++ b/src/protocols/secure_channel/CASESession.h @@ -90,7 +90,9 @@ class DLL_EXPORT CASESession : public Messaging::ExchangeDelegate, public Pairin * * @return CHIP_ERROR The result of initialization */ - CHIP_ERROR ListenForSessionEstablishment(uint16_t mySessionId, FabricTable * fabrics, SessionEstablishmentDelegate * delegate); + CHIP_ERROR ListenForSessionEstablishment( + uint16_t mySessionId, FabricTable * fabrics, SessionEstablishmentDelegate * delegate, + Optional mrpConfig = Optional::Missing()); /** * @brief @@ -105,9 +107,10 @@ class DLL_EXPORT CASESession : public Messaging::ExchangeDelegate, public Pairin * * @return CHIP_ERROR The result of initialization */ - CHIP_ERROR EstablishSession(const Transport::PeerAddress peerAddress, FabricInfo * fabric, NodeId peerNodeId, - uint16_t mySessionId, Messaging::ExchangeContext * exchangeCtxt, - SessionEstablishmentDelegate * delegate); + CHIP_ERROR + EstablishSession(const Transport::PeerAddress peerAddress, FabricInfo * fabric, NodeId peerNodeId, uint16_t mySessionId, + Messaging::ExchangeContext * exchangeCtxt, SessionEstablishmentDelegate * delegate, + Optional mrpConfig = Optional::Missing()); /** * Parse a sigma1 message. This function will return success only if the @@ -127,10 +130,9 @@ class DLL_EXPORT CASESession : public Messaging::ExchangeDelegate, public Pairin * and the resumptionID and initiatorResumeMIC outparams will be set to * valid values, or the resumptionRequested outparam will be set to false. */ - static CHIP_ERROR ParseSigma1(TLV::ContiguousBufferTLVReader & tlvReader, ByteSpan & initiatorRandom, - uint16_t & initiatorSessionId, ByteSpan & destinationId, ByteSpan & initiatorEphPubKey, - // TODO: MRP param parsing - bool & resumptionRequested, ByteSpan & resumptionId, ByteSpan & initiatorResumeMIC); + CHIP_ERROR ParseSigma1(TLV::ContiguousBufferTLVReader & tlvReader, ByteSpan & initiatorRandom, uint16_t & initiatorSessionId, + ByteSpan & destinationId, ByteSpan & initiatorEphPubKey, bool & resumptionRequested, + ByteSpan & resumptionId, ByteSpan & initiatorResumeMIC); /** * @brief @@ -261,6 +263,8 @@ class DLL_EXPORT CASESession : public Messaging::ExchangeDelegate, public Pairin uint8_t mLocalFabricIndex = 0; uint64_t mSessionSetupTimeStamp = 0; + Optional mLocalMRPConfig; + protected: bool mCASESessionEstablished = false; diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index 4861bad51b9c2d..5a090485976840 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -484,8 +484,9 @@ static CHIP_ERROR EncodeSigma1(MutableByteSpan & buf) bool resumptionRequested; \ ByteSpan resumptionId; \ ByteSpan initiatorResumeMIC; \ - err = CASESession::ParseSigma1(reader, initiatorRandom, initiatorSessionId, destinationId, initiatorEphPubKey, \ - resumptionRequested, resumptionId, initiatorResumeMIC); \ + CASESession session; \ + err = session.ParseSigma1(reader, initiatorRandom, initiatorSessionId, destinationId, initiatorEphPubKey, \ + resumptionRequested, resumptionId, initiatorResumeMIC); \ NL_TEST_ASSERT(inSuite, (err == CHIP_NO_ERROR) == params::expectSuccess); \ if (params::expectSuccess) \ { \