Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021-2022 Project CHIP Authors
4 : * All rights reserved.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * This file contains class definition of an example operational certificate
22 : * issuer for CHIP devices. The class can be used as a guideline on how to
23 : * construct your own certificate issuer. It can also be used in tests and tools
24 : * if a specific signing authority is not required.
25 : *
26 : * NOTE: This class stores the encryption key in clear storage. This is not suited
27 : * for production use. This should only be used in test tools.
28 : */
29 :
30 : #pragma once
31 :
32 : #include <controller/OperationalCredentialsDelegate.h>
33 : #include <crypto/CHIPCryptoPAL.h>
34 : #include <lib/core/CASEAuthTag.h>
35 : #include <lib/core/CHIPError.h>
36 : #include <lib/core/CHIPPersistentStorageDelegate.h>
37 : #include <lib/support/CodeUtils.h>
38 : #include <lib/support/Span.h>
39 :
40 : namespace chip {
41 : namespace Controller {
42 :
43 : class DLL_EXPORT ExampleOperationalCredentialsIssuer : public OperationalCredentialsDelegate
44 : {
45 : public:
46 : //
47 : // Constructor to create an instance of this object that vends out operational credentials for a given fabric.
48 : //
49 : // An index should be provided to numerically identify this instance relative to others in a multi-fabric deployment. This is
50 : // needed given the interactions of this object with persistent storage. Consequently, the index is used to scope the entries
51 : // read/written to/from storage.
52 : //
53 : // It is recommended that this index track the fabric index within which this issuer is operating.
54 : //
55 : ExampleOperationalCredentialsIssuer(uint32_t index = 0) { mIndex = index; }
56 0 : ~ExampleOperationalCredentialsIssuer() override {}
57 :
58 : CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature,
59 : const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI,
60 : Callback::Callback<OnNOCChainGeneration> * onCompletion) override;
61 :
62 0 : void SetNodeIdForNextNOCRequest(NodeId nodeId) override
63 : {
64 0 : mNextRequestedNodeId = nodeId;
65 0 : mNodeIdRequested = true;
66 0 : }
67 :
68 : void SetMaximallyLargeCertsUsed(bool areMaximallyLargeCertsUsed) { mUseMaximallySizedCerts = areMaximallyLargeCertsUsed; }
69 :
70 0 : void SetFabricIdForNextNOCRequest(FabricId fabricId) override { mNextFabricId = fabricId; }
71 :
72 : void SetCATValuesForNextNOCRequest(CATValues cats) { mNextCATs = cats; }
73 :
74 : /**
75 : * @brief Initialize the issuer with the keypair in the storage.
76 : * If the storage doesn't have one, it'll create one, and it to the storage.
77 : *
78 : * @param[in] storage A reference to the storage, where the keypair is stored.
79 : * The object of ExampleOperationalCredentialsIssuer doesn't hold
80 : * on the reference of storage.
81 : *
82 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
83 : **/
84 : [[deprecated("This class stores the encryption key in clear storage. Don't use it for production code.")]] CHIP_ERROR
85 : Initialize(PersistentStorageDelegate & storage);
86 :
87 : void SetIssuerId(uint32_t id) { mIssuerId = id; }
88 :
89 : void SetCurrentEpoch(uint32_t epoch) { mNow = epoch; }
90 :
91 : void SetCertificateValidityPeriod(uint32_t validity) { mValidity = validity; }
92 :
93 : /**
94 : * Generate a random operational node id.
95 : *
96 : * @param[out] aNodeId where to place the generated id.
97 : *
98 : * On error no guarantees are made about the state of aNodeId.
99 : */
100 : static CHIP_ERROR GetRandomOperationalNodeId(NodeId * aNodeId);
101 :
102 : /**
103 : * This is a utility method that generates a operational certificate chain for the given public key.
104 : * This method is expected to be called once all the checks (e.g. device attestation, CSR verification etc)
105 : * have been completed, or not required (e.g. for self trusted devices such as commissioner apps).
106 : */
107 : CHIP_ERROR GenerateNOCChainAfterValidation(NodeId nodeId, FabricId fabricId, const CATValues & cats,
108 : const Crypto::P256PublicKey & pubkey, MutableByteSpan & rcac, MutableByteSpan & icac,
109 : MutableByteSpan & noc);
110 :
111 : private:
112 : Crypto::P256Keypair mIssuer;
113 : Crypto::P256Keypair mIntermediateIssuer;
114 : bool mInitialized = false;
115 : uint32_t mIssuerId = 1;
116 : uint32_t mIntermediateIssuerId = 2;
117 : uint32_t mNow = 0;
118 :
119 : // By default, let's set validity to 10 years
120 : uint32_t mValidity = 365 * 24 * 60 * 60 * 10;
121 :
122 : NodeId mNextAvailableNodeId = 1;
123 : PersistentStorageDelegate * mStorage = nullptr;
124 : bool mUseMaximallySizedCerts = false;
125 :
126 : NodeId mNextRequestedNodeId = 1;
127 : FabricId mNextFabricId = 1;
128 : CATValues mNextCATs = kUndefinedCATs;
129 : bool mNodeIdRequested = false;
130 : uint64_t mIndex = 0;
131 : };
132 :
133 : } // namespace Controller
134 : } // namespace chip
|