1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "framework_executor_callback.h"
17
18 #include <mutex>
19 #include <sstream>
20
21 #include "auth_command.h"
22 #include "custom_command.h"
23 #include "enroll_command.h"
24 #include "hisysevent_adapter.h"
25 #include "iam_check.h"
26 #include "iam_defines.h"
27 #include "iam_hitrace_helper.h"
28 #include "iam_logger.h"
29 #include "iam_mem.h"
30 #include "iam_para2str.h"
31 #include "iam_ptr.h"
32 #include "identify_command.h"
33
34 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_EXECUTOR
35
36 namespace OHOS {
37 namespace UserIam {
38 namespace UserAuth {
FrameworkExecutorCallback(std::weak_ptr<Executor> executor)39 FrameworkExecutorCallback::FrameworkExecutorCallback(std::weak_ptr<Executor> executor) : executor_(executor)
40 {
41 uint32_t callbackId = GenerateExecutorCallbackId();
42 std::ostringstream ss;
43 ss << "ExecutorCallback(Id:" << callbackId << ")";
44 description_ = ss.str();
45 }
46
OnBeginExecute(uint64_t scheduleId,const std::vector<uint8_t> & publicKey,const Attributes & commandAttrs)47 int32_t FrameworkExecutorCallback::OnBeginExecute(uint64_t scheduleId, const std::vector<uint8_t> &publicKey,
48 const Attributes &commandAttrs)
49 {
50 auto pk(publicKey);
51
52 return OnBeginExecuteInner(scheduleId, pk, commandAttrs);
53 }
54
OnBeginExecuteInner(uint64_t scheduleId,std::vector<uint8_t> & publicKey,const Attributes & commandAttrs)55 ResultCode FrameworkExecutorCallback::OnBeginExecuteInner(uint64_t scheduleId, std::vector<uint8_t> &publicKey,
56 const Attributes &commandAttrs)
57 {
58 static_cast<void>(publicKey);
59 int32_t commandId = 0;
60 bool getScheduleModeRet =
61 commandAttrs.GetInt32Value(Attributes::ATTR_SCHEDULE_MODE, commandId);
62 IF_FALSE_LOGE_AND_RETURN_VAL(getScheduleModeRet == true, ResultCode::GENERAL_ERROR);
63
64 IAM_LOGI("%{public}s start process cmd %{public}u", GetDescription(), commandId);
65 ResultCode ret = ResultCode::GENERAL_ERROR;
66 switch (commandId) {
67 case ENROLL:
68 ret = ProcessEnrollCommand(scheduleId, commandAttrs);
69 break;
70 case AUTH:
71 ret = ProcessAuthCommand(scheduleId, commandAttrs);
72 break;
73 case IDENTIFY:
74 ret = ProcessIdentifyCommand(scheduleId, commandAttrs);
75 break;
76 default:
77 IAM_LOGE("command id %{public}u is not supported", commandId);
78 }
79
80 IAM_LOGI("command id = %{public}u ret = %{public}d", commandId, ret);
81 return ret;
82 }
83
OnEndExecute(uint64_t scheduleId,const Attributes & commandAttrs)84 int32_t FrameworkExecutorCallback::OnEndExecute(uint64_t scheduleId, const Attributes &commandAttrs)
85 {
86 return OnEndExecuteInner(scheduleId, commandAttrs);
87 }
88
OnEndExecuteInner(uint64_t scheduleId,const Attributes & consumerAttr)89 ResultCode FrameworkExecutorCallback::OnEndExecuteInner(uint64_t scheduleId, const Attributes &consumerAttr)
90 {
91 ResultCode ret = ProcessCancelCommand(scheduleId);
92 IAM_LOGI("%{public}s cancel scheduleId %{public}s ret %{public}d", GetDescription(),
93 GET_MASKED_STRING(scheduleId).c_str(), ret);
94 return ret;
95 }
96
OnMessengerReady(const std::shared_ptr<ExecutorMessenger> & messenger,const std::vector<uint8_t> & publicKey,const std::vector<uint64_t> & templateIds)97 void FrameworkExecutorCallback::OnMessengerReady(const std::shared_ptr<ExecutorMessenger> &messenger,
98 const std::vector<uint8_t> &publicKey, const std::vector<uint64_t> &templateIds)
99 {
100 IAM_LOGI("%{public}s start", GetDescription());
101 auto executor = executor_.lock();
102 if (executor == nullptr) {
103 IAM_LOGE("executor has been released, process failed");
104 return;
105 }
106 auto hdi = executor->GetExecutorHdi();
107 IF_FALSE_LOGE_AND_RETURN(hdi != nullptr);
108 executorMessenger_ = messenger;
109 std::vector<uint8_t> extraInfo;
110 hdi->OnRegisterFinish(templateIds, publicKey, extraInfo);
111 }
112
OnSetProperty(const Attributes & properties)113 int32_t FrameworkExecutorCallback::OnSetProperty(const Attributes &properties)
114 {
115 return OnSetPropertyInner(properties);
116 }
117
OnSetPropertyInner(const Attributes & properties)118 ResultCode FrameworkExecutorCallback::OnSetPropertyInner(const Attributes &properties)
119 {
120 uint32_t commandId = 0;
121 bool getAuthPropertyModeRet =
122 properties.GetUint32Value(Attributes::ATTR_PROPERTY_MODE, commandId);
123 IF_FALSE_LOGE_AND_RETURN_VAL(getAuthPropertyModeRet == true, ResultCode::GENERAL_ERROR);
124 IAM_LOGI("%{public}s start process cmd %{public}u", GetDescription(), commandId);
125 ResultCode ret;
126 if (commandId == PROPERTY_MODE_DEL) {
127 ret = ProcessDeleteTemplateCommand(properties);
128 } else if (commandId == PROPERTY_MODE_SET_CACHED_TEMPLATES) {
129 ret = ProcessSetCachedTemplates(properties);
130 } else {
131 ret = ProcessCustomCommand(properties);
132 }
133 IAM_LOGI("command id = %{public}u ret = %{public}d", commandId, ret);
134 return ret;
135 }
136
OnGetProperty(const Attributes & conditions,Attributes & results)137 int32_t FrameworkExecutorCallback::OnGetProperty(const Attributes &conditions, Attributes &results)
138 {
139 auto cond = Common::MakeShared<Attributes>(conditions.Serialize());
140 auto values = Common::MakeShared<Attributes>(results.Serialize());
141 auto ret = OnGetPropertyInner(cond, values);
142 if (values) {
143 results = std::move(*values);
144 }
145 return ret;
146 }
147
OnGetPropertyInner(std::shared_ptr<Attributes> conditions,std::shared_ptr<Attributes> values)148 ResultCode FrameworkExecutorCallback::OnGetPropertyInner(std::shared_ptr<Attributes> conditions,
149 std::shared_ptr<Attributes> values)
150 {
151 IAM_LOGI("%{public}s start", GetDescription());
152 IF_FALSE_LOGE_AND_RETURN_VAL(conditions != nullptr, ResultCode::GENERAL_ERROR);
153 IF_FALSE_LOGE_AND_RETURN_VAL(values != nullptr, ResultCode::GENERAL_ERROR);
154 uint32_t commandId = 0;
155 bool getAuthPropertyModeRet =
156 conditions->GetUint32Value(Attributes::ATTR_PROPERTY_MODE, commandId);
157 IF_FALSE_LOGE_AND_RETURN_VAL(getAuthPropertyModeRet == true, ResultCode::GENERAL_ERROR);
158 if (commandId != PROPERTY_MODE_GET) {
159 IAM_LOGE("command id not recognised");
160 return ResultCode::GENERAL_ERROR;
161 }
162
163 ResultCode ret = ProcessGetPropertyCommand(conditions, values);
164 IAM_LOGI("command id = %{public}u ret = %{public}d", commandId, ret);
165 return ret;
166 }
167
ProcessEnrollCommand(uint64_t scheduleId,const Attributes & properties)168 ResultCode FrameworkExecutorCallback::ProcessEnrollCommand(uint64_t scheduleId, const Attributes &properties)
169 {
170 auto command = Common::MakeShared<EnrollCommand>(executor_, scheduleId, properties, executorMessenger_);
171 IF_FALSE_LOGE_AND_RETURN_VAL(command != nullptr, ResultCode::GENERAL_ERROR);
172 return command->StartProcess();
173 }
174
ProcessAuthCommand(uint64_t scheduleId,const Attributes & properties)175 ResultCode FrameworkExecutorCallback::ProcessAuthCommand(uint64_t scheduleId, const Attributes &properties)
176 {
177 auto command = Common::MakeShared<AuthCommand>(executor_, scheduleId, properties, executorMessenger_);
178 IF_FALSE_LOGE_AND_RETURN_VAL(command != nullptr, ResultCode::GENERAL_ERROR);
179 return command->StartProcess();
180 }
181
ProcessIdentifyCommand(uint64_t scheduleId,const Attributes & properties)182 ResultCode FrameworkExecutorCallback::ProcessIdentifyCommand(uint64_t scheduleId, const Attributes &properties)
183 {
184 auto command = Common::MakeShared<IdentifyCommand>(executor_, scheduleId, properties, executorMessenger_);
185 IF_FALSE_LOGE_AND_RETURN_VAL(command != nullptr, ResultCode::GENERAL_ERROR);
186 return command->StartProcess();
187 }
188
ProcessCancelCommand(uint64_t scheduleId)189 ResultCode FrameworkExecutorCallback::ProcessCancelCommand(uint64_t scheduleId)
190 {
191 auto executor = executor_.lock();
192 if (executor == nullptr) {
193 IAM_LOGE("executor has been released, process failed");
194 return ResultCode::GENERAL_ERROR;
195 }
196 auto hdi = executor->GetExecutorHdi();
197 IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
198 return hdi->Cancel(scheduleId);
199 }
200
ProcessDeleteTemplateCommand(const Attributes & properties)201 ResultCode FrameworkExecutorCallback::ProcessDeleteTemplateCommand(const Attributes &properties)
202 {
203 IAM_LOGI("start");
204 auto executor = executor_.lock();
205 if (executor == nullptr) {
206 IAM_LOGE("executor has been released, process failed");
207 return ResultCode::GENERAL_ERROR;
208 }
209 auto hdi = executor->GetExecutorHdi();
210 IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
211 uint64_t templateId = 0;
212 bool getAuthTemplateIdRet = properties.GetUint64Value(Attributes::ATTR_TEMPLATE_ID, templateId);
213 IF_FALSE_LOGE_AND_RETURN_VAL(getAuthTemplateIdRet == true, ResultCode::GENERAL_ERROR);
214 std::vector<uint64_t> templateIdList;
215
216 templateIdList.push_back(templateId);
217 IamHitraceHelper traceHelper("hdi Delete");
218 ResultCode ret = hdi->Delete(templateIdList);
219 if (ret == ResultCode::SUCCESS) {
220 TemplateChangeTrace info = {};
221 info.changeType = TRACE_DELETE_CREDENTIAL;
222 std::string templateChangeReason = "";
223 properties.GetStringValue(Attributes::ATTR_TEMPLATE_CHANGE_REASON, templateChangeReason);
224 info.reason = templateChangeReason;
225 info.executorType = executor->GetAuthType();
226 UserIam::UserAuth::ReportSecurityTemplateChange(info);
227 }
228 return ret;
229 }
230
ProcessSetCachedTemplates(const Attributes & properties)231 ResultCode FrameworkExecutorCallback::ProcessSetCachedTemplates(const Attributes &properties)
232 {
233 IAM_LOGI("start");
234 auto executor = executor_.lock();
235 if (executor == nullptr) {
236 IAM_LOGE("executor has been released, process failed");
237 return ResultCode::GENERAL_ERROR;
238 }
239 auto hdi = executor->GetExecutorHdi();
240 IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
241
242 std::vector<uint64_t> templateIdList;
243 bool getTemplateIdListRet = properties.GetUint64ArrayValue(Attributes::ATTR_TEMPLATE_ID_LIST, templateIdList);
244 IF_FALSE_LOGE_AND_RETURN_VAL(getTemplateIdListRet == true, ResultCode::GENERAL_ERROR);
245
246 return hdi->SetCachedTemplates(templateIdList);
247 }
248
ProcessCustomCommand(const Attributes & properties)249 ResultCode FrameworkExecutorCallback::ProcessCustomCommand(const Attributes &properties)
250 {
251 auto command = Common::MakeShared<CustomCommand>(executor_, properties);
252 IF_FALSE_LOGE_AND_RETURN_VAL(command != nullptr, ResultCode::GENERAL_ERROR);
253 ResultCode ret = command->StartProcess();
254 if (ret != ResultCode::SUCCESS) {
255 IAM_LOGE("start process command fail ret = %{public}d", ret);
256 return ret;
257 }
258
259 return command->GetResult();
260 }
261
ProcessGetPropertyCommand(std::shared_ptr<Attributes> conditions,std::shared_ptr<Attributes> values)262 ResultCode FrameworkExecutorCallback::ProcessGetPropertyCommand(std::shared_ptr<Attributes> conditions,
263 std::shared_ptr<Attributes> values)
264 {
265 IAM_LOGI("start");
266 IF_FALSE_LOGE_AND_RETURN_VAL(conditions != nullptr, ResultCode::GENERAL_ERROR);
267 IF_FALSE_LOGE_AND_RETURN_VAL(values != nullptr, ResultCode::GENERAL_ERROR);
268 auto executor = executor_.lock();
269 if (executor == nullptr) {
270 IAM_LOGE("executor has been released, process failed");
271 return ResultCode::GENERAL_ERROR;
272 }
273 auto hdi = executor->GetExecutorHdi();
274 IF_FALSE_LOGE_AND_RETURN_VAL(hdi != nullptr, ResultCode::GENERAL_ERROR);
275
276 std::vector<uint64_t> templateIdList;
277 bool getTemplateIdListRet = conditions->GetUint64ArrayValue(Attributes::ATTR_TEMPLATE_ID_LIST, templateIdList);
278 IF_FALSE_LOGE_AND_RETURN_VAL(getTemplateIdListRet == true, ResultCode::GENERAL_ERROR);
279
280 std::vector<uint32_t> uint32KeyList;
281 bool getKeyListRet = conditions->GetUint32ArrayValue(Attributes::ATTR_KEY_LIST, uint32KeyList);
282 IF_FALSE_LOGE_AND_RETURN_VAL(getKeyListRet == true, ResultCode::GENERAL_ERROR);
283
284 std::vector<Attributes::AttributeKey> keyList;
285 keyList.reserve(uint32KeyList.size());
286 for (auto &uint32Key : uint32KeyList) {
287 keyList.push_back(static_cast<Attributes::AttributeKey>(uint32Key));
288 }
289
290 Property property = {};
291
292 ResultCode getPropertyRet = hdi->GetProperty(templateIdList, keyList, property);
293 IF_FALSE_LOGE_AND_RETURN_VAL(getPropertyRet == SUCCESS, ResultCode::GENERAL_ERROR);
294
295 ResultCode fillAttributeRet = FillPropertyToAttribute(keyList, property, values);
296 IF_FALSE_LOGE_AND_RETURN_VAL(fillAttributeRet == SUCCESS, ResultCode::GENERAL_ERROR);
297
298 return ResultCode::SUCCESS;
299 }
300
FillPropertyToAttribute(const std::vector<Attributes::AttributeKey> & keyList,const Property property,std::shared_ptr<Attributes> values)301 ResultCode FrameworkExecutorCallback::FillPropertyToAttribute(const std::vector<Attributes::AttributeKey> &keyList,
302 const Property property, std::shared_ptr<Attributes> values)
303 {
304 for (auto &key : keyList) {
305 switch (key) {
306 case Attributes::ATTR_PIN_SUB_TYPE: {
307 bool setAuthSubTypeRet = values->SetInt32Value(Attributes::ATTR_PIN_SUB_TYPE, property.authSubType);
308 IF_FALSE_LOGE_AND_RETURN_VAL(setAuthSubTypeRet == true, ResultCode::GENERAL_ERROR);
309 break;
310 }
311 case Attributes::ATTR_FREEZING_TIME: {
312 bool setAuthRemainTimeRet =
313 values->SetInt32Value(Attributes::ATTR_FREEZING_TIME, property.lockoutDuration);
314 IF_FALSE_LOGE_AND_RETURN_VAL(setAuthRemainTimeRet == true, ResultCode::GENERAL_ERROR);
315 break;
316 }
317 case Attributes::ATTR_REMAIN_TIMES: {
318 bool setAuthRemainCountRet =
319 values->SetInt32Value(Attributes::ATTR_REMAIN_TIMES, property.remainAttempts);
320 IF_FALSE_LOGE_AND_RETURN_VAL(setAuthRemainCountRet == true, ResultCode::GENERAL_ERROR);
321 break;
322 }
323 case Attributes::ATTR_ENROLL_PROGRESS: {
324 bool setEnrollProgressRet =
325 values->SetStringValue(Attributes::ATTR_ENROLL_PROGRESS, property.enrollmentProgress);
326 IF_FALSE_LOGE_AND_RETURN_VAL(setEnrollProgressRet == true, ResultCode::GENERAL_ERROR);
327 break;
328 }
329 case Attributes::ATTR_SENSOR_INFO: {
330 bool setSensorInfoRet = values->SetStringValue(Attributes::ATTR_SENSOR_INFO, property.sensorInfo);
331 IF_FALSE_LOGE_AND_RETURN_VAL(setSensorInfoRet == true, ResultCode::GENERAL_ERROR);
332 break;
333 }
334 default:
335 IAM_LOGE("key %{public}d is not recognized", key);
336 return ResultCode::GENERAL_ERROR;
337 }
338 }
339
340 return ResultCode::SUCCESS;
341 }
342
GenerateExecutorCallbackId()343 uint32_t FrameworkExecutorCallback::GenerateExecutorCallbackId()
344 {
345 static std::mutex mutex;
346 static uint32_t callbackId = 0;
347 std::lock_guard<std::mutex> guard(mutex);
348 // callbackId is only used in log, uint32 overflow or duplicate is ok
349 ++callbackId;
350 return callbackId;
351 }
352
GetDescription()353 const char *FrameworkExecutorCallback::GetDescription()
354 {
355 return description_.c_str();
356 }
357 } // namespace UserAuth
358 } // namespace UserIam
359 } // namespace OHOS
360