/* * Copyright (c) 2022 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. */ #pragma once #include #include #include #include #include #include #include #include "OperationalCertificateStore.h" namespace chip { namespace Credentials { /** * @brief OperationalCertificateStore implementation making use of PersistentStorageDelegate * to load/store certificates. This is the legacy behavior of `FabricTable` prior * to refactors to use `OperationalCertificateStore` and exists as a baseline example * of how to use the interface. */ class PersistentStorageOpCertStore final : public OperationalCertificateStore { public: PersistentStorageOpCertStore() {} virtual ~PersistentStorageOpCertStore() { Finish(); } // Non-copyable PersistentStorageOpCertStore(PersistentStorageOpCertStore const &) = delete; void operator=(PersistentStorageOpCertStore const &) = delete; /** * @brief Initialize the certificate store to map to a given storage delegate. * * @param storage Pointer to persistent storage delegate to use. Must outlive this instance. * @retval CHIP_NO_ERROR on success * @retval CHIP_ERROR_INCORRECT_STATE if already initialized */ CHIP_ERROR Init(PersistentStorageDelegate * storage) { VerifyOrReturnError(mStorage == nullptr, CHIP_ERROR_INCORRECT_STATE); RevertPendingOpCerts(); mStorage = storage; return CHIP_NO_ERROR; } /** * @brief Finalize the certificate store, so that subsequent operations fail */ void Finish() { VerifyOrReturn(mStorage != nullptr); RevertPendingOpCerts(); mStorage = nullptr; } bool HasPendingRootCert() const override; bool HasPendingNocChain() const override; bool HasCertificateForFabric(FabricIndex fabricIndex, CertChainElement element) const override; CHIP_ERROR AddNewTrustedRootCertForFabric(FabricIndex fabricIndex, const ByteSpan & rcac) override; CHIP_ERROR AddNewOpCertsForFabric(FabricIndex fabricIndex, const ByteSpan & noc, const ByteSpan & icac) override; CHIP_ERROR UpdateOpCertsForFabric(FabricIndex fabricIndex, const ByteSpan & noc, const ByteSpan & icac) override; CHIP_ERROR CommitOpCertsForFabric(FabricIndex fabricIndex) override; CHIP_ERROR RemoveOpCertsForFabric(FabricIndex fabricIndex) override; void RevertPendingOpCertsExceptRoot() override { mPendingIcac.Free(); mPendingNoc.Free(); if (mPendingRcac.Get() == nullptr) { mPendingFabricIndex = kUndefinedFabricIndex; } mStateFlags.Clear(StateFlags::kAddNewOpCertsCalled); mStateFlags.Clear(StateFlags::kUpdateOpCertsCalled); } void RevertPendingOpCerts() override { RevertPendingOpCertsExceptRoot(); // Clear the rest statelessly mPendingRcac.Free(); mPendingFabricIndex = kUndefinedFabricIndex; mStateFlags.ClearAll(); } CHIP_ERROR GetCertificate(FabricIndex fabricIndex, CertChainElement element, MutableByteSpan & outCertificate) const override; protected: enum class StateFlags : uint8_t { // Below are flags to assist interlock logic kAddNewOpCertsCalled = (1u << 0), kAddNewTrustedRootCalled = (1u << 1), kUpdateOpCertsCalled = (1u << 2), }; // Returns CHIP_ERROR_NOT_FOUND if a pending certificate couldn't be found, otherwise status of pending copy CHIP_ERROR GetPendingCertificate(FabricIndex fabricIndex, CertChainElement element, MutableByteSpan & outCertificate) const; // Returns true if any pending or persisted state exists for the fabricIndex, false if nothing at all is found. bool HasAnyCertificateForFabric(FabricIndex fabricIndex) const; PersistentStorageDelegate * mStorage = nullptr; // This pending fabric index is `kUndefinedFabricIndex` if there are no pending certs at all for the fabric FabricIndex mPendingFabricIndex = kUndefinedFabricIndex; Platform::ScopedMemoryBufferWithSize mPendingRcac; Platform::ScopedMemoryBufferWithSize mPendingIcac; Platform::ScopedMemoryBufferWithSize mPendingNoc; BitFlags mStateFlags; }; } // namespace Credentials } // namespace chip