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