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