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
|