LCOV - code coverage report
Current view: top level - crypto - PersistentStorageOperationalKeystore.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 13 14 92.9 %
Date: 2024-02-15 08:20:41 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /*
       2             :  *    Copyright (c) 2022 Project CHIP Authors
       3             :  *    All rights reserved.
       4             :  *
       5             :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6             :  *    you may not use this file except in compliance with the License.
       7             :  *    You may obtain a copy of the License at
       8             :  *
       9             :  *        http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  *    Unless required by applicable law or agreed to in writing, software
      12             :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13             :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  *    See the License for the specific language governing permissions and
      15             :  *    limitations under the License.
      16             :  */
      17             : 
      18             : #pragma once
      19             : 
      20             : #include <crypto/OperationalKeystore.h>
      21             : #include <lib/core/CHIPError.h>
      22             : #include <lib/core/CHIPPersistentStorageDelegate.h>
      23             : #include <lib/core/DataModelTypes.h>
      24             : #include <lib/support/CHIPMem.h>
      25             : #include <lib/support/CodeUtils.h>
      26             : 
      27             : namespace chip {
      28             : 
      29             : /**
      30             :  * @brief OperationalKeystore implementation making use of PersistentStorageDelegate
      31             :  *        to load/store keypairs. This is the legacy behavior of `FabricTable` prior
      32             :  *        to refactors to use `OperationalKeystore` and exists as a baseline example
      33             :  *        of how to use the interface.
      34             :  *
      35             :  * WARNING: Ensure that any implementation that uses this one as a starting point
      36             :  *          DOES NOT have the raw key material (in usable form) passed up/down to
      37             :  *          direct storage APIs that may make copies on heap/stack without sanitization.
      38             :  */
      39             : class PersistentStorageOperationalKeystore : public Crypto::OperationalKeystore
      40             : {
      41             : public:
      42             :     PersistentStorageOperationalKeystore() = default;
      43           1 :     virtual ~PersistentStorageOperationalKeystore() { Finish(); }
      44             : 
      45             :     // Non-copyable
      46             :     PersistentStorageOperationalKeystore(PersistentStorageOperationalKeystore const &) = delete;
      47             :     void operator=(PersistentStorageOperationalKeystore const &)                       = delete;
      48             : 
      49             :     /**
      50             :      * @brief Initialize the Operational Keystore to map to a given storage delegate.
      51             :      *
      52             :      * @param storage Pointer to persistent storage delegate to use. Must outlive this instance.
      53             :      * @retval CHIP_NO_ERROR on success
      54             :      * @retval CHIP_ERROR_INCORRECT_STATE if already initialized
      55             :      */
      56             :     CHIP_ERROR Init(PersistentStorageDelegate * storage)
      57             :     {
      58             :         VerifyOrReturnError(mStorage == nullptr, CHIP_ERROR_INCORRECT_STATE);
      59             :         mPendingFabricIndex       = kUndefinedFabricIndex;
      60             :         mIsExternallyOwnedKeypair = false;
      61             :         mStorage                  = storage;
      62             :         mPendingKeypair           = nullptr;
      63             :         mIsPendingKeypairActive   = false;
      64             :         return CHIP_NO_ERROR;
      65             :     }
      66             : 
      67             :     /**
      68             :      * @brief Finalize the keystore, so that subsequent operations fail
      69             :      */
      70           1 :     void Finish()
      71             :     {
      72           1 :         VerifyOrReturn(mStorage != nullptr);
      73             : 
      74           1 :         ResetPendingKey();
      75           1 :         mStorage = nullptr;
      76             :     }
      77             : 
      78          58 :     bool HasPendingOpKeypair() const override { return (mPendingKeypair != nullptr); }
      79             : 
      80             :     bool HasOpKeypairForFabric(FabricIndex fabricIndex) const override;
      81             :     CHIP_ERROR NewOpKeypairForFabric(FabricIndex fabricIndex, MutableByteSpan & outCertificateSigningRequest) override;
      82             :     CHIP_ERROR ActivateOpKeypairForFabric(FabricIndex fabricIndex, const Crypto::P256PublicKey & nocPublicKey) override;
      83             :     CHIP_ERROR CommitOpKeypairForFabric(FabricIndex fabricIndex) override;
      84             :     CHIP_ERROR ExportOpKeypairForFabric(FabricIndex fabricIndex, Crypto::P256SerializedKeypair & outKeypair) override;
      85             :     CHIP_ERROR RemoveOpKeypairForFabric(FabricIndex fabricIndex) override;
      86             :     void RevertPendingKeypair() override;
      87             :     CHIP_ERROR SignWithOpKeypair(FabricIndex fabricIndex, const ByteSpan & message,
      88             :                                  Crypto::P256ECDSASignature & outSignature) const override;
      89             :     Crypto::P256Keypair * AllocateEphemeralKeypairForCASE() override;
      90             :     void ReleaseEphemeralKeypair(Crypto::P256Keypair * keypair) override;
      91             :     CHIP_ERROR MigrateOpKeypairForFabric(FabricIndex fabricIndex, OperationalKeystore & operationalKeystore) const override;
      92             : 
      93             : protected:
      94           1 :     void ResetPendingKey()
      95             :     {
      96           1 :         if (!mIsExternallyOwnedKeypair && (mPendingKeypair != nullptr))
      97             :         {
      98           0 :             Platform::Delete(mPendingKeypair);
      99             :         }
     100           1 :         mPendingKeypair           = nullptr;
     101           1 :         mIsExternallyOwnedKeypair = false;
     102           1 :         mIsPendingKeypairActive   = false;
     103           1 :         mPendingFabricIndex       = kUndefinedFabricIndex;
     104           1 :     }
     105             : 
     106             :     PersistentStorageDelegate * mStorage = nullptr;
     107             : 
     108             :     // This pending fabric index is `kUndefinedFabricIndex` if there isn't a pending keypair override for a given fabric.
     109             :     FabricIndex mPendingFabricIndex       = kUndefinedFabricIndex;
     110             :     Crypto::P256Keypair * mPendingKeypair = nullptr;
     111             :     bool mIsPendingKeypairActive          = false;
     112             : 
     113             :     // If overridding NewOpKeypairForFabric method in a subclass, set this to true in
     114             :     // `NewOpKeypairForFabric` if the mPendingKeypair should not be deleted when no longer in use.
     115             :     bool mIsExternallyOwnedKeypair = false;
     116             : };
     117             : 
     118             : } // namespace chip

Generated by: LCOV version 1.14