From 2686057184bcb2bde0c0b47e51646384de69b244 Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Fri, 10 Nov 2023 01:55:39 +0000 Subject: [PATCH] Update session parameters to be inline with matter 1.3 spec --- src/lib/core/CHIPConfig.h | 13 +++ src/protocols/secure_channel/CASESession.cpp | 42 +++----- src/protocols/secure_channel/PASESession.cpp | 39 +++---- .../secure_channel/PairingSession.cpp | 102 ++++++++++++++---- src/protocols/secure_channel/PairingSession.h | 17 +-- .../secure_channel/SessionParameters.h | 85 +++++++++++++++ .../tests/TestPairingSession.cpp | 7 +- 7 files changed, 227 insertions(+), 78 deletions(-) create mode 100644 src/protocols/secure_channel/SessionParameters.h diff --git a/src/lib/core/CHIPConfig.h b/src/lib/core/CHIPConfig.h index 7363fb2b8d42ee..1d9374547ab1fd 100644 --- a/src/lib/core/CHIPConfig.h +++ b/src/lib/core/CHIPConfig.h @@ -1600,6 +1600,19 @@ extern const char CHIP_NON_PRODUCTION_MARKER[]; #define CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED 0 #endif +/** + * @def CHIP_CONFIG_MAX_PATHS_PER_INVOKE + * + * @brief The maximum number of elements in the InvokeRequests list that the Node is able to process. + */ +#ifndef CHIP_CONFIG_MAX_PATHS_PER_INVOKE +#define CHIP_CONFIG_MAX_PATHS_PER_INVOKE 1 +#endif + +#if CHIP_CONFIG_MAX_PATHS_PER_INVOKE < 1 || CHIP_CONFIG_MAX_PATHS_PER_INVOKE > 65535 +#error "CHIP_CONFIG_MAX_PATHS_PER_INVOKE is not allowed to be a number less than 1 or greater than 65535" +#endif + /** * @} */ diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index 2afc40feacaf02..432880edfe6eec 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -640,13 +641,11 @@ CHIP_ERROR CASESession::RecoverInitiatorIpk() CHIP_ERROR CASESession::SendSigma1() { MATTER_TRACE_SCOPE("SendSigma1", "CASESession"); - const size_t mrpParamsSize = - mLocalMRPConfig.HasValue() ? TLV::EstimateStructOverhead(sizeof(uint16_t), sizeof(uint16_t), sizeof(uint16_t)) : 0; size_t data_len = TLV::EstimateStructOverhead(kSigmaParamRandomNumberSize, // initiatorRandom sizeof(uint16_t), // initiatorSessionId, kSHA256_Hash_Length, // destinationId kP256_PublicKey_Length, // InitiatorEphPubKey, - mrpParamsSize, // initiatorMRPParams + kSessionParamSize, // initiatorSessionParams SessionResumptionStorage::kResumptionIdSize, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES); System::PacketBufferTLVWriter tlvWriter; @@ -699,11 +698,8 @@ 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)); - } + ChipLogDetail(SecureChannel, "Including MRP parameters"); + ReturnErrorOnFailure(EncodeSessionParameters(TLV::ContextTag(5), mLocalMRPConfig, tlvWriter)); // Try to find persistent session, and resume it. bool resuming = false; @@ -916,10 +912,8 @@ CHIP_ERROR CASESession::HandleSigma1(System::PacketBufferHandle && msg) CHIP_ERROR CASESession::SendSigma2Resume() { MATTER_TRACE_SCOPE("SendSigma2Resume", "CASESession"); - const size_t mrpParamsSize = - mLocalMRPConfig.HasValue() ? TLV::EstimateStructOverhead(sizeof(uint16_t), sizeof(uint16_t), sizeof(uint16_t)) : 0; size_t max_sigma2_resume_data_len = TLV::EstimateStructOverhead( - SessionResumptionStorage::kResumptionIdSize, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, sizeof(uint16_t), mrpParamsSize); + SessionResumptionStorage::kResumptionIdSize, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, sizeof(uint16_t), kSessionParamSize); System::PacketBufferTLVWriter tlvWriter; System::PacketBufferHandle msg_R2_resume; @@ -948,11 +942,8 @@ CHIP_ERROR CASESession::SendSigma2Resume() ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), GetLocalSessionId().Value())); - if (mLocalMRPConfig.HasValue()) - { - ChipLogDetail(SecureChannel, "Including MRP parameters"); - ReturnErrorOnFailure(EncodeMRPParameters(TLV::ContextTag(4), mLocalMRPConfig.Value(), tlvWriter)); - } + ChipLogDetail(SecureChannel, "Including MRP parameters"); + ReturnErrorOnFailure(EncodeSessionParameters(TLV::ContextTag(4), mLocalMRPConfig, tlvWriter)); ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriter.Finalize(&msg_R2_resume)); @@ -1067,10 +1058,8 @@ CHIP_ERROR CASESession::SendSigma2() msg_R2_Encrypted.Get() + msg_r2_signed_enc_len, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES)); // Construct Sigma2 Msg - const size_t mrpParamsSize = - mLocalMRPConfig.HasValue() ? TLV::EstimateStructOverhead(sizeof(uint16_t), sizeof(uint16_t), sizeof(uint16_t)) : 0; size_t data_len = TLV::EstimateStructOverhead(kSigmaParamRandomNumberSize, sizeof(uint16_t), kP256_PublicKey_Length, - msg_r2_signed_enc_len, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, mrpParamsSize); + msg_r2_signed_enc_len, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, kSessionParamSize); System::PacketBufferHandle msg_R2 = System::PacketBufferHandle::New(data_len); VerifyOrReturnError(!msg_R2.IsNull(), CHIP_ERROR_NO_MEMORY); @@ -1086,11 +1075,10 @@ CHIP_ERROR CASESession::SendSigma2() 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(), tlvWriterMsg2)); - } + + ChipLogDetail(SecureChannel, "Including MRP parameters"); + ReturnErrorOnFailure(EncodeSessionParameters(TLV::ContextTag(5), mLocalMRPConfig, tlvWriterMsg2)); + ReturnErrorOnFailure(tlvWriterMsg2.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriterMsg2.Finalize(&msg_R2)); @@ -1147,7 +1135,7 @@ CHIP_ERROR CASESession::HandleSigma2Resume(System::PacketBufferHandle && msg) if (tlvReader.Next() != CHIP_END_OF_TLV) { SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(4), tlvReader)); - mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(mRemoteMRPConfig); + mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(GetRemoteMRPConfig()); } ChipLogDetail(SecureChannel, "Peer assigned session session ID %d", responderSessionId); @@ -1340,7 +1328,7 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg) if (tlvReader.Next() != CHIP_END_OF_TLV) { SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(kTag_Sigma2_ResponderMRPParams), tlvReader)); - mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(mRemoteMRPConfig); + mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(GetRemoteMRPConfig()); } exit: @@ -2029,7 +2017,7 @@ CHIP_ERROR CASESession::ParseSigma1(TLV::ContiguousBufferTLVReader & tlvReader, if (err == CHIP_NO_ERROR && tlvReader.GetTag() == ContextTag(kInitiatorMRPParamsTag)) { ReturnErrorOnFailure(DecodeMRPParametersIfPresent(TLV::ContextTag(kInitiatorMRPParamsTag), tlvReader)); - mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(mRemoteMRPConfig); + mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(GetRemoteMRPConfig()); err = tlvReader.Next(); } diff --git a/src/protocols/secure_channel/PASESession.cpp b/src/protocols/secure_channel/PASESession.cpp index 966bc1dbe8dae0..e9e10064ec30fd 100644 --- a/src/protocols/secure_channel/PASESession.cpp +++ b/src/protocols/secure_channel/PASESession.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -270,13 +271,12 @@ CHIP_ERROR PASESession::SendPBKDFParamRequest() ReturnErrorOnFailure(DRBG_get_bytes(mPBKDFLocalRandomData, sizeof(mPBKDFLocalRandomData))); - const size_t mrpParamsSize = mLocalMRPConfig.HasValue() ? TLV::EstimateStructOverhead(sizeof(uint16_t), sizeof(uint16_t)) : 0; - const size_t max_msg_len = TLV::EstimateStructOverhead(kPBKDFParamRandomNumberSize, // initiatorRandom, - sizeof(uint16_t), // initiatorSessionId - sizeof(PasscodeId), // passcodeId, - sizeof(uint8_t), // hasPBKDFParameters - mrpParamsSize // MRP Parameters - ); + const size_t max_msg_len = TLV::EstimateStructOverhead(kPBKDFParamRandomNumberSize, // initiatorRandom, + sizeof(uint16_t), // initiatorSessionId + sizeof(PasscodeId), // passcodeId, + sizeof(uint8_t), // hasPBKDFParameters + kSessionParamSize // Session Parameters + ); System::PacketBufferHandle req = System::PacketBufferHandle::New(max_msg_len); VerifyOrReturnError(!req.IsNull(), CHIP_ERROR_NO_MEMORY); @@ -290,11 +290,10 @@ CHIP_ERROR PASESession::SendPBKDFParamRequest() ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), GetLocalSessionId().Value())); ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), kDefaultCommissioningPasscodeId)); ReturnErrorOnFailure(tlvWriter.PutBoolean(TLV::ContextTag(4), mHavePBKDFParameters)); - if (mLocalMRPConfig.HasValue()) - { - ChipLogDetail(SecureChannel, "Including MRP parameters in PBKDF param request"); - ReturnErrorOnFailure(EncodeMRPParameters(TLV::ContextTag(5), mLocalMRPConfig.Value(), tlvWriter)); - } + + ChipLogDetail(SecureChannel, "Including MRP parameters in PBKDF param request"); + ReturnErrorOnFailure(EncodeSessionParameters(TLV::ContextTag(5), mLocalMRPConfig, tlvWriter)); + ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriter.Finalize(&req)); @@ -357,7 +356,7 @@ CHIP_ERROR PASESession::HandlePBKDFParamRequest(System::PacketBufferHandle && ms if (tlvReader.Next() != CHIP_END_OF_TLV) { SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(5), tlvReader)); - mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(mRemoteMRPConfig); + mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(GetRemoteMRPConfig()); } err = SendPBKDFParamResponse(ByteSpan(initiatorRandom), hasPBKDFParameters); @@ -382,13 +381,12 @@ CHIP_ERROR PASESession::SendPBKDFParamResponse(ByteSpan initiatorRandom, bool in ReturnErrorOnFailure(DRBG_get_bytes(mPBKDFLocalRandomData, sizeof(mPBKDFLocalRandomData))); - const size_t mrpParamsSize = mLocalMRPConfig.HasValue() ? TLV::EstimateStructOverhead(sizeof(uint16_t), sizeof(uint16_t)) : 0; const size_t max_msg_len = TLV::EstimateStructOverhead(kPBKDFParamRandomNumberSize, // initiatorRandom kPBKDFParamRandomNumberSize, // responderRandom sizeof(uint16_t), // responderSessionId TLV::EstimateStructOverhead(sizeof(uint32_t), mSaltLength), // pbkdf_parameters - mrpParamsSize // MRP Parameters + kSessionParamSize // Session Parameters ); System::PacketBufferHandle resp = System::PacketBufferHandle::New(max_msg_len); @@ -413,11 +411,8 @@ CHIP_ERROR PASESession::SendPBKDFParamResponse(ByteSpan initiatorRandom, bool in ReturnErrorOnFailure(tlvWriter.EndContainer(pbkdfParamContainer)); } - if (mLocalMRPConfig.HasValue()) - { - ChipLogDetail(SecureChannel, "Including MRP parameters in PBKDF param response"); - ReturnErrorOnFailure(EncodeMRPParameters(TLV::ContextTag(5), mLocalMRPConfig.Value(), tlvWriter)); - } + ChipLogDetail(SecureChannel, "Including MRP parameters in PBKDF param response"); + ReturnErrorOnFailure(EncodeSessionParameters(TLV::ContextTag(5), mLocalMRPConfig, tlvWriter)); ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriter.Finalize(&resp)); @@ -481,7 +476,7 @@ CHIP_ERROR PASESession::HandlePBKDFParamResponse(System::PacketBufferHandle && m if (tlvReader.Next() != CHIP_END_OF_TLV) { SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(5), tlvReader)); - mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(mRemoteMRPConfig); + mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(GetRemoteMRPConfig()); } // TODO - Add a unit test that exercises mHavePBKDFParameters path @@ -506,7 +501,7 @@ CHIP_ERROR PASESession::HandlePBKDFParamResponse(System::PacketBufferHandle && m if (tlvReader.Next() != CHIP_END_OF_TLV) { SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(5), tlvReader)); - mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(mRemoteMRPConfig); + mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteMRPConfig(GetRemoteMRPConfig()); } } diff --git a/src/protocols/secure_channel/PairingSession.cpp b/src/protocols/secure_channel/PairingSession.cpp index af555bfeee5046..5a2a01a98a546d 100644 --- a/src/protocols/secure_channel/PairingSession.cpp +++ b/src/protocols/secure_channel/PairingSession.cpp @@ -18,9 +18,21 @@ #include +#include #include #include +#define IncrementReaderExitOnEndOfTlv(tlvReader) \ + do \ + { \ + CHIP_ERROR err = tlvReader.Next(); \ + if (err == CHIP_END_OF_TLV) \ + { \ + return tlvReader.ExitContainer(containerType); \ + } \ + ReturnErrorOnFailure(err); \ + } while (0) + namespace chip { CHIP_ERROR PairingSession::AllocateSecureSession(SessionManager & sessionManager, const ScopedNodeId & sessionEvictionHint) @@ -44,7 +56,7 @@ CHIP_ERROR PairingSession::ActivateSecureSession(const Transport::PeerAddress & // Call Activate last, otherwise errors on anything after would lead to // a partially valid session. - secureSession->Activate(GetLocalScopedNodeId(), GetPeer(), GetPeerCATs(), peerSessionId, mRemoteMRPConfig); + secureSession->Activate(GetLocalScopedNodeId(), GetPeer(), GetPeerCATs(), peerSessionId, GetRemoteMRPConfig()); ChipLogDetail(Inet, "New secure session activated for device " ChipLogFormatScopedNodeId ", LSID:%d PSID:%d!", ChipLogValueScopedNodeId(GetPeer()), secureSession->GetLocalSessionId(), peerSessionId); @@ -88,14 +100,38 @@ void PairingSession::DiscardExchange() } } -CHIP_ERROR PairingSession::EncodeMRPParameters(TLV::Tag tag, const ReliableMessageProtocolConfig & mrpLocalConfig, - TLV::TLVWriter & tlvWriter) +CHIP_ERROR PairingSession::EncodeSessionParameters(TLV::Tag tag, const Optional & providedMrpConfig, + TLV::TLVWriter & tlvWriter) { + ReliableMessageProtocolConfig mrpLocalConfig = GetDefaultMRPConfig(); + if (providedMrpConfig.HasValue()) + { + mrpLocalConfig = providedMrpConfig.Value(); + } TLV::TLVType mrpParamsContainer; ReturnErrorOnFailure(tlvWriter.StartContainer(tag, TLV::kTLVType_Structure, mrpParamsContainer)); ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(1), mrpLocalConfig.mIdleRetransTimeout.count())); ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), mrpLocalConfig.mActiveRetransTimeout.count())); ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), mrpLocalConfig.mActiveThresholdTime.count())); + + // TODO not sure where to grab CHIP_DEVICE_DATA_MODEL_REVISION, include "app/DataModelRevision.h" + // creates depenency loop, should I isolate those header to their own target to remove loop + // or provide these in a different way + uint16_t dataModel = 17; + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(4), dataModel)); // CHIP_DEVICE_INTERACTION_MODEL_REVISION + + // TODO not sure where to grab CHIP_DEVICE_DATA_MODEL_REVISION, include "app/InteractionModelRevision.h" + // creates depenency loop, should I isolate those header to their own target to remove loop + // or provide these in a different way + uint16_t interactionModel = 11; + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(5), interactionModel)); + + // TODO where do I get SPECIFICATION_VERSION from? For now I have just hardcoded 1.3. + uint32_t specVersion = 0x01030000; + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(6), specVersion)); + + uint16_t maxPathPerInvoke = CHIP_CONFIG_MAX_PATHS_PER_INVOKE; + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(7), maxPathPerInvoke)); return tlvWriter.EndContainer(mrpParamsContainer); } @@ -121,36 +157,66 @@ CHIP_ERROR PairingSession::DecodeMRPParametersIfPresent(TLV::Tag expectedTag, TL if (TLV::TagNumFromTag(tlvReader.GetTag()) == 1) { ReturnErrorOnFailure(tlvReader.Get(tlvElementValue)); - mRemoteMRPConfig.mIdleRetransTimeout = System::Clock::Milliseconds32(tlvElementValue); + mRemoteSessionParam.SetMRPIdleRetransTimeout(System::Clock::Milliseconds32(tlvElementValue)); // The next element is optional. If it's not present, return CHIP_NO_ERROR. - CHIP_ERROR err = tlvReader.Next(); - if (err == CHIP_END_OF_TLV) - { - return tlvReader.ExitContainer(containerType); - } - ReturnErrorOnFailure(err); + IncrementReaderExitOnEndOfTlv(tlvReader); } if (TLV::TagNumFromTag(tlvReader.GetTag()) == 2) { ReturnErrorOnFailure(tlvReader.Get(tlvElementValue)); - mRemoteMRPConfig.mActiveRetransTimeout = System::Clock::Milliseconds32(tlvElementValue); + mRemoteSessionParam.SetMRPActiveRetransTimeout(System::Clock::Milliseconds32(tlvElementValue)); // The next element is optional. If it's not present, return CHIP_NO_ERROR. - CHIP_ERROR err = tlvReader.Next(); - if (err == CHIP_END_OF_TLV) - { - return tlvReader.ExitContainer(containerType); - } - ReturnErrorOnFailure(err); + IncrementReaderExitOnEndOfTlv(tlvReader); } if (TLV::TagNumFromTag(tlvReader.GetTag()) == 3) { ReturnErrorOnFailure(tlvReader.Get(tlvElementValue)); - mRemoteMRPConfig.mActiveThresholdTime = System::Clock::Milliseconds16(tlvElementValue); + mRemoteSessionParam.SetMRPActiveThresholdTime(System::Clock::Milliseconds16(tlvElementValue)); + + // The next element is optional. If it's not present, return CHIP_NO_ERROR. + IncrementReaderExitOnEndOfTlv(tlvReader); + } + + if (TLV::TagNumFromTag(tlvReader.GetTag()) == 4) + { + ReturnErrorOnFailure(tlvReader.Get(tlvElementValue)); + mRemoteSessionParam.SetDataModelRev(static_cast(tlvElementValue)); + + // The next element is optional. If it's not present, return CHIP_NO_ERROR. + IncrementReaderExitOnEndOfTlv(tlvReader); + } + + if (TLV::TagNumFromTag(tlvReader.GetTag()) == 5) + { + ReturnErrorOnFailure(tlvReader.Get(tlvElementValue)); + mRemoteSessionParam.SetInteractionModelRev(static_cast(tlvElementValue)); + + // The next element is optional. If it's not present, return CHIP_NO_ERROR. + IncrementReaderExitOnEndOfTlv(tlvReader); } + + if (TLV::TagNumFromTag(tlvReader.GetTag()) == 6) + { + ReturnErrorOnFailure(tlvReader.Get(tlvElementValue)); + mRemoteSessionParam.SetSpecificationVersion(tlvElementValue); + + // The next element is optional. If it's not present, return CHIP_NO_ERROR. + IncrementReaderExitOnEndOfTlv(tlvReader); + } + + if (TLV::TagNumFromTag(tlvReader.GetTag()) == 7) + { + ReturnErrorOnFailure(tlvReader.Get(tlvElementValue)); + mRemoteSessionParam.SetMaxPathPerInvoke(static_cast(tlvElementValue)); + + // The next element is optional. If it's not present, return CHIP_NO_ERROR. + IncrementReaderExitOnEndOfTlv(tlvReader); + } + // Future proofing - Don't error out if there are other tags return tlvReader.ExitContainer(containerType); diff --git a/src/protocols/secure_channel/PairingSession.h b/src/protocols/secure_channel/PairingSession.h index c604cd0662dfd3..0c6d3ae89c2bd7 100644 --- a/src/protocols/secure_channel/PairingSession.h +++ b/src/protocols/secure_channel/PairingSession.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -96,14 +97,14 @@ class DLL_EXPORT PairingSession : public SessionDelegate */ virtual CHIP_ERROR DeriveSecureSession(CryptoContext & session) const = 0; - const ReliableMessageProtocolConfig & GetRemoteMRPConfig() const { return mRemoteMRPConfig; } - void SetRemoteMRPConfig(const ReliableMessageProtocolConfig & config) { mRemoteMRPConfig = config; } + const ReliableMessageProtocolConfig & GetRemoteMRPConfig() const { return mRemoteSessionParam.GetMRPConfig(); } + void SetRemoteMRPConfig(const ReliableMessageProtocolConfig & config) { mRemoteSessionParam.SetMRPConfig(config); } /** - * Encode the provided MRP parameters using the provided TLV tag. + * Encode the Session Parameters using the provided TLV tag. */ - static CHIP_ERROR EncodeMRPParameters(TLV::Tag tag, const ReliableMessageProtocolConfig & mrpLocalConfig, - TLV::TLVWriter & tlvWriter); + static CHIP_ERROR EncodeSessionParameters(TLV::Tag tag, const Optional & mrpLocalConfig, + TLV::TLVWriter & tlvWriter); protected: /** @@ -200,7 +201,7 @@ class DLL_EXPORT PairingSession : public SessionDelegate /** * Try to decode the current element (pointed by the TLV reader) as MRP parameters. - * If the MRP parameters are found, mRemoteMRPConfig is updated with the devoded values. + * If the MRP parameters are found, mRemoteSessionParam is updated with the devoded values. * * MRP parameters are optional. So, if the TLV reader is not pointing to the MRP parameters, * the function is a noop. @@ -231,9 +232,9 @@ class DLL_EXPORT PairingSession : public SessionDelegate SessionEstablishmentDelegate * mDelegate = nullptr; // mLocalMRPConfig is our config which is sent to the other end and used by the peer session. - // mRemoteMRPConfig is received from other end and set to our session. + // mRemoteSessionParam is received from other end and set to our session. Optional mLocalMRPConfig; - ReliableMessageProtocolConfig mRemoteMRPConfig = GetDefaultMRPConfig(); + SessionParameters mRemoteSessionParam; private: Optional mPeerSessionId; diff --git a/src/protocols/secure_channel/SessionParameters.h b/src/protocols/secure_channel/SessionParameters.h new file mode 100644 index 00000000000000..9518562ff4be4c --- /dev/null +++ b/src/protocols/secure_channel/SessionParameters.h @@ -0,0 +1,85 @@ +/* + * + * Copyright (c) 2023 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 + * TODO need to give this a proper description. + * This file defines a common interface to access various types of secure + * pairing sessions (e.g. PASE, CASE) + * + */ + +#pragma once + +#include +#include + +namespace chip { + +// TODO We should get part of this from constexpr that is in ReliableMessageProtocolConfig.h +inline constexpr size_t kSessionParamSize = TLV::EstimateStructOverhead( + sizeof(uint16_t), sizeof(uint16_t), sizeof(uint16_t), sizeof(uint16_t), sizeof(uint16_t), sizeof(uint32_t), sizeof(uint16_t)); + +class SessionParameters +{ +public: + SessionParameters(ReliableMessageProtocolConfig mrpConfig = GetDefaultMRPConfig()) : mMRPConfig(mrpConfig) {} + + const ReliableMessageProtocolConfig & GetMRPConfig() const { return mMRPConfig; } + void SetMRPConfig(const ReliableMessageProtocolConfig & config) { mMRPConfig = config; } + void SetMRPIdleRetransTimeout(const System::Clock::Milliseconds32 idleRetransTimeout) + { + mMRPConfig.mIdleRetransTimeout = idleRetransTimeout; + } + void SetMRPActiveRetransTimeout(const System::Clock::Milliseconds32 activeRetransTimeout) + { + mMRPConfig.mActiveRetransTimeout = activeRetransTimeout; + } + void SetMRPActiveThresholdTime(const System::Clock::Milliseconds16 activeThresholdTime) + { + mMRPConfig.mActiveThresholdTime = activeThresholdTime; + } + + const Optional & GetDataModelRev() const { return mDataModelRev; } + void SetDataModelRev(const uint16_t dataModelRev) { mDataModelRev = MakeOptional(dataModelRev); } + + const Optional & GetInteractionModelRev() const { return mInteractionModelRev; } + void SetInteractionModelRev(const uint16_t interactionModelRev) { mInteractionModelRev = MakeOptional(interactionModelRev); } + + const Optional & GetSpecificationVersion() const { return mSpecificationVersion; } + void SetSpecificationVersion(const uint32_t specVersion) { mSpecificationVersion = MakeOptional(specVersion); } + + uint16_t GetMaxPathPerInvoke() const { return mMaxPathPerInvoke; } + void SetMaxPathPerInvoke(const uint16_t maxPathPerInvoke) { mMaxPathPerInvoke = maxPathPerInvoke; } + +private: + ReliableMessageProtocolConfig mMRPConfig; + // For legacy reason if we do not get DataModelRev it means that either 16 or 17. But there isn't + // a way to know for certain. + Optional mDataModelRev = NullOptional; + // For legacy reason if we do not get InterationModelRev it means that either 10 or 11. But there + // isn't a way to know for certain. + Optional mInteractionModelRev = NullOptional; + // For legacy reason if we do not get Specification Version it means that version is less than + // 0x01030000. But there isn't a way to know for certain. + Optional mSpecificationVersion = MakeOptional(0x01030000u); + // When maxPathPerInvoke is not provide legacy is always 1 + uint16_t mMaxPathPerInvoke = 1; +}; + +} // namespace chip diff --git a/src/protocols/secure_channel/tests/TestPairingSession.cpp b/src/protocols/secure_channel/tests/TestPairingSession.cpp index 714a18e03fc1a4..fd0e3d104bd311 100644 --- a/src/protocols/secure_channel/tests/TestPairingSession.cpp +++ b/src/protocols/secure_channel/tests/TestPairingSession.cpp @@ -46,7 +46,7 @@ class TestPairingSession : public PairingSession void OnSessionReleased() override {} - const ReliableMessageProtocolConfig & GetRemoteMRPConfig() const { return mRemoteMRPConfig; } + const ReliableMessageProtocolConfig & GetRemoteMRPConfig() const { return PairingSession::GetRemoteMRPConfig(); } CHIP_ERROR DeriveSecureSession(CryptoContext & session) const override { return CHIP_NO_ERROR; } @@ -60,7 +60,8 @@ void PairingSessionEncodeDecodeMRPParams(nlTestSuite * inSuite, void * inContext { TestPairingSession session; - ReliableMessageProtocolConfig config(Milliseconds32(100), Milliseconds32(200), Milliseconds16(4000)); + Optional config = + MakeOptional(ReliableMessageProtocolConfig(Milliseconds32(100), Milliseconds32(200), Milliseconds16(4000))); System::PacketBufferHandle buf = System::PacketBufferHandle::New(64, 0); System::PacketBufferTLVWriter writer; @@ -70,7 +71,7 @@ void PairingSessionEncodeDecodeMRPParams(nlTestSuite * inSuite, void * inContext NL_TEST_ASSERT(inSuite, writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, PairingSession::EncodeMRPParameters(TLV::ContextTag(1), config, writer) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, PairingSession::EncodeSessionParameters(TLV::ContextTag(1), config, writer) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, writer.EndContainer(outerContainerType) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, writer.Finalize(&buf) == CHIP_NO_ERROR);