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 : #if CHIP_OP_KEYSTORE_ELE
27 : #include "EleManagerImpl.h"
28 : #endif
29 :
30 : namespace chip {
31 :
32 : /**
33 : * @brief OperationalKeystore implementation making use of PersistentStorageDelegate
34 : * to load/store keypairs. This is the legacy behavior of `FabricTable` prior
35 : * to refactors to use `OperationalKeystore` and exists as a baseline example
36 : * of how to use the interface.
37 : *
38 : * WARNING: Ensure that any implementation that uses this one as a starting point
39 : * DOES NOT have the raw key material (in usable form) passed up/down to
40 : * direct storage APIs that may make copies on heap/stack without sanitization.
41 : */
42 : class PersistentStorageOperationalKeystore : public Crypto::OperationalKeystore
43 : {
44 : public:
45 495 : PersistentStorageOperationalKeystore() = default;
46 498 : virtual ~PersistentStorageOperationalKeystore() { Finish(); }
47 :
48 : // Non-copyable
49 : PersistentStorageOperationalKeystore(PersistentStorageOperationalKeystore const &) = delete;
50 : void operator=(PersistentStorageOperationalKeystore const &) = delete;
51 :
52 : /**
53 : * @brief Initialize the Operational Keystore to map to a given storage delegate.
54 : *
55 : * @param storage Pointer to persistent storage delegate to use. Must outlive this instance.
56 : * @retval CHIP_NO_ERROR on success
57 : * @retval CHIP_ERROR_INCORRECT_STATE if already initialized
58 : */
59 498 : CHIP_ERROR Init(PersistentStorageDelegate * storage)
60 : {
61 498 : VerifyOrReturnError(mStorage == nullptr, CHIP_ERROR_INCORRECT_STATE);
62 498 : mPendingFabricIndex = kUndefinedFabricIndex;
63 498 : mIsExternallyOwnedKeypair = false;
64 498 : mStorage = storage;
65 498 : mPendingKeypair = nullptr;
66 498 : mIsPendingKeypairActive = false;
67 498 : return CHIP_NO_ERROR;
68 : }
69 :
70 : /**
71 : * @brief Finalize the keystore, so that subsequent operations fail
72 : */
73 995 : void Finish()
74 : {
75 995 : VerifyOrReturn(mStorage != nullptr);
76 :
77 498 : ResetPendingKey();
78 498 : mStorage = nullptr;
79 : }
80 :
81 : bool HasPendingOpKeypair() const override;
82 :
83 : bool HasOpKeypairForFabric(FabricIndex fabricIndex) const override;
84 : CHIP_ERROR NewOpKeypairForFabric(FabricIndex fabricIndex, MutableByteSpan & outCertificateSigningRequest) override;
85 : CHIP_ERROR ActivateOpKeypairForFabric(FabricIndex fabricIndex, const Crypto::P256PublicKey & nocPublicKey) override;
86 : CHIP_ERROR CommitOpKeypairForFabric(FabricIndex fabricIndex) override;
87 : CHIP_ERROR ExportOpKeypairForFabric(FabricIndex fabricIndex, Crypto::P256SerializedKeypair & outKeypair) override;
88 : CHIP_ERROR RemoveOpKeypairForFabric(FabricIndex fabricIndex) override;
89 : void RevertPendingKeypair() override;
90 : CHIP_ERROR SignWithOpKeypair(FabricIndex fabricIndex, const ByteSpan & message,
91 : Crypto::P256ECDSASignature & outSignature) const override;
92 : Crypto::P256Keypair * AllocateEphemeralKeypairForCASE() override;
93 : void ReleaseEphemeralKeypair(Crypto::P256Keypair * keypair) override;
94 : CHIP_ERROR MigrateOpKeypairForFabric(FabricIndex fabricIndex, OperationalKeystore & operationalKeystore) const override;
95 :
96 : protected:
97 1081 : void ResetPendingKey()
98 : {
99 1081 : if (!mIsExternallyOwnedKeypair && (mPendingKeypair != nullptr))
100 : {
101 35 : Platform::Delete(mPendingKeypair);
102 : }
103 1081 : mPendingKeypair = nullptr;
104 1081 : mIsExternallyOwnedKeypair = false;
105 1081 : mIsPendingKeypairActive = false;
106 1081 : mPendingFabricIndex = kUndefinedFabricIndex;
107 1081 : }
108 :
109 : PersistentStorageDelegate * mStorage = nullptr;
110 :
111 : // This pending fabric index is `kUndefinedFabricIndex` if there isn't a pending keypair override for a given fabric.
112 : FabricIndex mPendingFabricIndex = kUndefinedFabricIndex;
113 : Crypto::P256Keypair * mPendingKeypair = nullptr;
114 : bool mIsPendingKeypairActive = false;
115 :
116 : // If overridding NewOpKeypairForFabric method in a subclass, set this to true in
117 : // `NewOpKeypairForFabric` if the mPendingKeypair should not be deleted when no longer in use.
118 : bool mIsExternallyOwnedKeypair = false;
119 :
120 : #if CHIP_OP_KEYSTORE_ELE
121 : private:
122 : std::shared_ptr<Credentials::ele::EleManagerKeystore> mEleManager = Credentials::ele::EleManagerKeystore::getInstance();
123 : #endif
124 : };
125 :
126 : } // namespace chip
|