Line data Source code
1 : /*
2 : * Copyright (c) 2025 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 <cstdint>
21 : #include <string>
22 :
23 : #include <app-common/zap-generated/cluster-objects.h>
24 : #include <credentials/CHIPCert.h>
25 : #include <credentials/FabricTable.h>
26 : #include <crypto/CHIPCryptoPAL.h>
27 : #include <lib/core/CHIPCore.h>
28 : #include <lib/core/CHIPError.h>
29 : #include <lib/core/CHIPVendorIdentifiers.hpp>
30 : #include <lib/support/DLLUtil.h>
31 : #include <messaging/ExchangeMgr.h>
32 :
33 : #include <functional>
34 :
35 : namespace chip {
36 : namespace Credentials {
37 : namespace JCM {
38 :
39 : struct TrustVerificationInfo
40 : {
41 : EndpointId adminEndpointId = kInvalidEndpointId;
42 : FabricIndex adminFabricIndex = kUndefinedFabricIndex;
43 :
44 : VendorId adminVendorId;
45 : FabricId adminFabricId;
46 :
47 : Platform::ScopedMemoryBufferWithSize<uint8_t> rootPublicKey;
48 : Platform::ScopedMemoryBufferWithSize<uint8_t> adminRCAC;
49 : Platform::ScopedMemoryBufferWithSize<uint8_t> adminICAC;
50 : Platform::ScopedMemoryBufferWithSize<uint8_t> adminNOC;
51 :
52 1 : void Cleanup()
53 : {
54 1 : adminEndpointId = kInvalidEndpointId;
55 1 : adminFabricIndex = kUndefinedFabricIndex;
56 1 : adminVendorId = VendorId::Common;
57 1 : adminFabricId = kUndefinedFabricId;
58 1 : rootPublicKey.Free();
59 1 : adminNOC.Free();
60 1 : adminICAC.Free();
61 1 : adminRCAC.Free();
62 1 : }
63 : };
64 :
65 : enum class TrustVerificationError : uint16_t
66 : {
67 : kSuccess = 0,
68 : kAsync = 1,
69 :
70 : kInvalidAdministratorEndpointId = 100,
71 : kInvalidAdministratorFabricIndex = 101,
72 : kInvalidAdministratorCAT = 102,
73 : kTrustVerificationDelegateNotSet = 103,
74 : kUserDeniedConsent = 104,
75 : kVendorIdVerificationFailed = 105,
76 : kReadAdminAttributeFailed = 106,
77 : kAdministratorIdMismatched = 107,
78 :
79 : kInternalError = 200,
80 : };
81 :
82 : enum TrustVerificationStage : uint8_t
83 : {
84 : kIdle,
85 :
86 : kVerifyingAdministratorInformation,
87 : kPerformingVendorIDVerification,
88 : kAskingUserForConsent,
89 : kStoringEndpointID,
90 : kReadingCommissionerAdminFabricIndex,
91 : kCrossCheckingAdministratorIds,
92 :
93 : kComplete,
94 : kError,
95 : };
96 :
97 : /*
98 : * EnumToString is a utility function that converts a TrustVerificationError enum value
99 : * to its string representation for logging purposes.
100 : *
101 : * @param error The TrustVerificationError to convert.
102 : * @return A string representation of the TrustVerificationError.
103 : */
104 10 : inline std::string EnumToString(TrustVerificationError error)
105 : {
106 10 : switch (error)
107 : {
108 1 : case TrustVerificationError::kSuccess:
109 1 : return "SUCCESS";
110 1 : case TrustVerificationError::kAsync:
111 1 : return "ASYNC_OPERATION";
112 1 : case TrustVerificationError::kInvalidAdministratorEndpointId:
113 1 : return "INVALID_ADMINISTRATOR_ENDPOINT_ID";
114 1 : case TrustVerificationError::kInvalidAdministratorFabricIndex:
115 1 : return "INVALID_ADMINISTRATOR_FABRIC_INDEX";
116 1 : case TrustVerificationError::kInvalidAdministratorCAT:
117 1 : return "INVALID_ADMINISTRATOR_CAT";
118 1 : case TrustVerificationError::kTrustVerificationDelegateNotSet:
119 1 : return "TRUST_VERIFICATION_DELEGATE_NOT_SET";
120 1 : case TrustVerificationError::kUserDeniedConsent:
121 1 : return "USER_DENIED_CONSENT";
122 1 : case TrustVerificationError::kVendorIdVerificationFailed:
123 1 : return "VENDOR_ID_VERIFICATION_FAILED";
124 0 : case TrustVerificationError::kReadAdminAttributeFailed:
125 0 : return "READ_ADMIN_ATTRIBUTE_FAILED";
126 0 : case TrustVerificationError::kAdministratorIdMismatched:
127 0 : return "ADMINISTRATOR_ID_MISMATCHED";
128 2 : case TrustVerificationError::kInternalError:
129 2 : return "INTERNAL_ERROR";
130 :
131 0 : default:
132 0 : return "UNKNOWN_ERROR";
133 : }
134 : }
135 :
136 : /*
137 : * EnumToString is a utility function that converts a TrustVerificationStage enum value
138 : * to its string representation for logging purposes.
139 : *
140 : * @param stage The TrustVerificationStage to convert.
141 : * @return A string representation of the TrustVerificationStage.
142 : */
143 23 : inline std::string EnumToString(TrustVerificationStage stage)
144 : {
145 23 : switch (stage)
146 : {
147 2 : case kIdle:
148 2 : return "IDLE";
149 3 : case kVerifyingAdministratorInformation:
150 3 : return "VERIFYING_ADMINISTRATOR_INFORMATION";
151 5 : case kPerformingVendorIDVerification:
152 5 : return "PERFORMING_VENDOR_ID_VERIFICATION_PROCEDURE";
153 3 : case kAskingUserForConsent:
154 3 : return "ASKING_USER_FOR_CONSENT";
155 2 : case kStoringEndpointID:
156 2 : return "STORING_ENDPOINT_ID";
157 2 : case kReadingCommissionerAdminFabricIndex:
158 2 : return "READING_COMMISSIONER_ADMIN_FABRIC_INDEX";
159 1 : case kCrossCheckingAdministratorIds:
160 1 : return "CROSS_CHECKING_ADMINISTRATOR_IDS";
161 4 : case kComplete:
162 4 : return "COMPLETE";
163 1 : case kError:
164 1 : return "ERROR";
165 :
166 0 : default:
167 0 : return "UNKNOWN";
168 : }
169 : }
170 :
171 : class TrustVerificationDelegate;
172 :
173 : class DLL_EXPORT TrustVerificationStateMachine
174 : {
175 : public:
176 15 : virtual ~TrustVerificationStateMachine() = default;
177 :
178 : void RegisterTrustVerificationDelegate(TrustVerificationDelegate * trustVerificationDelegate);
179 :
180 : /*
181 : * ContinueAfterUserConsent is a method that continues the JCM trust verification process after the user has
182 : * provided consent or denied it. If the user grants consent, the trust verification process will continue;
183 : * otherwise, it will terminate with an error.
184 : *
185 : * @param consent A boolean indicating whether the user granted consent (true) or denied it (false).
186 : */
187 0 : virtual void ContinueAfterUserConsent(const bool & consent) {}
188 :
189 : protected:
190 : virtual TrustVerificationStage GetNextTrustVerificationStage(const TrustVerificationStage & currentStage) = 0;
191 : virtual void PerformTrustVerificationStage(const TrustVerificationStage & nextStage) = 0;
192 :
193 : void StartTrustVerification();
194 : void TrustVerificationStageFinished(const TrustVerificationStage & completedStage, const TrustVerificationError & error);
195 :
196 : /*
197 : * OnTrustVerificationComplete is a callback method that is called when the JCM trust verification process is complete.
198 : * It will handle the result of the trust verification and report it to the commissioning delegate.
199 : *
200 : * @param result The result of the JCM trust verification process.
201 : */
202 0 : virtual void OnTrustVerificationComplete(TrustVerificationError error) {}
203 :
204 : // JCM trust verification info
205 : // This structure contains the information needed for JCM trust verification
206 : // such as the administrator fabric index, endpoint ID, and vendor ID
207 : // It is used to store the results of the trust verification process
208 : // and is passed to the JCM trust verification delegate
209 : // when the trust verification process is complete
210 : TrustVerificationInfo mInfo;
211 :
212 : // Trust verification delegate for the commissioning client
213 : TrustVerificationDelegate * mTrustVerificationDelegate = nullptr;
214 : };
215 :
216 : /**
217 : * A delegate that can be notified of progress as the JCM Trust Verification check proceeds.
218 : */
219 : class DLL_EXPORT TrustVerificationDelegate
220 : {
221 : public:
222 7 : virtual ~TrustVerificationDelegate() = default;
223 :
224 : virtual void OnProgressUpdate(TrustVerificationStateMachine & stateMachine, TrustVerificationStage stage,
225 : TrustVerificationInfo & info, TrustVerificationError error) = 0;
226 : virtual void OnAskUserForConsent(TrustVerificationStateMachine & stateMachine, TrustVerificationInfo & info) = 0;
227 : virtual CHIP_ERROR OnLookupOperationalTrustAnchor(VendorId vendorID, CertificateKeyId & subjectKeyId,
228 : ByteSpan & globallyTrustedRootSpan) = 0;
229 : };
230 :
231 : } // namespace JCM
232 : } // namespace Credentials
233 : } // namespace chip
|