Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Evgeny Margolis | a8dcee4 | 2022-03-23 09:50:37 -0700 | [diff] [blame] | 3 | * Copyright (c) 2020-2022 Project CHIP Authors |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 4 | * Copyright (c) 2019-2020 Google LLC. |
| 5 | * Copyright (c) 2013-2018 Nest Labs, Inc. |
| 6 | * All rights reserved. |
| 7 | * |
| 8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 9 | * you may not use this file except in compliance with the License. |
| 10 | * You may obtain a copy of the License at |
| 11 | * |
| 12 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 13 | * |
| 14 | * Unless required by applicable law or agreed to in writing, software |
| 15 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 17 | * See the License for the specific language governing permissions and |
| 18 | * limitations under the License. |
| 19 | */ |
| 20 | |
| 21 | #include <type_traits> |
| 22 | |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 23 | #include "ChipDeviceController-ScriptDevicePairingDelegate.h" |
| 24 | #include "ChipDeviceController-StorageDelegate.h" |
| 25 | |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 26 | #include "controller/python/chip/crypto/p256keypair.h" |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 27 | #include "controller/python/chip/interaction_model/Delegate.h" |
| 28 | |
Song GUO | d8e7e43 | 2024-06-04 17:53:30 +0000 | [diff] [blame] | 29 | #include <app/icd/client/DefaultICDClientStorage.h> |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 30 | #include <controller/CHIPDeviceController.h> |
| 31 | #include <controller/CHIPDeviceControllerFactory.h> |
| 32 | #include <controller/ExampleOperationalCredentialsIssuer.h> |
| 33 | #include <lib/support/BytesToHex.h> |
| 34 | #include <lib/support/CHIPMem.h> |
| 35 | #include <lib/support/CodeUtils.h> |
| 36 | #include <lib/support/DLLUtil.h> |
| 37 | #include <lib/support/ScopedBuffer.h> |
Tennessee Carmel-Veilleux | 1c03d9c | 2022-03-30 17:44:08 -0400 | [diff] [blame] | 38 | #include <lib/support/TestGroupData.h> |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 39 | #include <lib/support/logging/CHIPLogging.h> |
| 40 | |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 41 | #include <controller/python/chip/commissioning/PlaceholderOperationalCredentialsIssuer.h> |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 42 | #include <controller/python/chip/native/PyChipError.h> |
Tennessee Carmel-Veilleux | 1c03d9c | 2022-03-30 17:44:08 -0400 | [diff] [blame] | 43 | #include <credentials/GroupDataProviderImpl.h> |
Tennessee Carmel-Veilleux | 22fb6c3 | 2022-02-22 16:49:16 -0500 | [diff] [blame] | 44 | #include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h> |
| 45 | #include <credentials/attestation_verifier/DeviceAttestationVerifier.h> |
Vijay Selvaraj | 395bb1f | 2022-03-23 15:36:37 -0400 | [diff] [blame] | 46 | #include <credentials/attestation_verifier/FileAttestationTrustStore.h> |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 47 | |
| 48 | using namespace chip; |
| 49 | |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 50 | using Py_GenerateNOCChainFunc = void (*)(void * pyContext, const char * csrElements, const char * attestationSignature, |
| 51 | const char * dac, const char * pai, const char * paa, |
| 52 | Controller::OnNOCChainGeneration onNocChainGenerationFunc); |
| 53 | using Py_SetNodeIdForNextNOCRequest = void (*)(void * pyContext, NodeId nodeId); |
| 54 | using Py_SetFabricIdForNextNOCRequest = void (*)(void * pyContext, FabricId fabricId); |
| 55 | |
Vijay Selvaraj | 395bb1f | 2022-03-23 15:36:37 -0400 | [diff] [blame] | 56 | namespace { |
| 57 | const chip::Credentials::AttestationTrustStore * GetTestFileAttestationTrustStore(const char * paaTrustStorePath) |
| 58 | { |
| 59 | static chip::Credentials::FileAttestationTrustStore attestationTrustStore{ paaTrustStorePath }; |
| 60 | |
| 61 | return &attestationTrustStore; |
| 62 | } |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 63 | |
| 64 | chip::Python::PlaceholderOperationalCredentialsIssuer sPlaceholderOperationalCredentialsIssuer; |
Vijay Selvaraj | 395bb1f | 2022-03-23 15:36:37 -0400 | [diff] [blame] | 65 | } // namespace |
| 66 | |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 67 | namespace chip { |
| 68 | namespace Controller { |
| 69 | namespace Python { |
| 70 | |
| 71 | class OperationalCredentialsAdapter : public OperationalCredentialsDelegate |
| 72 | { |
| 73 | public: |
| 74 | OperationalCredentialsAdapter(uint32_t fabricCredentialsIndex) : mExampleOpCredsIssuer(fabricCredentialsIndex) {} |
| 75 | |
| 76 | CHIP_ERROR Initialize(PersistentStorageDelegate & storageDelegate) { return mExampleOpCredsIssuer.Initialize(storageDelegate); } |
| 77 | |
Evgeny Margolis | a8dcee4 | 2022-03-23 09:50:37 -0700 | [diff] [blame] | 78 | CHIP_ERROR GenerateNOCChain(NodeId nodeId, FabricId fabricId, const CATValues & cats, const Crypto::P256PublicKey & pubKey, |
| 79 | MutableByteSpan & rcac, MutableByteSpan & icac, MutableByteSpan & noc) |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 80 | { |
Evgeny Margolis | a8dcee4 | 2022-03-23 09:50:37 -0700 | [diff] [blame] | 81 | return mExampleOpCredsIssuer.GenerateNOCChainAfterValidation(nodeId, fabricId, cats, pubKey, rcac, icac, noc); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 82 | } |
| 83 | |
Tennessee Carmel-Veilleux | dfc1a70 | 2022-08-19 18:20:12 -0400 | [diff] [blame] | 84 | void SetMaximallyLargeCertsUsed(bool enabled) { mExampleOpCredsIssuer.SetMaximallyLargeCertsUsed(enabled); } |
| 85 | |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 86 | private: |
C Freeman | a208c3d | 2022-04-04 08:23:45 -0400 | [diff] [blame] | 87 | CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, |
| 88 | const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 89 | Callback::Callback<OnNOCChainGeneration> * onCompletion) override |
| 90 | { |
C Freeman | a208c3d | 2022-04-04 08:23:45 -0400 | [diff] [blame] | 91 | return mExampleOpCredsIssuer.GenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, DAC, PAI, |
| 92 | onCompletion); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | void SetNodeIdForNextNOCRequest(NodeId nodeId) override { mExampleOpCredsIssuer.SetNodeIdForNextNOCRequest(nodeId); } |
| 96 | |
| 97 | void SetFabricIdForNextNOCRequest(FabricId fabricId) override { mExampleOpCredsIssuer.SetFabricIdForNextNOCRequest(fabricId); } |
| 98 | |
| 99 | ExampleOperationalCredentialsIssuer mExampleOpCredsIssuer; |
| 100 | }; |
| 101 | |
| 102 | } // namespace Python |
| 103 | } // namespace Controller |
| 104 | } // namespace chip |
| 105 | |
Tennessee Carmel-Veilleux | 1c03d9c | 2022-03-30 17:44:08 -0400 | [diff] [blame] | 106 | extern chip::Credentials::GroupDataProviderImpl sGroupDataProvider; |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 107 | extern chip::Controller::ScriptDevicePairingDelegate sPairingDelegate; |
Song GUO | d8e7e43 | 2024-06-04 17:53:30 +0000 | [diff] [blame] | 108 | extern chip::app::DefaultICDClientStorage sICDClientStorage; |
Tennessee Carmel-Veilleux | 1c03d9c | 2022-03-30 17:44:08 -0400 | [diff] [blame] | 109 | |
C Freeman | 8ffe422 | 2022-02-02 14:21:16 -0500 | [diff] [blame] | 110 | class TestCommissioner : public chip::Controller::AutoCommissioner |
| 111 | { |
| 112 | public: |
Andrei Litvin | 0c06ba5 | 2022-04-07 05:19:33 -1000 | [diff] [blame] | 113 | TestCommissioner() { Reset(); } |
C Freeman | 8ffe422 | 2022-02-02 14:21:16 -0500 | [diff] [blame] | 114 | ~TestCommissioner() {} |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 115 | CHIP_ERROR SetCommissioningParameters(const chip::Controller::CommissioningParameters & params) override |
| 116 | { |
| 117 | mIsWifi = false; |
| 118 | mIsThread = false; |
| 119 | if (params.GetWiFiCredentials().HasValue()) |
| 120 | { |
| 121 | mIsWifi = true; |
| 122 | } |
| 123 | else if (params.GetThreadOperationalDataset().HasValue()) |
| 124 | { |
| 125 | mIsThread = true; |
| 126 | } |
| 127 | return chip::Controller::AutoCommissioner::SetCommissioningParameters(params); |
| 128 | } |
C Freeman | 8ffe422 | 2022-02-02 14:21:16 -0500 | [diff] [blame] | 129 | CHIP_ERROR CommissioningStepFinished(CHIP_ERROR err, |
| 130 | chip::Controller::CommissioningDelegate::CommissioningReport report) override |
| 131 | { |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 132 | mTestCommissionerUsed = true; |
| 133 | if (mFailOnReportAfterStage == report.stageCompleted) |
| 134 | { |
| 135 | return CHIP_ERROR_INTERNAL; |
| 136 | } |
| 137 | if (mSimulateFailureOnStage == report.stageCompleted) |
| 138 | { |
| 139 | // Pretend we received an error from the device during this stage |
| 140 | err = CHIP_ERROR_INTERNAL; |
| 141 | } |
C Freeman | 89d538c | 2023-01-26 12:29:48 -0500 | [diff] [blame] | 142 | if (mPrematureCompleteAfter == report.stageCompleted) |
| 143 | { |
| 144 | auto commissioner = chip::Controller::AutoCommissioner::GetCommissioner(); |
| 145 | auto proxy = chip::Controller::AutoCommissioner::GetCommissioneeDeviceProxy(); |
| 146 | auto stage = chip::Controller::CommissioningStage::kSendComplete; |
| 147 | auto params = chip::Controller::CommissioningParameters(); |
| 148 | commissioner->PerformCommissioningStep(proxy, stage, params, this, 0, GetCommandTimeout(proxy, stage)); |
| 149 | return CHIP_NO_ERROR; |
| 150 | } |
| 151 | |
| 152 | if (mPrematureCompleteAfter != chip::Controller::CommissioningStage::kError && |
| 153 | report.stageCompleted == chip::Controller::CommissioningStage::kSendComplete) |
| 154 | { |
| 155 | if (report.Is<chip::Controller::CommissioningErrorInfo>()) |
| 156 | { |
| 157 | uint8_t code = chip::to_underlying(report.Get<chip::Controller::CommissioningErrorInfo>().commissioningError); |
| 158 | mCompletionError = chip::ChipError(chip::ChipError::SdkPart::kIMClusterStatus, code); |
| 159 | } |
| 160 | else |
| 161 | { |
| 162 | mCompletionError = err; |
| 163 | } |
| 164 | } |
Song GUO | 8e3d98c | 2023-12-14 12:11:32 +0800 | [diff] [blame] | 165 | if (report.stageCompleted == chip::Controller::CommissioningStage::kReadCommissioningInfo2) |
C Freeman | ac3535b | 2023-07-18 13:32:59 -0400 | [diff] [blame] | 166 | { |
| 167 | mReadCommissioningInfo = report.Get<chip::Controller::ReadCommissioningInfo>(); |
| 168 | } |
| 169 | if (report.stageCompleted == chip::Controller::CommissioningStage::kConfigureTimeZone) |
| 170 | { |
| 171 | mNeedsDST = report.Get<chip::Controller::TimeZoneResponseInfo>().requiresDSTOffsets; |
| 172 | } |
C Freeman | 89d538c | 2023-01-26 12:29:48 -0500 | [diff] [blame] | 173 | |
C Freeman | 8ffe422 | 2022-02-02 14:21:16 -0500 | [diff] [blame] | 174 | return chip::Controller::AutoCommissioner::CommissioningStepFinished(err, report); |
| 175 | } |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 176 | // This will cause the COMMISSIONER to fail after the given stage. Setting this to kSecurePairing will cause the |
| 177 | // StartCommissioning call to fail. |
| 178 | bool SimulateFailAfter(chip::Controller::CommissioningStage stage) |
| 179 | { |
| 180 | ChipLogProgress(Controller, "setting simulate fail after stage %s", chip::Controller::StageToString(stage)); |
| 181 | if (!ValidStage(stage) && stage != chip::Controller::CommissioningStage::kError) |
| 182 | { |
| 183 | return false; |
| 184 | } |
| 185 | mSimulateFailureOnStage = stage; |
| 186 | return true; |
| 187 | } |
| 188 | bool SimulateFailOnReport(chip::Controller::CommissioningStage stage) |
| 189 | { |
| 190 | if (!ValidStage(stage) && stage != chip::Controller::CommissioningStage::kError) |
| 191 | { |
| 192 | return false; |
| 193 | } |
| 194 | mFailOnReportAfterStage = stage; |
| 195 | return true; |
| 196 | } |
C Freeman | 89d538c | 2023-01-26 12:29:48 -0500 | [diff] [blame] | 197 | bool PrematureCompleteAfter(chip::Controller::CommissioningStage stage) |
| 198 | { |
| 199 | if (!ValidStage(stage) && stage != chip::Controller::CommissioningStage::kError) |
| 200 | { |
| 201 | return false; |
| 202 | } |
| 203 | mPrematureCompleteAfter = stage; |
| 204 | return true; |
| 205 | } |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 206 | bool CheckCallbacks() |
| 207 | { |
| 208 | bool successFailureOk; |
| 209 | bool updatesOk; |
| 210 | if (mFailOnReportAfterStage != chip::Controller::CommissioningStage::kError) |
| 211 | { |
| 212 | successFailureOk = mReceivedCommissioningFailureStage == mFailOnReportAfterStage && !mReceivedCommissioningSuccess; |
| 213 | updatesOk = StatusUpdatesOk(mFailOnReportAfterStage); |
| 214 | } |
| 215 | else if (mSimulateFailureOnStage != chip::Controller::CommissioningStage::kError) |
| 216 | { |
| 217 | successFailureOk = mReceivedCommissioningFailureStage == mSimulateFailureOnStage && !mReceivedCommissioningSuccess; |
| 218 | updatesOk = StatusUpdatesOk(mSimulateFailureOnStage); |
| 219 | } |
| 220 | else |
| 221 | { |
| 222 | successFailureOk = mReceivedCommissioningSuccess; |
| 223 | updatesOk = StatusUpdatesOk(chip::Controller::CommissioningStage::kError); |
| 224 | } |
| 225 | ChipLogProgress(Controller, "Checking callbacks: success failure ok? %d updates ok? %d", successFailureOk, updatesOk); |
| 226 | return successFailureOk && updatesOk; |
| 227 | } |
| 228 | bool CheckPaseConnection(NodeId nodeId) |
| 229 | { |
| 230 | bool paseShouldBeOpen = false; |
| 231 | if (chip::to_underlying(mFailOnReportAfterStage) >= |
| 232 | chip::to_underlying(chip::Controller::CommissioningStage::kWiFiNetworkSetup) || |
| 233 | chip::to_underlying(mSimulateFailureOnStage) >= |
| 234 | chip::to_underlying(chip::Controller::CommissioningStage::kWiFiNetworkSetup)) |
| 235 | { |
| 236 | // Pase should be open still |
| 237 | paseShouldBeOpen = true; |
| 238 | } |
| 239 | CommissioneeDeviceProxy * proxy; |
| 240 | bool paseIsOpen = |
| 241 | (chip::Controller::AutoCommissioner::GetCommissioner()->GetDeviceBeingCommissioned(nodeId, &proxy) == CHIP_NO_ERROR); |
| 242 | ChipLogProgress(Controller, "Checking pase connection state: Should be open? %d is open? %d", paseShouldBeOpen, paseIsOpen); |
| 243 | |
| 244 | return paseShouldBeOpen == paseIsOpen; |
| 245 | } |
C Freeman | ac3535b | 2023-07-18 13:32:59 -0400 | [diff] [blame] | 246 | bool CheckStageSuccessful(uint8_t stage) { return mReceivedStageSuccess[stage]; } |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 247 | void Reset() |
| 248 | { |
| 249 | mTestCommissionerUsed = false; |
| 250 | mReceivedCommissioningSuccess = false; |
| 251 | mReceivedCommissioningFailureStage = chip::Controller::CommissioningStage::kError; |
| 252 | for (size_t i = 0; i < kNumCommissioningStages; ++i) |
| 253 | { |
| 254 | mReceivedStageSuccess[i] = false; |
| 255 | mReceivedStageFailure[i] = false; |
| 256 | } |
| 257 | mSimulateFailureOnStage = chip::Controller::CommissioningStage::kError; |
| 258 | mFailOnReportAfterStage = chip::Controller::CommissioningStage::kError; |
C Freeman | 89d538c | 2023-01-26 12:29:48 -0500 | [diff] [blame] | 259 | mPrematureCompleteAfter = chip::Controller::CommissioningStage::kError; |
C Freeman | ac3535b | 2023-07-18 13:32:59 -0400 | [diff] [blame] | 260 | mReadCommissioningInfo = chip::Controller::ReadCommissioningInfo(); |
| 261 | mNeedsDST = false; |
Stefan Agner | 16a79eb | 2024-06-19 16:26:32 +0200 | [diff] [blame] | 262 | mCompletionError = CHIP_NO_ERROR; |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 263 | } |
| 264 | bool GetTestCommissionerUsed() { return mTestCommissionerUsed; } |
| 265 | void OnCommissioningSuccess(chip::PeerId peerId) { mReceivedCommissioningSuccess = true; } |
| 266 | void OnCommissioningFailure(chip::PeerId peerId, CHIP_ERROR error, chip::Controller::CommissioningStage stageFailed, |
| 267 | chip::Optional<chip::Credentials::AttestationVerificationResult> additionalErrorInfo) |
| 268 | { |
| 269 | mReceivedCommissioningFailureStage = stageFailed; |
| 270 | } |
| 271 | void OnCommissioningStatusUpdate(chip::PeerId peerId, chip::Controller::CommissioningStage stageCompleted, CHIP_ERROR error) |
| 272 | { |
| 273 | if (error == CHIP_NO_ERROR) |
| 274 | { |
| 275 | mReceivedStageSuccess[chip::to_underlying(stageCompleted)] = true; |
| 276 | } |
| 277 | else |
| 278 | { |
| 279 | mReceivedStageFailure[chip::to_underlying(stageCompleted)] = true; |
| 280 | } |
C Freeman | 89d538c | 2023-01-26 12:29:48 -0500 | [diff] [blame] | 281 | if (stageCompleted == chip::Controller::CommissioningStage::kCleanup && |
| 282 | mPrematureCompleteAfter != chip::Controller::CommissioningStage::kError) |
| 283 | { |
| 284 | // We need to manually clean up the proxy here because we're doing bad things in the name of testing |
| 285 | ChipLogProgress(Controller, "Cleaning up dangling proxies"); |
| 286 | auto commissioner = chip::Controller::AutoCommissioner::GetCommissioner(); |
| 287 | auto proxy = chip::Controller::AutoCommissioner::GetCommissioneeDeviceProxy(); |
| 288 | if (proxy != nullptr) |
| 289 | { |
| 290 | commissioner->StopPairing(proxy->GetDeviceId()); |
| 291 | } |
| 292 | } |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 293 | } |
| 294 | |
C Freeman | 89d538c | 2023-01-26 12:29:48 -0500 | [diff] [blame] | 295 | CHIP_ERROR GetCompletionError() { return mCompletionError; } |
| 296 | |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 297 | private: |
| 298 | static constexpr uint8_t kNumCommissioningStages = chip::to_underlying(chip::Controller::CommissioningStage::kCleanup) + 1; |
| 299 | chip::Controller::CommissioningStage mSimulateFailureOnStage = chip::Controller::CommissioningStage::kError; |
| 300 | chip::Controller::CommissioningStage mFailOnReportAfterStage = chip::Controller::CommissioningStage::kError; |
C Freeman | 89d538c | 2023-01-26 12:29:48 -0500 | [diff] [blame] | 301 | chip::Controller::CommissioningStage mPrematureCompleteAfter = chip::Controller::CommissioningStage::kError; |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 302 | bool mTestCommissionerUsed = false; |
| 303 | bool mReceivedCommissioningSuccess = false; |
| 304 | chip::Controller::CommissioningStage mReceivedCommissioningFailureStage = chip::Controller::CommissioningStage::kError; |
| 305 | bool mReceivedStageSuccess[kNumCommissioningStages]; |
| 306 | bool mReceivedStageFailure[kNumCommissioningStages]; |
C Freeman | 89d538c | 2023-01-26 12:29:48 -0500 | [diff] [blame] | 307 | bool mIsWifi = false; |
| 308 | bool mIsThread = false; |
| 309 | CHIP_ERROR mCompletionError = CHIP_NO_ERROR; |
C Freeman | ac3535b | 2023-07-18 13:32:59 -0400 | [diff] [blame] | 310 | // Contains information about whether the device needs time sync |
| 311 | chip::Controller::ReadCommissioningInfo mReadCommissioningInfo; |
| 312 | bool mNeedsDST = false; |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 313 | bool ValidStage(chip::Controller::CommissioningStage stage) |
| 314 | { |
C Freeman | ac3535b | 2023-07-18 13:32:59 -0400 | [diff] [blame] | 315 | switch (stage) |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 316 | { |
C Freeman | ac3535b | 2023-07-18 13:32:59 -0400 | [diff] [blame] | 317 | case chip::Controller::CommissioningStage::kWiFiNetworkEnable: |
| 318 | case chip::Controller::CommissioningStage::kFailsafeBeforeWiFiEnable: |
| 319 | case chip::Controller::CommissioningStage::kWiFiNetworkSetup: |
| 320 | return mIsWifi; |
| 321 | case chip::Controller::CommissioningStage::kThreadNetworkEnable: |
| 322 | case chip::Controller::CommissioningStage::kFailsafeBeforeThreadEnable: |
| 323 | case chip::Controller::CommissioningStage::kThreadNetworkSetup: |
| 324 | return mIsThread; |
| 325 | case chip::Controller::CommissioningStage::kConfigureUTCTime: |
| 326 | return mReadCommissioningInfo.requiresUTC; |
| 327 | case chip::Controller::CommissioningStage::kConfigureTimeZone: |
| 328 | return mReadCommissioningInfo.requiresTimeZone && mParams.GetTimeZone().HasValue(); |
| 329 | case chip::Controller::CommissioningStage::kConfigureTrustedTimeSource: |
| 330 | return mReadCommissioningInfo.requiresTrustedTimeSource && mParams.GetTrustedTimeSource().HasValue(); |
| 331 | case chip::Controller::CommissioningStage::kConfigureDefaultNTP: |
| 332 | return mReadCommissioningInfo.requiresDefaultNTP && mParams.GetDefaultNTP().HasValue(); |
| 333 | case chip::Controller::CommissioningStage::kConfigureDSTOffset: |
| 334 | return mNeedsDST && mParams.GetDSTOffsets().HasValue(); |
| 335 | case chip::Controller::CommissioningStage::kError: |
| 336 | case chip::Controller::CommissioningStage::kSecurePairing: |
Vijay Selvaraj | be9389c | 2024-05-09 15:05:38 -0400 | [diff] [blame] | 337 | // "not valid" because attestation verification always fails after entering revocation check step |
| 338 | case chip::Controller::CommissioningStage::kAttestationVerification: |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 339 | return false; |
C Freeman | ac3535b | 2023-07-18 13:32:59 -0400 | [diff] [blame] | 340 | default: |
| 341 | return true; |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 342 | } |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 343 | } |
| 344 | bool StatusUpdatesOk(chip::Controller::CommissioningStage failedStage) |
| 345 | { |
| 346 | // Because we're just simulating a failure here, we will have received a success callback even for the failed stage. |
| 347 | for (uint8_t i = 0; i < kNumCommissioningStages; ++i) |
| 348 | { |
| 349 | if (mReceivedStageFailure[i]) |
| 350 | { |
| 351 | return false; |
| 352 | } |
| 353 | if (!ValidStage(static_cast<chip::Controller::CommissioningStage>(i))) |
| 354 | { |
| 355 | continue; |
| 356 | } |
| 357 | // Anything above our current stage we won't have received a callback for. We also expect that the "failed" stage will |
| 358 | // have a success callback because we're just faking the failure here and overwriting error. |
| 359 | if (i == chip::to_underlying(failedStage)) |
| 360 | { |
| 361 | break; |
| 362 | } |
| 363 | } |
| 364 | return true; |
| 365 | } |
C Freeman | 8ffe422 | 2022-02-02 14:21:16 -0500 | [diff] [blame] | 366 | }; |
| 367 | TestCommissioner sTestCommissioner; |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 368 | |
| 369 | extern "C" { |
| 370 | struct OpCredsContext |
| 371 | { |
| 372 | Platform::UniquePtr<Controller::Python::OperationalCredentialsAdapter> mAdapter; |
| 373 | void * mPyContext; |
| 374 | }; |
| 375 | |
Jerry Johns | c517ba2 | 2022-08-18 09:48:09 -0700 | [diff] [blame] | 376 | void * pychip_OpCreds_InitializeDelegate(void * pyContext, uint32_t fabricCredentialsIndex, |
| 377 | Controller::Python::StorageAdapter * storageAdapter) |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 378 | { |
| 379 | auto context = Platform::MakeUnique<OpCredsContext>(); |
| 380 | context->mAdapter = Platform::MakeUnique<Controller::Python::OperationalCredentialsAdapter>(fabricCredentialsIndex); |
| 381 | |
Jerry Johns | c517ba2 | 2022-08-18 09:48:09 -0700 | [diff] [blame] | 382 | if (context->mAdapter->Initialize(*storageAdapter) != CHIP_NO_ERROR) |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 383 | { |
| 384 | return nullptr; |
| 385 | } |
| 386 | |
| 387 | return context.release(); |
| 388 | } |
| 389 | |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 390 | void pychip_OnCommissioningSuccess(PeerId peerId) |
| 391 | { |
| 392 | sTestCommissioner.OnCommissioningSuccess(peerId); |
| 393 | } |
| 394 | void pychip_OnCommissioningFailure(chip::PeerId peerId, CHIP_ERROR error, chip::Controller::CommissioningStage stageFailed, |
| 395 | chip::Optional<chip::Credentials::AttestationVerificationResult> additionalErrorInfo) |
| 396 | { |
| 397 | sTestCommissioner.OnCommissioningFailure(peerId, error, stageFailed, additionalErrorInfo); |
| 398 | } |
| 399 | void pychip_OnCommissioningStatusUpdate(chip::PeerId peerId, chip::Controller::CommissioningStage stageCompleted, CHIP_ERROR err) |
| 400 | { |
| 401 | return sTestCommissioner.OnCommissioningStatusUpdate(peerId, stageCompleted, err); |
| 402 | } |
| 403 | |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 404 | /** |
| 405 | * Allocates a controller that does not use auto-commisioning. |
| 406 | * |
| 407 | * TODO(#25214): Need clean up API |
| 408 | * |
| 409 | */ |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 410 | PyChipError pychip_OpCreds_AllocateControllerForPythonCommissioningFLow( |
| 411 | chip::Controller::DeviceCommissioner ** outDevCtrl, chip::Controller::ScriptDevicePairingDelegate ** outPairingDelegate, |
| 412 | chip::python::pychip_P256Keypair * operationalKey, uint8_t * noc, uint32_t nocLen, uint8_t * icac, uint32_t icacLen, |
| 413 | uint8_t * rcac, uint32_t rcacLen, const uint8_t * ipk, uint32_t ipkLen, chip::VendorId adminVendorId, |
| 414 | bool enableServerInteractions) |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 415 | { |
| 416 | ReturnErrorCodeIf(nocLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); |
| 417 | ReturnErrorCodeIf(icacLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); |
| 418 | ReturnErrorCodeIf(rcacLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); |
| 419 | |
| 420 | ChipLogDetail(Controller, "Creating New Device Controller"); |
| 421 | |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 422 | auto pairingDelegate = std::make_unique<chip::Controller::ScriptDevicePairingDelegate>(); |
| 423 | VerifyOrReturnError(pairingDelegate != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY)); |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 424 | auto devCtrl = std::make_unique<chip::Controller::DeviceCommissioner>(); |
| 425 | VerifyOrReturnError(devCtrl != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY)); |
| 426 | |
| 427 | Controller::SetupParams initParams; |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 428 | initParams.pairingDelegate = pairingDelegate.get(); |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 429 | initParams.operationalCredentialsDelegate = &sPlaceholderOperationalCredentialsIssuer; |
| 430 | initParams.operationalKeypair = operationalKey; |
| 431 | initParams.controllerRCAC = ByteSpan(rcac, rcacLen); |
| 432 | initParams.controllerICAC = ByteSpan(icac, icacLen); |
| 433 | initParams.controllerNOC = ByteSpan(noc, nocLen); |
| 434 | initParams.enableServerInteractions = enableServerInteractions; |
| 435 | initParams.controllerVendorId = adminVendorId; |
| 436 | initParams.permitMultiControllerFabrics = true; |
| 437 | initParams.hasExternallyOwnedOperationalKeypair = true; |
| 438 | |
| 439 | CHIP_ERROR err = Controller::DeviceControllerFactory::GetInstance().SetupCommissioner(initParams, *devCtrl); |
| 440 | VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); |
| 441 | |
| 442 | // Setup IPK in Group Data Provider for controller after Commissioner init which sets-up the fabric table entry |
| 443 | uint8_t compressedFabricId[sizeof(uint64_t)] = { 0 }; |
| 444 | chip::MutableByteSpan compressedFabricIdSpan(compressedFabricId); |
| 445 | |
| 446 | err = devCtrl->GetCompressedFabricIdBytes(compressedFabricIdSpan); |
| 447 | VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); |
| 448 | |
| 449 | ChipLogProgress(Support, "Setting up group data for Fabric Index %u with Compressed Fabric ID:", |
| 450 | static_cast<unsigned>(devCtrl->GetFabricIndex())); |
| 451 | ChipLogByteSpan(Support, compressedFabricIdSpan); |
| 452 | |
| 453 | chip::ByteSpan fabricIpk = |
| 454 | (ipk == nullptr) ? chip::GroupTesting::DefaultIpkValue::GetDefaultIpk() : chip::ByteSpan(ipk, ipkLen); |
| 455 | err = |
| 456 | chip::Credentials::SetSingleIpkEpochKey(&sGroupDataProvider, devCtrl->GetFabricIndex(), fabricIpk, compressedFabricIdSpan); |
| 457 | VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); |
| 458 | |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 459 | *outDevCtrl = devCtrl.release(); |
| 460 | *outPairingDelegate = pairingDelegate.release(); |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 461 | |
| 462 | return ToPyChipError(CHIP_NO_ERROR); |
| 463 | } |
| 464 | |
| 465 | // TODO(#25214): Need clean up API |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 466 | PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Controller::DeviceCommissioner ** outDevCtrl, |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 467 | chip::Controller::ScriptDevicePairingDelegate ** outPairingDelegate, |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 468 | FabricId fabricId, chip::NodeId nodeId, chip::VendorId adminVendorId, |
| 469 | const char * paaTrustStorePath, bool useTestCommissioner, |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 470 | bool enableServerInteractions, CASEAuthTag * caseAuthTags, uint32_t caseAuthTagLen, |
| 471 | chip::python::pychip_P256Keypair * operationalKey) |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 472 | { |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 473 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 474 | |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 475 | ChipLogDetail(Controller, "Creating New Device Controller"); |
| 476 | |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 477 | VerifyOrReturnError(context != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT)); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 478 | |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 479 | auto pairingDelegate = std::make_unique<chip::Controller::ScriptDevicePairingDelegate>(); |
| 480 | VerifyOrReturnError(pairingDelegate != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY)); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 481 | auto devCtrl = std::make_unique<chip::Controller::DeviceCommissioner>(); |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 482 | VerifyOrReturnError(devCtrl != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY)); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 483 | |
Stefan Agner | 51d67c4 | 2022-05-04 19:20:48 +0200 | [diff] [blame] | 484 | if (paaTrustStorePath == nullptr) |
| 485 | { |
| 486 | paaTrustStorePath = "./credentials/development/paa-root-certs"; |
| 487 | } |
Jerry Johns | c517ba2 | 2022-08-18 09:48:09 -0700 | [diff] [blame] | 488 | |
Stefan Agner | 51d67c4 | 2022-05-04 19:20:48 +0200 | [diff] [blame] | 489 | ChipLogProgress(Support, "Using device attestation PAA trust store path %s.", paaTrustStorePath); |
| 490 | |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 491 | // Initialize device attestation verifier |
Stefan Agner | 51d67c4 | 2022-05-04 19:20:48 +0200 | [diff] [blame] | 492 | const chip::Credentials::AttestationTrustStore * testingRootStore = GetTestFileAttestationTrustStore(paaTrustStorePath); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 493 | SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore)); |
| 494 | |
| 495 | chip::Crypto::P256Keypair ephemeralKey; |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 496 | chip::Crypto::P256Keypair * controllerKeyPair; |
| 497 | |
| 498 | if (operationalKey == nullptr) |
| 499 | { |
| 500 | err = ephemeralKey.Initialize(chip::Crypto::ECPKeyTarget::ECDSA); |
| 501 | VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); |
| 502 | controllerKeyPair = &ephemeralKey; |
| 503 | } |
| 504 | else |
| 505 | { |
| 506 | controllerKeyPair = operationalKey; |
| 507 | } |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 508 | |
| 509 | chip::Platform::ScopedMemoryBuffer<uint8_t> noc; |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 510 | ReturnErrorCodeIf(!noc.Alloc(Controller::kMaxCHIPDERCertLength), ToPyChipError(CHIP_ERROR_NO_MEMORY)); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 511 | MutableByteSpan nocSpan(noc.Get(), Controller::kMaxCHIPDERCertLength); |
| 512 | |
| 513 | chip::Platform::ScopedMemoryBuffer<uint8_t> icac; |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 514 | ReturnErrorCodeIf(!icac.Alloc(Controller::kMaxCHIPDERCertLength), ToPyChipError(CHIP_ERROR_NO_MEMORY)); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 515 | MutableByteSpan icacSpan(icac.Get(), Controller::kMaxCHIPDERCertLength); |
| 516 | |
| 517 | chip::Platform::ScopedMemoryBuffer<uint8_t> rcac; |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 518 | ReturnErrorCodeIf(!rcac.Alloc(Controller::kMaxCHIPDERCertLength), ToPyChipError(CHIP_ERROR_NO_MEMORY)); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 519 | MutableByteSpan rcacSpan(rcac.Get(), Controller::kMaxCHIPDERCertLength); |
| 520 | |
Jerry Johns | 3f69587 | 2022-08-18 20:25:15 -0700 | [diff] [blame] | 521 | CATValues catValues; |
| 522 | |
Tennessee Carmel-Veilleux | dfc1a70 | 2022-08-19 18:20:12 -0400 | [diff] [blame] | 523 | if (caseAuthTagLen > kMaxSubjectCATAttributeCount) |
Jerry Johns | 3f69587 | 2022-08-18 20:25:15 -0700 | [diff] [blame] | 524 | { |
Tennessee Carmel-Veilleux | dfc1a70 | 2022-08-19 18:20:12 -0400 | [diff] [blame] | 525 | ChipLogError(Controller, "Too many of CASE Tags (%u) exceeds kMaxSubjectCATAttributeCount", |
| 526 | static_cast<unsigned>(caseAuthTagLen)); |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 527 | return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT); |
Jerry Johns | 3f69587 | 2022-08-18 20:25:15 -0700 | [diff] [blame] | 528 | } |
| 529 | |
| 530 | memcpy(catValues.values.data(), caseAuthTags, caseAuthTagLen * sizeof(CASEAuthTag)); |
| 531 | |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 532 | err = |
| 533 | context->mAdapter->GenerateNOCChain(nodeId, fabricId, catValues, controllerKeyPair->Pubkey(), rcacSpan, icacSpan, nocSpan); |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 534 | VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 535 | |
| 536 | Controller::SetupParams initParams; |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 537 | initParams.pairingDelegate = pairingDelegate.get(); |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 538 | initParams.operationalCredentialsDelegate = context->mAdapter.get(); |
| 539 | initParams.operationalKeypair = controllerKeyPair; |
| 540 | initParams.controllerRCAC = rcacSpan; |
| 541 | initParams.controllerICAC = icacSpan; |
| 542 | initParams.controllerNOC = nocSpan; |
| 543 | initParams.enableServerInteractions = enableServerInteractions; |
| 544 | initParams.controllerVendorId = adminVendorId; |
| 545 | initParams.permitMultiControllerFabrics = true; |
| 546 | initParams.hasExternallyOwnedOperationalKeypair = operationalKey != nullptr; |
Jerry Johns | 75372d8 | 2022-03-01 06:32:40 -0800 | [diff] [blame] | 547 | |
C Freeman | 8ffe422 | 2022-02-02 14:21:16 -0500 | [diff] [blame] | 548 | if (useTestCommissioner) |
| 549 | { |
| 550 | initParams.defaultCommissioner = &sTestCommissioner; |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 551 | pairingDelegate->SetCommissioningSuccessCallback(pychip_OnCommissioningSuccess); |
| 552 | pairingDelegate->SetCommissioningFailureCallback(pychip_OnCommissioningFailure); |
| 553 | pairingDelegate->SetCommissioningStatusUpdateCallback(pychip_OnCommissioningStatusUpdate); |
C Freeman | 8ffe422 | 2022-02-02 14:21:16 -0500 | [diff] [blame] | 554 | } |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 555 | |
| 556 | err = Controller::DeviceControllerFactory::GetInstance().SetupCommissioner(initParams, *devCtrl); |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 557 | VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 558 | |
Tennessee Carmel-Veilleux | 1c03d9c | 2022-03-30 17:44:08 -0400 | [diff] [blame] | 559 | // Setup IPK in Group Data Provider for controller after Commissioner init which sets-up the fabric table entry |
Tennessee Carmel-Veilleux | 1c03d9c | 2022-03-30 17:44:08 -0400 | [diff] [blame] | 560 | uint8_t compressedFabricId[sizeof(uint64_t)] = { 0 }; |
| 561 | chip::MutableByteSpan compressedFabricIdSpan(compressedFabricId); |
| 562 | |
Tennessee Carmel-Veilleux | e5e09f5 | 2022-06-24 16:57:34 -0400 | [diff] [blame] | 563 | err = devCtrl->GetCompressedFabricIdBytes(compressedFabricIdSpan); |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 564 | VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); |
Tennessee Carmel-Veilleux | 1c03d9c | 2022-03-30 17:44:08 -0400 | [diff] [blame] | 565 | |
| 566 | ChipLogProgress(Support, "Setting up group data for Fabric Index %u with Compressed Fabric ID:", |
Tennessee Carmel-Veilleux | e5e09f5 | 2022-06-24 16:57:34 -0400 | [diff] [blame] | 567 | static_cast<unsigned>(devCtrl->GetFabricIndex())); |
Tennessee Carmel-Veilleux | 1c03d9c | 2022-03-30 17:44:08 -0400 | [diff] [blame] | 568 | ChipLogByteSpan(Support, compressedFabricIdSpan); |
| 569 | |
| 570 | chip::ByteSpan defaultIpk = chip::GroupTesting::DefaultIpkValue::GetDefaultIpk(); |
Tennessee Carmel-Veilleux | e5e09f5 | 2022-06-24 16:57:34 -0400 | [diff] [blame] | 571 | err = |
| 572 | chip::Credentials::SetSingleIpkEpochKey(&sGroupDataProvider, devCtrl->GetFabricIndex(), defaultIpk, compressedFabricIdSpan); |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 573 | VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); |
Tennessee Carmel-Veilleux | 1c03d9c | 2022-03-30 17:44:08 -0400 | [diff] [blame] | 574 | |
Song GUO | d8e7e43 | 2024-06-04 17:53:30 +0000 | [diff] [blame] | 575 | sICDClientStorage.UpdateFabricList(devCtrl->GetFabricIndex()); |
| 576 | pairingDelegate->SetFabricIndex(devCtrl->GetFabricIndex()); |
| 577 | |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 578 | *outDevCtrl = devCtrl.release(); |
| 579 | *outPairingDelegate = pairingDelegate.release(); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 580 | |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 581 | return ToPyChipError(CHIP_NO_ERROR); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 582 | } |
| 583 | |
Terence Hampson | ec2b5e3 | 2023-02-22 13:22:02 -0500 | [diff] [blame] | 584 | PyChipError pychip_OpCreds_InitGroupTestingData(chip::Controller::DeviceCommissioner * devCtrl) |
| 585 | { |
| 586 | VerifyOrReturnError(devCtrl != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT)); |
| 587 | |
| 588 | uint8_t compressedFabricId[sizeof(uint64_t)] = { 0 }; |
| 589 | chip::MutableByteSpan compressedFabricIdSpan(compressedFabricId); |
| 590 | |
| 591 | CHIP_ERROR err = devCtrl->GetCompressedFabricIdBytes(compressedFabricIdSpan); |
| 592 | VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); |
| 593 | |
| 594 | err = chip::GroupTesting::InitData(&sGroupDataProvider, devCtrl->GetFabricIndex(), compressedFabricIdSpan); |
| 595 | |
| 596 | return ToPyChipError(err); |
| 597 | } |
| 598 | |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 599 | PyChipError pychip_OpCreds_SetMaximallyLargeCertsUsed(OpCredsContext * context, bool enabled) |
Tennessee Carmel-Veilleux | dfc1a70 | 2022-08-19 18:20:12 -0400 | [diff] [blame] | 600 | { |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 601 | VerifyOrReturnError(context != nullptr && context->mAdapter != nullptr, ToPyChipError(CHIP_ERROR_INCORRECT_STATE)); |
Tennessee Carmel-Veilleux | dfc1a70 | 2022-08-19 18:20:12 -0400 | [diff] [blame] | 602 | |
| 603 | context->mAdapter->SetMaximallyLargeCertsUsed(enabled); |
| 604 | |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 605 | return ToPyChipError(CHIP_NO_ERROR); |
Tennessee Carmel-Veilleux | dfc1a70 | 2022-08-19 18:20:12 -0400 | [diff] [blame] | 606 | } |
| 607 | |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 608 | void pychip_OpCreds_FreeDelegate(OpCredsContext * context) |
| 609 | { |
| 610 | Platform::Delete(context); |
| 611 | } |
| 612 | |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 613 | PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl, |
| 614 | chip::Controller::ScriptDevicePairingDelegate * pairingDelegate) |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 615 | { |
Andrei Litvin | 697b155 | 2022-04-06 10:45:26 -1000 | [diff] [blame] | 616 | if (devCtrl != nullptr) |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 617 | { |
| 618 | devCtrl->Shutdown(); |
| 619 | delete devCtrl; |
| 620 | } |
| 621 | |
tianfeng.yang | b4a6213 | 2024-04-17 21:53:13 +0800 | [diff] [blame] | 622 | if (pairingDelegate != nullptr) |
| 623 | { |
| 624 | delete pairingDelegate; |
| 625 | } |
| 626 | |
Song GUO | b9d32ec | 2022-10-24 14:40:11 +0800 | [diff] [blame] | 627 | return ToPyChipError(CHIP_NO_ERROR); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 628 | } |
C Freeman | 8ffe422 | 2022-02-02 14:21:16 -0500 | [diff] [blame] | 629 | |
Song GUO | e75d35a | 2023-03-01 08:57:22 +0800 | [diff] [blame] | 630 | PyChipError pychip_DeviceController_SetIpk(chip::Controller::DeviceCommissioner * devCtrl, const uint8_t * ipk, size_t ipkLen) |
| 631 | { |
| 632 | VerifyOrReturnError(ipk != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT)); |
| 633 | |
| 634 | uint8_t compressedFabricId[sizeof(uint64_t)] = { 0 }; |
| 635 | chip::MutableByteSpan compressedFabricIdSpan(compressedFabricId); |
| 636 | |
| 637 | CHIP_ERROR err = devCtrl->GetCompressedFabricIdBytes(compressedFabricIdSpan); |
| 638 | VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); |
| 639 | |
| 640 | err = chip::Credentials::SetSingleIpkEpochKey(&sGroupDataProvider, devCtrl->GetFabricIndex(), ByteSpan(ipk, ipkLen), |
| 641 | compressedFabricIdSpan); |
| 642 | |
| 643 | return ToPyChipError(err); |
| 644 | } |
| 645 | |
C Freeman | 8ffe422 | 2022-02-02 14:21:16 -0500 | [diff] [blame] | 646 | bool pychip_TestCommissionerUsed() |
| 647 | { |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 648 | return sTestCommissioner.GetTestCommissionerUsed(); |
| 649 | } |
| 650 | |
| 651 | bool pychip_TestCommissioningCallbacks() |
| 652 | { |
| 653 | return sTestCommissioner.CheckCallbacks(); |
| 654 | } |
| 655 | |
C Freeman | ac3535b | 2023-07-18 13:32:59 -0400 | [diff] [blame] | 656 | bool pychip_TestCommissioningStageSuccessful(uint8_t stage) |
| 657 | { |
| 658 | return sTestCommissioner.CheckStageSuccessful(stage); |
| 659 | } |
| 660 | |
C Freeman | c3b1810 | 2022-04-04 16:17:09 -0400 | [diff] [blame] | 661 | bool pychip_TestPaseConnection(NodeId nodeId) |
| 662 | { |
| 663 | return sTestCommissioner.CheckPaseConnection(nodeId); |
| 664 | } |
| 665 | |
| 666 | void pychip_ResetCommissioningTests() |
| 667 | { |
| 668 | sTestCommissioner.Reset(); |
| 669 | } |
| 670 | |
| 671 | // Returns True if this is a valid test, false otherwise |
| 672 | bool pychip_SetTestCommissionerSimulateFailureOnStage(uint8_t failStage) |
| 673 | { |
| 674 | return sTestCommissioner.SimulateFailAfter(static_cast<chip::Controller::CommissioningStage>(failStage)); |
| 675 | } |
| 676 | bool pychip_SetTestCommissionerSimulateFailureOnReport(uint8_t failStage) |
| 677 | { |
| 678 | return sTestCommissioner.SimulateFailOnReport(static_cast<chip::Controller::CommissioningStage>(failStage)); |
Jerry Johns | f68cd64 | 2022-01-28 16:39:08 -0800 | [diff] [blame] | 679 | } |
C Freeman | 89d538c | 2023-01-26 12:29:48 -0500 | [diff] [blame] | 680 | bool pychip_SetTestCommissionerPrematureCompleteAfter(uint8_t stage) |
| 681 | { |
| 682 | return sTestCommissioner.PrematureCompleteAfter(static_cast<chip::Controller::CommissioningStage>(stage)); |
| 683 | } |
| 684 | |
| 685 | PyChipError pychip_GetCompletionError() |
| 686 | { |
| 687 | return ToPyChipError(sTestCommissioner.GetCompletionError()); |
| 688 | } |
C Freeman | 8ffe422 | 2022-02-02 14:21:16 -0500 | [diff] [blame] | 689 | |
| 690 | } // extern "C" |