Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020-2024 Project CHIP Authors
4 : * Copyright (c) 2013-2017 Nest Labs, Inc.
5 : * All rights reserved.
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : /**
21 : * @file
22 : * Declaration of CHIP Device Controller, a common class
23 : * that implements connecting and messaging and will later
24 : * be expanded to support discovery, pairing and
25 : * provisioning of CHIP devices.
26 : *
27 : */
28 :
29 : #pragma once
30 :
31 : #include <app/AppConfig.h>
32 : #include <app/CASEClientPool.h>
33 : #include <app/CASESessionManager.h>
34 : #include <app/ClusterStateCache.h>
35 : #include <app/OperationalSessionSetup.h>
36 : #include <app/OperationalSessionSetupPool.h>
37 : #include <controller/AbstractDnssdDiscoveryController.h>
38 : #include <controller/AutoCommissioner.h>
39 : #include <controller/CHIPCluster.h>
40 : #include <controller/CHIPDeviceControllerSystemState.h>
41 : #include <controller/CommissioneeDeviceProxy.h>
42 : #include <controller/CommissioningDelegate.h>
43 : #include <controller/DevicePairingDelegate.h>
44 : #include <controller/OperationalCredentialsDelegate.h>
45 : #include <controller/SetUpCodePairer.h>
46 : #include <credentials/FabricTable.h>
47 : #include <credentials/attestation_verifier/DeviceAttestationDelegate.h>
48 : #include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
49 : #include <crypto/CHIPCryptoPAL.h>
50 : #include <inet/IPAddress.h>
51 : #include <inet/InetInterface.h>
52 : #include <lib/core/CHIPConfig.h>
53 : #include <lib/core/CHIPCore.h>
54 : #include <lib/core/CHIPPersistentStorageDelegate.h>
55 : #include <lib/core/DataModelTypes.h>
56 : #include <lib/core/TLV.h>
57 : #include <lib/support/DLLUtil.h>
58 : #include <lib/support/Pool.h>
59 : #include <lib/support/SafeInt.h>
60 : #include <lib/support/Span.h>
61 : #include <lib/support/ThreadOperationalDataset.h>
62 : #include <messaging/ExchangeMgr.h>
63 : #include <protocols/secure_channel/MessageCounterManager.h>
64 : #include <protocols/secure_channel/RendezvousParameters.h>
65 : #include <protocols/user_directed_commissioning/UserDirectedCommissioning.h>
66 : #include <system/SystemClock.h>
67 : #include <transport/SessionManager.h>
68 : #include <transport/TransportMgr.h>
69 : #include <transport/raw/UDP.h>
70 :
71 : #if CONFIG_DEVICE_LAYER
72 : #include <platform/CHIPDeviceLayer.h>
73 : #endif
74 :
75 : #if CHIP_SUPPORT_THREAD_MESHCOP
76 : #include <controller/ThreadMeshcopCommissionProxy.h>
77 : #endif
78 :
79 : #if CONFIG_NETWORK_LAYER_BLE
80 : #include <ble/Ble.h>
81 : #endif
82 : #include <controller/DeviceDiscoveryDelegate.h>
83 :
84 : namespace chip {
85 :
86 : namespace Testing {
87 :
88 : class DeviceCommissionerTestAccess;
89 :
90 : } // namespace Testing
91 :
92 : namespace Controller {
93 :
94 : inline constexpr uint16_t kNumMaxActiveDevices = CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES;
95 :
96 : struct ControllerInitParams
97 : {
98 : DeviceControllerSystemState * systemState = nullptr;
99 : DeviceDiscoveryDelegate * deviceDiscoveryDelegate = nullptr;
100 : OperationalCredentialsDelegate * operationalCredentialsDelegate = nullptr;
101 :
102 : /* The following keypair must correspond to the public key used for generating
103 : controllerNOC. It's used by controller to establish CASE sessions with devices */
104 : Crypto::P256Keypair * operationalKeypair = nullptr;
105 :
106 : /**
107 : * Controls whether or not the operationalKeypair should be owned by the caller.
108 : * By default, this is false, but if the keypair cannot be serialized, then
109 : * setting this to true will allow the caller to manage this keypair's lifecycle.
110 : */
111 : bool hasExternallyOwnedOperationalKeypair = false;
112 :
113 : /* The following certificates must be in x509 DER format */
114 : ByteSpan controllerNOC;
115 : ByteSpan controllerICAC;
116 : ByteSpan controllerRCAC;
117 :
118 : /**
119 : * Controls whether we permit multiple DeviceController instances to exist
120 : * on the same logical fabric (identified by the tuple of the fabric's
121 : * root public key + fabric id).
122 : *
123 : * Each controller instance will be associated with its own FabricIndex.
124 : * This pivots the FabricTable to tracking identities instead of fabrics,
125 : * represented by FabricInfo instances that can have colliding logical fabrics.
126 : *
127 : */
128 : bool permitMultiControllerFabrics = false;
129 :
130 : //
131 : // Controls enabling server cluster interactions on a controller. This in turn
132 : // causes the following to get enabled:
133 : //
134 : // - Advertisement of active controller operational identities.
135 : //
136 : bool enableServerInteractions = false;
137 :
138 : /**
139 : * Controls whether shutdown of the controller removes the corresponding
140 : * entry from the in-memory fabric table, but NOT from storage.
141 : *
142 : * Note that this means that after controller shutdown the storage and
143 : * in-memory versions of the fabric table will be out of sync.
144 : * For compatibility reasons this is the default behavior.
145 : *
146 : * @see deleteFromFabricTableOnShutdown
147 : */
148 : bool removeFromFabricTableOnShutdown = true;
149 :
150 : /**
151 : * Controls whether shutdown of the controller deletes the corresponding
152 : * entry from the fabric table (both in-memory and storage).
153 : *
154 : * If both `removeFromFabricTableOnShutdown` and this setting are true,
155 : * this setting will take precedence.
156 : *
157 : * @see removeFromFabricTableOnShutdown
158 : */
159 : bool deleteFromFabricTableOnShutdown = false;
160 :
161 : /**
162 : * Specifies whether to utilize the fabric table entry for the given FabricIndex
163 : * for initialization. If provided and neither the operational key pair nor the NOC
164 : * chain are provided, then attempt to locate a fabric corresponding to the given FabricIndex.
165 : */
166 : chip::Optional<FabricIndex> fabricIndex;
167 :
168 : chip::VendorId controllerVendorId;
169 : };
170 :
171 : struct CommissionerInitParams : public ControllerInitParams
172 : {
173 : DevicePairingDelegate * pairingDelegate = nullptr;
174 : CommissioningDelegate * defaultCommissioner = nullptr;
175 : // Device attestation verifier instance for the commissioning.
176 : // If null, the globally set attestation verifier (e.g. from GetDeviceAttestationVerifier()
177 : // singleton) will be used.
178 : Credentials::DeviceAttestationVerifier * deviceAttestationVerifier = nullptr;
179 : };
180 :
181 : /**
182 : * @brief
183 : * Controller applications can use this class to communicate with already paired CHIP devices. The
184 : * application is required to provide access to the persistent storage, where the paired device information
185 : * is stored. This object of this class can be initialized with the data from the storage (List of devices,
186 : * and device pairing information for individual devices). Alternatively, this class can retrieve the
187 : * relevant information when the application tries to communicate with the device
188 : */
189 : class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController
190 : {
191 : public:
192 : DeviceController();
193 25 : ~DeviceController() override {}
194 :
195 : virtual CHIP_ERROR Init(ControllerInitParams params);
196 :
197 : /**
198 : * @brief
199 : * Tears down the entirety of the stack, including destructing key objects in the system.
200 : * This expects to be called with external thread synchronization, and will not internally
201 : * grab the CHIP stack lock.
202 : *
203 : * This will also not stop the CHIP event queue / thread (if one exists). Consumers are expected to
204 : * ensure this happened before calling this method.
205 : */
206 : virtual void Shutdown();
207 :
208 : SessionManager * SessionMgr()
209 : {
210 : if (mSystemState)
211 : {
212 : return mSystemState->SessionMgr();
213 : }
214 :
215 : return nullptr;
216 : }
217 :
218 : CASESessionManager * CASESessionMgr()
219 : {
220 : if (mSystemState)
221 : {
222 : return mSystemState->CASESessionMgr();
223 : }
224 :
225 : return nullptr;
226 : }
227 :
228 : Messaging::ExchangeManager * ExchangeMgr()
229 : {
230 : if (mSystemState != nullptr)
231 : {
232 : return mSystemState->ExchangeMgr();
233 : }
234 :
235 : return nullptr;
236 : }
237 :
238 : CHIP_ERROR GetPeerAddressAndPort(NodeId peerId, Inet::IPAddress & addr, uint16_t & port);
239 :
240 : /**
241 : * @brief
242 : * Looks up the PeerAddress for an established CASE session.
243 : *
244 : * @param[in] nodeId the NodeId of the target.
245 : * @param[out] addr the PeerAddress to be filled on success
246 : *
247 : * @return CHIP_ERROR CHIP_ERROR_NOT_CONNECTED if no CASE session exists for the device
248 : */
249 : CHIP_ERROR GetPeerAddress(NodeId nodeId, Transport::PeerAddress & addr);
250 :
251 0 : ScopedNodeId GetPeerScopedId(NodeId nodeId) { return ScopedNodeId(nodeId, GetFabricIndex()); }
252 :
253 : /**
254 : * This function finds the device corresponding to deviceId, and establishes
255 : * a CASE session with it.
256 : *
257 : * Once the CASE session is successfully established the `onConnection`
258 : * callback is called. This can happen before GetConnectedDevice returns if
259 : * there is an existing CASE session.
260 : *
261 : * If a CASE sessions fails to be established, the `onFailure` callback will
262 : * be called. This can also happen before GetConnectedDevice returns.
263 : *
264 : * An error return from this function means that neither callback has been
265 : * called yet, and neither callback will be called in the future.
266 : */
267 : virtual CHIP_ERROR
268 0 : GetConnectedDevice(NodeId peerNodeId, Callback::Callback<OnDeviceConnected> * onConnection,
269 : Callback::Callback<OnDeviceConnectionFailure> * onFailure,
270 : TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload)
271 : {
272 0 : VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
273 0 : mSystemState->CASESessionMgr()->FindOrEstablishSession(ScopedNodeId(peerNodeId, GetFabricIndex()), onConnection, onFailure,
274 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
275 : 1, nullptr,
276 : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
277 : transportPayloadCapability);
278 0 : return CHIP_NO_ERROR;
279 : }
280 :
281 : /**
282 : * This function finds the device corresponding to deviceId, and establishes
283 : * a CASE session with it.
284 : *
285 : * Once the CASE session is successfully established the `onConnection`
286 : * callback is called. This can happen before GetConnectedDevice returns if
287 : * there is an existing CASE session.
288 : *
289 : * If a CASE sessions fails to be established, the `onSetupFailure` callback will
290 : * be called. This can also happen before GetConnectedDevice returns.
291 : *
292 : * An error return from this function means that neither callback has been
293 : * called yet, and neither callback will be called in the future.
294 : */
295 : CHIP_ERROR
296 : GetConnectedDevice(NodeId peerNodeId, Callback::Callback<OnDeviceConnected> * onConnection,
297 : chip::Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure,
298 : TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload)
299 : {
300 : VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
301 : mSystemState->CASESessionMgr()->FindOrEstablishSession(ScopedNodeId(peerNodeId, GetFabricIndex()), onConnection,
302 : onSetupFailure,
303 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
304 : 1, nullptr,
305 : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
306 : transportPayloadCapability);
307 : return CHIP_NO_ERROR;
308 : }
309 :
310 : /**
311 : * @brief
312 : * Compute a PASE verifier and passcode ID for the desired setup pincode.
313 : *
314 : * This can be used to open a commissioning window on the device for
315 : * additional administrator commissioning.
316 : *
317 : * @param[in] iterations The number of iterations to use when generating the verifier
318 : * @param[in] setupPincode The desired PIN code to use
319 : * @param[in] salt The 16-byte salt for verifier computation
320 : * @param[out] outVerifier The Spake2pVerifier to be populated on success
321 : *
322 : * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error
323 : */
324 : CHIP_ERROR ComputePASEVerifier(uint32_t iterations, uint32_t setupPincode, const ByteSpan & salt,
325 : Crypto::Spake2pVerifier & outVerifier);
326 :
327 0 : void RegisterDeviceDiscoveryDelegate(DeviceDiscoveryDelegate * delegate) { mDeviceDiscoveryDelegate = delegate; }
328 :
329 : /**
330 : * @brief Get the Compressed Fabric ID assigned to the device.
331 : */
332 0 : uint64_t GetCompressedFabricId() const
333 : {
334 0 : const auto * fabricInfo = GetFabricInfo();
335 0 : return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetCompressedFabricId()) : kUndefinedCompressedFabricId;
336 : }
337 :
338 : /**
339 : * @brief Get the Compressed Fabric Id as a big-endian 64 bit octet string.
340 : *
341 : * Output span is resized to 8 bytes on success if it was larger.
342 : *
343 : * @param outBytes span to contain the compressed fabric ID, must be at least 8 bytes long
344 : * @return CHIP_ERROR_BUFFER_TOO_SMALL if `outBytes` is too small, CHIP_ERROR_INVALID_FABRIC_INDEX
345 : * if the controller is somehow not associated with a fabric (internal error!) or
346 : * CHIP_NO_ERROR on success.
347 : */
348 : CHIP_ERROR GetCompressedFabricIdBytes(MutableByteSpan & outBytes) const;
349 :
350 : /**
351 : * @brief Get the raw Fabric ID assigned to the device.
352 : */
353 0 : uint64_t GetFabricId() const
354 : {
355 0 : const auto * fabricInfo = GetFabricInfo();
356 0 : return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetFabricId()) : kUndefinedFabricId;
357 : }
358 :
359 : /**
360 : * @brief Get the Node ID of this instance.
361 : */
362 0 : NodeId GetNodeId() const
363 : {
364 0 : const auto * fabricInfo = GetFabricInfo();
365 0 : return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetNodeId()) : kUndefinedNodeId;
366 : }
367 :
368 : /**
369 : * @brief Get the root public key for the fabric
370 : *
371 : * @param outRootPublicKey reference to public key object that gets updated on success.
372 : *
373 : * @return CHIP_NO_ERROR on success, CHIP_ERROR_INCORRECT_STATE if fabric table is unset, or another internal error
374 : * on storage access failure.
375 : */
376 : CHIP_ERROR GetRootPublicKey(Crypto::P256PublicKey & outRootPublicKey) const;
377 :
378 0 : FabricIndex GetFabricIndex() const { return mFabricIndex; }
379 :
380 0 : const FabricTable * GetFabricTable() const
381 : {
382 0 : if (mSystemState == nullptr)
383 : {
384 0 : return nullptr;
385 : }
386 0 : return mSystemState->Fabrics();
387 : }
388 :
389 : OperationalCredentialsDelegate * GetOperationalCredentialsDelegate() { return mOperationalCredentialsDelegate; }
390 :
391 : /**
392 : * @brief
393 : * Reconfigures a new set of operational credentials to be used with this
394 : * controller given ControllerInitParams state.
395 : *
396 : * WARNING: This is a low-level method that should only be called directly
397 : * if you know exactly how this will interact with controller state,
398 : * since there are several integrations that do this call for you.
399 : * It can be used for fine-grained dependency injection of a controller's
400 : * NOC and operational keypair.
401 : */
402 : CHIP_ERROR InitControllerNOCChain(const ControllerInitParams & params);
403 :
404 : /**
405 : * @brief Update the NOC chain of controller.
406 : *
407 : * @param[in] noc NOC in CHIP certificate format.
408 : * @param[in] icac ICAC in CHIP certificate format. If no icac is present, an empty
409 : * ByteSpan should be passed.
410 : * @param[in] operationalKeypair External operational keypair. If null, use keypair in OperationalKeystore.
411 : * @param[in] operationalKeypairExternalOwned If true, external operational keypair must outlive the fabric.
412 : * If false, the keypair is copied and owned in heap of a FabricInfo.
413 : *
414 : * @return CHIP_ERROR CHIP_NO_ERROR on success.
415 : */
416 : CHIP_ERROR UpdateControllerNOCChain(const ByteSpan & noc, const ByteSpan & icac, Crypto::P256Keypair * operationalKeypair,
417 : bool operationalKeypairExternalOwned);
418 :
419 : protected:
420 : enum class State
421 : {
422 : NotInitialized,
423 : Initialized
424 : };
425 :
426 : // This is not public to avoid users of DeviceController relying on "innards" access to
427 : // the raw fabric table. Everything needed should be available with getters on DeviceController.
428 0 : const FabricInfo * GetFabricInfo() const
429 : {
430 0 : VerifyOrReturnError((mState == State::Initialized) && (mFabricIndex != kUndefinedFabricIndex), nullptr);
431 0 : VerifyOrReturnError(GetFabricTable() != nullptr, nullptr);
432 :
433 0 : return GetFabricTable()->FindFabricWithIndex(mFabricIndex);
434 : }
435 :
436 : State mState;
437 :
438 : FabricIndex mFabricIndex = kUndefinedFabricIndex;
439 :
440 : bool mRemoveFromFabricTableOnShutdown = true;
441 : bool mDeleteFromFabricTableOnShutdown = false;
442 :
443 : FabricTable::AdvertiseIdentity mAdvertiseIdentity = FabricTable::AdvertiseIdentity::Yes;
444 :
445 : // TODO(cecille): Make this configuarable.
446 : static constexpr int kMaxCommissionableNodes = 10;
447 : Dnssd::CommissionNodeData mCommissionableNodes[kMaxCommissionableNodes];
448 : DeviceControllerSystemState * mSystemState = nullptr;
449 :
450 : ControllerDeviceInitParams GetControllerDeviceInitParams();
451 :
452 : OperationalCredentialsDelegate * mOperationalCredentialsDelegate;
453 :
454 : chip::VendorId mVendorId;
455 :
456 0 : DiscoveredNodeList GetDiscoveredNodes() override { return DiscoveredNodeList(mCommissionableNodes); }
457 : };
458 :
459 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
460 : using UdcTransportMgr = TransportMgr<Transport::UDP /* IPv6 */
461 : #if INET_CONFIG_ENABLE_IPV4
462 : ,
463 : Transport::UDP /* IPv4 */
464 : #endif
465 : >;
466 : #endif
467 :
468 : /**
469 : * @brief Callback prototype for ExtendArmFailSafe command.
470 : */
471 : typedef void (*OnExtendFailsafeSuccess)(
472 : void * context, const app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
473 : typedef void (*OnExtendFailsafeFailure)(void * context, CHIP_ERROR error);
474 :
475 : /**
476 : * @brief
477 : * The commissioner applications can use this class to pair new/unpaired CHIP devices. The application is
478 : * required to provide write access to the persistent storage, where the paired device information
479 : * will be stored.
480 : */
481 : class DLL_EXPORT DeviceCommissioner : public DeviceController,
482 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
483 : public Protocols::UserDirectedCommissioning::InstanceNameResolver,
484 : #endif
485 : #if CHIP_CONFIG_ENABLE_READ_CLIENT
486 : public app::ClusterStateCache::Callback,
487 : #endif
488 : public SessionEstablishmentDelegate
489 : {
490 : friend class chip::Testing::DeviceCommissionerTestAccess;
491 :
492 : public:
493 : DeviceCommissioner();
494 17 : ~DeviceCommissioner() override {}
495 :
496 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
497 : /**
498 : * Set port for User Directed Commissioning
499 : */
500 : CHIP_ERROR SetUdcListenPort(uint16_t listenPort);
501 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
502 :
503 : using DeviceController::Init;
504 :
505 : /**
506 : * Commissioner-specific initialization, includes parameters such as the pairing delegate.
507 : */
508 : CHIP_ERROR Init(CommissionerInitParams params);
509 :
510 : /**
511 : * @brief
512 : * Tears down the entirety of the stack, including destructing key objects in the system.
513 : * This is not a thread-safe API, and should be called with external synchronization.
514 : *
515 : * Please see implementation for more details.
516 : */
517 : void Shutdown() override;
518 :
519 : // ----- Connection Management -----
520 : /**
521 : * @brief
522 : * Pair a CHIP device with the provided code. The code can be either a QRCode
523 : * or a Manual Setup Code.
524 : * Use registered DevicePairingDelegate object to receive notifications on
525 : * pairing status updates.
526 : *
527 : * Note: Pairing process requires that the caller has registered PersistentStorageDelegate
528 : * in the Init() call.
529 : *
530 : * @param[in] remoteDeviceId The remote device Id.
531 : * @param[in] setUpCode The setup code for connecting to the device
532 : * @param[in] discoveryType The network discovery type, defaults to DiscoveryType::kAll.
533 : * @param[in] resolutionData Optional resolution data previously discovered on the network for the target device.
534 : */
535 : CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode, DiscoveryType discoveryType = DiscoveryType::kAll,
536 : Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
537 : CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode, const CommissioningParameters & CommissioningParameters,
538 : DiscoveryType discoveryType = DiscoveryType::kAll,
539 : Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional,
540 : Optional<SetUpCodePairer::ThreadMeshcopCommissionParameters> meshcopCommissionParams = NullOptional);
541 :
542 : CHIP_ERROR GetLastThreadMeshcopDiscoveryDiagnosticJson(char * buffer, size_t bufferSize);
543 :
544 : /**
545 : * @brief
546 : * Pair a CHIP device with the provided Rendezvous connection parameters.
547 : * Use registered DevicePairingDelegate object to receive notifications on
548 : * pairing status updates.
549 : *
550 : * Note: Pairing process requires that the caller has registered PersistentStorageDelegate
551 : * in the Init() call.
552 : *
553 : * @param[in] remoteDeviceId The remote device Id.
554 : * @param[in] rendezvousParams The Rendezvous connection parameters
555 : */
556 : CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams);
557 :
558 : /**
559 : * @overload
560 : * @param[in] remoteDeviceId The remote device Id.
561 : * @param[in] rendezvousParams The Rendezvous connection parameters
562 : * @param[in] commissioningParams The commissioning parameters (uses default if not supplied)
563 : */
564 : CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams,
565 : CommissioningParameters & commissioningParams);
566 :
567 : /**
568 : * @brief
569 : * Start establishing a PASE connection with a node for the purposes of commissioning.
570 : * Commissioners that wish to use the auto-commissioning functions should use the
571 : * supplied "PairDevice" functions above to automatically establish a connection then
572 : * perform commissioning. This function is intended to be use by commissioners that
573 : * are not using the supplied auto-commissioner.
574 : *
575 : * This function is non-blocking. PASE is established once the DevicePairingDelegate
576 : * receives the OnPairingComplete call.
577 : *
578 : * PASE connections can only be established with nodes that have their commissioning
579 : * window open. The PASE connection will fail if this window is not open and the
580 : * OnPairingComplete will be called with an error.
581 : *
582 : * @param[in] remoteDeviceId The remote device Id.
583 : * @param[in] params The Rendezvous connection parameters
584 : */
585 : CHIP_ERROR EstablishPASEConnection(NodeId remoteDeviceId, RendezvousParameters & params);
586 :
587 : /**
588 : * @brief
589 : * Start establishing a PASE connection with a node for the purposes of commissioning.
590 : * Commissioners that wish to use the auto-commissioning functions should use the
591 : * supplied "PairDevice" functions above to automatically establish a connection then
592 : * perform commissioning. This function is intended to be used by commissioners that
593 : * are not using the supplied auto-commissioner.
594 : *
595 : * This function is non-blocking. PASE is established once the DevicePairingDelegate
596 : * receives the OnPairingComplete call.
597 : *
598 : * PASE connections can only be established with nodes that have their commissioning
599 : * window open. The PASE connection will fail if this window is not open and in that case
600 : * OnPairingComplete will be called with an error.
601 : *
602 : * @param[in] remoteDeviceId The remote device Id.
603 : * @param[in] setUpCode The setup code for connecting to the device
604 : * @param[in] discoveryType The network discovery type, defaults to DiscoveryType::kAll.
605 : * @param[in] resolutionData Optional resolution data previously discovered on the network for the target device.
606 : */
607 : CHIP_ERROR
608 : EstablishPASEConnection(NodeId remoteDeviceId, const char * setUpCode, DiscoveryType discoveryType = DiscoveryType::kAll,
609 : Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional,
610 : Optional<SetUpCodePairer::ThreadMeshcopCommissionParameters> meshcopCommissionParams = NullOptional);
611 :
612 : /**
613 : * @brief
614 : * Start the auto-commissioning process on a node after establishing a PASE connection.
615 : * This function is intended to be used in conjunction with the EstablishPASEConnection
616 : * function. It can be called either before or after the DevicePairingDelegate receives
617 : * the OnPairingComplete call. Commissioners that want to perform simple auto-commissioning
618 : * should use the supplied "PairDevice" functions above, which will establish the PASE
619 : * connection and commission automatically.
620 : *
621 : * @param[in] remoteDeviceId The remote device Id.
622 : * @param[in] params The commissioning parameters
623 : */
624 : virtual CHIP_ERROR Commission(NodeId remoteDeviceId, CommissioningParameters & params);
625 : CHIP_ERROR Commission(NodeId remoteDeviceId);
626 :
627 : /**
628 : * @brief
629 : * This function instructs the commissioner to proceed to the next stage of commissioning after
630 : * attestation is reported to an installed attestation delegate.
631 : *
632 : * @param[in] device The device being commissioned.
633 : * @param[in] attestationResult The attestation result to use instead of whatever the device
634 : * attestation verifier came up with. May be a success or an error result.
635 : */
636 : CHIP_ERROR
637 : ContinueCommissioningAfterDeviceAttestation(DeviceProxy * device, Credentials::AttestationVerificationResult attestationResult);
638 :
639 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
640 : /**
641 : * @brief
642 : * This method instructs the commissioner to proceed to the commissioning complete stage for a device
643 : * that had previously being commissioned until request to connect to network.
644 : *
645 : * @param[in] remoteDeviceId The remote device Id.
646 : */
647 : CHIP_ERROR ContinueCommissioningAfterConnectNetworkRequest(NodeId remoteDeviceId);
648 : #endif
649 :
650 : CHIP_ERROR GetDeviceBeingCommissioned(NodeId deviceId, CommissioneeDeviceProxy ** device);
651 :
652 : /**
653 : * @brief
654 : * This function stops a pairing or commissioning process that is in progress.
655 : * It does not delete the pairing of a previously paired device.
656 : *
657 : * Note that cancelling an ongoing commissioning process is an asynchronous operation.
658 : * The pairing delegate (if any) will receive OnCommissioningComplete and OnCommissioningFailure
659 : * failure callbacks with a status code of CHIP_ERROR_CANCELLED once cancellation is complete.
660 : *
661 : * @param[in] remoteDeviceId The remote device Id.
662 : *
663 : * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error
664 : */
665 : CHIP_ERROR StopPairing(NodeId remoteDeviceId);
666 :
667 : /**
668 : * @brief
669 : * Remove pairing for a paired device. If the device is currently being paired, it'll stop the pairing process.
670 : *
671 : * @param[in] remoteDeviceId The remote device Id.
672 : *
673 : * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error
674 : */
675 : CHIP_ERROR UnpairDevice(NodeId remoteDeviceId);
676 :
677 : //////////// SessionEstablishmentDelegate Implementation ///////////////
678 : void OnSessionEstablishmentError(CHIP_ERROR error) override;
679 : void OnSessionEstablished(const SessionHandle & session) override;
680 :
681 : void RendezvousCleanup(CHIP_ERROR status);
682 :
683 : void PerformCommissioningStep(DeviceProxy * device, CommissioningStage step, CommissioningParameters & params,
684 : CommissioningDelegate * delegate, EndpointId endpoint, Optional<System::Clock::Timeout> timeout);
685 :
686 : /**
687 : * @brief
688 : * This function validates the Attestation Information sent by the device.
689 : *
690 : * @param[in] info Structure containing all the required information for validating the device attestation.
691 : */
692 : CHIP_ERROR ValidateAttestationInfo(const Credentials::DeviceAttestationVerifier::AttestationInfo & info);
693 :
694 : /**
695 : * @brief
696 : * Sends CommissioningStepComplete report to the commissioning delegate. Function will fill in current step.
697 : * @params[in] err error from the current step
698 : * @params[in] report report to send. Current step will be filled in automatically
699 : */
700 : void
701 : CommissioningStageComplete(CHIP_ERROR err,
702 : CommissioningDelegate::CommissioningReport report = CommissioningDelegate::CommissioningReport());
703 :
704 : /**
705 : * @brief
706 : * This function is called by the DevicePairingDelegate to indicate that network credentials have been set
707 : * on the CommissioningParameters of the CommissioningDelegate using CommissioningDelegate.SetCommissioningParameters().
708 : * As a result, commissioning can advance to the next stage.
709 : *
710 : * The DevicePairingDelegate may call this method from the OnScanNetworksSuccess and OnScanNetworksFailure callbacks,
711 : * or it may call this method after obtaining network credentials using asynchronous methods (prompting user, cloud API call,
712 : * etc).
713 : *
714 : * If an error happens in the subsequent network commissioning step (either NetworkConfig or ConnectNetwork commands)
715 : * then the DevicePairingDelegate will receive the error in completionStatus.networkCommissioningStatus and the
716 : * commissioning stage will return to kNeedsNetworkCreds so that the DevicePairingDelegate can re-attempt with new
717 : * network information. The DevicePairingDelegate can exit the commissioning process by calling StopPairing.
718 : *
719 : * @return CHIP_ERROR The return status. Returns CHIP_ERROR_INCORRECT_STATE if not in the correct state (kNeedsNetworkCreds).
720 : */
721 : CHIP_ERROR NetworkCredentialsReady();
722 :
723 : /**
724 : * @brief
725 : * This function is called by the DevicePairingDelegate to indicate that ICD registration info (ICDSymmetricKey,
726 : * ICDCheckInNodeId and ICDMonitoredSubject) have been set on the CommissioningParameters of the CommissioningDelegate
727 : * using CommissioningDelegate.SetCommissioningParameters(). As a result, commissioning can advance to the next stage.
728 : *
729 : * The DevicePairingDelegate may call this method from the OnICDRegistrationInfoRequired callback, or it may call this
730 : * method after obtaining required parameters for ICD registration using asynchronous methods (like RPC call etc).
731 : *
732 : * When the ICD Registration completes, OnICDRegistrationComplete will be called.
733 : *
734 : * @return CHIP_ERROR The return status. Returns CHIP_ERROR_INCORRECT_STATE if not in the correct state
735 : * (kICDGetRegistrationInfo).
736 : */
737 : CHIP_ERROR ICDRegistrationInfoReady();
738 :
739 : /**
740 : * @brief
741 : * This function returns the current CommissioningStage for this commissioner.
742 : */
743 0 : CommissioningStage GetCommissioningStage() { return mCommissioningStage; }
744 :
745 : #if CONFIG_NETWORK_LAYER_BLE
746 : #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
747 : /**
748 : * @brief
749 : * Prior to commissioning, the Controller should make sure the BleLayer transport
750 : * is set to the Commissioner transport and not the Server transport.
751 : */
752 : void ConnectBleTransportToSelf();
753 : #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
754 :
755 : /**
756 : * @brief
757 : * Once we have finished all commissioning work, the Controller should close the BLE
758 : * connection to the device and establish CASE session / another PASE session to the device
759 : * if needed.
760 : */
761 : void CloseBleConnection();
762 : #endif
763 :
764 : /**
765 : * @brief
766 : * Discover all devices advertising as commissionable.
767 : * Should be called on main loop thread.
768 : * * @param[in] filter Browse filter - controller will look for only the specified subtype.
769 : * @return CHIP_ERROR The return status
770 : */
771 : CHIP_ERROR DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter);
772 :
773 : /**
774 : * Stop commissionable discovery triggered by a previous
775 : * DiscoverCommissionableNodes call.
776 : */
777 : CHIP_ERROR StopCommissionableDiscovery();
778 :
779 : /**
780 : * @brief
781 : * Returns information about discovered devices.
782 : * Should be called on main loop thread.
783 : * @return const DiscoveredNodeData* info about the selected device. May be nullptr if no information has been returned yet.
784 : */
785 : const Dnssd::CommissionNodeData * GetDiscoveredDevice(int idx);
786 :
787 : /**
788 : * @brief
789 : * Returns the max number of commissionable nodes this commissioner can track mdns information for.
790 : * @return int The max number of commissionable nodes supported
791 : */
792 : int GetMaxCommissionableNodesSupported() { return kMaxCommissionableNodes; }
793 :
794 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
795 : /**
796 : * @brief
797 : * Called when a UDC message is received specifying the given instanceName
798 : * This method indicates that UDC Server needs the Commissionable Node corresponding to
799 : * the given instance name to be found. UDC Server will wait for OnCommissionableNodeFound.
800 : *
801 : * @param instanceName DNS-SD instance name for the client requesting commissioning
802 : *
803 : */
804 : void FindCommissionableNode(const char * instanceName) override;
805 :
806 : /**
807 : * @brief
808 : * Return the UDC Server instance
809 : *
810 : */
811 : Protocols::UserDirectedCommissioning::UserDirectedCommissioningServer * GetUserDirectedCommissioningServer()
812 : {
813 : return mUdcServer;
814 : }
815 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
816 :
817 : /**
818 : * @brief
819 : * Overrides method from AbstractDnssdDiscoveryController
820 : *
821 : * @param nodeData DNS-SD node information
822 : *
823 : */
824 : void OnNodeDiscovered(const chip::Dnssd::DiscoveredNodeData & nodeData) override;
825 :
826 4 : void RegisterPairingDelegate(DevicePairingDelegate * pairingDelegate) { mPairingDelegate = pairingDelegate; }
827 2 : DevicePairingDelegate * GetPairingDelegate() const { return mPairingDelegate; }
828 :
829 : #if CHIP_CONFIG_ENABLE_READ_CLIENT
830 : // ClusterStateCache::Callback impl
831 : void OnDone(app::ReadClient *) override;
832 : #endif // CHIP_CONFIG_ENABLE_READ_CLIENT
833 :
834 : // Issue an NOC chain using the associated OperationalCredentialsDelegate. The NOC chain will
835 : // be provided in X509 DER format.
836 : // NOTE: This is only valid assuming that `mOperationalCredentialsDelegate` is what is desired
837 : // to issue the NOC chain.
838 : CHIP_ERROR IssueNOCChain(const ByteSpan & NOCSRElements, NodeId nodeId,
839 : chip::Callback::Callback<OnNOCChainGeneration> * callback);
840 :
841 : void SetDeviceAttestationVerifier(Credentials::DeviceAttestationVerifier * deviceAttestationVerifier)
842 : {
843 : mDeviceAttestationVerifier = deviceAttestationVerifier;
844 : }
845 :
846 : Credentials::DeviceAttestationVerifier * GetDeviceAttestationVerifier() const { return mDeviceAttestationVerifier; }
847 :
848 0 : const CommissioningParameters & GetCommissioningParameters() { return mDefaultCommissioner->GetCommissioningParameters(); }
849 :
850 : CHIP_ERROR UpdateCommissioningParameters(const CommissioningParameters & newParameters)
851 : {
852 : return mDefaultCommissioner->SetCommissioningParameters(newParameters);
853 : }
854 :
855 : // Reset the arm failsafe timer during commissioning. If this returns
856 : // false, that means that the timer was already set for a longer time period
857 : // than the new time we are trying to set. In this case, neither
858 : // onSuccess nor onFailure will be called.
859 0 : bool ExtendArmFailSafe(DeviceProxy * proxy, CommissioningStage step, uint16_t armFailSafeTimeout,
860 : Optional<System::Clock::Timeout> commandTimeout, OnExtendFailsafeSuccess onSuccess,
861 : OnExtendFailsafeFailure onFailure)
862 : {
863 : // If this method is called directly by a client, assume it's fire-and-forget (not a commissioning stage)
864 0 : return ExtendArmFailSafeInternal(proxy, step, armFailSafeTimeout, commandTimeout, onSuccess, onFailure,
865 0 : /* fireAndForget = */ true);
866 : }
867 :
868 : // Check if the commissioning mode is valid for the current commissioning parameters.
869 : virtual bool HasValidCommissioningMode(const Dnssd::CommissionNodeData & nodeData);
870 :
871 : protected:
872 : // Cleans up and resets failsafe as appropriate depending on the error and the failed stage.
873 : // For success, sends completion report with the CommissioningDelegate and sends callbacks to the PairingDelegate
874 : // For failures after AddNOC succeeds, sends completion report with the CommissioningDelegate and sends callbacks to the
875 : // PairingDelegate. In this case, it does not disarm the failsafe or close the pase connection. For failures up through AddNOC,
876 : // sends a command to immediately expire the failsafe, then sends completion report with the CommissioningDelegate and callbacks
877 : // to the PairingDelegate upon arm failsafe command completion.
878 : virtual void CleanupCommissioning(DeviceProxy * proxy, NodeId nodeId, const CompletionStatus & completionStatus);
879 :
880 : /* This function start the JCM verification steps
881 : */
882 0 : virtual CHIP_ERROR StartJCMTrustVerification(DeviceProxy * proxy) { return CHIP_ERROR_NOT_IMPLEMENTED; }
883 :
884 : #if CHIP_CONFIG_ENABLE_READ_CLIENT
885 2 : virtual CHIP_ERROR ParseExtraCommissioningInfo(ReadCommissioningInfo & info, const CommissioningParameters & params)
886 : {
887 2 : return CHIP_NO_ERROR;
888 : }
889 : #endif // CHIP_CONFIG_ENABLE_READ_CLIENT
890 :
891 : #if CHIP_CONFIG_ENABLE_READ_CLIENT
892 : Platform::UniquePtr<app::ClusterStateCache> mAttributeCache;
893 : Platform::UniquePtr<app::ReadClient> mReadClient;
894 : #endif // CHIP_CONFIG_ENABLE_READ_CLIENT
895 :
896 : private:
897 : DevicePairingDelegate * mPairingDelegate = nullptr;
898 :
899 : DeviceProxy * mDeviceBeingCommissioned = nullptr;
900 : CommissioneeDeviceProxy * mDeviceInPASEEstablishment = nullptr;
901 :
902 : Optional<System::Clock::Timeout> mCommissioningStepTimeout; // Note: For multi-interaction steps this is per interaction
903 : CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing;
904 : uint8_t mReadCommissioningInfoProgress = 0; // see ContinueReadingCommissioningInfo()
905 :
906 : // Stores the PASE session address to use as fallback during operational discovery
907 : Optional<AddressResolve::ResolveResult> mFallbackOperationalResolveResult;
908 :
909 : bool mRunCommissioningAfterConnection = false;
910 : Internal::InvokeCancelFn mInvokeCancelFn;
911 : Internal::WriteCancelFn mWriteCancelFn;
912 :
913 : ObjectPool<CommissioneeDeviceProxy, kNumMaxActiveDevices> mCommissioneeDevicePool;
914 :
915 : // While we have an ongoing PASE attempt (i.e. after calling Pair() on the
916 : // PASESession), track which RendezvousParameters we used for that attempt.
917 : // This allows us to notify delegates about which thing it was we actually
918 : // established PASE with, especially in the context of concatenated QR
919 : // codes.
920 : //
921 : // This member only has a value while we are in the middle of session
922 : // establishment.
923 : std::optional<RendezvousParameters> mRendezvousParametersForPASEEstablishment;
924 :
925 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
926 : Protocols::UserDirectedCommissioning::UserDirectedCommissioningServer * mUdcServer = nullptr;
927 : // mUdcTransportMgr is for insecure communication (ex. user directed commissioning)
928 : UdcTransportMgr * mUdcTransportMgr = nullptr;
929 : uint16_t mUdcListenPort = CHIP_UDC_PORT;
930 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
931 :
932 : #if CONFIG_NETWORK_LAYER_BLE
933 : static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj);
934 : static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err);
935 : RendezvousParameters mRendezvousParametersForDeviceDiscoveredOverBle;
936 : #endif
937 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
938 : static void OnWiFiPAFSubscribeComplete(void * appState);
939 : static void OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err);
940 : RendezvousParameters mRendezvousParametersForDeviceDiscoveredOverWiFiPAF;
941 : #endif
942 :
943 : static void OnBasicFailure(void * context, CHIP_ERROR err);
944 : static void OnBasicSuccess(void * context, const chip::app::DataModel::NullObjectType &);
945 :
946 : /* This function sends a Device Attestation Certificate chain request to the device.
947 : The function does not hold a reference to the device object.
948 : */
949 : CHIP_ERROR SendCertificateChainRequestCommand(DeviceProxy * device, Credentials::CertificateType certificateType,
950 : Optional<System::Clock::Timeout> timeout);
951 : /* This function sends an Attestation request to the device.
952 : The function does not hold a reference to the device object.
953 : */
954 : CHIP_ERROR SendAttestationRequestCommand(DeviceProxy * device, const ByteSpan & attestationNonce,
955 : Optional<System::Clock::Timeout> timeout);
956 : /* This function sends an CSR request to the device.
957 : The function does not hold a reference to the device object.
958 : */
959 : CHIP_ERROR SendOperationalCertificateSigningRequestCommand(DeviceProxy * device, const ByteSpan & csrNonce,
960 : Optional<System::Clock::Timeout> timeout);
961 : /* This function sends the operational credentials to the device.
962 : The function does not hold a reference to the device object.
963 : */
964 : CHIP_ERROR SendOperationalCertificate(DeviceProxy * device, const ByteSpan & nocCertBuf, const Optional<ByteSpan> & icaCertBuf,
965 : Crypto::IdentityProtectionKeySpan ipk, NodeId adminSubject,
966 : Optional<System::Clock::Timeout> timeout);
967 : /* This function sends the trusted root certificate to the device.
968 : The function does not hold a reference to the device object.
969 : */
970 : CHIP_ERROR SendTrustedRootCertificate(DeviceProxy * device, const ByteSpan & rcac, Optional<System::Clock::Timeout> timeout);
971 :
972 : /* This function is called by the commissioner code when the device completes
973 : the operational credential provisioning process.
974 : The function does not hold a reference to the device object.
975 : */
976 : CHIP_ERROR OnOperationalCredentialsProvisioningCompletion(DeviceProxy * device);
977 :
978 : /* Callback when the previously sent CSR request results in failure */
979 : static void OnCSRFailureResponse(void * context, CHIP_ERROR error);
980 :
981 : void ExtendArmFailSafeForDeviceAttestation(const Credentials::DeviceAttestationVerifier::AttestationInfo & info,
982 : Credentials::AttestationVerificationResult result);
983 : static void OnCertificateChainFailureResponse(void * context, CHIP_ERROR error);
984 : static void OnCertificateChainResponse(
985 : void * context, const app::Clusters::OperationalCredentials::Commands::CertificateChainResponse::DecodableType & response);
986 :
987 : static void OnAttestationFailureResponse(void * context, CHIP_ERROR error);
988 : static void
989 : OnAttestationResponse(void * context,
990 : const app::Clusters::OperationalCredentials::Commands::AttestationResponse::DecodableType & data);
991 :
992 : /**
993 : * @brief
994 : * This function is called by the IM layer when the commissioner receives the CSR from the device.
995 : * (Reference: Specifications section 11.18.5.6. NOCSR Elements)
996 : *
997 : * @param[in] context The context provided while registering the callback.
998 : * @param[in] data The response struct containing the following fields:
999 : * NOCSRElements: CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
1000 : * AttestationSignature: Cryptographic signature generated for the fields in the response
1001 : * message.
1002 : */
1003 : static void OnOperationalCertificateSigningRequest(
1004 : void * context, const app::Clusters::OperationalCredentials::Commands::CSRResponse::DecodableType & data);
1005 :
1006 : /* Callback when adding operational certs to device results in failure */
1007 : static void OnAddNOCFailureResponse(void * context, CHIP_ERROR errro);
1008 : /* Callback when the device confirms that it has added the operational certificates */
1009 : static void
1010 : OnOperationalCertificateAddResponse(void * context,
1011 : const app::Clusters::OperationalCredentials::Commands::NOCResponse::DecodableType & data);
1012 :
1013 : /* Callback when the device confirms that it has added the root certificate */
1014 : static void OnRootCertSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &);
1015 : /* Callback called when adding root cert to device results in failure */
1016 : static void OnRootCertFailureResponse(void * context, CHIP_ERROR error);
1017 :
1018 : static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
1019 : static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
1020 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
1021 : static void OnDeviceConnectionRetryFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error,
1022 : System::Clock::Seconds16 retryTimeout);
1023 : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
1024 :
1025 : static void OnDeviceAttestationInformationVerification(void * context,
1026 : const Credentials::DeviceAttestationVerifier::AttestationInfo & info,
1027 : Credentials::AttestationVerificationResult result);
1028 :
1029 : static void OnDeviceNOCChainGeneration(void * context, CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac,
1030 : const ByteSpan & rcac, Optional<Crypto::IdentityProtectionKeySpan> ipk,
1031 : Optional<NodeId> adminSubject);
1032 : static void OnArmFailSafe(void * context,
1033 : const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
1034 : static void OnSetRegulatoryConfigResponse(
1035 : void * context,
1036 : const chip::app::Clusters::GeneralCommissioning::Commands::SetRegulatoryConfigResponse::DecodableType & data);
1037 : static void OnSetTCAcknowledgementsResponse(
1038 : void * context,
1039 : const chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType & data);
1040 : static void OnSetUTCError(void * context, CHIP_ERROR error);
1041 : static void
1042 : OnSetTimeZoneResponse(void * context,
1043 : const chip::app::Clusters::TimeSynchronization::Commands::SetTimeZoneResponse::DecodableType & data);
1044 :
1045 : static void
1046 : OnScanNetworksResponse(void * context,
1047 : const app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & data);
1048 : static void OnScanNetworksFailure(void * context, CHIP_ERROR err);
1049 : static void
1050 : OnNetworkConfigResponse(void * context,
1051 : const app::Clusters::NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & data);
1052 : static void OnConnectNetworkResponse(
1053 : void * context, const chip::app::Clusters::NetworkCommissioning::Commands::ConnectNetworkResponse::DecodableType & data);
1054 : static void OnCommissioningCompleteResponse(
1055 : void * context,
1056 : const chip::app::Clusters::GeneralCommissioning::Commands::CommissioningCompleteResponse::DecodableType & data);
1057 : static void OnDisarmFailsafe(void * context,
1058 : const app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
1059 : static void OnDisarmFailsafeFailure(void * context, CHIP_ERROR error);
1060 : void CleanupDoneAfterError();
1061 : static void OnArmFailSafeExtendedForDeviceAttestation(
1062 : void * context, const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
1063 : static void OnFailedToExtendedArmFailSafeDeviceAttestation(void * context, CHIP_ERROR error);
1064 : void HandleDeviceAttestationCompleted();
1065 :
1066 : static void OnICDManagementRegisterClientResponse(
1067 : void * context, const app::Clusters::IcdManagement::Commands::RegisterClientResponse::DecodableType & data);
1068 :
1069 : static void
1070 : OnICDManagementStayActiveResponse(void * context,
1071 : const app::Clusters::IcdManagement::Commands::StayActiveResponse::DecodableType & data);
1072 :
1073 : /**
1074 : * @brief
1075 : * This function processes the CSR sent by the device.
1076 : * (Reference: Specifications section 11.18.5.6. NOCSR Elements)
1077 : *
1078 : * @param[in] proxy device proxy
1079 : * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
1080 : * @param[in] AttestationSignature Cryptographic signature generated for all the above fields.
1081 : * @param[in] dac device attestation certificate
1082 : * @param[in] pai Product Attestation Intermediate certificate
1083 : * @param[in] csrNonce certificate signing request nonce
1084 : */
1085 : CHIP_ERROR ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature,
1086 : const ByteSpan & dac, const ByteSpan & pai, const ByteSpan & csrNonce);
1087 :
1088 : /**
1089 : * @brief
1090 : * This function validates the CSR information from the device.
1091 : * (Reference: Specifications section 11.18.5.6. NOCSR Elements)
1092 : *
1093 : * @param[in] proxy device proxy
1094 : * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
1095 : * @param[in] AttestationSignature Cryptographic signature generated for all the above fields.
1096 : * @param[in] dac device attestation certificate
1097 : * @param[in] csrNonce certificate signing request nonce
1098 : */
1099 : CHIP_ERROR ValidateCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature,
1100 : const ByteSpan & dac, const ByteSpan & csrNonce);
1101 :
1102 : /**
1103 : * @brief
1104 : * This function validates the revocation status of the DAC Chain sent by the device.
1105 : *
1106 : * @param[in] info Structure containing all the required information for validating the device attestation.
1107 : */
1108 : CHIP_ERROR CheckForRevokedDACChain(const Credentials::DeviceAttestationVerifier::AttestationInfo & info);
1109 :
1110 : CommissioneeDeviceProxy * FindCommissioneeDevice(NodeId id);
1111 : CommissioneeDeviceProxy * FindCommissioneeDevice(const Transport::PeerAddress & peerAddress);
1112 : void ReleaseCommissioneeDevice(CommissioneeDeviceProxy * device);
1113 :
1114 : bool ExtendArmFailSafeInternal(DeviceProxy * proxy, CommissioningStage step, uint16_t armFailSafeTimeout,
1115 : Optional<System::Clock::Timeout> commandTimeout, OnExtendFailsafeSuccess onSuccess,
1116 : OnExtendFailsafeFailure onFailure, bool fireAndForget);
1117 : template <typename RequestObjectT>
1118 : CHIP_ERROR SendCommissioningCommand(DeviceProxy * device, const RequestObjectT & request,
1119 : CommandResponseSuccessCallback<typename RequestObjectT::ResponseType> successCb,
1120 : CommandResponseFailureCallback failureCb, EndpointId endpoint,
1121 : Optional<System::Clock::Timeout> timeout = NullOptional, bool fireAndForget = false);
1122 : void SendCommissioningReadRequest(DeviceProxy * proxy, Optional<System::Clock::Timeout> timeout,
1123 : app::AttributePathParams * readPaths, size_t readPathsSize);
1124 : template <typename AttrType>
1125 : CHIP_ERROR SendCommissioningWriteRequest(DeviceProxy * device, EndpointId endpoint, ClusterId cluster, AttributeId attribute,
1126 : const AttrType & requestData, WriteResponseSuccessCallback successCb,
1127 : WriteResponseFailureCallback failureCb);
1128 : void CancelCommissioningInteractions();
1129 : void CancelCASECallbacks();
1130 :
1131 : #if CHIP_CONFIG_ENABLE_READ_CLIENT
1132 : void ContinueReadingCommissioningInfo(const CommissioningParameters & params);
1133 : void FinishReadingCommissioningInfo(const CommissioningParameters & params);
1134 : CHIP_ERROR ParseGeneralCommissioningInfo(ReadCommissioningInfo & info);
1135 : CHIP_ERROR ParseBasicInformation(ReadCommissioningInfo & info);
1136 : CHIP_ERROR ParseNetworkCommissioningInfo(ReadCommissioningInfo & info);
1137 : CHIP_ERROR ParseNetworkCommissioningTimeouts(NetworkClusterInfo & networkInfo, const char * networkType);
1138 : CHIP_ERROR ParseFabrics(ReadCommissioningInfo & info);
1139 : CHIP_ERROR ParseICDInfo(ReadCommissioningInfo & info);
1140 : CHIP_ERROR ParseTimeSyncInfo(ReadCommissioningInfo & info);
1141 : #endif // CHIP_CONFIG_ENABLE_READ_CLIENT
1142 :
1143 : static CHIP_ERROR
1144 : ConvertFromOperationalCertStatus(chip::app::Clusters::OperationalCredentials::NodeOperationalCertStatusEnum err);
1145 :
1146 : // Sends commissioning complete callbacks to the delegate depending on the status. Sends
1147 : // OnCommissioningComplete and either OnCommissioningSuccess or OnCommissioningFailure depending on the given completion status.
1148 : void SendCommissioningCompleteCallbacks(NodeId nodeId, const CompletionStatus & completionStatus);
1149 :
1150 : // Extend the fail-safe before trying to do network-enable (since after that
1151 : // point, for non-concurrent-commissioning devices, we may not have a way to
1152 : // extend it).
1153 : void ExtendFailsafeBeforeNetworkEnable(DeviceProxy * device, CommissioningParameters & params, CommissioningStage step);
1154 :
1155 : bool IsAttestationInformationMissing(const CommissioningParameters & params);
1156 :
1157 : #if CHIP_SUPPORT_THREAD_MESHCOP
1158 : CHIP_ERROR PairThreadMeshcop(RendezvousParameters & rendezvousParams, CommissioningParameters & commissioningParams);
1159 :
1160 : ThreadMeshcopCommissionProxy mThreadMeshcopCommissionProxy;
1161 : #endif
1162 :
1163 : chip::Callback::Callback<OnDeviceConnected> mOnDeviceConnectedCallback;
1164 : chip::Callback::Callback<OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback;
1165 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
1166 : chip::Callback::Callback<OnDeviceConnectionRetry> mOnDeviceConnectionRetryCallback;
1167 : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
1168 :
1169 : chip::Callback::Callback<Credentials::DeviceAttestationVerifier::OnAttestationInformationVerification>
1170 : mDeviceAttestationInformationVerificationCallback;
1171 :
1172 : chip::Callback::Callback<OnNOCChainGeneration> mDeviceNOCChainCallback;
1173 : SetUpCodePairer mSetUpCodePairer;
1174 : AutoCommissioner mAutoCommissioner;
1175 : CommissioningDelegate * mDefaultCommissioner =
1176 : &mAutoCommissioner; // Commissioning delegate to call when PairDevice / Commission functions are used
1177 : CommissioningDelegate * mCommissioningDelegate =
1178 : nullptr; // Commissioning delegate that issued the PerformCommissioningStep command
1179 : CompletionStatus mCommissioningCompletionStatus;
1180 : Credentials::AttestationVerificationResult mAttestationResult;
1181 : Platform::UniquePtr<Credentials::DeviceAttestationVerifier::AttestationDeviceInfo> mAttestationDeviceInfo;
1182 : Credentials::DeviceAttestationVerifier * mDeviceAttestationVerifier = nullptr;
1183 :
1184 : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
1185 : Optional<Crypto::P256PublicKey> mTrustedIcacPublicKeyB;
1186 : EndpointId mPeerAdminJFAdminClusterEndpointId = kInvalidEndpointId;
1187 : #endif
1188 : };
1189 :
1190 : } // namespace Controller
1191 : } // namespace chip
|