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