Matter SDK Coverage Report
Current view: top level - app/server-cluster/testing - FabricTestFixture.h (source / functions) Coverage Total Hit
Test: SHA:3f9cd168e84cd831b7699126f5296f5c5498690f Lines: 96.8 % 63 61
Test Date: 2026-04-27 19:52:19 Functions: 100.0 % 6 6

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2025 Project CHIP Authors
       3              :  *
       4              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       5              :  *    you may not use this file except in compliance with the License.
       6              :  *    You may obtain a copy of the License at
       7              :  *
       8              :  *        http://www.apache.org/licenses/LICENSE-2.0
       9              :  *
      10              :  *    Unless required by applicable law or agreed to in writing, software
      11              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      12              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13              :  *    See the License for the specific language governing permissions and
      14              :  *    limitations under the License.
      15              :  */
      16              : #pragma once
      17              : #include <credentials/FabricTable.h>
      18              : #include <credentials/PersistentStorageOpCertStore.h>
      19              : #include <crypto/CHIPCryptoPAL.h>
      20              : #include <lib/core/CHIPError.h>
      21              : #include <lib/core/CHIPPersistentStorageDelegate.h>
      22              : #include <lib/support/logging/CHIPLogging.h>
      23              : #include <memory>
      24              : #include <optional>
      25              : #include <vector>
      26              : 
      27              : namespace chip {
      28              : namespace Testing {
      29              : /**
      30              :  * @brief Fixture class to manage the lifecycle of a Fabric for testing.
      31              :  *
      32              :  * This encapsulates the logic required to initialize a FabricTable,
      33              :  * create a mock Fabric, and manage related certificate storage.
      34              :  * It is designed to be used by ClusterTester or a test fixture but not mandatory.
      35              :  */
      36              : class FabricTestFixture
      37              : {
      38              : public:
      39           26 :     FabricTestFixture(PersistentStorageDelegate * storage) :
      40           26 :         mStorage(storage), mRootCertSpan(mRootCertDER, sizeof(mRootCertDER)), mNocSpan(mNocDER, sizeof(mNocDER))
      41           26 :     {}
      42              : 
      43              :     /**
      44              :      * @brief Initializes the Fabric table and adds a new test fabric.
      45              :      *
      46              :      * @param fabricIndexOut Output parameter for the newly created FabricIndex.
      47              :      * @return CHIP_ERROR
      48              :      */
      49              : 
      50           26 :     CHIP_ERROR SetUpTestFabric(FabricIndex & fabricIndexOut)
      51              :     {
      52           26 :         ReturnErrorOnFailure(mOpCertStore.Init(mStorage));
      53           26 :         initParams.opCertStore         = &mOpCertStore;
      54           26 :         initParams.storage             = mStorage;
      55           26 :         initParams.operationalKeystore = nullptr; // Use default
      56           26 :         ReturnErrorOnFailure(mfabricTable.Init(initParams));
      57              : 
      58           26 :         ReturnErrorOnFailure(mfabricTable.SetFabricIndexForNextAddition(fabricIndexOut));
      59           26 :         ReturnErrorOnFailure(SetUpCertificates());
      60              : 
      61          104 :         CHIP_ERROR err = mfabricTable.AddNewFabricForTest(
      62           78 :             mRootCertSpan, ByteSpan(), mNocSpan, ByteSpan(mSerializedOpKey.Bytes(), mSerializedOpKey.Length()), &fabricIndexOut);
      63           26 :         ReturnErrorOnFailure(err);
      64              : 
      65           26 :         return mfabricTable.CommitPendingFabricData();
      66              :     }
      67              : 
      68              :     /**
      69              :      * @brief Tears down the created fabric and cleans up storage.
      70              :      *
      71              :      * @param fabricIndex The FabricIndex to tear down.
      72              :      * @return CHIP_ERROR
      73              :      */
      74           26 :     CHIP_ERROR TearDownTestFabric(FabricIndex & fabricIndex)
      75              :     {
      76           26 :         VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX);
      77              : 
      78              :         // Credentials::SetGroupDataProvider(nullptr); // Done in the test fixture's TearDown
      79              :         // GroupDataProviderImpl::RemoveFabric is usually done separately
      80              :         // However, we just need to ensure the fabric is deleted from FabricTable and storage is cleaned.
      81              : 
      82           26 :         CHIP_ERROR err = CHIP_NO_ERROR;
      83              : 
      84           52 :         if ((err = mOpCertStore.RemoveOpCertsForFabric(fabricIndex)) != CHIP_NO_ERROR)
      85              :         {
      86            0 :             ChipLogError(Test, "TearDownFabric: RemoveOpCertsForFabric failed: %" CHIP_ERROR_FORMAT, err.Format());
      87              :         }
      88           52 :         if ((err = mfabricTable.Delete(fabricIndex)) != CHIP_NO_ERROR)
      89              :         {
      90            0 :             ChipLogError(Test, "TearDownFabric: Delete fabric failed: %" CHIP_ERROR_FORMAT, err.Format());
      91              :         }
      92              : 
      93           26 :         mfabricTable.Shutdown();
      94           26 :         mOpCertStore.Finish();
      95              : 
      96           26 :         return CHIP_NO_ERROR;
      97              :     }
      98              : 
      99           45 :     FabricTable & GetFabricTable() { return mfabricTable; }
     100              : 
     101              :     /**
     102              :      * @brief Adds an additional test fabric to an already-initialized FabricTable.
     103              :      *        Must be called after SetUpTestFabric().
     104              :      *
     105              :      * @param fabricIndexOut Desired FabricIndex for the new fabric; updated on success.
     106              :      * @return CHIP_ERROR
     107              :      */
     108            2 :     CHIP_ERROR AddAdditionalTestFabric(FabricIndex & fabricIndexOut)
     109              :     {
     110            2 :         ReturnErrorOnFailure(mfabricTable.SetFabricIndexForNextAddition(fabricIndexOut));
     111            2 :         ReturnErrorOnFailure(SetUpCertificates());
     112            8 :         CHIP_ERROR err = mfabricTable.AddNewFabricForTestIgnoringCollisions(
     113            6 :             mRootCertSpan, ByteSpan(), mNocSpan, ByteSpan(mSerializedOpKey.Bytes(), mSerializedOpKey.Length()), &fabricIndexOut);
     114            2 :         ReturnErrorOnFailure(err);
     115            2 :         return mfabricTable.CommitPendingFabricData();
     116              :     }
     117              : 
     118              : private:
     119           28 :     CHIP_ERROR SetUpCertificates()
     120              :     {
     121           28 :         Crypto::P256Keypair rootCACredentials;
     122           28 :         ReturnErrorOnFailure(rootCACredentials.Initialize(Crypto::ECPKeyTarget::ECDSA));
     123              : 
     124           28 :         Crypto::P256Keypair deviceOpKey;
     125           28 :         ReturnErrorOnFailure(deviceOpKey.Initialize(Crypto::ECPKeyTarget::ECDSA));
     126              : 
     127           28 :         ReturnErrorOnFailure(deviceOpKey.Serialize(mSerializedOpKey));
     128              : 
     129              :         // Create temporary X.509 (DER) buffers
     130              :         uint8_t rootCertDER_temp[chip::Credentials::kMaxDERCertLength];
     131           28 :         MutableByteSpan rootCertDERSpan(rootCertDER_temp);
     132              : 
     133              :         uint8_t nocDER_temp[chip::Credentials::kMaxDERCertLength];
     134           28 :         MutableByteSpan nocDERSpan(nocDER_temp);
     135              : 
     136           28 :         mRootCertSpan = MutableByteSpan(mRootCertDER);
     137           28 :         mNocSpan      = MutableByteSpan(mNocDER);
     138              : 
     139           28 :         chip::Credentials::X509CertRequestParams rootRequestParams;
     140           28 :         rootRequestParams.SerialNumber  = kRootCertSerial;
     141           28 :         rootRequestParams.ValidityStart = kCertValidityStart;
     142           28 :         rootRequestParams.ValidityEnd   = kRootCertValidityDurationSeconds;
     143              : 
     144           28 :         const char * rootName = "My Test Root CA";
     145           28 :         ReturnErrorOnFailure(rootRequestParams.IssuerDN.AddAttribute(
     146              :             chip::ASN1::kOID_AttributeType_CommonName, CharSpan(rootName, strlen(rootName)), true /* isPrintableString */
     147              :             ));
     148           28 :         ReturnErrorOnFailure(rootRequestParams.IssuerDN.AddAttribute(chip::ASN1::kOID_AttributeType_MatterRCACId, kTestRcacId));
     149           28 :         rootRequestParams.SubjectDN = rootRequestParams.IssuerDN;
     150              : 
     151           28 :         ReturnErrorOnFailure(chip::Credentials::NewRootX509Cert(rootRequestParams, rootCACredentials, rootCertDERSpan));
     152              : 
     153              :         // Convert X.509 DER to Matter TLV
     154           28 :         ReturnErrorOnFailure(chip::Credentials::ConvertX509CertToChipCert(rootCertDERSpan, mRootCertSpan));
     155              : 
     156           28 :         chip::Credentials::X509CertRequestParams nocRequestParams;
     157           28 :         nocRequestParams.SerialNumber  = kNocSerial;
     158           28 :         nocRequestParams.ValidityStart = kCertValidityStart;
     159           28 :         nocRequestParams.ValidityEnd   = kNocCertValidityDurationSeconds;
     160           28 :         nocRequestParams.IssuerDN      = rootRequestParams.SubjectDN;
     161           28 :         ReturnErrorOnFailure(nocRequestParams.SubjectDN.AddAttribute(chip::ASN1::kOID_AttributeType_MatterFabricId, kTestFabricId));
     162           28 :         ReturnErrorOnFailure(nocRequestParams.SubjectDN.AddAttribute(chip::ASN1::kOID_AttributeType_MatterNodeId, kTestNodeId));
     163           28 :         ReturnErrorOnFailure(
     164              :             chip::Credentials::NewNodeOperationalX509Cert(nocRequestParams, deviceOpKey.Pubkey(), rootCACredentials, nocDERSpan));
     165              : 
     166           28 :         return chip::Credentials::ConvertX509CertToChipCert(nocDERSpan, mNocSpan);
     167           28 :     }
     168              : 
     169              :     PersistentStorageDelegate * mStorage;
     170              : 
     171              :     // Certificates and keys
     172              :     uint8_t mRootCertDER[chip::Credentials::kMaxDERCertLength];
     173              :     MutableByteSpan mRootCertSpan;
     174              :     uint8_t mNocDER[chip::Credentials::kMaxDERCertLength];
     175              :     MutableByteSpan mNocSpan;
     176              :     Crypto::P256SerializedKeypair mSerializedOpKey;
     177              : 
     178              :     // Fabric-related storage
     179              :     chip::Credentials::PersistentStorageOpCertStore mOpCertStore;
     180              :     FabricTable mfabricTable;
     181              :     FabricTable::InitParams initParams;
     182              : 
     183              :     // Test constants (copied from test fixture)
     184              :     static constexpr FabricId kTestFabricId                    = 0xDEADBEEF00000001;
     185              :     static constexpr NodeId kTestNodeId                        = 0xDEADBEEF00000002;
     186              :     static constexpr uint64_t kTestRcacId                      = 0x1111222233334444;
     187              :     static constexpr uint64_t kRootCertSerial                  = 1;
     188              :     static constexpr uint64_t kNocSerial                       = 2;
     189              :     static constexpr uint64_t kCertValidityStart               = 0;
     190              :     static constexpr uint32_t kRootCertValidityDurationSeconds = 315360000; // 10 years
     191              :     static constexpr uint32_t kNocCertValidityDurationSeconds  = 31536000;  // 1 year
     192              : };
     193              : 
     194              : } // namespace Testing
     195              : } // namespace chip
        

Generated by: LCOV version 2.0-1