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 2 : PersistentStorageOpCertStore() {}
43 2 : 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 2 : void Finish()
68 : {
69 2 : VerifyOrReturn(mStorage != nullptr);
70 :
71 1 : RevertPendingOpCerts();
72 1 : mStorage = nullptr;
73 : }
74 :
75 : bool HasPendingRootCert() const override;
76 : bool HasPendingNocChain() const override;
77 : bool HasPendingVidVerificationElements() const override;
78 :
79 : bool HasCertificateForFabric(FabricIndex fabricIndex, CertChainElement element) const override;
80 :
81 : CHIP_ERROR AddNewTrustedRootCertForFabric(FabricIndex fabricIndex, const ByteSpan & rcac) override;
82 : CHIP_ERROR AddNewOpCertsForFabric(FabricIndex fabricIndex, const ByteSpan & noc, const ByteSpan & icac) override;
83 : CHIP_ERROR UpdateOpCertsForFabric(FabricIndex fabricIndex, const ByteSpan & noc, const ByteSpan & icac) override;
84 : CHIP_ERROR UpdateVidVerificationSignerCertForFabric(FabricIndex fabricIndex, ByteSpan vvsc) override;
85 : CHIP_ERROR UpdateVidVerificationStatementForFabric(FabricIndex fabricIndex, ByteSpan vidVerificationStatement) override;
86 :
87 : CHIP_ERROR CommitOpCertsForFabric(FabricIndex fabricIndex) override;
88 : CHIP_ERROR RemoveOpCertsForFabric(FabricIndex fabricIndex) override;
89 :
90 0 : void RevertPendingOpCertsExceptRoot() override
91 : {
92 0 : mPendingIcac.Free();
93 0 : mPendingNoc.Free();
94 :
95 0 : if (mPendingRcac.Get() == nullptr)
96 : {
97 0 : mPendingFabricIndex = kUndefinedFabricIndex;
98 : }
99 0 : mStateFlags.Clear(StateFlags::kAddNewOpCertsCalled);
100 0 : mStateFlags.Clear(StateFlags::kUpdateOpCertsCalled);
101 0 : RevertVidVerificationStatement();
102 0 : }
103 :
104 0 : void RevertPendingOpCerts() override
105 : {
106 0 : RevertPendingOpCertsExceptRoot();
107 :
108 : // Clear the rest statelessly
109 0 : mPendingRcac.Free();
110 0 : mPendingFabricIndex = kUndefinedFabricIndex;
111 0 : mStateFlags.ClearAll();
112 0 : }
113 :
114 : CHIP_ERROR GetCertificate(FabricIndex fabricIndex, CertChainElement element, MutableByteSpan & outCertificate) const override;
115 : CHIP_ERROR GetVidVerificationElement(FabricIndex fabricIndex, VidVerificationElement element,
116 : MutableByteSpan & outElement) const override;
117 :
118 : protected:
119 : enum class StateFlags : uint8_t
120 : {
121 : // Below are flags to assist interlock logic
122 : kAddNewOpCertsCalled = (1u << 0),
123 : kAddNewTrustedRootCalled = (1u << 1),
124 : kUpdateOpCertsCalled = (1u << 2),
125 : kVidVerificationStatementUpdated = (1u << 3),
126 : kVvscUpdated = (1u << 4),
127 : };
128 :
129 : // Returns CHIP_ERROR_NOT_FOUND if a pending certificate couldn't be found, otherwise status of pending copy
130 : CHIP_ERROR GetPendingCertificate(FabricIndex fabricIndex, CertChainElement element, MutableByteSpan & outCertificate) const;
131 :
132 : // Returns true if any pending or persisted state exists for the fabricIndex, false if nothing at all is found.
133 : bool HasAnyCertificateForFabric(FabricIndex fabricIndex) const;
134 :
135 : // Returns true if any pending or persisted state exists for the VVSC.
136 : bool HasVvscForFabric(FabricIndex fabricIndex) const;
137 :
138 : // Returns true if there is stored or pending NOC chain .
139 : bool HasNocChainForFabric(FabricIndex fabricIndex) const;
140 :
141 : // Returns CHIP_NO_ERROR if all assumptions for VID Verification update operations are OK.
142 : CHIP_ERROR BasicVidVerificationAssumptionsAreMet(FabricIndex fabricIndex) const;
143 :
144 : // Commits pending VID Verification data (called only from CommitOpCertsForFabric).
145 : CHIP_ERROR CommitVidVerificationForFabric(FabricIndex fabricIndex);
146 :
147 : // Reverts pending VID Verification data if any.
148 0 : void RevertVidVerificationStatement()
149 : {
150 0 : mPendingVvsc.Free();
151 0 : mPendingVidVerificationStatement.Free();
152 0 : mStateFlags.Clear(StateFlags::kVidVerificationStatementUpdated);
153 0 : mStateFlags.Clear(StateFlags::kVvscUpdated);
154 0 : }
155 :
156 : PersistentStorageDelegate * mStorage = nullptr;
157 :
158 : // This pending fabric index is `kUndefinedFabricIndex` if there are no pending certs at all for the fabric
159 : FabricIndex mPendingFabricIndex = kUndefinedFabricIndex;
160 :
161 : Platform::ScopedMemoryBufferWithSize<uint8_t> mPendingRcac;
162 : Platform::ScopedMemoryBufferWithSize<uint8_t> mPendingIcac;
163 : Platform::ScopedMemoryBufferWithSize<uint8_t> mPendingNoc;
164 : Platform::ScopedMemoryBufferWithSize<uint8_t> mPendingVvsc;
165 : Platform::ScopedMemoryBufferWithSize<uint8_t> mPendingVidVerificationStatement;
166 :
167 : BitFlags<StateFlags> mStateFlags;
168 : };
169 :
170 : } // namespace Credentials
171 : } // namespace chip
|