blob: 4bc2f9f5669f3512fbdcd3677037d6470654e78d [file] [log] [blame]
/*
* Copyright (c) 2025 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/InteractionModelEngine.h>
#include <app/data-model-provider/Context.h>
#include <app/tests/AppTestContext.h>
#include <app/util/mock/Functions.h>
#include <app/util/mock/MockNodeConfig.h>
#include <controller/CommissioningDelegate.h>
#include <controller/jcm/AutoCommissioner.h>
#include <controller/jcm/DeviceCommissioner.h>
#include <credentials/CHIPCert.h>
#include <credentials/tests/CHIPCert_unit_test_vectors.h>
#include <data-model-providers/codegen/CodegenDataModelProvider.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPError.h>
#include <lib/support/TestPersistentStorageDelegate.h>
#include <lib/support/tests/ExtraPwTestMacros.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/ReliableMessageProtocolConfig.h>
#include <messaging/tests/MessagingContext.h>
#include <pw_unit_test/framework.h>
#include <transport/SecureSession.h>
#include <transport/SecureSessionTable.h>
using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::Controller;
using namespace chip::Crypto;
using namespace chip::Credentials;
using namespace chip::Messaging;
using namespace chip::Platform;
using namespace chip::Testing;
using namespace chip::TestCerts;
using namespace chip::Transport;
// Mock function for linking
__attribute__((weak)) void InitDataModelHandler() {}
namespace chip {
namespace app {
__attribute__((weak)) void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath,
chip::TLV::TLVReader & aReader, CommandHandler * apCommandObj)
{}
} // namespace app
namespace Controller {
namespace JCM {
using namespace ::chip::Credentials::JCM;
class MockTrustVerificationDelegate : public TrustVerificationDelegate
{
public:
void OnProgressUpdate(TrustVerificationStateMachine & stateMachine, TrustVerificationStage stage, TrustVerificationInfo & info,
TrustVerificationError error) override
{
mProgressUpdates++;
mLastStage = stage;
mLastError = error;
mRemoteAdminTrustedRoot = info.adminRCAC.Span();
}
void OnAskUserForConsent(TrustVerificationStateMachine & stateMachine, TrustVerificationInfo & info) override
{
mAskedForConsent = true;
mLastVendorId = info.adminVendorId;
stateMachine.ContinueAfterUserConsent(mShouldConsent);
}
CHIP_ERROR OnLookupOperationalTrustAnchor(VendorId vendorID, CertificateKeyId & subjectKeyId,
ByteSpan & globallyTrustedRootSpan) override
{
mLookedUpOperationalTrustAnchor = true;
globallyTrustedRootSpan = mRemoteAdminTrustedRoot;
return CHIP_NO_ERROR;
}
int mProgressUpdates = 0;
TrustVerificationStage mLastStage = TrustVerificationStage::kIdle;
TrustVerificationError mLastError = TrustVerificationError::kSuccess;
bool mAskedForConsent = false;
bool mLookedUpOperationalTrustAnchor = false;
bool mShouldConsent = true;
CHIP_ERROR mVerifyVendorIdError = CHIP_NO_ERROR;
VendorId mLastVendorId = VendorId::Common;
ByteSpan mRemoteAdminTrustedRoot;
};
class MockClusterStateCache : public ClusterStateCache
{
public:
MockClusterStateCache() : ClusterStateCache(mClusterStateCacheCallback) {}
class MockClusterStateCacheCallback : public ClusterStateCache::Callback
{
void OnDone(ReadClient *) override {}
void OnAttributeData(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const StatusIB & aStatus) override {}
};
CHIP_ERROR SetUp(const FabricTable & fabricTable, const FabricIndex fabricIndex, const NodeId nodeId)
{
const FabricInfo * fabricInfo = fabricTable.FindFabricWithIndex(fabricIndex);
// Setup JF Administrator cluster attributes
ConcreteAttributePath adminFabricIndexPath(1, JointFabricAdministrator::Id,
JointFabricAdministrator::Attributes::AdministratorFabricIndex::Id);
ReturnErrorOnFailure(SetAttribute(adminFabricIndexPath, static_cast<FabricIndex>(fabricIndex)));
// Setup trusted root certificates
uint8_t rcacBuf[Credentials::kMaxCHIPCertLength];
MutableByteSpan rcacSpan{ rcacBuf };
ReturnErrorOnFailure(fabricTable.FetchRootCert(fabricIndex, rcacSpan));
chip::ByteSpan rcacCertsData[] = { rcacSpan };
DataModel::List<chip::ByteSpan> rcacCerts;
rcacCerts = rcacCertsData;
ConcreteAttributePath trustedRootsPath(0, OperationalCredentials::Id,
OperationalCredentials::Attributes::TrustedRootCertificates::Id);
ReturnErrorOnFailure(SetAttribute(trustedRootsPath, rcacCerts));
// Setup Operational Credentials cluster fabrics list attribute
OperationalCredentials::Structs::FabricDescriptorStruct::Type fabricDescriptor;
fabricDescriptor.fabricIndex = static_cast<chip::FabricIndex>(fabricIndex);
fabricDescriptor.vendorID = static_cast<chip::VendorId>(fabricInfo->GetVendorId()); // Example vendor ID
fabricDescriptor.fabricID = static_cast<chip::FabricId>(fabricInfo->GetFabricId());
fabricDescriptor.nodeID = static_cast<chip::NodeId>(nodeId);
Credentials::P256PublicKeySpan trustedCAPublicKeySpan;
ReturnErrorOnFailure(Credentials::ExtractPublicKeyFromChipCert(rcacSpan, trustedCAPublicKeySpan));
Crypto::P256PublicKey trustedCAPublicKey{ trustedCAPublicKeySpan };
fabricDescriptor.rootPublicKey = ByteSpan{ trustedCAPublicKey.ConstBytes(), trustedCAPublicKey.Length() };
OperationalCredentials::Structs::FabricDescriptorStruct::Type fabricListData[1] = { std::move(fabricDescriptor) };
DataModel::List<const OperationalCredentials::Structs::FabricDescriptorStruct::Type> fabricsList;
fabricsList = fabricListData;
ConcreteAttributePath fabricsPath(0, OperationalCredentials::Id, OperationalCredentials::Attributes::Fabrics::Id);
ReturnErrorOnFailure(SetAttributeForWrite(fabricsPath, fabricsList));
// Setup NOCs list attribute
OperationalCredentials::Structs::NOCStruct::Type nocStruct;
nocStruct.fabricIndex = static_cast<chip::FabricIndex>(fabricIndex);
uint8_t icacBuf[Credentials::kMaxCHIPCertLength];
MutableByteSpan icacSpan{ icacBuf };
ReturnErrorOnFailure(fabricTable.FetchICACert(fabricIndex, icacSpan));
nocStruct.icac = icacSpan;
uint8_t nocBuf[Credentials::kMaxCHIPCertLength];
MutableByteSpan nocSpan{ nocBuf };
ReturnErrorOnFailure(fabricTable.FetchNOCCert(fabricIndex, nocSpan));
nocStruct.noc = nocSpan;
OperationalCredentials::Structs::NOCStruct::Type nocListData[1] = { nocStruct };
DataModel::List<OperationalCredentials::Structs::NOCStruct::Type> nocsList;
nocsList = nocListData;
ConcreteAttributePath nocsPath(0, OperationalCredentials::Id, OperationalCredentials::Attributes::NOCs::Id);
ReturnErrorOnFailure(SetAttributeForWrite(nocsPath, nocsList));
return CHIP_NO_ERROR;
}
void TearDown() { ClearEventCache(); }
template <typename AttrType>
CHIP_ERROR SetAttribute(const ConcreteAttributePath & path, const AttrType data)
{
Platform::ScopedMemoryBufferWithSize<uint8_t> handle;
handle.Calloc(3000);
TLV::ScopedBufferTLVWriter writer(std::move(handle), 3000);
ReturnErrorOnFailure(DataModel::Encode(writer, TLV::AnonymousTag(), data));
uint32_t writtenLength = writer.GetLengthWritten();
ReturnErrorOnFailure(writer.Finalize(handle));
TLV::ScopedBufferTLVReader reader;
StatusIB aStatus;
reader.Init(std::move(handle), writtenLength);
ReturnErrorOnFailure(reader.Next());
ReadClient::Callback & callback = GetBufferedCallback();
callback.OnAttributeData(path, &reader, aStatus);
return CHIP_NO_ERROR;
}
template <typename AttrType>
CHIP_ERROR SetAttributeForWrite(const ConcreteAttributePath & path, const AttrType data)
{
Platform::ScopedMemoryBufferWithSize<uint8_t> handle;
handle.Calloc(3000);
TLV::ScopedBufferTLVWriter writer(std::move(handle), 3000);
ReturnErrorOnFailure(DataModel::EncodeForRead(writer, TLV::AnonymousTag(), static_cast<chip::FabricIndex>(1), data));
uint32_t writtenLength = writer.GetLengthWritten();
ReturnErrorOnFailure(writer.Finalize(handle));
TLV::ScopedBufferTLVReader reader;
StatusIB aStatus;
reader.Init(std::move(handle), writtenLength);
ReturnErrorOnFailure(reader.Next());
ReadClient::Callback & callback = GetBufferedCallback();
callback.OnAttributeData(path, &reader, aStatus);
return CHIP_NO_ERROR;
}
private:
MockClusterStateCacheCallback mClusterStateCacheCallback;
};
class MockDeviceProxy : public DeviceProxy, public SessionDelegate
{
public:
MockDeviceProxy(Messaging::ExchangeManager * exchangeManager, const SessionHandle & session, NodeId nodeId) :
mExchangeManager(exchangeManager), mSecureSession(*this), mRemoteNodeId(nodeId)
{
mSecureSession.Grab(session);
}
void Disconnect() override {}
NodeId GetDeviceId() const override { return mRemoteNodeId; }
Messaging::ExchangeManager * GetExchangeManager() const override { return mExchangeManager; }
chip::Optional<SessionHandle> GetSecureSession() const override { return mSecureSession.Get(); }
bool IsSecureConnected() const override { return true; }
void OnSessionReleased() override {}
private:
Messaging::ExchangeManager * mExchangeManager;
SessionHolderWithDelegate mSecureSession;
const NodeId mRemoteNodeId;
};
class TestableDeviceCommissioner : public DeviceCommissioner
{
public:
void OnTrustVerificationComplete(TrustVerificationError result) override
{
mResult = result;
ChipLogProgress(Controller, "TestableDeviceCommissioner::OnTrustVerificationComplete called with result: %hu",
static_cast<uint16_t>(result));
}
TrustVerificationError mResult;
};
class TestVendorIDVerificationDataModel : public CodegenDataModelProvider
{
public:
TestVendorIDVerificationDataModel() : mMessagingContext(nullptr) {}
static TestVendorIDVerificationDataModel & Instance(MessagingContext * messagingContext)
{
static TestVendorIDVerificationDataModel instance;
instance.SetMessagingContext(messagingContext);
return instance;
}
void SetMessagingContext(MessagingContext * messagingContext) { mMessagingContext = messagingContext; }
std::optional<DataModel::ActionReturnStatus> InvokeCommand(const DataModel::InvokeRequest & aRequest,
chip::TLV::TLVReader & aReader, CommandHandler * aHandler) override
{
VerifyOrDie(mMessagingContext != nullptr);
if (aRequest.path.mClusterId != Clusters::OperationalCredentials::Id ||
aRequest.path.mCommandId !=
Clusters::OperationalCredentials::Commands::SignVIDVerificationRequest::Type::GetCommandId())
{
aHandler->AddStatus(aRequest.path, Protocols::InteractionModel::Status::UnsupportedCommand, "Invalid cluster/command");
return std::nullopt; // handler status is set by the dispatch
}
Clusters::OperationalCredentials::Commands::SignVIDVerificationRequest::DecodableType dataRequest;
if (DataModel::Decode(aReader, dataRequest) != CHIP_NO_ERROR)
{
aHandler->AddStatus(aRequest.path, Protocols::InteractionModel::Status::Failure, "Unable to decode the request");
return std::nullopt; // handler status is set by the dispatch
}
ChipLogDetail(Controller, "Received Cluster Command: Endpoint=%x Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI,
aRequest.path.mEndpointId, ChipLogValueMEI(aRequest.path.mClusterId),
ChipLogValueMEI(aRequest.path.mCommandId));
// Get the fabric table.
FabricTable & fabricTable = mMessagingContext->GetFabricTable();
// Sign the VID verification request.
SessionHandle sessionHandle = mMessagingContext->GetJFSessionAToB();
ByteSpan attestationChallengeSpan = sessionHandle->AsSecureSession()->GetCryptoContext().GetAttestationChallenge();
FabricTable::SignVIDVerificationResponseData responseData;
CHIP_ERROR err = fabricTable.SignVIDVerificationRequest(dataRequest.fabricIndex, dataRequest.clientChallenge,
attestationChallengeSpan, responseData);
if (err != CHIP_NO_ERROR)
{
aHandler->AddStatus(aRequest.path, Protocols::InteractionModel::Status::Failure);
return std::nullopt; // handler status is set by the dispatch
}
// Return the response
Clusters::OperationalCredentials::Commands::SignVIDVerificationResponse::Type response;
response.fabricIndex = responseData.fabricIndex;
response.fabricBindingVersion = responseData.fabricBindingVersion;
response.signature = responseData.signature.Span();
aHandler->AddResponse(aRequest.path, response);
aHandler->AddStatus(aRequest.path, Protocols::InteractionModel::Status::Success);
return std::nullopt; // handler status is set by the dispatch
}
private:
MessagingContext * mMessagingContext;
};
const MockNodeConfig & TestMockNodeConfig()
{
using namespace chip::app;
using namespace chip::app::Clusters::Globals::Attributes;
// clang-format off
static const MockNodeConfig config({
MockEndpointConfig(kRootEndpointId, {
MockClusterConfig(Clusters::OperationalCredentials::Id, {
ClusterRevision::Id, FeatureMap::Id,
},
{}, // events
{
Clusters::OperationalCredentials::Commands::SignVIDVerificationRequest::Id,
}, // accepted commands
{} // generated commands
),
}),
});
// clang-format on
return config;
}
class TestCommissioner : public AppContext
{
public:
TestCommissioner() { mInfo.attributes = &mClusterStateCache; }
static void SetUpTestSuite()
{
ASSERT_EQ(Platform::MemoryInit(), CHIP_NO_ERROR);
AppContext::SetUpTestSuite();
}
// Performs shared teardown for all tests in the test suite. Run once for the whole suite.
static void TearDownTestSuite()
{
AppContext::TearDownTestSuite();
Platform::MemoryShutdown();
}
void TestTrustVerificationStageFinishedProgressesThroughStages();
void TestTrustVerificationStageFinishedHandlesUserConsent();
void TestTrustVerificationStageFinishedHandlesError();
void TestParseExtraCommissioningInfo();
void TestParseAdminFabricIndexAndEndpointId();
void TestParseOperationalCredentials();
void TestParseTrustedRoot();
protected:
void SetUp() override
{
SetupForJFTests();
AppContext::SetUp();
mOldProvider =
InteractionModelEngine::GetInstance()->SetDataModelProvider(&TestVendorIDVerificationDataModel::Instance(this));
SetMockNodeConfig(TestMockNodeConfig());
mDeviceCommissioner = new TestableDeviceCommissioner();
mDeviceCommissioner->RegisterTrustVerificationDelegate(&mTrustVerificationDelegate);
SessionHandle session = GetJFSessionAToB();
NodeId jfbNodeId = GetJFBFabric()->GetNodeId();
mDeviceProxy = new MockDeviceProxy(&GetExchangeManager(), session, jfbNodeId);
mDeviceCommissioner->mDeviceProxy = mDeviceProxy;
#if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
mCommissioningParams.SetUseJCM(true);
#endif // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
CHIP_ERROR err = mAutoCommissioner.SetCommissioningParameters(mCommissioningParams);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "mAutoCommissioner.SetCommissioningParameters failed with error: %s", ErrorStr(err));
}
err = mClusterStateCache.SetUp(GetFabricTable(), GetJFBFabricIndex(), jfbNodeId);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "MockClusterStateCache::SetUp failed with error: %s", ErrorStr(err));
}
}
void TearDown() override
{
ExpireJFSessionAToB();
chip::Testing::ResetMockNodeConfig();
InteractionModelEngine::GetInstance()->SetDataModelProvider(mOldProvider);
AppContext::TearDown();
mClusterStateCache.TearDown();
delete mDeviceCommissioner;
mDeviceCommissioner = nullptr;
delete mDeviceProxy;
mDeviceProxy = nullptr;
}
protected:
chip::app::DataModel::Provider * mOldProvider = nullptr;
private:
AutoCommissioner mAutoCommissioner;
DeviceCommissioner * mDeviceCommissioner;
MockTrustVerificationDelegate mTrustVerificationDelegate;
MockClusterStateCache mClusterStateCache;
ReadCommissioningInfo mInfo;
CommissioningParameters mCommissioningParams;
DeviceProxy * mDeviceProxy = nullptr;
};
TEST_F_FROM_FIXTURE(TestCommissioner, TestTrustVerificationStageFinishedProgressesThroughStages)
{
// Simulate user consenting
mTrustVerificationDelegate.mShouldConsent = true;
// Set up the mock ReadCommissioningInfo
CHIP_ERROR err = mDeviceCommissioner->ParseExtraCommissioningInfo(mInfo, mCommissioningParams);
EXPECT_EQ(err, CHIP_NO_ERROR);
TrustVerificationStage stage = TrustVerificationStage::kIdle;
TrustVerificationError error = TrustVerificationError::kSuccess;
// Start at Started, advance through all stages
// Advance to kAskUserForConsent (should trigger consent)
mDeviceCommissioner->TrustVerificationStageFinished(stage, error);
// Wait for JCM to complete
DrainAndServiceIO();
EXPECT_EQ(mTrustVerificationDelegate.mProgressUpdates, 5); // Progress not incremented for consent
EXPECT_EQ(mTrustVerificationDelegate.mLastStage, TrustVerificationStage::kComplete);
EXPECT_EQ(mTrustVerificationDelegate.mLastError, TrustVerificationError::kSuccess);
EXPECT_TRUE(mTrustVerificationDelegate.mAskedForConsent);
EXPECT_TRUE(mTrustVerificationDelegate.mLookedUpOperationalTrustAnchor);
EXPECT_EQ(mTrustVerificationDelegate.mLastVendorId, chip::VendorId(65521));
}
TEST_F_FROM_FIXTURE(TestCommissioner, TestTrustVerificationStageFinishedHandlesUserConsent)
{
// Simulate user rejecting consent
mTrustVerificationDelegate.mShouldConsent = false;
// Simulate reaching consent stage
mDeviceCommissioner->mInfo.adminFabricIndex = 1;
mDeviceCommissioner->mInfo.adminEndpointId = 1;
TrustVerificationStage stage = TrustVerificationStage::kPerformingVendorIDVerification;
TrustVerificationError error = TrustVerificationError::kSuccess;
mDeviceCommissioner->TrustVerificationStageFinished(stage, error);
EXPECT_TRUE(mTrustVerificationDelegate.mAskedForConsent);
EXPECT_EQ(mTrustVerificationDelegate.mProgressUpdates, 2); // Only OnProgressUpdate called for error
EXPECT_EQ(mTrustVerificationDelegate.mLastStage, TrustVerificationStage::kAskingUserForConsent);
EXPECT_EQ(mTrustVerificationDelegate.mLastError, TrustVerificationError::kUserDeniedConsent);
}
TEST_F_FROM_FIXTURE(TestCommissioner, TestTrustVerificationStageFinishedHandlesError)
{
// Simulate vendor id verification failure
mTrustVerificationDelegate.mVerifyVendorIdError = CHIP_ERROR_INTERNAL;
TrustVerificationStage stage = TrustVerificationStage::kVerifyingAdministratorInformation;
TrustVerificationError error = TrustVerificationError::kSuccess;
// Simulate error at operational credentials stage
mDeviceCommissioner->TrustVerificationStageFinished(stage, error);
// Wait for JCM to complete
DrainAndServiceIO();
EXPECT_EQ(mTrustVerificationDelegate.mProgressUpdates, 2);
EXPECT_EQ(mTrustVerificationDelegate.mLastStage, TrustVerificationStage::kPerformingVendorIDVerification);
EXPECT_EQ(mTrustVerificationDelegate.mLastError, TrustVerificationError::kVendorIdVerificationFailed);
}
// Test getting admin fabric index and endpoint ID
TEST_F_FROM_FIXTURE(TestCommissioner, TestParseAdminFabricIndexAndEndpointId)
{
// Call the method directly to test it
EXPECT_EQ(CHIP_NO_ERROR, mDeviceCommissioner->ParseAdminFabricIndexAndEndpointId(mInfo));
// Verify the ParseAdminFabricIndexAndEndpointId results
EXPECT_EQ(mDeviceCommissioner->mInfo.adminFabricIndex, GetJFBFabricIndex());
EXPECT_EQ(mDeviceCommissioner->mInfo.adminEndpointId, 1);
}
// Test getting operational credentials
TEST_F_FROM_FIXTURE(TestCommissioner, TestParseOperationalCredentials)
{
// Set up the prerequisites for ParseTrustedRoot
EXPECT_EQ(CHIP_NO_ERROR, mDeviceCommissioner->ParseAdminFabricIndexAndEndpointId(mInfo));
// Call the method directly to test it
EXPECT_EQ(CHIP_NO_ERROR, mDeviceCommissioner->ParseOperationalCredentials(mInfo));
// Verify the ParseAdminFabricIndexAndEndpointId results
EXPECT_EQ(mDeviceCommissioner->mInfo.adminFabricIndex, GetJFBFabricIndex());
EXPECT_EQ(mDeviceCommissioner->mInfo.adminEndpointId, 1);
// Verify the ParseOperationalCredentials results
EXPECT_EQ(mDeviceCommissioner->mInfo.rootPublicKey.AllocatedSize(), Crypto::kP256_PublicKey_Length);
EXPECT_EQ(mDeviceCommissioner->mInfo.adminVendorId, static_cast<VendorId>(chip::VendorId::TestVendor1));
EXPECT_EQ(mDeviceCommissioner->mInfo.adminFabricId, GetJFBFabric()->GetFabricId());
auto nocCertAsset = GetJFBNodeCertAsset();
EXPECT_EQ(mDeviceCommissioner->mInfo.adminNOC.AllocatedSize(), static_cast<size_t>(nocCertAsset.mCert.size()));
auto iaCertAsset = GetJFBIACertAsset();
EXPECT_EQ(mDeviceCommissioner->mInfo.adminICAC.AllocatedSize(), static_cast<size_t>(iaCertAsset.mCert.size()));
}
// Test getting trusted root
TEST_F_FROM_FIXTURE(TestCommissioner, TestParseTrustedRoot)
{
// Set up the prerequisites for ParseTrustedRoot
EXPECT_EQ(CHIP_NO_ERROR, mDeviceCommissioner->ParseAdminFabricIndexAndEndpointId(mInfo));
EXPECT_EQ(CHIP_NO_ERROR, mDeviceCommissioner->ParseOperationalCredentials(mInfo));
// Call the method directly to test it
EXPECT_EQ(CHIP_NO_ERROR, mDeviceCommissioner->ParseTrustedRoot(mInfo));
// Verify the ParseAdminFabricIndexAndEndpointId results
EXPECT_EQ(mDeviceCommissioner->mInfo.adminFabricIndex, GetJFBFabricIndex());
EXPECT_EQ(mDeviceCommissioner->mInfo.adminEndpointId, 1);
// Verify the ParseOperationalCredentials results
EXPECT_EQ(mDeviceCommissioner->mInfo.rootPublicKey.AllocatedSize(), Crypto::kP256_PublicKey_Length);
EXPECT_EQ(mDeviceCommissioner->mInfo.adminVendorId, static_cast<VendorId>(chip::VendorId::TestVendor1));
EXPECT_EQ(mDeviceCommissioner->mInfo.adminFabricId, GetJFBFabric()->GetFabricId());
auto nocCertAsset = GetJFBNodeCertAsset();
EXPECT_EQ(mDeviceCommissioner->mInfo.adminNOC.AllocatedSize(), static_cast<size_t>(nocCertAsset.mCert.size()));
auto iaCertAsset = GetJFBIACertAsset();
EXPECT_EQ(mDeviceCommissioner->mInfo.adminICAC.AllocatedSize(), static_cast<size_t>(iaCertAsset.mCert.size()));
// Verify the ParseTrustedRoot results
auto rootCertAsset = GetJFBRootCertAsset();
EXPECT_EQ(mDeviceCommissioner->mInfo.adminRCAC.AllocatedSize(), static_cast<size_t>(rootCertAsset.mCert.size()));
}
// Test parsing administrator info
TEST_F_FROM_FIXTURE(TestCommissioner, TestParseExtraCommissioningInfo)
{
// Call the method directly to test it
EXPECT_EQ(CHIP_NO_ERROR, mDeviceCommissioner->ParseExtraCommissioningInfo(mInfo, mCommissioningParams));
// Verify the ParseExtraCommissioningInfo results
EXPECT_EQ(mDeviceCommissioner->mInfo.adminFabricIndex, GetJFBFabricIndex());
EXPECT_EQ(mDeviceCommissioner->mInfo.adminEndpointId, 1);
EXPECT_EQ(mDeviceCommissioner->mInfo.rootPublicKey.AllocatedSize(), Crypto::kP256_PublicKey_Length);
EXPECT_EQ(mDeviceCommissioner->mInfo.adminVendorId, static_cast<VendorId>(chip::VendorId::TestVendor1));
EXPECT_EQ(mDeviceCommissioner->mInfo.adminFabricId, GetJFBFabric()->GetFabricId());
auto nocCertAsset = GetJFBNodeCertAsset();
EXPECT_EQ(mDeviceCommissioner->mInfo.adminNOC.AllocatedSize(), static_cast<size_t>(nocCertAsset.mCert.size()));
auto iaCertAsset = GetJFBIACertAsset();
EXPECT_EQ(mDeviceCommissioner->mInfo.adminICAC.AllocatedSize(), static_cast<size_t>(iaCertAsset.mCert.size()));
// Verify the ParseTrustedRoot results
auto rootCertAsset = GetJFBRootCertAsset();
EXPECT_EQ(mDeviceCommissioner->mInfo.adminRCAC.AllocatedSize(), static_cast<size_t>(rootCertAsset.mCert.size()));
}
} // namespace JCM
} // namespace Controller
} // namespace chip