From ade4ad689ada096efd9fe1374dd75328ef7be9e3 Mon Sep 17 00:00:00 2001 From: Pankaj Garg Date: Thu, 20 Aug 2020 14:16:55 -0700 Subject: [PATCH] Integrate secure pairing with example app and device controller (#2230) * Fixes and cleanup in Secure Pairing class * Integrate secure pairing with example app and device controller * Fix override warning * Remove manual keys from Android wrapper * Remove pairing logs * Restyled by clang-format * Fix LGTM warning * Fix controller logs * const nodeID Co-authored-by: Restyled.io --- examples/chip-tool/main.cpp | 21 --- examples/lock-app/nrfconnect/main/Server.cpp | 18 --- examples/platform/nrf528xx/app/Server.cpp | 19 --- .../server/esp32/main/EchoServer.cpp | 17 +-- .../server/esp32/main/RendezvousSession.cpp | 101 ++++++++++++--- .../esp32/main/include/RendezvousSession.h | 16 ++- .../wifi-echo/server/esp32/main/wifi-echo.cpp | 11 +- src/controller/CHIPDeviceController.cpp | 120 +++++++++++++----- src/controller/CHIPDeviceController.h | 50 ++++++-- .../java/CHIPDeviceController-JNI.cpp | 30 +---- .../Framework/CHIP/CHIPDeviceController.mm | 25 +--- src/transport/SecurePairingSession.cpp | 10 +- src/transport/SecurePairingSession.h | 5 +- src/transport/SecureSession.cpp | 27 +--- src/transport/SecureSession.h | 16 --- src/transport/SecureSessionMgr.cpp | 79 +++++------- src/transport/SecureSessionMgr.h | 20 ++- .../tests/TestSecurePairingSession.cpp | 2 +- src/transport/tests/TestSecureSessionMgr.cpp | 60 +++++---- 19 files changed, 333 insertions(+), 314 deletions(-) diff --git a/examples/chip-tool/main.cpp b/examples/chip-tool/main.cpp index 164ad1436e01ab..7031e6b5034bff 100644 --- a/examples/chip-tool/main.cpp +++ b/examples/chip-tool/main.cpp @@ -60,16 +60,6 @@ constexpr NodeId kLocalDeviceId = 112233; constexpr NodeId kRemoteDeviceId = 12344321; constexpr std::chrono::seconds kWaitingForResponseTimeout(1); -static const unsigned char local_private_key[] = { 0x00, 0xd1, 0x90, 0xd9, 0xb3, 0x95, 0x1c, 0x5f, 0xa4, 0xe7, 0x47, - 0x92, 0x5b, 0x0a, 0xa9, 0xa7, 0xc1, 0x1c, 0xe7, 0x06, 0x10, 0xe2, - 0xdd, 0x16, 0x41, 0x52, 0x55, 0xb7, 0xb8, 0x80, 0x8d, 0x87, 0xa1 }; - -static const unsigned char remote_public_key[] = { 0x04, 0xe2, 0x07, 0x64, 0xff, 0x6f, 0x6a, 0x91, 0xd9, 0xc2, 0xc3, 0x0a, 0xc4, - 0x3c, 0x56, 0x4b, 0x42, 0x8a, 0xf3, 0xb4, 0x49, 0x29, 0x39, 0x95, 0xa2, 0xf7, - 0x02, 0x8c, 0xa5, 0xce, 0xf3, 0xc9, 0xca, 0x24, 0xc5, 0xd4, 0x5c, 0x60, 0x79, - 0x48, 0x30, 0x3c, 0x53, 0x86, 0xd9, 0x23, 0xe6, 0x61, 0x1f, 0x5a, 0x3d, 0xdf, - 0x9f, 0xdc, 0x35, 0xea, 0xd0, 0xde, 0x16, 0x7e, 0x64, 0xde, 0x7f, 0x3c, 0xa6 }; - static const char * PAYLOAD = "Message from Standalone CHIP echo client!"; bool isDeviceConnected = false; static bool waitingForResponse = true; @@ -79,17 +69,6 @@ static void OnConnect(DeviceController::ChipDeviceController * controller, Trans void * appReqState) { isDeviceConnected = true; - - if (state != NULL) - { - CHIP_ERROR err = controller->ManualKeyExchange(state, remote_public_key, sizeof(remote_public_key), local_private_key, - sizeof(local_private_key)); - - if (err != CHIP_NO_ERROR) - { - fprintf(stderr, "Failed to exchange keys\n"); - } - } } static bool ContentMayBeADataModelMessage(System::PacketBuffer * buffer) diff --git a/examples/lock-app/nrfconnect/main/Server.cpp b/examples/lock-app/nrfconnect/main/Server.cpp index 5086630b703018..7912829fefbfc7 100644 --- a/examples/lock-app/nrfconnect/main/Server.cpp +++ b/examples/lock-app/nrfconnect/main/Server.cpp @@ -50,16 +50,6 @@ namespace { #define EXAMPLE_SERVER_NODEID 0x3546526e #endif // EXAMPLE_SERVER_NODEID -const uint8_t local_private_key[] = { 0xc6, 0x1a, 0x2f, 0x89, 0x36, 0x67, 0x2b, 0x26, 0x12, 0x47, 0x4f, - 0x11, 0x0e, 0x34, 0x15, 0x81, 0x81, 0x12, 0xfc, 0x36, 0xeb, 0x65, - 0x61, 0x07, 0xaa, 0x63, 0xe8, 0xc5, 0x22, 0xac, 0x52, 0xa1 }; - -const uint8_t remote_public_key[] = { 0x04, 0x30, 0x77, 0x2c, 0xe7, 0xd4, 0x0a, 0xf2, 0xf3, 0x19, 0xbd, 0xfb, 0x1f, - 0xcc, 0x88, 0xd9, 0x83, 0x25, 0x89, 0xf2, 0x09, 0xf3, 0xab, 0xe4, 0x33, 0xb6, - 0x7a, 0xff, 0x73, 0x3b, 0x01, 0x35, 0x34, 0x92, 0x73, 0x14, 0x59, 0x0b, 0xbd, - 0x44, 0x72, 0x1b, 0xcd, 0xb9, 0x02, 0x53, 0xd9, 0xaf, 0xcc, 0x1a, 0xcd, 0xae, - 0xe8, 0x87, 0x2e, 0x52, 0x3b, 0x98, 0xf0, 0xa1, 0x88, 0x4a, 0xe3, 0x03, 0x75 }; - class ServerCallback : public SecureSessionMgrCallback { public: @@ -93,15 +83,7 @@ class ServerCallback : public SecureSessionMgrCallback void OnNewConnection(Transport::PeerConnectionState * state, SecureSessionMgrBase * mgr) override { - CHIP_ERROR err; - LOG_INF("Received a new connection."); - - err = state->GetSecureSession().TemporaryManualKeyExchange(remote_public_key, sizeof(remote_public_key), local_private_key, - sizeof(local_private_key)); - - if (err != CHIP_NO_ERROR) - LOG_INF("Failed to setup encryption"); } private: diff --git a/examples/platform/nrf528xx/app/Server.cpp b/examples/platform/nrf528xx/app/Server.cpp index 6ba9df994c4f5f..4099e1b7a6d4c8 100644 --- a/examples/platform/nrf528xx/app/Server.cpp +++ b/examples/platform/nrf528xx/app/Server.cpp @@ -68,16 +68,6 @@ namespace { char deviceName[128]; constexpr uint16_t kUDPBroadcastPort = 23367; -const uint8_t local_private_key[] = { 0xc6, 0x1a, 0x2f, 0x89, 0x36, 0x67, 0x2b, 0x26, 0x12, 0x47, 0x4f, - 0x11, 0x0e, 0x34, 0x15, 0x81, 0x81, 0x12, 0xfc, 0x36, 0xeb, 0x65, - 0x61, 0x07, 0xaa, 0x63, 0xe8, 0xc5, 0x22, 0xac, 0x52, 0xa1 }; - -const uint8_t remote_public_key[] = { 0x04, 0x30, 0x77, 0x2c, 0xe7, 0xd4, 0x0a, 0xf2, 0xf3, 0x19, 0xbd, 0xfb, 0x1f, - 0xcc, 0x88, 0xd9, 0x83, 0x25, 0x89, 0xf2, 0x09, 0xf3, 0xab, 0xe4, 0x33, 0xb6, - 0x7a, 0xff, 0x73, 0x3b, 0x01, 0x35, 0x34, 0x92, 0x73, 0x14, 0x59, 0x0b, 0xbd, - 0x44, 0x72, 0x1b, 0xcd, 0xb9, 0x02, 0x53, 0xd9, 0xaf, 0xcc, 0x1a, 0xcd, 0xae, - 0xe8, 0x87, 0x2e, 0x52, 0x3b, 0x98, 0xf0, 0xa1, 0x88, 0x4a, 0xe3, 0x03, 0x75 }; - class ServerCallback : public SecureSessionMgrCallback { public: @@ -110,16 +100,7 @@ class ServerCallback : public SecureSessionMgrCallback virtual void OnNewConnection(Transport::PeerConnectionState * state, SecureSessionMgrBase * mgr) { - CHIP_ERROR err; - NRF_LOG_INFO("Received a new connection."); - - err = state->GetSecureSession().TemporaryManualKeyExchange(remote_public_key, sizeof(remote_public_key), local_private_key, - sizeof(local_private_key)); - VerifyOrExit(err == CHIP_NO_ERROR, NRF_LOG_INFO("Failed to setup encryption")); - - exit: - return; } private: diff --git a/examples/wifi-echo/server/esp32/main/EchoServer.cpp b/examples/wifi-echo/server/esp32/main/EchoServer.cpp index bb83a6310c424d..c1c4ae468b547a 100644 --- a/examples/wifi-echo/server/esp32/main/EchoServer.cpp +++ b/examples/wifi-echo/server/esp32/main/EchoServer.cpp @@ -55,7 +55,7 @@ using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::Transport; -constexpr NodeId kLocalNodeId = 12344321; +extern const NodeId kLocalNodeId = 12344321; extern LEDWidget statusLED; // In wifi-echo.cpp namespace { @@ -200,16 +200,7 @@ class EchoServerCallback : public SecureSessionMgrCallback void OnNewConnection(Transport::PeerConnectionState * state, SecureSessionMgrBase * mgr) override { - CHIP_ERROR err; - ESP_LOGI(TAG, "Received a new connection."); - - err = state->GetSecureSession().TemporaryManualKeyExchange(remote_public_key, sizeof(remote_public_key), local_private_key, - sizeof(local_private_key)); - VerifyOrExit(err == CHIP_NO_ERROR, ESP_LOGE(TAG, "Failed to setup encryption")); - - exit: - return; } private: @@ -247,6 +238,12 @@ SecureSessionMgr peerNodeId, uint16_t peerKeyId, uint16_t localKeyId, SecurePairingSession * pairing) +{ + Optional peer(Transport::Type::kUndefined); + sessions.NewPairing(peerNodeId, peer, peerKeyId, localKeyId, pairing); +} + // The echo server assumes the platform's networking has been setup already void startServer() { diff --git a/examples/wifi-echo/server/esp32/main/RendezvousSession.cpp b/examples/wifi-echo/server/esp32/main/RendezvousSession.cpp index e06364c6268824..4458d27ca50a14 100644 --- a/examples/wifi-echo/server/esp32/main/RendezvousSession.cpp +++ b/examples/wifi-echo/server/esp32/main/RendezvousSession.cpp @@ -29,11 +29,55 @@ BluetoothWidget * RendezvousSession::mVirtualLed; Ble::BLEEndPoint * RendezvousSession::mEndPoint = nullptr; -RendezvousSession::RendezvousSession(BluetoothWidget * virtualLed) +bool RendezvousSession::mPairingInProgress = false; +SecurePairingSession RendezvousSession::mPairing; + +static constexpr uint32_t kSpake2p_Iteration_Count = 50000; +static const char * kSpake2pKeyExchangeSalt = "SPAKE2P Key Exchange Salt"; + +extern void PairingComplete(Optional peerNodeId, uint16_t peerKeyId, uint16_t localKeyId, SecurePairingSession * pairing); + +RendezvousSession::RendezvousSession(BluetoothWidget * virtualLed, uint32_t setUpPINCode, NodeId myNodeId) { mVirtualLed = virtualLed; DeviceLayer::ConnectivityMgr().AddCHIPoBLEConnectionHandler(HandleConnectionOpened); + + RendezvousSession::mPairing.WaitForPairing(setUpPINCode, kSpake2p_Iteration_Count, + (const unsigned char *) kSpake2pKeyExchangeSalt, strlen(kSpake2pKeyExchangeSalt), + Optional::Value(myNodeId), 0, this); + RendezvousSession::mPairingInProgress = true; + mSetUpPINCode = setUpPINCode; + mNodeId = myNodeId; +} + +CHIP_ERROR RendezvousSession::OnNewMessageForPeer(System::PacketBuffer * buffer) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(mEndPoint, err = CHIP_ERROR_INCORRECT_STATE); + err = mEndPoint->Send(buffer); + +exit: + return err; +} + +void RendezvousSession::OnPairingError(CHIP_ERROR error) +{ + ChipLogError(Ble, "RendezvousSession: failed in pairing"); + mPaired = false; + RendezvousSession::mPairing.WaitForPairing(mSetUpPINCode, kSpake2p_Iteration_Count, + (const unsigned char *) kSpake2pKeyExchangeSalt, strlen(kSpake2pKeyExchangeSalt), + Optional::Value(mNodeId), 0, this); + RendezvousSession::mPairingInProgress = true; +} + +void RendezvousSession::OnPairingComplete(Optional peerNodeId, uint16_t peerKeyId, uint16_t localKeyId) +{ + ChipLogProgress(Ble, "RendezvousSession: pairing complete"); + mPaired = true; + RendezvousSession::mPairingInProgress = false; + PairingComplete(peerNodeId, peerKeyId, localKeyId, &RendezvousSession::mPairing); } CHIP_ERROR RendezvousSession::Send(const char * msg) @@ -74,32 +118,49 @@ void RendezvousSession::HandleConnectionClosed(Ble::BLEEndPoint * endPoint, BLE_ void RendezvousSession::HandleMessageReceived(Ble::BLEEndPoint * endPoint, PacketBuffer * buffer) { - const size_t bufferLen = buffer->DataLength(); - char msg[bufferLen]; - msg[bufferLen] = 0; - memcpy(msg, buffer->Start(), bufferLen); + if (RendezvousSession::mPairingInProgress) + { + MessageHeader header; + size_t headerSize = 0; - ChipLogProgress(Ble, "RendezvousSession: Receive message: %s", msg); + CHIP_ERROR err = header.Decode(buffer->Start(), buffer->DataLength(), &headerSize); + SuccessOrExit(err); - if ((bufferLen > 3) && (msg[0] == msg[1]) && (msg[0] == msg[bufferLen - 1])) + buffer->ConsumeHead(headerSize); + RendezvousSession::mPairing.HandlePeerMessage(header, buffer); + } + else { - // WiFi credentials, of the form ‘::SSID:password:’, where ‘:’ can be any single ASCII character. - msg[1] = 0; - char * ssid = strtok(&msg[2], msg); - char * key = strtok(NULL, msg); - if (ssid && key) + const size_t bufferLen = buffer->DataLength(); + char msg[bufferLen]; + msg[bufferLen] = 0; + memcpy(msg, buffer->Start(), bufferLen); + + ChipLogProgress(Ble, "RendezvousSession: Receive message: %s", msg); + + if ((bufferLen > 3) && (msg[0] == msg[1]) && (msg[0] == msg[bufferLen - 1])) { - ChipLogProgress(Ble, "RendezvousSession: SSID: %s, key: %s", ssid, key); - SetWiFiStationProvisioning(ssid, key); + // WiFi credentials, of the form ‘::SSID:password:’, where ‘:’ can be any single ASCII character. + msg[1] = 0; + char * ssid = strtok(&msg[2], msg); + char * key = strtok(NULL, msg); + if (ssid && key) + { + ChipLogProgress(Ble, "RendezvousSession: SSID: %s, key: %s", ssid, key); + SetWiFiStationProvisioning(ssid, key); + } + else + { + ChipLogError(Ble, "RendezvousSession: SSID: %p, key: %p", ssid, key); + } } else { - ChipLogError(Ble, "RendezvousSession: SSID: %p, key: %p", ssid, key); + // Echo. + mEndPoint->Send(buffer); } } - else - { - // Echo. - mEndPoint->Send(buffer); - } + +exit: + return; } diff --git a/examples/wifi-echo/server/esp32/main/include/RendezvousSession.h b/examples/wifi-echo/server/esp32/main/include/RendezvousSession.h index fa56bf88b6c8b0..536d3ec6239f59 100644 --- a/examples/wifi-echo/server/esp32/main/include/RendezvousSession.h +++ b/examples/wifi-echo/server/esp32/main/include/RendezvousSession.h @@ -18,13 +18,14 @@ #include "BluetoothWidget.h" #include +#include using namespace ::chip; -class RendezvousSession +class RendezvousSession : public SecurePairingSessionDelegate { public: - RendezvousSession(BluetoothWidget * virtualLed); + RendezvousSession(BluetoothWidget * virtualLed, uint32_t setUpPINCode, NodeId myNodeId); CHIP_ERROR Send(const char * msg); private: @@ -32,6 +33,17 @@ class RendezvousSession static void HandleConnectionClosed(Ble::BLEEndPoint * endPoint, BLE_ERROR err); static void HandleMessageReceived(Ble::BLEEndPoint * endPoint, System::PacketBuffer * buffer); + virtual CHIP_ERROR OnNewMessageForPeer(System::PacketBuffer * msgBuf); + virtual void OnPairingError(CHIP_ERROR error); + virtual void OnPairingComplete(Optional peerNodeId, uint16_t peerKeyId, uint16_t localKeyId); + static BluetoothWidget * mVirtualLed; static Ble::BLEEndPoint * mEndPoint; + + static SecurePairingSession mPairing; + static bool mPairingInProgress; + + bool mPaired = false; + uint32_t mSetUpPINCode = 0; + NodeId mNodeId; }; diff --git a/examples/wifi-echo/server/esp32/main/wifi-echo.cpp b/examples/wifi-echo/server/esp32/main/wifi-echo.cpp index 07312d77e27420..9c9ab5c6a5fdde 100644 --- a/examples/wifi-echo/server/esp32/main/wifi-echo.cpp +++ b/examples/wifi-echo/server/esp32/main/wifi-echo.cpp @@ -102,6 +102,8 @@ LEDWidget statusLED; BluetoothWidget bluetoothLED; WiFiWidget wifiLED; +extern NodeId kLocalNodeId; + const char * TAG = "wifi-echo-demo"; static EchoDeviceCallbacks EchoCallbacks; @@ -463,7 +465,14 @@ extern "C" void app_main() if (isRendezvousBLE()) { - rendezvousSession = new RendezvousSession(&bluetoothLED); + uint32_t setupPINCode; + err = ConfigurationMgr().GetSetupPinCode(setupPINCode); + if (err != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "GetSetupPinCode() failed: %s", ErrorStr(err)); + return; + } + rendezvousSession = new RendezvousSession(&bluetoothLED, setupPINCode, kLocalNodeId); } #if CONFIG_USE_ECHO_CLIENT diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index fbe6240a48423b..1ff36d882e1e89 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -53,6 +53,9 @@ namespace DeviceController { using namespace chip::Encoding; +static constexpr uint32_t kSpake2p_Iteration_Count = 50000; +static const char * kSpake2pKeyExchangeSalt = "SPAKE2P Key Exchange Salt"; + ChipDeviceController::ChipDeviceController() { mState = kState_NotInitialized; @@ -146,6 +149,72 @@ CHIP_ERROR ChipDeviceController::Shutdown() return err; } +CHIP_ERROR ChipDeviceController::OnNewMessageForPeer(System::PacketBuffer * msgBuf) +{ + return SendMessage(mAppReqState, msgBuf); +} + +void ChipDeviceController::OnPairingError(CHIP_ERROR error) +{ + ChipLogError(Controller, "Failed to pair with accessory. Error %d", error); + mPairingInProgress = false; + + if (mOnError != nullptr) + { + mOnError(this, mAppReqState, error, nullptr); + } +} + +void ChipDeviceController::OnPairingComplete(Optional peerNodeId, uint16_t peerKeyId, uint16_t localKeyId) +{ + ChipLogProgress(Controller, "Successfully paired with accessory. Key Id %d", peerKeyId); + mPairingInProgress = false; + + if (mPairingComplete != nullptr) + { + mPeerKeyId = peerKeyId; + mLocalPairedKeyId = localKeyId; + ChipLogProgress(Controller, "Calling mPairingComplete"); + mPairingComplete(this, nullptr, mAppReqState); + } +} + +void ChipDeviceController::PairingMessageHandler(ChipDeviceController * controller, void * appReqState, + System::PacketBuffer * payload) +{ + if (controller->mPairingInProgress) + { + MessageHeader header; + size_t headerSize = 0; + CHIP_ERROR err = header.Decode(payload->Start(), payload->DataLength(), &headerSize); + SuccessOrExit(err); + + payload->ConsumeHead(headerSize); + controller->mPairingSession.HandlePeerMessage(header, payload); + } + else if (controller->mAppMsgHandler != nullptr) + { + controller->mAppMsgHandler(controller, appReqState, payload); + } + +exit: + return; +} + +void ChipDeviceController::BLEConnectionHandler(ChipDeviceController * controller, Transport::PeerConnectionState * state, + void * appReqState) +{ + ChipLogProgress(Controller, "Starting pairing session"); + controller->mPairingInProgress = true; + CHIP_ERROR err = controller->mPairingSession.Pair( + controller->mSetupPINCode, kSpake2p_Iteration_Count, (const unsigned char *) kSpake2pKeyExchangeSalt, + strlen(kSpake2pKeyExchangeSalt), Optional::Value(controller->mLocalDeviceId), controller->mNextKeyId++, controller); + SuccessOrExit(err); + +exit: + return; +} + CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, const uint16_t discriminator, const uint32_t setupPINCode, void * appReqState, NewConnectionHandler onConnected, MessageReceiveHandler onMessageReceived, ErrorHandler onError) @@ -155,11 +224,22 @@ CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, const uint #if CONFIG_DEVICE_LAYER && CONFIG_NETWORK_LAYER_BLE Transport::BLE * transport; + ChipLogProgress(Controller, "Received new pairing request"); + ChipLogProgress(Controller, "mState %d. mConState %d", mState, mConState); VerifyOrExit(mState == kState_Initialized && mConState == kConnectionState_NotConnected, err = CHIP_ERROR_INCORRECT_STATE); + if (mPairingInProgress) + { + ChipLogError(Controller, "Pairing was already is progress. This will restart pairing."); + } + mRemoteDeviceId = Optional::Value(remoteDeviceId); mAppReqState = appReqState; - mOnNewConnection = onConnected; + mPairingComplete = onConnected; + mOnNewConnection = BLEConnectionHandler; + mAppMsgHandler = onMessageReceived; + + mSetupPINCode = setupPINCode; transport = new Transport::BLE(); err = transport->Init(Transport::BleConnectionParameters(this, DeviceLayer::ConnectivityMgr().GetBleLayer()) @@ -172,7 +252,7 @@ CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, const uint // connected state before 'OnConnect' mConState = kConnectionState_Connected; - mOnComplete.Response = onMessageReceived; + mOnComplete.Response = PairingMessageHandler; mOnError = onError; if (err != CHIP_NO_ERROR) @@ -214,15 +294,16 @@ CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, IPAddress mSessionManager->SetDelegate(this); - // connected state before 'OnConnect' so that key exchange is accepted - mConState = kConnectionState_Connected; - - err = mSessionManager->Connect(remoteDeviceId, Transport::PeerAddress::UDP(deviceAddr, devicePort)); - SuccessOrExit(err); + mConState = kConnectionState_SecureConnected; mOnComplete.Response = onMessageReceived; mOnError = onError; + err = mSessionManager->NewPairing(mRemoteDeviceId, + Optional::Value(Transport::PeerAddress::UDP(deviceAddr, devicePort)), + mPeerKeyId, mLocalPairedKeyId, &mPairingSession); + SuccessOrExit(err); + mMessageNumber = 1; exit: @@ -239,26 +320,6 @@ CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, IPAddress return err; } -CHIP_ERROR ChipDeviceController::ManualKeyExchange(Transport::PeerConnectionState * state, const unsigned char * remote_public_key, - const size_t public_key_length, const unsigned char * local_private_key, - const size_t private_key_length) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - if (!IsConnected() || mSessionManager == NULL) - { - return CHIP_ERROR_INCORRECT_STATE; - } - - err = state->GetSecureSession().TemporaryManualKeyExchange(remote_public_key, public_key_length, local_private_key, - private_key_length); - SuccessOrExit(err); - mConState = kConnectionState_SecureConnected; - -exit: - return err; -} - CHIP_ERROR ChipDeviceController::PopulatePeerAddress(Transport::PeerAddress & peerAddress) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -376,10 +437,7 @@ void ChipDeviceController::ClearRequestState() } } -void ChipDeviceController::OnNewConnection(Transport::PeerConnectionState * state, SecureSessionMgrBase * mgr) -{ - mOnNewConnection(this, state, mAppReqState); -} +void ChipDeviceController::OnNewConnection(Transport::PeerConnectionState * state, SecureSessionMgrBase * mgr) {} void ChipDeviceController::OnMessageReceived(const MessageHeader & header, Transport::PeerConnectionState * state, System::PacketBuffer * msgBuf, SecureSessionMgrBase * mgr) diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 2d290bfff13a51..624aa72d0ddff6 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -50,7 +51,9 @@ typedef void (*ErrorHandler)(ChipDeviceController * deviceController, void * app typedef void (*MessageReceiveHandler)(ChipDeviceController * deviceController, void * appReqState, System::PacketBuffer * payload); }; -class DLL_EXPORT ChipDeviceController : public SecureSessionMgrCallback, public Transport::BLECallbackHandler +class DLL_EXPORT ChipDeviceController : public SecureSessionMgrCallback, + public SecurePairingSessionDelegate, + public Transport::BLECallbackHandler { friend class ChipDeviceControllerCallback; @@ -105,20 +108,26 @@ class DLL_EXPORT ChipDeviceController : public SecureSessionMgrCallback, public /** * @brief - * The keypair for the secure channel. This is a utility function that will be used - * until we have automatic key exchange in place. The function is useful only for - * example applications for now. It will eventually be removed. + * Called when pairing session generates a new message that should be sent to peer. * - * @param state Peer connection for which to establish the key - * @param remote_public_key A pointer to peer's public key - * @param public_key_length Length of remote_public_key - * @param local_private_key A pointer to local private key - * @param private_key_length Length of local_private_key - * @return CHIP_ERROR The result of key derivation + * @param msgBuf the new message that should be sent to the peer */ - CHIP_ERROR ManualKeyExchange(Transport::PeerConnectionState * state, const unsigned char * remote_public_key, - const size_t public_key_length, const unsigned char * local_private_key, - const size_t private_key_length); + virtual CHIP_ERROR OnNewMessageForPeer(System::PacketBuffer * msgBuf) override; + + /** + * @brief + * Called when pairing fails with an error + * + * @param error error code + */ + virtual void OnPairingError(CHIP_ERROR error) override; + + /** + * @brief + * Called when the pairing is complete and the new secure session has been established + * + */ + virtual void OnPairingComplete(Optional peerNodeId, uint16_t peerKeyId, uint16_t localKeyId) override; /** * @brief @@ -226,6 +235,8 @@ class DLL_EXPORT ChipDeviceController : public SecureSessionMgrCallback, public ErrorHandler mOnError; NewConnectionHandler mOnNewConnection; + NewConnectionHandler mPairingComplete = nullptr; + MessageReceiveHandler mAppMsgHandler = nullptr; System::PacketBuffer * mCurReqMsg; NodeId mLocalDeviceId; @@ -234,8 +245,21 @@ class DLL_EXPORT ChipDeviceController : public SecureSessionMgrCallback, public Optional mRemoteDeviceId; uint32_t mMessageNumber = 0; + SecurePairingSession mPairingSession; + uint16_t mNextKeyId = 0; + bool mPairingInProgress = false; + + uint32_t mSetupPINCode = 0; + uint16_t mPeerKeyId = 0; + uint16_t mLocalPairedKeyId = 0; + void ClearRequestState(); void ClearOpState(); + + static void PairingMessageHandler(ChipDeviceController * deviceController, void * appReqState, System::PacketBuffer * payload); + + static void BLEConnectionHandler(ChipDeviceController * deviceController, Transport::PeerConnectionState * state, + void * appReqState); }; } // namespace DeviceController diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 67fbc260867488..b8b912f66ab0ca 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -80,16 +80,6 @@ static jclass sChipDeviceControllerExceptionCls = NULL; chip::NodeId kLocalDeviceId = 112233; chip::NodeId kRemoteDeviceId = 12344321; -static const unsigned char local_private_key[] = { 0x00, 0xd1, 0x90, 0xd9, 0xb3, 0x95, 0x1c, 0x5f, 0xa4, 0xe7, 0x47, - 0x92, 0x5b, 0x0a, 0xa9, 0xa7, 0xc1, 0x1c, 0xe7, 0x06, 0x10, 0xe2, - 0xdd, 0x16, 0x41, 0x52, 0x55, 0xb7, 0xb8, 0x80, 0x8d, 0x87, 0xa1 }; - -static const unsigned char remote_public_key[] = { 0x04, 0xe2, 0x07, 0x64, 0xff, 0x6f, 0x6a, 0x91, 0xd9, 0xc2, 0xc3, 0x0a, 0xc4, - 0x3c, 0x56, 0x4b, 0x42, 0x8a, 0xf3, 0xb4, 0x49, 0x29, 0x39, 0x95, 0xa2, 0xf7, - 0x02, 0x8c, 0xa5, 0xce, 0xf3, 0xc9, 0xca, 0x24, 0xc5, 0xd4, 0x5c, 0x60, 0x79, - 0x48, 0x30, 0x3c, 0x53, 0x86, 0xd9, 0x23, 0xe6, 0x61, 0x1f, 0x5a, 0x3d, 0xdf, - 0x9f, 0xdc, 0x35, 0xea, 0xd0, 0xde, 0x16, 0x7e, 0x64, 0xde, 0x7f, 0x3c, 0xa6 }; - jint JNI_OnLoad(JavaVM * jvm, void * reserved) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -412,25 +402,7 @@ void HandleSimpleOperationComplete(ChipDeviceController * deviceController, void env->ExceptionClear(); } -void HandleKeyExchange(ChipDeviceController * deviceController, Transport::PeerConnectionState * state, void * appReqState) -{ - JNIEnv * env; - - sJVM->GetEnv((void **) &env, JNI_VERSION_1_6); - - CHIP_ERROR err = deviceController->ManualKeyExchange(state, remote_public_key, sizeof(remote_public_key), local_private_key, - sizeof(local_private_key)); - - if (err != CHIP_NO_ERROR) - { - ChipLogError(Controller, "Failed to exchange keys"); - ThrowError(env, err); - } - else - { - HandleSimpleOperationComplete(deviceController, appReqState); - } -} +void HandleKeyExchange(ChipDeviceController * deviceController, Transport::PeerConnectionState * state, void * appReqState) {} void HandleEchoResponse(ChipDeviceController * deviceController, void * appReqState, System::PacketBuffer * payload) { diff --git a/src/darwin/Framework/CHIP/CHIPDeviceController.mm b/src/darwin/Framework/CHIP/CHIPDeviceController.mm index be79df336318aa..0c84c14c714038 100644 --- a/src/darwin/Framework/CHIP/CHIPDeviceController.mm +++ b/src/darwin/Framework/CHIP/CHIPDeviceController.mm @@ -115,13 +115,6 @@ static void onConnected( [controller _dispatchAsyncConnectBlock]; } -static void doKeyExchange( - chip::DeviceController::ChipDeviceController * cppController, chip::Transport::PeerConnectionState * state, void * appReqState) -{ - CHIPDeviceController * controller = (__bridge CHIPDeviceController *) appReqState; - [controller _manualKeyExchange:state]; -} - static void onMessageReceived( chip::DeviceController::ChipDeviceController * deviceController, void * appReqState, chip::System::PacketBuffer * buffer) { @@ -188,22 +181,6 @@ - (void)_dispatchAsyncConnectBlock } } -- (void)_manualKeyExchange:(chip::Transport::PeerConnectionState *)state -{ - [self.lock lock]; - const unsigned char * local_key_bytes = (const unsigned char *) [self.localKey bytes]; - const unsigned char * peer_key_bytes = (const unsigned char *) [self.peerKey bytes]; - - CHIP_ERROR err - = self.cppController->ManualKeyExchange(state, peer_key_bytes, self.peerKey.length, local_key_bytes, self.localKey.length); - [self.lock unlock]; - - if (err != CHIP_NO_ERROR) { - CHIP_LOG_ERROR("Failed to exchange keys"); - [self _dispatchAsyncErrorBlock:[CHIPError errorForCHIPErrorCode:err]]; - } -} - - (BOOL)connect:(NSString *)ipAddress local_key:(NSData *)local_key peer_key:(NSData *)peer_key @@ -219,7 +196,7 @@ - (BOOL)connect:(NSString *)ipAddress chip::Inet::IPAddress addr; chip::Inet::IPAddress::FromString([ipAddress UTF8String], addr); err = self.cppController->ConnectDevice( - kRemoteDeviceId, addr, (__bridge void *) self, doKeyExchange, onMessageReceived, onInternalError, CHIP_PORT); + kRemoteDeviceId, addr, (__bridge void *) self, nil, onMessageReceived, onInternalError, CHIP_PORT); [self.lock unlock]; if (err != CHIP_NO_ERROR) { diff --git a/src/transport/SecurePairingSession.cpp b/src/transport/SecurePairingSession.cpp index de14e411d8e51a..d8528a0d5c3538 100644 --- a/src/transport/SecurePairingSession.cpp +++ b/src/transport/SecurePairingSession.cpp @@ -237,8 +237,8 @@ CHIP_ERROR SecurePairingSession::HandleCompute_pA(const MessageHeader & header, { BufBound bbuf(resp->Start(), Y_len + verifier_len); - VerifyOrExit(bbuf.Put(&Y[0], Y_len) == Y_len, err = CHIP_ERROR_NO_MEMORY); - VerifyOrExit(bbuf.Put(verifier, verifier_len) == Y_len + verifier_len, err = CHIP_ERROR_NO_MEMORY); + bbuf.Put(&Y[0], Y_len); + bbuf.Put(verifier, verifier_len); VerifyOrExit(bbuf.Fit(), err = CHIP_ERROR_NO_MEMORY); } @@ -289,7 +289,7 @@ CHIP_ERROR SecurePairingSession::HandleCompute_pB_cB(const MessageHeader & heade { BufBound bbuf(resp->Start(), verifier_len); - VerifyOrExit(bbuf.Put(verifier, verifier_len) == verifier_len, err = CHIP_ERROR_NO_MEMORY); + bbuf.Put(verifier, verifier_len); VerifyOrExit(bbuf.Fit(), err = CHIP_ERROR_NO_MEMORY); } @@ -313,7 +313,7 @@ CHIP_ERROR SecurePairingSession::HandleCompute_pB_cB(const MessageHeader & heade mPairingComplete = true; // Call delegate to indicate pairing completion - mDelegate->OnPairingComplete(mPeerNodeId, mPeerKeyId); + mDelegate->OnPairingComplete(mPeerNodeId, mPeerKeyId, mKeyId); exit: @@ -347,7 +347,7 @@ CHIP_ERROR SecurePairingSession::HandleCompute_cA(const MessageHeader & header, mPairingComplete = true; // Call delegate to indicate pairing completion - mDelegate->OnPairingComplete(mPeerNodeId, mPeerKeyId); + mDelegate->OnPairingComplete(mPeerNodeId, mPeerKeyId, mKeyId); exit: diff --git a/src/transport/SecurePairingSession.h b/src/transport/SecurePairingSession.h index e8c0758bafa4c9..32391a142ee499 100644 --- a/src/transport/SecurePairingSession.h +++ b/src/transport/SecurePairingSession.h @@ -64,8 +64,9 @@ class DLL_EXPORT SecurePairingSessionDelegate : public ReferenceCounted peerNodeId, uint16_t peerKeyId) {} + virtual void OnPairingComplete(Optional peerNodeId, uint16_t peerKeyId, uint16_t localKeyId) {} virtual ~SecurePairingSessionDelegate() {} }; @@ -79,7 +80,7 @@ class DLL_EXPORT SecurePairingSession SecurePairingSession & operator=(const SecurePairingSession &) = delete; SecurePairingSession & operator=(SecurePairingSession &&) = default; - ~SecurePairingSession(void); + virtual ~SecurePairingSession(void); /** * @brief diff --git a/src/transport/SecureSession.cpp b/src/transport/SecureSession.cpp index b4ce2ee768f6a5..1142df61a5f4b2 100644 --- a/src/transport/SecureSession.cpp +++ b/src/transport/SecureSession.cpp @@ -35,8 +35,6 @@ namespace chip { namespace { -const char * kManualKeyExchangeChannelInfo = "Manual Key Exchanged Channel"; - constexpr size_t kAESCCMIVLen = 12; constexpr size_t kMaxAADLen = 128; @@ -110,9 +108,8 @@ void SecureSession::Reset(void) CHIP_ERROR SecureSession::GetIV(const MessageHeader & header, uint8_t * iv, size_t len) { - CHIP_ERROR err = CHIP_NO_ERROR; - uint64_t nodeID = 0; - uint32_t messageID = 0; + CHIP_ERROR err = CHIP_NO_ERROR; + uint64_t nodeID = 0; BufBound bbuf(iv, len); @@ -123,10 +120,8 @@ CHIP_ERROR SecureSession::GetIV(const MessageHeader & header, uint8_t * iv, size nodeID = header.GetSourceNodeId().Value(); } - VerifyOrExit(bbuf.Put(&nodeID, sizeof(nodeID)) == sizeof(nodeID), err = CHIP_ERROR_NO_MEMORY); - - messageID = header.GetMessageId(); - VerifyOrExit(bbuf.Put(&messageID, sizeof(messageID)) == sizeof(nodeID) + sizeof(messageID), err = CHIP_ERROR_NO_MEMORY); + bbuf.PutLE64(nodeID); + bbuf.PutLE32(header.GetMessageId()); VerifyOrExit(bbuf.Fit(), err = CHIP_ERROR_NO_MEMORY); exit: @@ -208,18 +203,4 @@ CHIP_ERROR SecureSession::Decrypt(const unsigned char * input, size_t input_leng return error; } -CHIP_ERROR SecureSession::TemporaryManualKeyExchange(const unsigned char * remote_public_key, const size_t public_key_length, - const unsigned char * local_private_key, const size_t private_key_length) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - size_t info_len = strlen(kManualKeyExchangeChannelInfo); - - err = Init(remote_public_key, public_key_length, local_private_key, private_key_length, NULL, 0, - (const unsigned char *) kManualKeyExchangeChannelInfo, info_len); - SuccessOrExit(err); - -exit: - return err; -} - } // namespace chip diff --git a/src/transport/SecureSession.h b/src/transport/SecureSession.h index a76ba3f8b280bd..38b3e91b622de9 100644 --- a/src/transport/SecureSession.h +++ b/src/transport/SecureSession.h @@ -107,22 +107,6 @@ class DLL_EXPORT SecureSession */ void Reset(void); - /** - * @brief - * The keypair for the secure channel. This is a utility function that will be used - * until we have automatic key exchange in place. The function is useful only for - * example applications for now. It will eventually be removed. - * - * @param remote_public_key A pointer to peer's public key - * @param public_key_length Length of remote_public_key - * @param local_private_key A pointer to local private key - * @param private_key_length Length of local_private_key - * @return CHIP_ERROR The result of key derivation - */ - [[deprecated("Available until actual key exchange is implemented")]] CHIP_ERROR - TemporaryManualKeyExchange(const unsigned char * remote_public_key, const size_t public_key_length, - const unsigned char * local_private_key, const size_t private_key_length); - private: static constexpr size_t kAES_CCM128_Key_Length = 16; diff --git a/src/transport/SecureSessionMgr.cpp b/src/transport/SecureSessionMgr.cpp index ec3bff13866ebc..a57a65046462e8 100644 --- a/src/transport/SecureSessionMgr.cpp +++ b/src/transport/SecureSessionMgr.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -85,27 +86,6 @@ CHIP_ERROR SecureSessionMgrBase::InitInternal(NodeId localNodeId, System::Layer return err; } -CHIP_ERROR SecureSessionMgrBase::Connect(NodeId peerNodeId, const Transport::PeerAddress & peerAddress) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - PeerConnectionState * state = nullptr; - - VerifyOrExit(mState == State::kInitialized, err = CHIP_ERROR_INCORRECT_STATE); - - err = mPeerConnections.CreateNewPeerConnectionState(peerAddress, &state); - SuccessOrExit(err); - - state->SetPeerNodeId(peerNodeId); - - if (mCB != nullptr) - { - mCB->OnNewConnection(state, this); - } - -exit: - return err; -} - CHIP_ERROR SecureSessionMgrBase::SendMessage(NodeId peerNodeId, System::PacketBuffer * msgBuf) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -135,6 +115,7 @@ CHIP_ERROR SecureSessionMgrBase::SendMessage(NodeId peerNodeId, System::PacketBu .SetSourceNodeId(mLocalNodeId) // .SetDestinationNodeId(peerNodeId) // .SetMessageId(state->GetSendMessageIndex()) // + .SetEncryptionKeyID(state->GetLocalKeyID()) // .SetPayloadLength(headerSize + msgBuf->TotalLength()); VerifyOrExit(msgBuf->EnsureReservedSize(headerSize), err = CHIP_ERROR_NO_MEMORY); @@ -181,22 +162,33 @@ CHIP_ERROR SecureSessionMgrBase::SendMessage(NodeId peerNodeId, System::PacketBu return err; } -CHIP_ERROR SecureSessionMgrBase::AllocateNewConnection(const MessageHeader & header, const PeerAddress & address, - Transport::PeerConnectionState ** state) +CHIP_ERROR SecureSessionMgrBase::NewPairing(Optional peerNodeId, const Optional & peerAddr, + uint16_t peerKeyId, uint16_t localKeyId, SecurePairingSession * pairing) { CHIP_ERROR err = CHIP_NO_ERROR; - err = mPeerConnections.CreateNewPeerConnectionState(address, state); + PeerConnectionState * state = nullptr; + + // Find any existing connection with the same node and key ID + if (mPeerConnections.FindPeerConnectionState(peerNodeId, peerKeyId, &state)) + { + mPeerConnections.MarkConnectionExpired(state); + } + + ChipLogProgress(Inet, "New pairing for key %d!!", peerKeyId); + state = nullptr; + err = mPeerConnections.CreateNewPeerConnectionState(peerNodeId, peerKeyId, localKeyId, &state); SuccessOrExit(err); - if (header.GetSourceNodeId().HasValue()) + if (peerAddr.HasValue()) { - (*state)->SetPeerNodeId(header.GetSourceNodeId().Value()); + state->SetPeerAddress(peerAddr.Value()); } - if (mCB != nullptr) + if (state != nullptr) { - mCB->OnNewConnection(*state, this); + err = pairing->DeriveSecureSession((const unsigned char *) kSpake2pI2RSessionInfo, strlen(kSpake2pI2RSessionInfo), + state->GetSecureSession()); } exit: @@ -229,30 +221,19 @@ void SecureSessionMgrBase::HandleDataReceived(MessageHeader & header, const Peer VerifyOrExit(msg != nullptr, ChipLogError(Inet, "Secure transport received NULL packet, discarding")); + if (!connection->mPeerConnections.FindPeerConnectionState(header.GetSourceNodeId(), header.GetEncryptionKeyID(), &state)) { - if (!connection->mPeerConnections.FindPeerConnectionState(peerAddress, &state)) - { - if (header.GetSourceNodeId().HasValue()) - { - // If the data is from a new address BUT the node id is the same as a previous - // connection, mark the previous connection invalid in order to not have duplicate node ids. - if (connection->mPeerConnections.FindPeerConnectionState(header.GetSourceNodeId().Value(), &state)) - { - connection->mPeerConnections.MarkConnectionExpired(state); - } - } - - ChipLogProgress(Inet, "New peer connection received."); - - err = connection->AllocateNewConnection(header, peerAddress, &state); - SuccessOrExit(err); - } - else - { - connection->mPeerConnections.MarkConnectionActive(state); - } + ChipLogProgress(Inet, "Data received on an unknown connection (%d). Dropping it!!", header.GetEncryptionKeyID()); + ExitNow(err = CHIP_ERROR_KEY_NOT_FOUND_FROM_PEER); } + if (!state->GetPeerAddress().IsInitialized()) + { + state->SetPeerAddress(peerAddress); + } + + connection->mPeerConnections.MarkConnectionActive(state); + // TODO this is where messages should be decoded { uint8_t * data = msg->Start(); diff --git a/src/transport/SecureSessionMgr.h b/src/transport/SecureSessionMgr.h index 91995f839316d9..b447e5182f00ed 100644 --- a/src/transport/SecureSessionMgr.h +++ b/src/transport/SecureSessionMgr.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -91,13 +92,6 @@ class DLL_EXPORT SecureSessionMgrCallback : public ReferenceCounted { public: - /** - * Establishes a connection to the given peer node. - * - * A connection needs to be established before SendMessage can be called. - */ - CHIP_ERROR Connect(NodeId peerNodeId, const Transport::PeerAddress & peerAddress); - /** * @brief * Send a message to a currently connected peer @@ -127,6 +121,18 @@ class DLL_EXPORT SecureSessionMgrBase : public ReferenceCountedRetain(); } + /** + * @brief + * Establish a new pairing with a peer node + * + * @details + * This method sets up a new pairing with the peer node. It also + * establishes the security keys for secure communication with the + * peer node. + */ + CHIP_ERROR NewPairing(Optional peerNodeId, const Optional & peerAddr, uint16_t peerKeyId, + uint16_t localKeyId, SecurePairingSession * pairing); + protected: /** * @brief diff --git a/src/transport/tests/TestSecurePairingSession.cpp b/src/transport/tests/TestSecurePairingSession.cpp index c99c0b9755ff6c..d36db69054cf78 100644 --- a/src/transport/tests/TestSecurePairingSession.cpp +++ b/src/transport/tests/TestSecurePairingSession.cpp @@ -56,7 +56,7 @@ class TestSecurePairingDelegate : public SecurePairingSessionDelegate virtual void OnPairingError(CHIP_ERROR error) { mNumPairingErrors++; } - virtual void OnPairingComplete(Optional peerNodeId, uint16_t peerKeyId) { mNumPairingComplete++; } + virtual void OnPairingComplete(Optional peerNodeId, uint16_t peerKeyId, uint16_t localKeyId) { mNumPairingComplete++; } uint32_t mNumMessageSend = 0; uint32_t mNumPairingErrors = 0; diff --git a/src/transport/tests/TestSecureSessionMgr.cpp b/src/transport/tests/TestSecureSessionMgr.cpp index 8d7434a350f0e2..e8d653b4491b36 100644 --- a/src/transport/tests/TestSecureSessionMgr.cpp +++ b/src/transport/tests/TestSecureSessionMgr.cpp @@ -43,16 +43,6 @@ using TestContext = chip::Test::IOContext; TestContext sContext; -static const unsigned char local_private_key[] = { 0x00, 0xd1, 0x90, 0xd9, 0xb3, 0x95, 0x1c, 0x5f, 0xa4, 0xe7, 0x47, - 0x92, 0x5b, 0x0a, 0xa9, 0xa7, 0xc1, 0x1c, 0xe7, 0x06, 0x10, 0xe2, - 0xdd, 0x16, 0x41, 0x52, 0x55, 0xb7, 0xb8, 0x80, 0x8d, 0x87, 0xa1 }; - -static const unsigned char remote_public_key[] = { 0x04, 0xe2, 0x07, 0x64, 0xff, 0x6f, 0x6a, 0x91, 0xd9, 0xc2, 0xc3, 0x0a, 0xc4, - 0x3c, 0x56, 0x4b, 0x42, 0x8a, 0xf3, 0xb4, 0x49, 0x29, 0x39, 0x95, 0xa2, 0xf7, - 0x02, 0x8c, 0xa5, 0xce, 0xf3, 0xc9, 0xca, 0x24, 0xc5, 0xd4, 0x5c, 0x60, 0x79, - 0x48, 0x30, 0x3c, 0x53, 0x86, 0xd9, 0x23, 0xe6, 0x61, 0x1f, 0x5a, 0x3d, 0xdf, - 0x9f, 0xdc, 0x35, 0xea, 0xd0, 0xde, 0x16, 0x7e, 0x64, 0xde, 0x7f, 0x3c, 0xa6 }; - static const char PAYLOAD[] = "Hello!"; constexpr NodeId kSourceNodeId = 123654; constexpr NodeId kDestinationNodeId = 111222333; @@ -80,7 +70,7 @@ class TestSessMgrCallback : public SecureSessionMgrCallback { NL_TEST_ASSERT(mSuite, header.GetSourceNodeId() == Optional::Value(kSourceNodeId)); NL_TEST_ASSERT(mSuite, header.GetDestinationNodeId() == Optional::Value(kDestinationNodeId)); - NL_TEST_ASSERT(mSuite, state->GetPeerNodeId() == kDestinationNodeId); + NL_TEST_ASSERT(mSuite, state->GetPeerNodeId() == kSourceNodeId); size_t data_len = msgBuf->DataLength(); @@ -90,20 +80,41 @@ class TestSessMgrCallback : public SecureSessionMgrCallback ReceiveHandlerCallCount++; } - virtual void OnNewConnection(PeerConnectionState * state, SecureSessionMgrBase * mgr) + virtual void OnNewConnection(PeerConnectionState * state, SecureSessionMgrBase * mgr) { NewConnectionHandlerCallCount++; } + + nlTestSuite * mSuite = nullptr; + int ReceiveHandlerCallCount = 0; + int NewConnectionHandlerCallCount = 0; +}; + +class TestSecurePairing : public SecurePairingSession +{ +public: + TestSecurePairing() : SecurePairingSession() {} + + ~TestSecurePairing(void) {} + + CHIP_ERROR WaitForPairing(uint32_t mySetUpPINCode, uint32_t pbkdf2IterCount, const unsigned char * salt, size_t saltLen, + Optional myNodeId, uint16_t myKeyId, SecurePairingSessionDelegate * delegate) { - CHIP_ERROR err; + return CHIP_NO_ERROR; + } - NewConnectionHandlerCallCount++; + CHIP_ERROR Pair(uint32_t peerSetUpPINCode, uint32_t pbkdf2IterCount, const unsigned char * salt, size_t saltLen, + Optional myNodeId, uint16_t myKeyId, SecurePairingSessionDelegate * delegate) + { + return CHIP_NO_ERROR; + } - err = state->GetSecureSession().TemporaryManualKeyExchange(remote_public_key, sizeof(remote_public_key), local_private_key, - sizeof(local_private_key)); - NL_TEST_ASSERT(mSuite, err == CHIP_NO_ERROR); + CHIP_ERROR DeriveSecureSession(const unsigned char * info, size_t info_len, SecureSession & session) + { + const char * secret = "Secure Session Mgr Test Secret"; + size_t secretLen = strlen(secret); + return session.InitFromSecret((const unsigned char *) secret, secretLen, (const unsigned char *) "", 0, + (const unsigned char *) secret, secretLen); } - nlTestSuite * mSuite = nullptr; - int ReceiveHandlerCallCount = 0; - int NewConnectionHandlerCallCount = 0; + CHIP_ERROR HandlePeerMessage(const MessageHeader & header, System::PacketBuffer * msg) { return CHIP_NO_ERROR; } }; TestSessMgrCallback callback; @@ -146,11 +157,14 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) conn.SetDelegate(&callback); - callback.NewConnectionHandlerCallCount = 0; + TestSecurePairing pairing1, pairing2; + Optional peer(Transport::PeerAddress::UDP(addr, CHIP_PORT)); + + err = conn.NewPairing(Optional::Value(kSourceNodeId), peer, 1, 2, &pairing1); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - err = conn.Connect(kDestinationNodeId, PeerAddress::UDP(addr)); + err = conn.NewPairing(Optional::Value(kDestinationNodeId), peer, 2, 1, &pairing2); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, callback.NewConnectionHandlerCallCount == 1); // Should be able to send a message to itself by just calling send. callback.ReceiveHandlerCallCount = 0;