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 : // When enabled, chains will be Root -> NOC, for the given fabric ID, and not include an ICAC.
71 : void SetAlwaysOmitIcac(bool enabled) { mAlwaysOmitIcac = enabled; }
72 :
73 0 : void SetFabricIdForNextNOCRequest(FabricId fabricId) override { mNextFabricId = fabricId; }
74 :
75 : void SetCATValuesForNextNOCRequest(CATValues cats) { mNextCATs = cats; }
76 :
77 : /**
78 : * @brief Initialize the issuer with the keypair in the storage.
79 : * If the storage doesn't have one, it'll create one, and it to the storage.
80 : *
81 : * @param[in] storage A reference to the storage, where the keypair is stored.
82 : * The object of ExampleOperationalCredentialsIssuer doesn't hold
83 : * on the reference of storage.
84 : *
85 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
86 : **/
87 : [[deprecated("This class stores the encryption key in clear storage. Don't use it for production code.")]] CHIP_ERROR
88 : Initialize(PersistentStorageDelegate & storage);
89 :
90 : void SetIssuerId(uint32_t id) { mRootIssuerId = id; }
91 :
92 : void SetCurrentEpoch(uint32_t epoch) { mNow = epoch; }
93 :
94 : void SetCertificateValidityPeriod(uint32_t validity) { mValidity = validity; }
95 :
96 : /**
97 : * Generate a random operational node id.
98 : *
99 : * @param[out] aNodeId where to place the generated id.
100 : *
101 : * On error no guarantees are made about the state of aNodeId.
102 : */
103 : static CHIP_ERROR GetRandomOperationalNodeId(NodeId * aNodeId);
104 :
105 : /**
106 : * This is a utility method that generates a operational certificate chain for the given public key.
107 : * This method is expected to be called once all the checks (e.g. device attestation, CSR verification etc)
108 : * have been completed, or not required (e.g. for self trusted devices such as commissioner apps).
109 : */
110 : CHIP_ERROR GenerateNOCChainAfterValidation(NodeId nodeId, FabricId fabricId, const CATValues & cats,
111 : const Crypto::P256PublicKey & pubkey, MutableByteSpan & rcac, MutableByteSpan & icac,
112 : MutableByteSpan & noc);
113 :
114 : private:
115 : Crypto::P256Keypair mRootIssuer;
116 : Crypto::P256Keypair mIntermediateIssuer;
117 : bool mInitialized = false;
118 : uint32_t mRootIssuerId = 1;
119 : uint32_t mIntermediateIssuerId = 2;
120 : uint32_t mNow = 0;
121 :
122 : // By default, let's set validity to 10 years
123 : uint32_t mValidity = 365 * 24 * 60 * 60 * 10;
124 :
125 : NodeId mNextAvailableNodeId = 1;
126 : PersistentStorageDelegate * mStorage = nullptr;
127 : bool mUseMaximallySizedCerts = false;
128 : bool mAlwaysOmitIcac = false;
129 :
130 : NodeId mNextRequestedNodeId = 1;
131 : FabricId mNextFabricId = 1;
132 : CATValues mNextCATs = kUndefinedCATs;
133 : bool mNodeIdRequested = false;
134 : uint64_t mIndex = 0;
135 : };
136 :
137 : } // namespace Controller
138 : } // namespace chip
|