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 0 : ~DeviceController() override {}
183 :
184 : 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 : /**
491 : * Commissioner-specific initialization, includes parameters such as the pairing delegate.
492 : */
493 : CHIP_ERROR Init(CommissionerInitParams params);
494 :
495 : /**
496 : * @brief
497 : * Tears down the entirety of the stack, including destructing key objects in the system.
498 : * This is not a thread-safe API, and should be called with external synchronization.
499 : *
500 : * Please see implementation for more details.
501 : */
502 : void Shutdown() override;
503 :
504 : // ----- Connection Management -----
505 : /**
506 : * @brief
507 : * Pair a CHIP device with the provided code. The code can be either a QRCode
508 : * or a Manual Setup Code.
509 : * Use registered DevicePairingDelegate object to receive notifications on
510 : * pairing status updates.
511 : *
512 : * Note: Pairing process requires that the caller has registered PersistentStorageDelegate
513 : * in the Init() call.
514 : *
515 : * @param[in] remoteDeviceId The remote device Id.
516 : * @param[in] setUpCode The setup code for connecting to the device
517 : * @param[in] discoveryType The network discovery type, defaults to DiscoveryType::kAll.
518 : * @param[in] resolutionData Optional resolution data previously discovered on the network for the target device.
519 : */
520 : CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode, DiscoveryType discoveryType = DiscoveryType::kAll,
521 : Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
522 : CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode, const CommissioningParameters & CommissioningParameters,
523 : DiscoveryType discoveryType = DiscoveryType::kAll,
524 : Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
525 :
526 : /**
527 : * @brief
528 : * Pair a CHIP device with the provided Rendezvous connection parameters.
529 : * Use registered DevicePairingDelegate object to receive notifications on
530 : * pairing status updates.
531 : *
532 : * Note: Pairing process requires that the caller has registered PersistentStorageDelegate
533 : * in the Init() call.
534 : *
535 : * @param[in] remoteDeviceId The remote device Id.
536 : * @param[in] rendezvousParams The Rendezvous connection parameters
537 : */
538 : CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams);
539 :
540 : /**
541 : * @overload
542 : * @param[in] remoteDeviceId The remote device Id.
543 : * @param[in] rendezvousParams The Rendezvous connection parameters
544 : * @param[in] commissioningParams The commissioning parameters (uses default if not supplied)
545 : */
546 : CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams,
547 : CommissioningParameters & commissioningParams);
548 :
549 : /**
550 : * @brief
551 : * Start establishing a PASE connection with a node for the purposes of commissioning.
552 : * Commissioners that wish to use the auto-commissioning functions should use the
553 : * supplied "PairDevice" functions above to automatically establish a connection then
554 : * perform commissioning. This function is intended to be use by commissioners that
555 : * are not using the supplied auto-commissioner.
556 : *
557 : * This function is non-blocking. PASE is established once the DevicePairingDelegate
558 : * receives the OnPairingComplete call.
559 : *
560 : * PASE connections can only be established with nodes that have their commissioning
561 : * window open. The PASE connection will fail if this window is not open and the
562 : * OnPairingComplete will be called with an error.
563 : *
564 : * @param[in] remoteDeviceId The remote device Id.
565 : * @param[in] params The Rendezvous connection parameters
566 : */
567 : CHIP_ERROR EstablishPASEConnection(NodeId remoteDeviceId, RendezvousParameters & params);
568 :
569 : /**
570 : * @brief
571 : * Start establishing a PASE connection with a node for the purposes of commissioning.
572 : * Commissioners that wish to use the auto-commissioning functions should use the
573 : * supplied "PairDevice" functions above to automatically establish a connection then
574 : * perform commissioning. This function is intended to be used by commissioners that
575 : * are not using the supplied auto-commissioner.
576 : *
577 : * This function is non-blocking. PASE is established once the DevicePairingDelegate
578 : * receives the OnPairingComplete call.
579 : *
580 : * PASE connections can only be established with nodes that have their commissioning
581 : * window open. The PASE connection will fail if this window is not open and in that case
582 : * OnPairingComplete will be called with an error.
583 : *
584 : * @param[in] remoteDeviceId The remote device Id.
585 : * @param[in] setUpCode The setup code for connecting to the device
586 : * @param[in] discoveryType The network discovery type, defaults to DiscoveryType::kAll.
587 : * @param[in] resolutionData Optional resolution data previously discovered on the network for the target device.
588 : */
589 : CHIP_ERROR EstablishPASEConnection(NodeId remoteDeviceId, const char * setUpCode,
590 : DiscoveryType discoveryType = DiscoveryType::kAll,
591 : Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
592 :
593 : /**
594 : * @brief
595 : * Start the auto-commissioning process on a node after establishing a PASE connection.
596 : * This function is intended to be used in conjunction with the EstablishPASEConnection
597 : * function. It can be called either before or after the DevicePairingDelegate receives
598 : * the OnPairingComplete call. Commissioners that want to perform simple auto-commissioning
599 : * should use the supplied "PairDevice" functions above, which will establish the PASE
600 : * connection and commission automatically.
601 : *
602 : * @param[in] remoteDeviceId The remote device Id.
603 : * @param[in] params The commissioning parameters
604 : */
605 : CHIP_ERROR Commission(NodeId remoteDeviceId, CommissioningParameters & params);
606 : CHIP_ERROR Commission(NodeId remoteDeviceId);
607 :
608 : /**
609 : * @brief
610 : * This function instructs the commissioner to proceed to the next stage of commissioning after
611 : * attestation is reported to an installed attestation delegate.
612 : *
613 : * @param[in] device The device being commissioned.
614 : * @param[in] attestationResult The attestation result to use instead of whatever the device
615 : * attestation verifier came up with. May be a success or an error result.
616 : */
617 : CHIP_ERROR
618 : ContinueCommissioningAfterDeviceAttestation(DeviceProxy * device, Credentials::AttestationVerificationResult attestationResult);
619 :
620 : CHIP_ERROR GetDeviceBeingCommissioned(NodeId deviceId, CommissioneeDeviceProxy ** device);
621 :
622 : /**
623 : * @brief
624 : * This function stops a pairing or commissioning process that is in progress.
625 : * It does not delete the pairing of a previously paired device.
626 : *
627 : * Note that cancelling an ongoing commissioning process is an asynchronous operation.
628 : * The pairing delegate (if any) will receive OnCommissioningComplete and OnCommissioningFailure
629 : * failure callbacks with a status code of CHIP_ERROR_CANCELLED once cancellation is complete.
630 : *
631 : * @param[in] remoteDeviceId The remote device Id.
632 : *
633 : * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error
634 : */
635 : CHIP_ERROR StopPairing(NodeId remoteDeviceId);
636 :
637 : /**
638 : * @brief
639 : * Remove pairing for a paired device. If the device is currently being paired, it'll stop the pairing process.
640 : *
641 : * @param[in] remoteDeviceId The remote device Id.
642 : *
643 : * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error
644 : */
645 : CHIP_ERROR UnpairDevice(NodeId remoteDeviceId);
646 :
647 : //////////// SessionEstablishmentDelegate Implementation ///////////////
648 : void OnSessionEstablishmentError(CHIP_ERROR error) override;
649 : void OnSessionEstablished(const SessionHandle & session) override;
650 :
651 : void RendezvousCleanup(CHIP_ERROR status);
652 :
653 : void PerformCommissioningStep(DeviceProxy * device, CommissioningStage step, CommissioningParameters & params,
654 : CommissioningDelegate * delegate, EndpointId endpoint, Optional<System::Clock::Timeout> timeout);
655 :
656 : /**
657 : * @brief
658 : * This function validates the Attestation Information sent by the device.
659 : *
660 : * @param[in] info Structure containing all the required information for validating the device attestation.
661 : */
662 : CHIP_ERROR ValidateAttestationInfo(const Credentials::DeviceAttestationVerifier::AttestationInfo & info);
663 :
664 : /**
665 : * @brief
666 : * Sends CommissioningStepComplete report to the commissioning delegate. Function will fill in current step.
667 : * @params[in] err error from the current step
668 : * @params[in] report report to send. Current step will be filled in automatically
669 : */
670 : void
671 : CommissioningStageComplete(CHIP_ERROR err,
672 : CommissioningDelegate::CommissioningReport report = CommissioningDelegate::CommissioningReport());
673 :
674 : /**
675 : * @brief
676 : * This function is called by the DevicePairingDelegate to indicate that network credentials have been set
677 : * on the CommissioningParameters of the CommissioningDelegate using CommissioningDelegate.SetCommissioningParameters().
678 : * As a result, commissioning can advance to the next stage.
679 : *
680 : * The DevicePairingDelegate may call this method from the OnScanNetworksSuccess and OnScanNetworksFailure callbacks,
681 : * or it may call this method after obtaining network credentials using asynchronous methods (prompting user, cloud API call,
682 : * etc).
683 : *
684 : * If an error happens in the subsequent network commissioning step (either NetworkConfig or ConnectNetwork commands)
685 : * then the DevicePairingDelegate will receive the error in completionStatus.networkCommissioningStatus and the
686 : * commissioning stage will return to kNeedsNetworkCreds so that the DevicePairingDelegate can re-attempt with new
687 : * network information. The DevicePairingDelegate can exit the commissioning process by calling StopPairing.
688 : *
689 : * @return CHIP_ERROR The return status. Returns CHIP_ERROR_INCORRECT_STATE if not in the correct state (kNeedsNetworkCreds).
690 : */
691 : CHIP_ERROR NetworkCredentialsReady();
692 :
693 : /**
694 : * @brief
695 : * This function is called by the DevicePairingDelegate to indicate that ICD registration info (ICDSymmetricKey,
696 : * ICDCheckInNodeId and ICDMonitoredSubject) have been set on the CommissioningParameters of the CommissioningDelegate
697 : * using CommissioningDelegate.SetCommissioningParameters(). As a result, commissioning can advance to the next stage.
698 : *
699 : * The DevicePairingDelegate may call this method from the OnICDRegistrationInfoRequired callback, or it may call this
700 : * method after obtaining required parameters for ICD registration using asynchronous methods (like RPC call etc).
701 : *
702 : * When the ICD Registration completes, OnICDRegistrationComplete will be called.
703 : *
704 : * @return CHIP_ERROR The return status. Returns CHIP_ERROR_INCORRECT_STATE if not in the correct state
705 : * (kICDGetRegistrationInfo).
706 : */
707 : CHIP_ERROR ICDRegistrationInfoReady();
708 :
709 : /**
710 : * @brief
711 : * This function returns the current CommissioningStage for this commissioner.
712 : */
713 0 : CommissioningStage GetCommissioningStage() { return mCommissioningStage; }
714 :
715 : #if CONFIG_NETWORK_LAYER_BLE
716 : #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
717 : /**
718 : * @brief
719 : * Prior to commissioning, the Controller should make sure the BleLayer transport
720 : * is set to the Commissioner transport and not the Server transport.
721 : */
722 : void ConnectBleTransportToSelf();
723 : #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
724 :
725 : /**
726 : * @brief
727 : * Once we have finished all commissioning work, the Controller should close the BLE
728 : * connection to the device and establish CASE session / another PASE session to the device
729 : * if needed.
730 : */
731 : void CloseBleConnection();
732 : #endif
733 :
734 : /**
735 : * @brief
736 : * Discover all devices advertising as commissionable.
737 : * Should be called on main loop thread.
738 : * * @param[in] filter Browse filter - controller will look for only the specified subtype.
739 : * @return CHIP_ERROR The return status
740 : */
741 : CHIP_ERROR DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter);
742 :
743 : /**
744 : * Stop commissionable discovery triggered by a previous
745 : * DiscoverCommissionableNodes call.
746 : */
747 : CHIP_ERROR StopCommissionableDiscovery();
748 :
749 : /**
750 : * @brief
751 : * Returns information about discovered devices.
752 : * Should be called on main loop thread.
753 : * @return const DiscoveredNodeData* info about the selected device. May be nullptr if no information has been returned yet.
754 : */
755 : const Dnssd::CommissionNodeData * GetDiscoveredDevice(int idx);
756 :
757 : /**
758 : * @brief
759 : * Returns the max number of commissionable nodes this commissioner can track mdns information for.
760 : * @return int The max number of commissionable nodes supported
761 : */
762 : int GetMaxCommissionableNodesSupported() { return kMaxCommissionableNodes; }
763 :
764 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
765 : /**
766 : * @brief
767 : * Called when a UDC message is received specifying the given instanceName
768 : * This method indicates that UDC Server needs the Commissionable Node corresponding to
769 : * the given instance name to be found. UDC Server will wait for OnCommissionableNodeFound.
770 : *
771 : * @param instanceName DNS-SD instance name for the client requesting commissioning
772 : *
773 : */
774 : void FindCommissionableNode(char * instanceName) override;
775 :
776 : /**
777 : * @brief
778 : * Return the UDC Server instance
779 : *
780 : */
781 : Protocols::UserDirectedCommissioning::UserDirectedCommissioningServer * GetUserDirectedCommissioningServer()
782 : {
783 : return mUdcServer;
784 : }
785 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
786 :
787 : /**
788 : * @brief
789 : * Overrides method from AbstractDnssdDiscoveryController
790 : *
791 : * @param nodeData DNS-SD node information
792 : *
793 : */
794 : void OnNodeDiscovered(const chip::Dnssd::DiscoveredNodeData & nodeData) override;
795 :
796 0 : void RegisterPairingDelegate(DevicePairingDelegate * pairingDelegate) { mPairingDelegate = pairingDelegate; }
797 0 : DevicePairingDelegate * GetPairingDelegate() const { return mPairingDelegate; }
798 :
799 : #if CHIP_CONFIG_ENABLE_READ_CLIENT
800 : // ClusterStateCache::Callback impl
801 : void OnDone(app::ReadClient *) override;
802 : #endif // CHIP_CONFIG_ENABLE_READ_CLIENT
803 :
804 : // Issue an NOC chain using the associated OperationalCredentialsDelegate. The NOC chain will
805 : // be provided in X509 DER format.
806 : // NOTE: This is only valid assuming that `mOperationalCredentialsDelegate` is what is desired
807 : // to issue the NOC chain.
808 : CHIP_ERROR IssueNOCChain(const ByteSpan & NOCSRElements, NodeId nodeId,
809 : chip::Callback::Callback<OnNOCChainGeneration> * callback);
810 :
811 : void SetDeviceAttestationVerifier(Credentials::DeviceAttestationVerifier * deviceAttestationVerifier)
812 : {
813 : mDeviceAttestationVerifier = deviceAttestationVerifier;
814 : }
815 :
816 : Credentials::DeviceAttestationVerifier * GetDeviceAttestationVerifier() const { return mDeviceAttestationVerifier; }
817 :
818 : Optional<CommissioningParameters> GetCommissioningParameters()
819 : {
820 : // TODO: Return a non-optional const & to avoid a copy, mDefaultCommissioner is never null
821 : return mDefaultCommissioner == nullptr ? NullOptional : MakeOptional(mDefaultCommissioner->GetCommissioningParameters());
822 : }
823 :
824 : // Reset the arm failsafe timer during commissioning. If this returns
825 : // false, that means that the timer was already set for a longer time period
826 : // than the new time we are trying to set. In this case, neither
827 : // onSuccess nor onFailure will be called.
828 0 : bool ExtendArmFailSafe(DeviceProxy * proxy, CommissioningStage step, uint16_t armFailSafeTimeout,
829 : Optional<System::Clock::Timeout> commandTimeout, OnExtendFailsafeSuccess onSuccess,
830 : OnExtendFailsafeFailure onFailure)
831 : {
832 : // If this method is called directly by a client, assume it's fire-and-forget (not a commissioning stage)
833 0 : return ExtendArmFailSafeInternal(proxy, step, armFailSafeTimeout, commandTimeout, onSuccess, onFailure,
834 0 : /* fireAndForget = */ true);
835 : }
836 :
837 : private:
838 : DevicePairingDelegate * mPairingDelegate = nullptr;
839 :
840 : DeviceProxy * mDeviceBeingCommissioned = nullptr;
841 : CommissioneeDeviceProxy * mDeviceInPASEEstablishment = nullptr;
842 :
843 : Optional<System::Clock::Timeout> mCommissioningStepTimeout; // Note: For multi-interaction steps this is per interaction
844 : CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing;
845 : uint8_t mReadCommissioningInfoProgress = 0; // see ContinueReadingCommissioningInfo()
846 :
847 : bool mRunCommissioningAfterConnection = false;
848 : Internal::InvokeCancelFn mInvokeCancelFn;
849 : Internal::WriteCancelFn mWriteCancelFn;
850 :
851 : ObjectPool<CommissioneeDeviceProxy, kNumMaxActiveDevices> mCommissioneeDevicePool;
852 :
853 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
854 : Protocols::UserDirectedCommissioning::UserDirectedCommissioningServer * mUdcServer = nullptr;
855 : // mUdcTransportMgr is for insecure communication (ex. user directed commissioning)
856 : UdcTransportMgr * mUdcTransportMgr = nullptr;
857 : uint16_t mUdcListenPort = CHIP_UDC_PORT;
858 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
859 :
860 : #if CONFIG_NETWORK_LAYER_BLE
861 : static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj);
862 : static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err);
863 : RendezvousParameters mRendezvousParametersForDeviceDiscoveredOverBle;
864 : #endif
865 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
866 : static void OnWiFiPAFSubscribeComplete(void * appState);
867 : static void OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err);
868 : RendezvousParameters mRendezvousParametersForDeviceDiscoveredOverWiFiPAF;
869 : #endif
870 :
871 : static void OnBasicFailure(void * context, CHIP_ERROR err);
872 : static void OnBasicSuccess(void * context, const chip::app::DataModel::NullObjectType &);
873 :
874 : /* This function sends a Device Attestation Certificate chain request to the device.
875 : The function does not hold a reference to the device object.
876 : */
877 : CHIP_ERROR SendCertificateChainRequestCommand(DeviceProxy * device, Credentials::CertificateType certificateType,
878 : Optional<System::Clock::Timeout> timeout);
879 : /* This function sends an Attestation request to the device.
880 : The function does not hold a reference to the device object.
881 : */
882 : CHIP_ERROR SendAttestationRequestCommand(DeviceProxy * device, const ByteSpan & attestationNonce,
883 : Optional<System::Clock::Timeout> timeout);
884 : /* This function sends an CSR request to the device.
885 : The function does not hold a reference to the device object.
886 : */
887 : CHIP_ERROR SendOperationalCertificateSigningRequestCommand(DeviceProxy * device, const ByteSpan & csrNonce,
888 : Optional<System::Clock::Timeout> timeout);
889 : /* This function sends the operational credentials to the device.
890 : The function does not hold a reference to the device object.
891 : */
892 : CHIP_ERROR SendOperationalCertificate(DeviceProxy * device, const ByteSpan & nocCertBuf, const Optional<ByteSpan> & icaCertBuf,
893 : Crypto::IdentityProtectionKeySpan ipk, NodeId adminSubject,
894 : Optional<System::Clock::Timeout> timeout);
895 : /* This function sends the trusted root certificate to the device.
896 : The function does not hold a reference to the device object.
897 : */
898 : CHIP_ERROR SendTrustedRootCertificate(DeviceProxy * device, const ByteSpan & rcac, Optional<System::Clock::Timeout> timeout);
899 :
900 : /* This function is called by the commissioner code when the device completes
901 : the operational credential provisioning process.
902 : The function does not hold a reference to the device object.
903 : */
904 : CHIP_ERROR OnOperationalCredentialsProvisioningCompletion(DeviceProxy * device);
905 :
906 : /* Callback when the previously sent CSR request results in failure */
907 : static void OnCSRFailureResponse(void * context, CHIP_ERROR error);
908 :
909 : void ExtendArmFailSafeForDeviceAttestation(const Credentials::DeviceAttestationVerifier::AttestationInfo & info,
910 : Credentials::AttestationVerificationResult result);
911 : static void OnCertificateChainFailureResponse(void * context, CHIP_ERROR error);
912 : static void OnCertificateChainResponse(
913 : void * context, const app::Clusters::OperationalCredentials::Commands::CertificateChainResponse::DecodableType & response);
914 :
915 : static void OnAttestationFailureResponse(void * context, CHIP_ERROR error);
916 : static void
917 : OnAttestationResponse(void * context,
918 : const app::Clusters::OperationalCredentials::Commands::AttestationResponse::DecodableType & data);
919 :
920 : /**
921 : * @brief
922 : * This function is called by the IM layer when the commissioner receives the CSR from the device.
923 : * (Reference: Specifications section 11.18.5.6. NOCSR Elements)
924 : *
925 : * @param[in] context The context provided while registering the callback.
926 : * @param[in] data The response struct containing the following fields:
927 : * NOCSRElements: CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
928 : * AttestationSignature: Cryptographic signature generated for the fields in the response
929 : * message.
930 : */
931 : static void OnOperationalCertificateSigningRequest(
932 : void * context, const app::Clusters::OperationalCredentials::Commands::CSRResponse::DecodableType & data);
933 :
934 : /* Callback when adding operational certs to device results in failure */
935 : static void OnAddNOCFailureResponse(void * context, CHIP_ERROR errro);
936 : /* Callback when the device confirms that it has added the operational certificates */
937 : static void
938 : OnOperationalCertificateAddResponse(void * context,
939 : const app::Clusters::OperationalCredentials::Commands::NOCResponse::DecodableType & data);
940 :
941 : /* Callback when the device confirms that it has added the root certificate */
942 : static void OnRootCertSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &);
943 : /* Callback called when adding root cert to device results in failure */
944 : static void OnRootCertFailureResponse(void * context, CHIP_ERROR error);
945 :
946 : static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
947 : static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
948 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
949 : static void OnDeviceConnectionRetryFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error,
950 : System::Clock::Seconds16 retryTimeout);
951 : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
952 :
953 : static void OnDeviceAttestationInformationVerification(void * context,
954 : const Credentials::DeviceAttestationVerifier::AttestationInfo & info,
955 : Credentials::AttestationVerificationResult result);
956 :
957 : static void OnDeviceNOCChainGeneration(void * context, CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac,
958 : const ByteSpan & rcac, Optional<Crypto::IdentityProtectionKeySpan> ipk,
959 : Optional<NodeId> adminSubject);
960 : static void OnArmFailSafe(void * context,
961 : const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
962 : static void OnSetRegulatoryConfigResponse(
963 : void * context,
964 : const chip::app::Clusters::GeneralCommissioning::Commands::SetRegulatoryConfigResponse::DecodableType & data);
965 : static void OnSetTCAcknowledgementsResponse(
966 : void * context,
967 : const chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType & data);
968 : static void OnSetUTCError(void * context, CHIP_ERROR error);
969 : static void
970 : OnSetTimeZoneResponse(void * context,
971 : const chip::app::Clusters::TimeSynchronization::Commands::SetTimeZoneResponse::DecodableType & data);
972 :
973 : static void
974 : OnScanNetworksResponse(void * context,
975 : const app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & data);
976 : static void OnScanNetworksFailure(void * context, CHIP_ERROR err);
977 : static void
978 : OnNetworkConfigResponse(void * context,
979 : const app::Clusters::NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & data);
980 : static void OnConnectNetworkResponse(
981 : void * context, const chip::app::Clusters::NetworkCommissioning::Commands::ConnectNetworkResponse::DecodableType & data);
982 : static void OnCommissioningCompleteResponse(
983 : void * context,
984 : const chip::app::Clusters::GeneralCommissioning::Commands::CommissioningCompleteResponse::DecodableType & data);
985 : static void OnDisarmFailsafe(void * context,
986 : const app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
987 : static void OnDisarmFailsafeFailure(void * context, CHIP_ERROR error);
988 : void CleanupDoneAfterError();
989 : static void OnArmFailSafeExtendedForDeviceAttestation(
990 : void * context, const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
991 : static void OnFailedToExtendedArmFailSafeDeviceAttestation(void * context, CHIP_ERROR error);
992 : void HandleDeviceAttestationCompleted();
993 :
994 : static void OnICDManagementRegisterClientResponse(
995 : void * context, const app::Clusters::IcdManagement::Commands::RegisterClientResponse::DecodableType & data);
996 :
997 : static void
998 : OnICDManagementStayActiveResponse(void * context,
999 : const app::Clusters::IcdManagement::Commands::StayActiveResponse::DecodableType & data);
1000 :
1001 : /**
1002 : * @brief
1003 : * This function processes the CSR sent by the device.
1004 : * (Reference: Specifications section 11.18.5.6. NOCSR Elements)
1005 : *
1006 : * @param[in] proxy device proxy
1007 : * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
1008 : * @param[in] AttestationSignature Cryptographic signature generated for all the above fields.
1009 : * @param[in] dac device attestation certificate
1010 : * @param[in] pai Product Attestation Intermediate certificate
1011 : * @param[in] csrNonce certificate signing request nonce
1012 : */
1013 : CHIP_ERROR ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature,
1014 : const ByteSpan & dac, const ByteSpan & pai, const ByteSpan & csrNonce);
1015 :
1016 : /**
1017 : * @brief
1018 : * This function validates the CSR information from the device.
1019 : * (Reference: Specifications section 11.18.5.6. NOCSR Elements)
1020 : *
1021 : * @param[in] proxy device proxy
1022 : * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
1023 : * @param[in] AttestationSignature Cryptographic signature generated for all the above fields.
1024 : * @param[in] dac device attestation certificate
1025 : * @param[in] csrNonce certificate signing request nonce
1026 : */
1027 : CHIP_ERROR ValidateCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature,
1028 : const ByteSpan & dac, const ByteSpan & csrNonce);
1029 :
1030 : /**
1031 : * @brief
1032 : * This function validates the revocation status of the DAC Chain sent by the device.
1033 : *
1034 : * @param[in] info Structure containing all the required information for validating the device attestation.
1035 : */
1036 : CHIP_ERROR CheckForRevokedDACChain(const Credentials::DeviceAttestationVerifier::AttestationInfo & info);
1037 :
1038 : CommissioneeDeviceProxy * FindCommissioneeDevice(NodeId id);
1039 : CommissioneeDeviceProxy * FindCommissioneeDevice(const Transport::PeerAddress & peerAddress);
1040 : void ReleaseCommissioneeDevice(CommissioneeDeviceProxy * device);
1041 :
1042 : bool ExtendArmFailSafeInternal(DeviceProxy * proxy, CommissioningStage step, uint16_t armFailSafeTimeout,
1043 : Optional<System::Clock::Timeout> commandTimeout, OnExtendFailsafeSuccess onSuccess,
1044 : OnExtendFailsafeFailure onFailure, bool fireAndForget);
1045 :
1046 : template <typename RequestObjectT>
1047 : CHIP_ERROR SendCommissioningCommand(DeviceProxy * device, const RequestObjectT & request,
1048 : CommandResponseSuccessCallback<typename RequestObjectT::ResponseType> successCb,
1049 : CommandResponseFailureCallback failureCb, EndpointId endpoint,
1050 : Optional<System::Clock::Timeout> timeout = NullOptional, bool fireAndForget = false);
1051 : void SendCommissioningReadRequest(DeviceProxy * proxy, Optional<System::Clock::Timeout> timeout,
1052 : app::AttributePathParams * readPaths, size_t readPathsSize);
1053 : template <typename AttrType>
1054 : CHIP_ERROR SendCommissioningWriteRequest(DeviceProxy * device, EndpointId endpoint, ClusterId cluster, AttributeId attribute,
1055 : const AttrType & requestData, WriteResponseSuccessCallback successCb,
1056 : WriteResponseFailureCallback failureCb);
1057 : void CancelCommissioningInteractions();
1058 : void CancelCASECallbacks();
1059 :
1060 : #if CHIP_CONFIG_ENABLE_READ_CLIENT
1061 : void ContinueReadingCommissioningInfo(const CommissioningParameters & params);
1062 : void FinishReadingCommissioningInfo();
1063 : CHIP_ERROR ParseGeneralCommissioningInfo(ReadCommissioningInfo & info);
1064 : CHIP_ERROR ParseBasicInformation(ReadCommissioningInfo & info);
1065 : CHIP_ERROR ParseNetworkCommissioningInfo(ReadCommissioningInfo & info);
1066 : CHIP_ERROR ParseFabrics(ReadCommissioningInfo & info);
1067 : CHIP_ERROR ParseICDInfo(ReadCommissioningInfo & info);
1068 : CHIP_ERROR ParseTimeSyncInfo(ReadCommissioningInfo & info);
1069 : #endif // CHIP_CONFIG_ENABLE_READ_CLIENT
1070 :
1071 : static CHIP_ERROR
1072 : ConvertFromOperationalCertStatus(chip::app::Clusters::OperationalCredentials::NodeOperationalCertStatusEnum err);
1073 :
1074 : // Sends commissioning complete callbacks to the delegate depending on the status. Sends
1075 : // OnCommissioningComplete and either OnCommissioningSuccess or OnCommissioningFailure depending on the given completion status.
1076 : void SendCommissioningCompleteCallbacks(NodeId nodeId, const CompletionStatus & completionStatus);
1077 :
1078 : // Cleans up and resets failsafe as appropriate depending on the error and the failed stage.
1079 : // For success, sends completion report with the CommissioningDelegate and sends callbacks to the PairingDelegate
1080 : // For failures after AddNOC succeeds, sends completion report with the CommissioningDelegate and sends callbacks to the
1081 : // PairingDelegate. In this case, it does not disarm the failsafe or close the pase connection. For failures up through AddNOC,
1082 : // sends a command to immediately expire the failsafe, then sends completion report with the CommissioningDelegate and callbacks
1083 : // to the PairingDelegate upon arm failsafe command completion.
1084 : void CleanupCommissioning(DeviceProxy * proxy, NodeId nodeId, const CompletionStatus & completionStatus);
1085 :
1086 : // Extend the fail-safe before trying to do network-enable (since after that
1087 : // point, for non-concurrent-commissioning devices, we may not have a way to
1088 : // extend it).
1089 : void ExtendFailsafeBeforeNetworkEnable(DeviceProxy * device, CommissioningParameters & params, CommissioningStage step);
1090 :
1091 : bool IsAttestationInformationMissing(const CommissioningParameters & params);
1092 :
1093 : chip::Callback::Callback<OnDeviceConnected> mOnDeviceConnectedCallback;
1094 : chip::Callback::Callback<OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback;
1095 : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
1096 : chip::Callback::Callback<OnDeviceConnectionRetry> mOnDeviceConnectionRetryCallback;
1097 : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
1098 :
1099 : chip::Callback::Callback<Credentials::DeviceAttestationVerifier::OnAttestationInformationVerification>
1100 : mDeviceAttestationInformationVerificationCallback;
1101 :
1102 : chip::Callback::Callback<OnNOCChainGeneration> mDeviceNOCChainCallback;
1103 : SetUpCodePairer mSetUpCodePairer;
1104 : AutoCommissioner mAutoCommissioner;
1105 : CommissioningDelegate * mDefaultCommissioner =
1106 : nullptr; // Commissioning delegate to call when PairDevice / Commission functions are used
1107 : CommissioningDelegate * mCommissioningDelegate =
1108 : nullptr; // Commissioning delegate that issued the PerformCommissioningStep command
1109 : CompletionStatus mCommissioningCompletionStatus;
1110 :
1111 : #if CHIP_CONFIG_ENABLE_READ_CLIENT
1112 : Platform::UniquePtr<app::ClusterStateCache> mAttributeCache;
1113 : Platform::UniquePtr<app::ReadClient> mReadClient;
1114 : #endif
1115 : Credentials::AttestationVerificationResult mAttestationResult;
1116 : Platform::UniquePtr<Credentials::DeviceAttestationVerifier::AttestationDeviceInfo> mAttestationDeviceInfo;
1117 : Credentials::DeviceAttestationVerifier * mDeviceAttestationVerifier = nullptr;
1118 : };
1119 :
1120 : } // namespace Controller
1121 : } // namespace chip
|