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 <lib/core/CHIPError.h> 21 : #include <lib/core/CHIPPersistentStorageDelegate.h> 22 : #include <lib/core/DataModelTypes.h> 23 : #include <lib/support/BitFlags.h> 24 : #include <lib/support/CHIPMem.h> 25 : #include <lib/support/CodeUtils.h> 26 : #include <lib/support/ScopedBuffer.h> 27 : 28 : #include "OperationalCertificateStore.h" 29 : 30 : namespace chip { 31 : namespace Credentials { 32 : 33 : /** 34 : * @brief OperationalCertificateStore implementation making use of PersistentStorageDelegate 35 : * to load/store certificates. This is the legacy behavior of `FabricTable` prior 36 : * to refactors to use `OperationalCertificateStore` and exists as a baseline example 37 : * of how to use the interface. 38 : */ 39 : class PersistentStorageOpCertStore final : public OperationalCertificateStore 40 : { 41 : public: 42 1 : PersistentStorageOpCertStore() {} 43 1 : virtual ~PersistentStorageOpCertStore() { Finish(); } 44 : 45 : // Non-copyable 46 : PersistentStorageOpCertStore(PersistentStorageOpCertStore const &) = delete; 47 : void operator=(PersistentStorageOpCertStore const &) = delete; 48 : 49 : /** 50 : * @brief Initialize the certificate store 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 : RevertPendingOpCerts(); 60 : mStorage = storage; 61 : return CHIP_NO_ERROR; 62 : } 63 : 64 : /** 65 : * @brief Finalize the certificate store, so that subsequent operations fail 66 : */ 67 1 : void Finish() 68 : { 69 1 : VerifyOrReturn(mStorage != nullptr); 70 : 71 1 : RevertPendingOpCerts(); 72 1 : mStorage = nullptr; 73 : } 74 : 75 : bool HasPendingRootCert() const override; 76 : bool HasPendingNocChain() const override; 77 : 78 : bool HasCertificateForFabric(FabricIndex fabricIndex, CertChainElement element) const override; 79 : 80 : CHIP_ERROR AddNewTrustedRootCertForFabric(FabricIndex fabricIndex, const ByteSpan & rcac) override; 81 : CHIP_ERROR AddNewOpCertsForFabric(FabricIndex fabricIndex, const ByteSpan & noc, const ByteSpan & icac) override; 82 : CHIP_ERROR UpdateOpCertsForFabric(FabricIndex fabricIndex, const ByteSpan & noc, const ByteSpan & icac) override; 83 : 84 : CHIP_ERROR CommitOpCertsForFabric(FabricIndex fabricIndex) override; 85 : CHIP_ERROR RemoveOpCertsForFabric(FabricIndex fabricIndex) override; 86 : 87 0 : void RevertPendingOpCertsExceptRoot() override 88 : { 89 0 : mPendingIcac.Free(); 90 0 : mPendingNoc.Free(); 91 : 92 0 : if (mPendingRcac.Get() == nullptr) 93 : { 94 0 : mPendingFabricIndex = kUndefinedFabricIndex; 95 : } 96 0 : mStateFlags.Clear(StateFlags::kAddNewOpCertsCalled); 97 0 : mStateFlags.Clear(StateFlags::kUpdateOpCertsCalled); 98 0 : } 99 : 100 0 : void RevertPendingOpCerts() override 101 : { 102 0 : RevertPendingOpCertsExceptRoot(); 103 : 104 : // Clear the rest statelessly 105 0 : mPendingRcac.Free(); 106 0 : mPendingFabricIndex = kUndefinedFabricIndex; 107 0 : mStateFlags.ClearAll(); 108 0 : } 109 : 110 : CHIP_ERROR GetCertificate(FabricIndex fabricIndex, CertChainElement element, MutableByteSpan & outCertificate) const override; 111 : 112 : protected: 113 : enum class StateFlags : uint8_t 114 : { 115 : // Below are flags to assist interlock logic 116 : kAddNewOpCertsCalled = (1u << 0), 117 : kAddNewTrustedRootCalled = (1u << 1), 118 : kUpdateOpCertsCalled = (1u << 2), 119 : }; 120 : 121 : // Returns CHIP_ERROR_NOT_FOUND if a pending certificate couldn't be found, otherwise status of pending copy 122 : CHIP_ERROR GetPendingCertificate(FabricIndex fabricIndex, CertChainElement element, MutableByteSpan & outCertificate) const; 123 : 124 : // Returns true if any pending or persisted state exists for the fabricIndex, false if nothing at all is found. 125 : bool HasAnyCertificateForFabric(FabricIndex fabricIndex) const; 126 : 127 : PersistentStorageDelegate * mStorage = nullptr; 128 : 129 : // This pending fabric index is `kUndefinedFabricIndex` if there are no pending certs at all for the fabric 130 : FabricIndex mPendingFabricIndex = kUndefinedFabricIndex; 131 : 132 : Platform::ScopedMemoryBufferWithSize<uint8_t> mPendingRcac; 133 : Platform::ScopedMemoryBufferWithSize<uint8_t> mPendingIcac; 134 : Platform::ScopedMemoryBufferWithSize<uint8_t> mPendingNoc; 135 : 136 : BitFlags<StateFlags> mStateFlags; 137 : }; 138 : 139 : } // namespace Credentials 140 : } // namespace chip