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