Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit 35fb312

Browse files
author
Jay Logue
authored
Merge pull request #48 from openweave/feature/jay/case-auth-delegate-enhancements
WeaveCASEAuthDelegate Enhancements
2 parents 8a26b0e + 543e8f9 commit 35fb312

19 files changed

+1408
-505
lines changed

build/config/standalone/WeaveProjectConfig.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,6 @@
5757

5858
#define WEAVE_CONFIG_ENABLE_WDM_UPDATE 1
5959

60+
#define WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE 0
61+
6062
#endif /* WEAVEPROJECTCONFIG_H */

src/device-manager/WeaveDeviceManager.cpp

Lines changed: 87 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5169,6 +5169,83 @@ WEAVE_ERROR WeaveDeviceManager::DecodeNetworkInfoList(PacketBuffer *msgBuf, uint
51695169
return err;
51705170
}
51715171

5172+
5173+
#if !WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE
5174+
5175+
WEAVE_ERROR WeaveDeviceManager::EncodeNodeCertInfo(const Security::CASE::BeginSessionContext & msgCtx,
5176+
TLVWriter & writer)
5177+
{
5178+
WEAVE_ERROR err = WEAVE_NO_ERROR;
5179+
TLVReader reader;
5180+
5181+
// Initialize a reader to read the access token.
5182+
reader.Init((const uint8_t *)mAuthKey, mAuthKeyLen);
5183+
reader.ImplicitProfileId = kWeaveProfile_Security;
5184+
5185+
// Generate a CASE CertificateInformation structure from the information in the access token.
5186+
err = CASECertInfoFromAccessToken(reader, writer);
5187+
SuccessOrExit(err);
5188+
5189+
exit:
5190+
if (err != WEAVE_NO_ERROR)
5191+
err = WEAVE_ERROR_INVALID_ACCESS_TOKEN;
5192+
return err;
5193+
}
5194+
5195+
WEAVE_ERROR WeaveDeviceManager::GenerateNodeSignature(const Security::CASE::BeginSessionContext & msgCtx,
5196+
const uint8_t * msgHash, uint8_t msgHashLen,
5197+
TLVWriter & writer, uint64_t tag)
5198+
{
5199+
WEAVE_ERROR err = WEAVE_NO_ERROR;
5200+
const uint8_t * privKey = NULL;
5201+
uint16_t privKeyLen;
5202+
5203+
// Get the private key from the access token.
5204+
err = GetNodePrivateKey(msgCtx.IsInitiator(), privKey, privKeyLen);
5205+
SuccessOrExit(err);
5206+
5207+
// Generate a signature using the access token private key.
5208+
err = GenerateAndEncodeWeaveECDSASignature(writer, tag, msgHash, msgHashLen, privKey, privKeyLen);
5209+
SuccessOrExit(err);
5210+
5211+
exit:
5212+
if (privKey != NULL)
5213+
{
5214+
WEAVE_ERROR relErr = ReleaseNodePrivateKey(privKey);
5215+
err = (err == WEAVE_NO_ERROR) ? relErr : err;
5216+
}
5217+
return err;
5218+
}
5219+
5220+
WEAVE_ERROR WeaveDeviceManager::EncodeNodePayload(const Security::CASE::BeginSessionContext & msgCtx,
5221+
uint8_t * payloadBuf, uint16_t payloadBufSize, uint16_t & payloadLen)
5222+
{
5223+
// No payload
5224+
payloadLen = 0;
5225+
return WEAVE_NO_ERROR;
5226+
}
5227+
5228+
WEAVE_ERROR WeaveDeviceManager::BeginValidation(const Security::CASE::BeginSessionContext & msgCtx,
5229+
Security::ValidationContext & validCtx, Security::WeaveCertificateSet & certSet)
5230+
{
5231+
return BeginCertValidation(msgCtx.IsInitiator(), certSet, validCtx);
5232+
}
5233+
5234+
WEAVE_ERROR WeaveDeviceManager::HandleValidationResult(const Security::CASE::BeginSessionContext & msgCtx,
5235+
Security::ValidationContext & validCtx,
5236+
Security::WeaveCertificateSet & certSet, WEAVE_ERROR & validRes)
5237+
{
5238+
return HandleCertValidationResult(msgCtx.IsInitiator(), validRes, validCtx.SigningCert, msgCtx.PeerNodeId, certSet, validCtx);
5239+
}
5240+
5241+
void WeaveDeviceManager::EndValidation(const Security::CASE::BeginSessionContext & msgCtx,
5242+
Security::ValidationContext & validCtx, Security::WeaveCertificateSet & certSet)
5243+
{
5244+
EndCertValidation(certSet, validCtx);
5245+
}
5246+
5247+
#else // !WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE
5248+
51725249
WEAVE_ERROR WeaveDeviceManager::GetNodeCertInfo(bool isInitiator, uint8_t *buf, uint16_t bufSize, uint16_t& certInfoLen)
51735250
{
51745251
WEAVE_ERROR err;
@@ -5184,6 +5261,16 @@ WEAVE_ERROR WeaveDeviceManager::GetNodeCertInfo(bool isInitiator, uint8_t *buf,
51845261
return err;
51855262
}
51865263

5264+
// Get payload information, if any, to be included in the message to the peer.
5265+
WEAVE_ERROR WeaveDeviceManager::GetNodePayload(bool isInitiator, uint8_t *buf, uint16_t bufSize, uint16_t& payloadLen)
5266+
{
5267+
// No payload
5268+
payloadLen = 0;
5269+
return WEAVE_NO_ERROR;
5270+
}
5271+
5272+
#endif // WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE
5273+
51875274
// Get the local node's private key.
51885275
WEAVE_ERROR WeaveDeviceManager::GetNodePrivateKey(bool isInitiator, const uint8_t *& weavePrivKey, uint16_t& weavePrivKeyLen)
51895276
{
@@ -5218,14 +5305,6 @@ WEAVE_ERROR WeaveDeviceManager::ReleaseNodePrivateKey(const uint8_t *weavePrivKe
52185305
return WEAVE_NO_ERROR;
52195306
}
52205307

5221-
// Get payload information, if any, to be included in the message to the peer.
5222-
WEAVE_ERROR WeaveDeviceManager::GetNodePayload(bool isInitiator, uint8_t *buf, uint16_t bufSize, uint16_t& payloadLen)
5223-
{
5224-
// No payload
5225-
payloadLen = 0;
5226-
return WEAVE_NO_ERROR;
5227-
}
5228-
52295308
// Prepare the supplied certificate set and validation context for use in validating the certificate of a peer.
52305309
// This method is responsible for loading the trust anchors into the certificate set.
52315310
WEAVE_ERROR WeaveDeviceManager::BeginCertValidation(bool isInitiator, WeaveCertificateSet& certSet, ValidationContext& validContext)

src/device-manager/WeaveDeviceManager.h

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <Weave/Profiles/network-provisioning/NetworkInfo.h>
4343
#include <Weave/Profiles/security/WeaveSecurity.h>
4444
#include <Weave/Profiles/security/WeaveCASE.h>
45+
#include <Weave/Profiles/security/WeaveSig.h>
4546
#include <Weave/Profiles/service-directory/ServiceDirectory.h>
4647
#include <Weave/Profiles/status-report/StatusReportProfile.h>
4748
#include <Weave/Profiles/token-pairing/TokenPairing.h>
@@ -620,15 +621,39 @@ class NL_DLL_EXPORT WeaveDeviceManager : private Security::CASE::WeaveCASEAuthDe
620621
static WEAVE_ERROR DecodeStatusReport(PacketBuffer *msgBuf, DeviceStatus& status);
621622
static WEAVE_ERROR DecodeNetworkInfoList(PacketBuffer *buf, uint16_t& count, NetworkInfo *& netInfoList);
622623

623-
// CASE auth delegate methods
624-
virtual WEAVE_ERROR GetNodeCertInfo(bool isInitiator, uint8_t *buf, uint16_t bufSize, uint16_t& certInfoLen);
625-
virtual WEAVE_ERROR GetNodePrivateKey(bool isInitiator, const uint8_t *& weavePrivKey, uint16_t& weavePrivKeyLen);
626-
virtual WEAVE_ERROR ReleaseNodePrivateKey(const uint8_t *weavePrivKey);
627-
virtual WEAVE_ERROR GetNodePayload(bool isInitiator, uint8_t *buf, uint16_t bufSize, uint16_t& payloadLen);
628-
virtual WEAVE_ERROR BeginCertValidation(bool isInitiator, Security::WeaveCertificateSet& certSet, Security::ValidationContext& validContext);
629-
virtual WEAVE_ERROR HandleCertValidationResult(bool isInitiator, WEAVE_ERROR& validRes, Security::WeaveCertificateData *peerCert,
624+
#if !WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE
625+
626+
// ===== Methods that implement the WeaveCASEAuthDelegate interface
627+
628+
WEAVE_ERROR EncodeNodeCertInfo(const Security::CASE::BeginSessionContext & msgCtx, TLVWriter & writer) __OVERRIDE;
629+
WEAVE_ERROR GenerateNodeSignature(const Security::CASE::BeginSessionContext & msgCtx,
630+
const uint8_t * msgHash, uint8_t msgHashLen,
631+
TLVWriter & writer, uint64_t tag) __OVERRIDE;
632+
WEAVE_ERROR EncodeNodePayload(const Security::CASE::BeginSessionContext & msgCtx,
633+
uint8_t * payloadBuf, uint16_t payloadBufSize, uint16_t & payloadLen) __OVERRIDE;
634+
WEAVE_ERROR BeginValidation(const Security::CASE::BeginSessionContext & msgCtx, Security::ValidationContext & validCtx,
635+
Security::WeaveCertificateSet & certSet) __OVERRIDE;
636+
WEAVE_ERROR HandleValidationResult(const Security::CASE::BeginSessionContext & msgCtx, Security::ValidationContext & validCtx,
637+
Security::WeaveCertificateSet & certSet, WEAVE_ERROR & validRes) __OVERRIDE;
638+
void EndValidation(const Security::CASE::BeginSessionContext & msgCtx, Security::ValidationContext & validCtx,
639+
Security::WeaveCertificateSet & certSet) __OVERRIDE;
640+
641+
#else // !WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE
642+
643+
// ===== Methods that implement the legacy WeaveCASEAuthDelegate interface
644+
645+
WEAVE_ERROR GetNodeCertInfo(bool isInitiator, uint8_t *buf, uint16_t bufSize, uint16_t& certInfoLen) __OVERRIDE;
646+
WEAVE_ERROR GetNodePayload(bool isInitiator, uint8_t *buf, uint16_t bufSize, uint16_t& payloadLen) __OVERRIDE;
647+
648+
#endif // WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE
649+
650+
WEAVE_ERROR GetNodePrivateKey(bool isInitiator, const uint8_t *& weavePrivKey, uint16_t& weavePrivKeyLen);
651+
WEAVE_ERROR ReleaseNodePrivateKey(const uint8_t *weavePrivKey);
652+
WEAVE_ERROR BeginCertValidation(bool isInitiator, Security::WeaveCertificateSet& certSet,
653+
Security::ValidationContext& validContext);
654+
WEAVE_ERROR HandleCertValidationResult(bool isInitiator, WEAVE_ERROR& validRes, Security::WeaveCertificateData *peerCert,
630655
uint64_t peerNodeId, Security::WeaveCertificateSet& certSet, Security::ValidationContext& validContext);
631-
virtual WEAVE_ERROR EndCertValidation(Security::WeaveCertificateSet& certSet, Security::ValidationContext& validContext);
656+
WEAVE_ERROR EndCertValidation(Security::WeaveCertificateSet& certSet, Security::ValidationContext& validContext);
632657

633658
// Locale
634659
static void WriteLocaleRequest(nl::Weave::TLV::TLVWriter &aWriter, void *ctx);

src/lib/core/WeaveConfig.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,16 @@
14441444
#endif
14451445
#endif // WEAVE_CONFIG_DEFAULT_CASE_ALLOWED_CURVES
14461446

1447+
/**
1448+
* @def WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE
1449+
*
1450+
* @brief
1451+
* Enable use of the legacy WeaveCASEAuthDelegate interface.
1452+
*/
1453+
#ifndef WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE
1454+
#define WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE 1
1455+
#endif
1456+
14471457
/**
14481458
* @def WEAVE_CONFIG_MAX_SHARED_SESSIONS_END_NODES
14491459
*

src/lib/core/WeaveFabricState.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ enum
145145
* WeaveAuthMode includes a set of pre-defined values describing common
146146
* authentication modes. These are broken down by the key agreement mechanism
147147
* (CASE, PASE, GroupKey, etc.). Developers can extend WeaveAuthMode by defining
148-
* application-specific mode, which they can attach to specific encryption keys.
148+
* application-specific modes, which they can attach to specific encryption keys.
149149
*
150150
* @note WeaveAuthMode is an API data type only; it should never be sent over-the-wire.
151151
*/

src/lib/core/WeaveSecurityMgr.cpp

Lines changed: 62 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,29 +1055,34 @@ WEAVE_ERROR WeaveSecurityManager::StartCASESession(WeaveConnection *con, uint64_
10551055

10561056
void WeaveSecurityManager::StartCASESession(uint32_t config, uint32_t curveId)
10571057
{
1058-
WEAVE_ERROR err;
1059-
CASE::BeginSessionRequestMessage req;
1060-
PacketBuffer* msgBuf = NULL;
1061-
uint16_t sendFlags = 0;
1058+
WEAVE_ERROR err;
1059+
PacketBuffer * msgBuf = NULL;
1060+
uint16_t sendFlags = 0;
10621061

10631062
// Allocate a buffer to hold the Begin Session message.
10641063
msgBuf = PacketBuffer::New();
10651064
VerifyOrExit(msgBuf != NULL, err = WEAVE_ERROR_NO_MEMORY);
10661065

10671066
// Generate the CASE Begin Session message.
1068-
req.Reset();
1069-
req.PeerNodeId = mEC->PeerNodeId;
1070-
req.ProtocolConfig = config;
1071-
mCASEEngine->SetAlternateConfigs(req);
1072-
req.CurveId = curveId;
1073-
mCASEEngine->SetAlternateCurves(req);
1074-
req.PerformKeyConfirm = true;
1075-
req.SessionKeyId = mSessionKeyId;
1076-
req.EncryptionType = mEncType;
1077-
Platform::Security::OnTimeConsumingCryptoStart();
1078-
err = mCASEEngine->GenerateBeginSessionRequest(req, msgBuf);
1079-
Platform::Security::OnTimeConsumingCryptoDone();
1080-
SuccessOrExit(err);
1067+
{
1068+
CASE::BeginSessionRequestContext reqCtx;
1069+
1070+
reqCtx.Reset();
1071+
reqCtx.SetIsInitiator(true);
1072+
reqCtx.PeerNodeId = mEC->PeerNodeId;
1073+
reqCtx.ProtocolConfig = config;
1074+
mCASEEngine->SetAlternateConfigs(reqCtx);
1075+
reqCtx.CurveId = curveId;
1076+
mCASEEngine->SetAlternateCurves(reqCtx);
1077+
reqCtx.SetPerformKeyConfirm(true);
1078+
reqCtx.SessionKeyId = mSessionKeyId;
1079+
reqCtx.EncryptionType = mEncType;
1080+
1081+
Platform::Security::OnTimeConsumingCryptoStart();
1082+
err = mCASEEngine->GenerateBeginSessionRequest(reqCtx, msgBuf);
1083+
Platform::Security::OnTimeConsumingCryptoDone();
1084+
SuccessOrExit(err);
1085+
}
10811086

10821087
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
10831088
if (mCon == NULL)
@@ -1133,12 +1138,15 @@ void WeaveSecurityManager::HandleCASEMessageInitiator(ExchangeContext *ec, const
11331138

11341139
// Decode and process the BeginSessionResponse.
11351140
{
1136-
CASE::BeginSessionResponseMessage resp;
1137-
resp.Reset();
1138-
resp.PeerNodeId = ec->PeerNodeId;
1141+
CASE::BeginSessionResponseContext respCtx;
1142+
1143+
respCtx.Reset();
1144+
respCtx.SetIsInitiator(true);
1145+
respCtx.PeerNodeId = ec->PeerNodeId;
1146+
respCtx.MsgInfo = msgInfo;
11391147

11401148
Platform::Security::OnTimeConsumingCryptoStart();
1141-
err = secMgr->mCASEEngine->ProcessBeginSessionResponse(msgBuf, resp);
1149+
err = secMgr->mCASEEngine->ProcessBeginSessionResponse(msgBuf, respCtx);
11421150
Platform::Security::OnTimeConsumingCryptoDone();
11431151
SuccessOrExit(err);
11441152
}
@@ -1193,8 +1201,8 @@ void WeaveSecurityManager::HandleCASEMessageInitiator(ExchangeContext *ec, const
11931201
{
11941202
// Process the reconfigure message. If this proposed alternate configuration is not acceptable,
11951203
// the call will fail with an error.
1196-
CASE::ReconfigureMessage reconfMsg;
1197-
err = secMgr->mCASEEngine->ProcessReconfigure(msgBuf, reconfMsg);
1204+
CASE::ReconfigureContext reconfCtx;
1205+
err = secMgr->mCASEEngine->ProcessReconfigure(msgBuf, reconfCtx);
11981206
SuccessOrExit(err);
11991207

12001208
// Release the buffer containing the response.
@@ -1208,7 +1216,7 @@ void WeaveSecurityManager::HandleCASEMessageInitiator(ExchangeContext *ec, const
12081216
SuccessOrExit(err);
12091217

12101218
// Restart the CASE session using the peer's propose parameters.
1211-
secMgr->StartCASESession(reconfMsg.ProtocolConfig, reconfMsg.CurveId);
1219+
secMgr->StartCASESession(reconfCtx.ProtocolConfig, reconfCtx.CurveId);
12121220
}
12131221

12141222
// Fail if the message is unrecognized.
@@ -1238,12 +1246,12 @@ WEAVE_ERROR WeaveSecurityManager::StartCASESession(WeaveConnection *con, uint64_
12381246

12391247
void WeaveSecurityManager::HandleCASESessionStart(ExchangeContext *ec, const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, PacketBuffer* msgBuf)
12401248
{
1241-
WEAVE_ERROR err;
1242-
WeaveSessionKey *sessionKey;
1243-
CASE::BeginSessionRequestMessage req;
1244-
CASE::ReconfigureMessage reconf;
1245-
PacketBuffer *respMsgBuf = NULL;
1246-
uint16_t sendFlags = 0;
1249+
WEAVE_ERROR err;
1250+
WeaveSessionKey * sessionKey;
1251+
CASE::BeginSessionRequestContext reqCtx;
1252+
CASE::ReconfigureContext reconfCtx;
1253+
PacketBuffer * respMsgBuf = NULL;
1254+
uint16_t sendFlags = 0;
12471255

12481256
State = kState_CASEInProgress;
12491257
mEC = ec;
@@ -1293,11 +1301,12 @@ void WeaveSecurityManager::HandleCASESessionStart(ExchangeContext *ec, const IPP
12931301
#endif
12941302

12951303
// Process the BeginSessionRequest
1296-
req.Reset();
1297-
req.PeerNodeId = ec->PeerNodeId;
1298-
reconf.Reset();
1304+
reqCtx.Reset();
1305+
reqCtx.PeerNodeId = ec->PeerNodeId;
1306+
reqCtx.MsgInfo = msgInfo;
1307+
reconfCtx.Reset();
12991308
Platform::Security::OnTimeConsumingCryptoStart();
1300-
err = mCASEEngine->ProcessBeginSessionRequest(msgBuf, req, reconf);
1309+
err = mCASEEngine->ProcessBeginSessionRequest(msgBuf, reqCtx, reconfCtx);
13011310
Platform::Security::OnTimeConsumingCryptoDone();
13021311
if (err != WEAVE_ERROR_CASE_RECONFIG_REQUIRED)
13031312
SuccessOrExit(err);
@@ -1312,7 +1321,7 @@ void WeaveSecurityManager::HandleCASESessionStart(ExchangeContext *ec, const IPP
13121321
// Encode a CASE Reconfigure message into a new buffer.
13131322
respMsgBuf = PacketBuffer::New();
13141323
VerifyOrExit(respMsgBuf != NULL, err = WEAVE_ERROR_NO_MEMORY);
1315-
err = reconf.Encode(respMsgBuf);
1324+
err = reconfCtx.Encode(respMsgBuf);
13161325
SuccessOrExit(err);
13171326

13181327
// Send the Reconfigure message to the peer.
@@ -1332,32 +1341,35 @@ void WeaveSecurityManager::HandleCASESessionStart(ExchangeContext *ec, const IPP
13321341
// be bound to the connection, such that when the connection closes, the key is removed.
13331342
// Set the RemoveOnIdle flag so that the session will be automatically removed after a period of
13341343
// inactivity (note that this only applies to sessions that are NOT bound to connections).
1335-
err = FabricState->AllocSessionKey(ec->PeerNodeId, req.SessionKeyId, ec->Con, sessionKey);
1344+
err = FabricState->AllocSessionKey(ec->PeerNodeId, reqCtx.SessionKeyId, ec->Con, sessionKey);
13361345
SuccessOrExit(err);
13371346
sessionKey->SetLocallyInitiated(false);
13381347
sessionKey->SetRemoveOnIdle(true);
13391348

13401349
// Save the proposed session key id and encryption type.
1341-
mSessionKeyId = req.SessionKeyId;
1342-
mEncType = req.EncryptionType;
1343-
1344-
// Prepare the contents of a BeginSessionResponse message to be sent to the initiator.
1345-
CASE::BeginSessionResponseMessage resp;
1346-
resp.Reset();
1347-
resp.PeerNodeId = ec->PeerNodeId;
1348-
resp.ProtocolConfig = req.ProtocolConfig;
1349-
resp.CurveId = req.CurveId;
1350-
resp.PerformKeyConfirm = true;
1350+
mSessionKeyId = reqCtx.SessionKeyId;
1351+
mEncType = reqCtx.EncryptionType;
13511352

13521353
// Allocate a buffer to hold the encoded BeginSessionResponse message.
13531354
respMsgBuf = PacketBuffer::New();
13541355
VerifyOrExit(respMsgBuf != NULL, err = WEAVE_ERROR_NO_MEMORY);
13551356

13561357
// Generate the BeginSessionResponse message.
1357-
Platform::Security::OnTimeConsumingCryptoStart();
1358-
err = mCASEEngine->GenerateBeginSessionResponse(resp, respMsgBuf, req);
1359-
Platform::Security::OnTimeConsumingCryptoDone();
1360-
SuccessOrExit(err);
1358+
{
1359+
CASE::BeginSessionResponseContext respCtx;
1360+
1361+
respCtx.Reset();
1362+
respCtx.PeerNodeId = ec->PeerNodeId;
1363+
respCtx.MsgInfo = msgInfo;
1364+
respCtx.ProtocolConfig = reqCtx.ProtocolConfig;
1365+
respCtx.CurveId = reqCtx.CurveId;
1366+
respCtx.SetPerformKeyConfirm(true);
1367+
1368+
Platform::Security::OnTimeConsumingCryptoStart();
1369+
err = mCASEEngine->GenerateBeginSessionResponse(respCtx, respMsgBuf, reqCtx);
1370+
Platform::Security::OnTimeConsumingCryptoDone();
1371+
SuccessOrExit(err);
1372+
}
13611373

13621374
// Send the BeginSessionResponse message to the peer.
13631375
err = ec->SendMessage(kWeaveProfile_Security, kMsgType_CASEBeginSessionResponse, respMsgBuf, sendFlags);

0 commit comments

Comments
 (0)