diff --git a/examples/chip-tool/main.cpp b/examples/chip-tool/main.cpp index d775883ed43a93..3b011d5c48cf53 100644 --- a/examples/chip-tool/main.cpp +++ b/examples/chip-tool/main.cpp @@ -470,14 +470,14 @@ CHIP_ERROR ExecuteCommand(DeviceController::ChipDeviceController * controller, C case Command::Echo: err = - controller->ConnectDevice(kRemoteDeviceId, commandArgs.hostAddr, NULL, OnConnect, OnMessage, OnError, commandArgs.port); + controller->ConnectDeviceWithoutSecurePairing(kRemoteDeviceId, commandArgs.hostAddr, NULL, OnConnect, OnMessage, OnError, commandArgs.port); VerifyOrExit(err == CHIP_NO_ERROR, fprintf(stderr, "Failed to connect to the device")); DoEchoIP(controller, commandArgs.hostAddr, commandArgs.port); break; default: err = - controller->ConnectDevice(kRemoteDeviceId, commandArgs.hostAddr, NULL, OnConnect, OnMessage, OnError, commandArgs.port); + controller->ConnectDeviceWithoutSecurePairing(kRemoteDeviceId, commandArgs.hostAddr, NULL, OnConnect, OnMessage, OnError, commandArgs.port); VerifyOrExit(err == CHIP_NO_ERROR, fprintf(stderr, "Failed to connect to the device")); DoOnOff(controller, command, commandArgs); controller->ServiceEventSignal(); diff --git a/examples/lock-app/nrfconnect/main/Server.cpp b/examples/lock-app/nrfconnect/main/Server.cpp index ce3a181ebbec0d..6b8ae06d08586c 100644 --- a/examples/lock-app/nrfconnect/main/Server.cpp +++ b/examples/lock-app/nrfconnect/main/Server.cpp @@ -128,6 +128,7 @@ class ServerCallback : public SecureSessionMgrCallback }; static ServerCallback gCallbacks; +static SecurePairingUsingTestSecret gTestPairing; } // namespace @@ -135,10 +136,14 @@ static ServerCallback gCallbacks; void StartServer(DemoSessionManager * sessions) { CHIP_ERROR err = CHIP_NO_ERROR; + Optional peer(Transport::Type::kUndefined); err = sessions->Init(EXAMPLE_SERVER_NODEID, &DeviceLayer::SystemLayer, UdpListenParameters(&DeviceLayer::InetLayer).SetAddressType(kIPAddressType_IPv6)); SuccessOrExit(err); + + err = sessions->NewPairing(Optional::Value(kUndefinedNodeId), peer, 0, 0, &gTestPairing) + SuccessOrExit(err); sessions->SetDelegate(&gCallbacks); exit: diff --git a/examples/platform/nrf528xx/app/Server.cpp b/examples/platform/nrf528xx/app/Server.cpp index 7b2179e51f01df..2f211402352fa1 100644 --- a/examples/platform/nrf528xx/app/Server.cpp +++ b/examples/platform/nrf528xx/app/Server.cpp @@ -149,6 +149,7 @@ class ServerCallback : public SecureSessionMgrCallback }; static ServerCallback gCallbacks; +static SecurePairingUsingTestSecret gTestPairing; } // namespace @@ -212,11 +213,14 @@ void InitDataModelHandler() void StartServer(DemoSessionManager * sessions) { CHIP_ERROR err = CHIP_NO_ERROR; + Optional peer(Transport::Type::kUndefined); err = sessions->Init(EXAMPLE_SERVER_NODEID, &DeviceLayer::SystemLayer, UdpListenParameters(&DeviceLayer::InetLayer).SetAddressType(kIPAddressType_IPv6)); SuccessOrExit(err); + err = sessions->NewPairing(Optional::Value(kUndefinedNodeId), peer, 0, 0, &gTestPairing) + SuccessOrExit(err); sessions->SetDelegate(&gCallbacks); exit: diff --git a/examples/wifi-echo/server/esp32/main/Kconfig.projbuild b/examples/wifi-echo/server/esp32/main/Kconfig.projbuild index 2dc367081fbb2d..29e80d2e94b9ae 100644 --- a/examples/wifi-echo/server/esp32/main/Kconfig.projbuild +++ b/examples/wifi-echo/server/esp32/main/Kconfig.projbuild @@ -41,6 +41,8 @@ menu "WiFi Echo Demo" help Specifies the Rendezvous mode of the peripheral. + config RENDEZVOUS_MODE_BYPASS + bool "Bypass" config RENDEZVOUS_MODE_WIFI bool "Wi-Fi" config RENDEZVOUS_MODE_BLE @@ -77,6 +79,7 @@ menu "WiFi Echo Demo" config RENDEZVOUS_MODE int range 0 8 + default 0 if RENDEZVOUS_MODE_BYPASS default 1 if RENDEZVOUS_MODE_WIFI default 2 if RENDEZVOUS_MODE_BLE default 4 if RENDEZVOUS_MODE_THREAD diff --git a/examples/wifi-echo/server/esp32/main/wifi-echo.cpp b/examples/wifi-echo/server/esp32/main/wifi-echo.cpp index 9c9ab5c6a5fdde..d990d336f7715c 100644 --- a/examples/wifi-echo/server/esp32/main/wifi-echo.cpp +++ b/examples/wifi-echo/server/esp32/main/wifi-echo.cpp @@ -103,6 +103,7 @@ BluetoothWidget bluetoothLED; WiFiWidget wifiLED; extern NodeId kLocalNodeId; +extern void PairingComplete(Optional peerNodeId, uint16_t peerKeyId, uint16_t localKeyId, SecurePairingSession * pairing); const char * TAG = "wifi-echo-demo"; @@ -357,6 +358,11 @@ bool isRendezvousBLE() return static_cast(CONFIG_RENDEZVOUS_MODE) == RendezvousInformationFlags::kBLE; } +bool isRendezvousBypassed() +{ + return static_cast(CONFIG_RENDEZVOUS_MODE) == RendezvousInformationFlags::kNone; +} + std::string createSetupPayload() { CHIP_ERROR err = CHIP_NO_ERROR; @@ -411,6 +417,8 @@ std::string createSetupPayload() return result; }; +static SecurePairingUsingTestSecret gTestPairing; + } // namespace extern "C" void app_main() @@ -474,6 +482,11 @@ extern "C" void app_main() } rendezvousSession = new RendezvousSession(&bluetoothLED, setupPINCode, kLocalNodeId); } + else if (isRendezvousBypassed()) + { + ChipLogProgress(Ble, "Rendezvous and Secure Pairing skipped. Using test secret."); + PairingComplete(Optional::Value(kUndefinedNodeId), 0, 0, &gTestPairing); + } #if CONFIG_USE_ECHO_CLIENT startClient(); diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 1ff36d882e1e89..4236a8d25ffc64 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -269,9 +269,9 @@ CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, const uint return err; } -CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, IPAddress deviceAddr, void * appReqState, +CHIP_ERROR ChipDeviceController::ConnectDeviceUsingPairing(NodeId remoteDeviceId, IPAddress deviceAddr, void * appReqState, NewConnectionHandler onConnected, MessageReceiveHandler onMessageReceived, - ErrorHandler onError, uint16_t devicePort) + ErrorHandler onError, uint16_t devicePort, uint16_t localKeyId, SecurePairingSession* pairing) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -301,11 +301,16 @@ CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, IPAddress err = mSessionManager->NewPairing(mRemoteDeviceId, Optional::Value(Transport::PeerAddress::UDP(deviceAddr, devicePort)), - mPeerKeyId, mLocalPairedKeyId, &mPairingSession); + mPeerKeyId, localKeyId, pairing); SuccessOrExit(err); mMessageNumber = 1; + if (mOnNewConnection) + { + mOnNewConnection(this, NULL, mAppReqState); + } + exit: if (err != CHIP_NO_ERROR) @@ -320,6 +325,21 @@ CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, IPAddress return err; } +CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, IPAddress deviceAddr, void * appReqState, + NewConnectionHandler onConnected, MessageReceiveHandler onMessageReceived, + ErrorHandler onError, uint16_t devicePort) +{ + return ConnectDeviceUsingPairing(remoteDeviceId, deviceAddr, appReqState, onConnected, onMessageReceived, onError, devicePort, mLocalPairedKeyId, &mPairingSession); +} + +CHIP_ERROR ChipDeviceController::ConnectDeviceWithoutSecurePairing(NodeId remoteDeviceId, IPAddress deviceAddr, void * appReqState, + NewConnectionHandler onConnected, MessageReceiveHandler onMessageReceived, + ErrorHandler onError, uint16_t devicePort) +{ + SecurePairingUsingTestSecret pairing; + return ConnectDeviceUsingPairing(remoteDeviceId, deviceAddr, appReqState, onConnected, onMessageReceived, onError, devicePort, 0, &pairing); +} + CHIP_ERROR ChipDeviceController::PopulatePeerAddress(Transport::PeerAddress & peerAddress) { CHIP_ERROR err = CHIP_NO_ERROR; diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 624aa72d0ddff6..8dfb1a3920d40e 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -106,6 +106,23 @@ class DLL_EXPORT ChipDeviceController : public SecureSessionMgrCallback, CHIP_ERROR ConnectDevice(NodeId remoteDeviceId, IPAddress deviceAddr, void * appReqState, NewConnectionHandler onConnected, MessageReceiveHandler onMessageReceived, ErrorHandler onError, uint16_t devicePort = CHIP_PORT); + /** + * @brief + * Connect to a CHIP device at a given address and an optional port. This is a test only API + * that bypasses Rendezvous and Secure Pairing process. + * + * @param[in] remoteDeviceId The remote device Id. + * @param[in] deviceAddr The IPAddress of the requested Device + * @param[in] appReqState Application specific context to be passed back when a message is received or on error + * @param[in] onConnected Callback for when the connection is established + * @param[in] onMessageReceived Callback for when a message is received + * @param[in] onError Callback for when an error occurs + * @param[in] devicePort [Optional] The CHIP Device's port, defaults to CHIP_PORT + * @return CHIP_ERROR The connection status + */ + [[deprecated("Available until Rendezvous is implemented")]] CHIP_ERROR ConnectDeviceWithoutSecurePairing(NodeId remoteDeviceId, IPAddress deviceAddr, void * appReqState, NewConnectionHandler onConnected, + MessageReceiveHandler onMessageReceived, ErrorHandler onError, uint16_t devicePort = CHIP_PORT); + /** * @brief * Called when pairing session generates a new message that should be sent to peer. @@ -260,6 +277,11 @@ class DLL_EXPORT ChipDeviceController : public SecureSessionMgrCallback, static void BLEConnectionHandler(ChipDeviceController * deviceController, Transport::PeerConnectionState * state, void * appReqState); + + CHIP_ERROR ConnectDeviceUsingPairing(NodeId remoteDeviceId, IPAddress deviceAddr, void * appReqState, + NewConnectionHandler onConnected, MessageReceiveHandler onMessageReceived, + ErrorHandler onError, uint16_t devicePort, uint16_t localKeyId, SecurePairingSession* pairing); + }; } // namespace DeviceController diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index e703bb881fd735..3f5a49c3ceede4 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -206,7 +206,7 @@ JNI_METHOD(void, beginConnectDevice)(JNIEnv * env, jobject self, jlong deviceCon env->ReleaseStringUTFChars(deviceAddr, deviceAddrStr); pthread_mutex_lock(&sStackLock); - err = deviceController->ConnectDevice(kRemoteDeviceId, deviceIPAddr, (void *) "ConnectDevice", HandleKeyExchange, + err = deviceController->ConnectDeviceWithoutSecurePairing(kRemoteDeviceId, deviceIPAddr, (void *) "ConnectDevice", HandleKeyExchange, HandleEchoResponse, HandleError, CHIP_PORT); pthread_mutex_unlock(&sStackLock); diff --git a/src/transport/PeerConnections.h b/src/transport/PeerConnections.h index 15ebae352d3266..113c8fb7d08c51 100644 --- a/src/transport/PeerConnections.h +++ b/src/transport/PeerConnections.h @@ -201,7 +201,7 @@ class PeerConnections } if (mStates[i].GetPeerKeyID() == peerKeyId) { - if (!nodeId.HasValue() || mStates[i].GetPeerNodeId() == nodeId.Value()) + if (!nodeId.HasValue() || mStates[i].GetPeerNodeId() == kUndefinedNodeId || mStates[i].GetPeerNodeId() == nodeId.Value()) { *state = &mStates[i]; break; @@ -233,7 +233,7 @@ class PeerConnections } if (mStates[i].GetLocalKeyID() == localKeyId) { - if (!nodeId.HasValue() || mStates[i].GetPeerNodeId() == nodeId.Value()) + if (!nodeId.HasValue() || mStates[i].GetPeerNodeId() == kUndefinedNodeId || mStates[i].GetPeerNodeId() == nodeId.Value()) { *state = &mStates[i]; break; diff --git a/src/transport/SecurePairingSession.h b/src/transport/SecurePairingSession.h index 32391a142ee499..0d85326632d508 100644 --- a/src/transport/SecurePairingSession.h +++ b/src/transport/SecurePairingSession.h @@ -186,6 +186,42 @@ class DLL_EXPORT SecurePairingSession uint16_t mPeerKeyId; }; +/* + * The following class should only be used for test usecases. + * The class is currently also used for devices that do no yet support + * rendezvous. Once all the non-test usecases start supporting + * rendezvous, this class will be moved to the test code. + */ +class SecurePairingUsingTestSecret : public SecurePairingSession +{ +public: + SecurePairingUsingTestSecret() : SecurePairingSession() {} + + ~SecurePairingUsingTestSecret(void) {} + + CHIP_ERROR WaitForPairing(uint32_t mySetUpPINCode, uint32_t pbkdf2IterCount, const unsigned char * salt, size_t saltLen, + Optional myNodeId, uint16_t myKeyId, SecurePairingSessionDelegate * delegate) + { + return CHIP_NO_ERROR; + } + + 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; + } + + CHIP_ERROR DeriveSecureSession(const unsigned char * info, size_t info_len, SecureSession & session) + { + const char * secret = "Test secret for key derivation"; + size_t secretLen = strlen(secret); + return session.InitFromSecret((const unsigned char *) secret, secretLen, (const unsigned char *) "", 0, + (const unsigned char *) secret, secretLen); + } + + CHIP_ERROR HandlePeerMessage(const MessageHeader & header, System::PacketBuffer * msg) { return CHIP_NO_ERROR; } +}; + } // namespace chip #endif // __SECUREPAIRINGSESSION_H__ diff --git a/src/transport/SecureSessionMgr.cpp b/src/transport/SecureSessionMgr.cpp index a57a65046462e8..8473fdb3a185e5 100644 --- a/src/transport/SecureSessionMgr.cpp +++ b/src/transport/SecureSessionMgr.cpp @@ -267,6 +267,11 @@ void SecureSessionMgrBase::HandleDataReceived(MessageHeader & header, const Peer msg->ConsumeHead(headerSize); + if (state->GetPeerNodeId() == kUndefinedNodeId && header.GetSourceNodeId().HasValue()) + { + state->SetPeerNodeId(header.GetSourceNodeId().Value()); + } + if (connection->mCB != nullptr) { connection->mCB->OnMessageReceived(header, state, msg, connection); diff --git a/src/transport/tests/TestPeerConnections.cpp b/src/transport/tests/TestPeerConnections.cpp index b055e9ccbb948e..6bddf3eb96f1fd 100644 --- a/src/transport/tests/TestPeerConnections.cpp +++ b/src/transport/tests/TestPeerConnections.cpp @@ -149,12 +149,10 @@ void TestFindByKeyId(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, statePtr == nullptr); // Lookup using a node ID, and peer key - NL_TEST_ASSERT(inSuite, !connections.FindPeerConnectionState(Optional::Value(kPeer1NodeId), 1, &statePtr)); - NL_TEST_ASSERT(inSuite, statePtr == nullptr); + NL_TEST_ASSERT(inSuite, connections.FindPeerConnectionState(Optional::Value(kPeer1NodeId), 1, &statePtr)); // Lookup using a node ID, and local key - NL_TEST_ASSERT(inSuite, !connections.FindPeerConnectionStateByLocalKey(Optional::Value(kPeer1NodeId), 2, &statePtr)); - NL_TEST_ASSERT(inSuite, statePtr == nullptr); + NL_TEST_ASSERT(inSuite, connections.FindPeerConnectionStateByLocalKey(Optional::Value(kPeer1NodeId), 2, &statePtr)); // Some Node ID, peer key 3, local key 4 err = connections.CreateNewPeerConnectionState(Optional::Value(kPeer1NodeId), 3, 4, &statePtr); diff --git a/src/transport/tests/TestSecureSessionMgr.cpp b/src/transport/tests/TestSecureSessionMgr.cpp index e8d653b4491b36..90fe9fc41fcb3e 100644 --- a/src/transport/tests/TestSecureSessionMgr.cpp +++ b/src/transport/tests/TestSecureSessionMgr.cpp @@ -87,36 +87,6 @@ class TestSessMgrCallback : public SecureSessionMgrCallback 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) - { - return CHIP_NO_ERROR; - } - - 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; - } - - 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); - } - - CHIP_ERROR HandlePeerMessage(const MessageHeader & header, System::PacketBuffer * msg) { return CHIP_NO_ERROR; } -}; - TestSessMgrCallback callback; void CheckSimpleInitTest(nlTestSuite * inSuite, void * inContext) @@ -157,7 +127,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) conn.SetDelegate(&callback); - TestSecurePairing pairing1, pairing2; + SecurePairingUsingTestSecret pairing1, pairing2; Optional peer(Transport::PeerAddress::UDP(addr, CHIP_PORT)); err = conn.NewPairing(Optional::Value(kSourceNodeId), peer, 1, 2, &pairing1);