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