1 /*
2  * Copyright (c) 2022-2024 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 "v3_0/user_auth_interface_service.h"
17 
18 #include <cinttypes>
19 #include <mutex>
20 #include <hdf_base.h>
21 #include "securec.h"
22 #include <set>
23 #include <string>
24 
25 #include "iam_logger.h"
26 #include "iam_para2str.h"
27 #include "iam_ptr.h"
28 
29 #include "adaptor_time.h"
30 #include "useriam_common.h"
31 #include "auth_level.h"
32 #include "buffer.h"
33 #include "coauth_funcs.h"
34 #include "executor_message.h"
35 #include "hmac_key.h"
36 #include "identify_funcs.h"
37 #include "idm_database.h"
38 #include "idm_session.h"
39 #include "ed25519_key.h"
40 #include "udid_manager.h"
41 #include "user_auth_hdi.h"
42 #include "user_auth_funcs.h"
43 #include "user_idm_funcs.h"
44 #include "enroll_specification_check.h"
45 
46 #undef LOG_TAG
47 #define LOG_TAG "USER_AUTH_HDI"
48 
49 namespace OHOS {
50 namespace HDI {
51 namespace UserAuth {
52 namespace {
53 static std::mutex g_mutex;
54 static std::string g_localUdid;
55 constexpr uint32_t INVALID_CAPABILITY_LEVEL = 100;
56 const std::string SETTRINGS_NAME = "settings";
57 
58 enum UserAuthCallerType : int32_t {
59     TOKEN_INVALID = -1,
60     TOKEN_HAP = 0,
61     TOKEN_NATIVE,
62 };
63 const uint32_t PUBLIC_KEY_STR_LEN = 33;
FormatHexString(uint8_t * data,int32_t dataSize,char * outBuffer,int32_t outBufferSize)64 void FormatHexString(uint8_t* data, int32_t dataSize, char* outBuffer, int32_t outBufferSize)
65 {
66     int32_t writeIndex = 0;
67     do {
68         for (int i = 0; i < dataSize; i++) {
69             int ret = sprintf_s(outBuffer + writeIndex, outBufferSize - writeIndex, "%X", data[i]);
70             if (ret < 0) {
71                 writeIndex = 0;
72                 break;
73             }
74             writeIndex += ret;
75         }
76     } while (0);
77 
78     if (writeIndex == 0) {
79         memset_s(outBuffer, outBufferSize, 0, outBufferSize);
80     }
81 }
82 } // namespace
83 
84 using namespace std;
85 
UserAuthInterfaceImplGetInstance(void)86 extern "C" IUserAuthInterface *UserAuthInterfaceImplGetInstance(void)
87 {
88     auto userAuthInterfaceService = new (std::nothrow) UserAuthInterfaceService();
89     if (userAuthInterfaceService == nullptr) {
90         IAM_LOGE("userAuthInterfaceService is nullptr");
91         return nullptr;
92     }
93     std::lock_guard<std::mutex> lock(g_mutex);
94     OHOS::UserIam::Common::Init();
95     return userAuthInterfaceService;
96 }
97 
Init(const std::string & deviceUdid)98 int32_t UserAuthInterfaceService::Init(const std::string &deviceUdid)
99 {
100     IAM_LOGI("start");
101     std::lock_guard<std::mutex> lock(g_mutex);
102     g_localUdid = deviceUdid;
103     bool ret = SetLocalUdid(g_localUdid.c_str());
104     IF_TRUE_LOGE_AND_RETURN_VAL(!ret, HDF_FAILURE);
105     OHOS::UserIam::Common::Close();
106     return OHOS::UserIam::Common::Init();
107 }
108 
CopyScheduleInfo(const CoAuthSchedule * in,HdiScheduleInfo * out)109 static bool CopyScheduleInfo(const CoAuthSchedule *in, HdiScheduleInfo *out)
110 {
111     IAM_LOGI("start");
112     if (in->executorSize == 0 || (in->templateIds.data == NULL && in->templateIds.len != 0)) {
113         IAM_LOGE("executorSize is zero");
114         return false;
115     }
116     out->executorIndexes.clear();
117     out->templateIds.clear();
118     out->scheduleId = in->scheduleId;
119     out->authType = static_cast<AuthType>(in->authType);
120     for (uint32_t i = 0; i < in->templateIds.len; ++i) {
121         out->templateIds.push_back(in->templateIds.data[i]);
122     }
123     out->executorMatcher = static_cast<uint32_t>(in->executors[0].executorMatcher);
124     out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
125     for (uint32_t i = 0; i < in->executorSize; ++i) {
126         out->executorIndexes.push_back(in->executors[i].executorIndex);
127     }
128     out->executorMessages.clear();
129     return true;
130 }
131 
SetAttributeToCoAuthExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array publicKey,Attribute * attribute)132 static int32_t SetAttributeToCoAuthExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info,
133     Uint8Array publicKey, Attribute *attribute)
134 {
135     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
136 
137     if (SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, info.scheduleId) != RESULT_SUCCESS) {
138         IAM_LOGE("SetAttributeUint64 scheduleId failed");
139         return RESULT_GENERAL_ERROR;
140     }
141 
142     Uint8Array localUdidIn = { paramHal.localUdid, sizeof(paramHal.localUdid) };
143     if (SetAttributeUint8Array(attribute, ATTR_VERIFIER_UDID, localUdidIn) != RESULT_SUCCESS) {
144         IAM_LOGE("SetAttributeUint8Array verifierUdid failed");
145         return RESULT_GENERAL_ERROR;
146     }
147     if (SetAttributeUint8Array(attribute, ATTR_LOCAL_UDID, localUdidIn) != RESULT_SUCCESS) {
148         IAM_LOGE("SetAttributeUint8Array localUdid failed");
149         return RESULT_GENERAL_ERROR;
150     }
151     Uint8Array peerUdidIn = { paramHal.collectorUdid, sizeof(paramHal.collectorUdid) };
152     if (SetAttributeUint8Array(attribute, ATTR_COLLECTOR_UDID, peerUdidIn) != RESULT_SUCCESS) {
153         IAM_LOGE("SetAttributeUint8Array collectorUdid failed");
154         return RESULT_GENERAL_ERROR;
155     }
156     if (SetAttributeUint8Array(attribute, ATTR_PEER_UDID, peerUdidIn) != RESULT_SUCCESS) {
157         IAM_LOGE("SetAttributeUint8Array peerUdid failed");
158         return RESULT_GENERAL_ERROR;
159     }
160     char publicKeyStrBuffer[PUBLIC_KEY_STR_LEN] = {0};
161     FormatHexString(&publicKey.data[0], publicKey.len, publicKeyStrBuffer, PUBLIC_KEY_STR_LEN);
162     IAM_LOGI("public key: %{public}s", publicKeyStrBuffer);
163     if (SetAttributeUint8Array(attribute, ATTR_PUBLIC_KEY, publicKey) != RESULT_SUCCESS) {
164         IAM_LOGE("SetAttributeUint8Array publicKey failed");
165         return RESULT_GENERAL_ERROR;
166     }
167     Uint8Array challenge = { paramHal.challenge, CHALLENGE_LEN };
168     if (SetAttributeUint8Array(attribute, ATTR_CHALLENGE, challenge) != RESULT_SUCCESS) {
169         IAM_LOGE("SetAttributeUint8Array challenge failed");
170         return RESULT_GENERAL_ERROR;
171     }
172 
173     return RESULT_SUCCESS;
174 }
175 
SetAttributeToCollectorExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array publicKey,Uint8Array * retExtraInfo)176 static int32_t SetAttributeToCollectorExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info,
177     Uint8Array publicKey, Uint8Array *retExtraInfo)
178 {
179     Attribute *attribute = CreateEmptyAttribute();
180     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
181 
182     ResultCode ret = RESULT_GENERAL_ERROR;
183     do {
184         if (SetAttributeUint32(attribute, ATTR_TYPE, paramHal.authType) != RESULT_SUCCESS) {
185             IAM_LOGE("SetAttributeUint32 authType failed");
186             break;
187         }
188         if (SetAttributeUint32(attribute, ATTR_EXECUTOR_MATCHER, info.executorMatcher) != RESULT_SUCCESS) {
189             IAM_LOGE("SetAttributeUint64 executorMatcher failed");
190             break;
191         }
192         if (SetAttributeInt32(attribute, ATTR_SCHEDULE_MODE, info.scheduleMode) != RESULT_SUCCESS) {
193             IAM_LOGE("SetAttributeUint64 scheduleMode failed");
194             break;
195         }
196         if (SetAttributeUint32(attribute, ATTR_EXECUTOR_ROLE, COLLECTOR) != RESULT_SUCCESS) {
197             IAM_LOGE("SetAttributeUint32 executorRole failed");
198             break;
199         }
200         if (SetAttributeToCoAuthExecMsg(paramHal, info, publicKey, attribute) != RESULT_SUCCESS) {
201             IAM_LOGE("SetAttributeToCoAuthExecMsg failed");
202             break;
203         }
204 
205         SignParam signParam = {
206             .needSignature = true,
207             .keyType = KEY_TYPE_CROSS_DEVICE,
208             .peerUdid = { paramHal.collectorUdid, sizeof(paramHal.collectorUdid) }
209         };
210         if (GetAttributeExecutorMsg(attribute, retExtraInfo, signParam) != RESULT_SUCCESS) {
211             IAM_LOGE("GetAttributeExecutorMsg failed");
212             break;
213         }
214         ret = RESULT_SUCCESS;
215     } while (0);
216 
217     FreeAttribute(&attribute);
218     return ret;
219 }
220 
GetCapabilityLevel(int32_t userId,HdiScheduleInfo & info,uint32_t & capabilityLevel)221 static int32_t GetCapabilityLevel(int32_t userId, HdiScheduleInfo &info, uint32_t &capabilityLevel)
222 {
223     capabilityLevel = INVALID_CAPABILITY_LEVEL;
224     LinkedList *credList = nullptr;
225     int32_t ret = QueryCredentialFunc(userId, info.authType, &credList);
226     if (ret != RESULT_SUCCESS) {
227         IAM_LOGE("query credential failed");
228         return ret;
229     }
230     LinkedListNode *temp = credList->head;
231     while (temp != nullptr) {
232         if (temp->data == nullptr) {
233             IAM_LOGE("list node is invalid");
234             DestroyLinkedList(credList);
235             return RESULT_UNKNOWN;
236         }
237         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
238         // Only the lowest acl is returned
239         capabilityLevel = (capabilityLevel < credentialHal->capabilityLevel) ?
240             capabilityLevel : credentialHal->capabilityLevel;
241         temp = temp->next;
242     }
243 
244     DestroyLinkedList(credList);
245     return RESULT_SUCCESS;
246 }
247 
GetExpiredSysTime(AuthParamHal paramHal)248 static uint64_t GetExpiredSysTime(AuthParamHal paramHal)
249 {
250     UserAuthContext *context = GetContext(paramHal.contextId);
251     if (context == NULL) {
252         IAM_LOGE("context is null");
253         return NO_CHECK_PIN_EXPIRED_PERIOD;
254     }
255 
256     if (!context->isExpiredReturnSuccess) {
257         return context->authExpiredSysTime;
258     }
259 
260     return NO_CHECK_PIN_EXPIRED_PERIOD;
261 }
262 
SetAttributeToVerifierExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array publicKey,Uint8Array * retExtraInfo)263 static int32_t SetAttributeToVerifierExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info,
264     Uint8Array publicKey, Uint8Array *retExtraInfo)
265 {
266     Attribute *attribute = CreateEmptyAttribute();
267     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
268 
269     ResultCode ret = RESULT_GENERAL_ERROR;
270     do {
271         Uint64Array templateIdsIn = {info.templateIds.data(), info.templateIds.size()};
272         if (SetAttributeUint64Array(attribute, ATTR_TEMPLATE_ID_LIST, templateIdsIn) != RESULT_SUCCESS) {
273             IAM_LOGE("SetAttributeUint64Array templateIdsIn failed");
274             break;
275         }
276         uint32_t capabilityLevel = INVALID_CAPABILITY_LEVEL;
277         int32_t result = GetCapabilityLevel(paramHal.userId, info, capabilityLevel);
278         if (result != RESULT_SUCCESS) {
279             IAM_LOGE("GetCapabilityLevel fail");
280             return result;
281         }
282         if (capabilityLevel != INVALID_CAPABILITY_LEVEL &&
283             SetAttributeUint32(attribute, ATTR_CAPABILITY_LEVEL, capabilityLevel) != RESULT_SUCCESS) {
284             IAM_LOGE("SetAttributeUint32 capabilityLevel failed");
285             break;
286         }
287         if (SetAttributeUint64(attribute, ATTR_EXPIRED_SYS_TIME, GetExpiredSysTime(paramHal)) != RESULT_SUCCESS) {
288             IAM_LOGE("SetAttributeUint64 authExpiredSysTime failed");
289             break;
290         }
291         if (SetAttributeToCoAuthExecMsg(paramHal, info, publicKey, attribute) != RESULT_SUCCESS) {
292             IAM_LOGE("SetAttributeToCoAuthExecMsg failed");
293             break;
294         }
295 
296         SignParam signParam = { .needSignature = true, .keyType = KEY_TYPE_EXECUTOR };
297         if (GetAttributeExecutorMsg(attribute, retExtraInfo, signParam) != RESULT_SUCCESS) {
298             IAM_LOGE("GetAttributeExecutorMsg failed");
299             break;
300         }
301         ret = RESULT_SUCCESS;
302     } while (0);
303 
304     FreeAttribute(&attribute);
305     return ret;
306 }
307 
SetAttributeToExtraInfo(HdiScheduleInfo & info,uint32_t capabilityLevel,uint64_t scheduleId)308 static int32_t SetAttributeToExtraInfo(HdiScheduleInfo &info, uint32_t capabilityLevel, uint64_t scheduleId)
309 {
310     Attribute *attribute = CreateEmptyAttribute();
311     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
312 
313     ResultCode ret = RESULT_GENERAL_ERROR;
314     do {
315         Uint64Array templateIdsIn = {info.templateIds.data(), info.templateIds.size()};
316         if (SetAttributeUint64Array(attribute, ATTR_TEMPLATE_ID_LIST, templateIdsIn) != RESULT_SUCCESS) {
317             IAM_LOGE("SetAttributeUint64Array templateIdsIn failed");
318             break;
319         }
320         if (capabilityLevel != INVALID_CAPABILITY_LEVEL &&
321             SetAttributeUint32(attribute, ATTR_CAPABILITY_LEVEL, capabilityLevel) != RESULT_SUCCESS) {
322             IAM_LOGE("SetAttributeUint32 capabilityLevel failed");
323             break;
324         }
325         if (SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, scheduleId) != RESULT_SUCCESS) {
326             IAM_LOGE("SetAttributeUint64 scheduleId failed");
327             break;
328         }
329 
330         info.executorMessages.resize(1);
331         info.executorMessages[0].resize(MAX_EXECUTOR_MSG_LEN);
332         Uint8Array retExtraInfo = { info.executorMessages[0].data(), MAX_EXECUTOR_MSG_LEN };
333         SignParam signParam = { .needSignature = true, .keyType = KEY_TYPE_EXECUTOR };
334         if (GetAttributeExecutorMsg(attribute, &retExtraInfo, signParam) != RESULT_SUCCESS) {
335             IAM_LOGE("GetAttributeExecutorMsg failed");
336             info.executorMessages.clear();
337             break;
338         }
339         info.executorMessages[0].resize(retExtraInfo.len);
340         ret = RESULT_SUCCESS;
341     } while (0);
342 
343     FreeAttribute(&attribute);
344     return ret;
345 }
346 
SetAttributeToAllInOneExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array * retExtraInfo)347 static int32_t SetAttributeToAllInOneExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info, Uint8Array *retExtraInfo)
348 {
349     uint32_t capabilityLevel = INVALID_CAPABILITY_LEVEL;
350     int32_t result = GetCapabilityLevel(paramHal.userId, info, capabilityLevel);
351     if (result != RESULT_SUCCESS) {
352         IAM_LOGE("GetCapabilityLevel fail");
353         return result;
354     }
355 
356     Attribute *attribute = CreateEmptyAttribute();
357     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
358 
359     ResultCode ret = RESULT_GENERAL_ERROR;
360     do {
361         Uint64Array templateIdsIn = {info.templateIds.data(), info.templateIds.size()};
362         if (SetAttributeUint64Array(attribute, ATTR_TEMPLATE_ID_LIST, templateIdsIn) != RESULT_SUCCESS) {
363             IAM_LOGE("SetAttributeUint64Array templateIdsIn failed");
364             break;
365         }
366         if (capabilityLevel != INVALID_CAPABILITY_LEVEL &&
367             SetAttributeUint32(attribute, ATTR_CAPABILITY_LEVEL, capabilityLevel) != RESULT_SUCCESS) {
368             IAM_LOGE("SetAttributeUint32 capabilityLevel failed");
369             break;
370         }
371         if (SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, info.scheduleId) != RESULT_SUCCESS) {
372             IAM_LOGE("SetAttributeUint64 scheduleId failed");
373             break;
374         }
375 
376         if (SetAttributeUint64(attribute, ATTR_EXPIRED_SYS_TIME, GetExpiredSysTime(paramHal)) != RESULT_SUCCESS) {
377             IAM_LOGE("SetAttributeUint64 authExpiredSysTime failed");
378             break;
379         }
380 
381         Uint8Array challenge = { paramHal.challenge, CHALLENGE_LEN };
382         if (SetAttributeUint8Array(attribute, ATTR_CHALLENGE, challenge) != RESULT_SUCCESS) {
383             IAM_LOGE("SetAttributeUint8Array challenge failed");
384             break;
385         }
386 
387         SignParam signParam = { .needSignature = true, .keyType = KEY_TYPE_EXECUTOR };
388         if (GetAttributeExecutorMsg(attribute, retExtraInfo, signParam) != RESULT_SUCCESS) {
389             IAM_LOGE("GetAttributeExecutorMsg failed");
390             break;
391         }
392         ret = RESULT_SUCCESS;
393     } while (0);
394 
395     FreeAttribute(&attribute);
396     return ret;
397 }
398 
GetAuthExecutorMsg(uint32_t executorRole,AuthParamHal paramHal,Uint8Array publicKey,HdiScheduleInfo & info,Uint8Array * retMsg)399 static int32_t GetAuthExecutorMsg(uint32_t executorRole, AuthParamHal paramHal,
400     Uint8Array publicKey, HdiScheduleInfo &info, Uint8Array *retMsg)
401 {
402     if (executorRole == COLLECTOR) {
403         if (SetAttributeToCollectorExecMsg(paramHal, info, publicKey, retMsg) != RESULT_SUCCESS) {
404             IAM_LOGE("SetAttributeToCollectorExecMsg failed");
405             return RESULT_GENERAL_ERROR;
406         }
407     } else if (executorRole == VERIFIER) {
408         if (SetAttributeToVerifierExecMsg(paramHal, info, publicKey, retMsg) != RESULT_SUCCESS) {
409             IAM_LOGE("SetAttributeToVerifierExecMsg failed");
410             return RESULT_GENERAL_ERROR;
411         }
412     } else if (executorRole == ALL_IN_ONE) {
413         if (SetAttributeToAllInOneExecMsg(paramHal, info, retMsg) != RESULT_SUCCESS) {
414             IAM_LOGE("SetAttributeToAllInOneExecMsg fail");
415             return RESULT_GENERAL_ERROR;
416         }
417     } else {
418         IAM_LOGE("Unsupported executorRole %{public}u", executorRole);
419         return RESULT_GENERAL_ERROR;
420     }
421     return RESULT_SUCCESS;
422 }
423 
CopyAuthScheduleInfo(AuthParamHal paramHal,const CoAuthSchedule * in,HdiScheduleInfo * out)424 static bool CopyAuthScheduleInfo(AuthParamHal paramHal, const CoAuthSchedule *in, HdiScheduleInfo *out)
425 {
426     IAM_LOGI("CopyAuthScheduleInfo start");
427     if (in->executorSize == 0 || (in->templateIds.data == NULL && in->templateIds.len != 0)) {
428         IAM_LOGE("executorSize is zero");
429         return false;
430     }
431     out->executorIndexes.clear();
432     out->templateIds.clear();
433     out->scheduleId = in->scheduleId;
434     out->authType = static_cast<AuthType>(in->authType);
435     for (uint32_t i = 0; i < in->templateIds.len; ++i) {
436         out->templateIds.push_back(in->templateIds.data[i]);
437     }
438     out->executorMatcher = static_cast<uint32_t>(in->executors[0].executorMatcher);
439     out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
440 
441     out->executorIndexes.resize(in->executorSize);
442     out->executorMessages.resize(in->executorSize);
443     for (uint32_t i = 0; i < in->executorSize; ++i) {
444         out->executorIndexes[i] = in->executors[i].executorIndex;
445         out->executorMessages[i].resize(MAX_EXECUTOR_MSG_LEN);
446         Uint8Array retExtraInfo = { out->executorMessages[i].data(), MAX_EXECUTOR_MSG_LEN };
447         uint32_t executorRoleTemp = static_cast<ExecutorRole>(in->executors[i].executorRole);
448         Uint8Array publicKeyInfo = { (uint8_t *)in->executors[1 - i].pubKey, PUBLIC_KEY_LEN };
449         if (GetAuthExecutorMsg(executorRoleTemp, paramHal, publicKeyInfo, *out, &retExtraInfo) != RESULT_SUCCESS) {
450             IAM_LOGE("GetAuthExecutorMsg failed");
451             out->executorIndexes.clear();
452             out->templateIds.clear();
453             out->executorMessages.clear();
454             return false;
455         }
456         out->executorMessages[i].resize(retExtraInfo.len);
457     }
458     return true;
459 }
460 
CopyAuthParamToHal(uint64_t contextId,const HdiAuthParam & param,AuthParamHal & paramHal)461 static int32_t CopyAuthParamToHal(uint64_t contextId, const HdiAuthParam &param,
462     AuthParamHal &paramHal)
463 {
464     paramHal.contextId = contextId;
465     paramHal.userId = param.baseParam.userId;
466     paramHal.authType = static_cast<int32_t>(param.authType);
467     paramHal.authTrustLevel = param.baseParam.authTrustLevel;
468     if (!param.baseParam.challenge.empty() && memcpy_s(paramHal.challenge, CHALLENGE_LEN,
469         param.baseParam.challenge.data(), param.baseParam.challenge.size()) != EOK) {
470         IAM_LOGE("challenge copy failed");
471         return RESULT_BAD_COPY;
472     }
473     paramHal.authIntent = param.authIntent;
474     paramHal.isExpiredReturnSuccess = false;
475     if (param.baseParam.callerType == TOKEN_HAP &&
476         (param.baseParam.callerName.find(SETTRINGS_NAME) != std::string::npos ||
477         param.authIntent == HdiAuthIntent::UNLOCK)) {
478         paramHal.isExpiredReturnSuccess = true;
479     }
480     if (!param.collectorUdid.empty()) {
481         if (memcpy_s(paramHal.collectorUdid, sizeof(paramHal.collectorUdid),
482             (uint8_t *)param.collectorUdid.c_str(), param.collectorUdid.length()) != EOK) {
483             IAM_LOGE("collectorUdid copy failed");
484             return RESULT_BAD_COPY;
485         }
486     } else {
487         Uint8Array collectorUdid = { paramHal.collectorUdid, sizeof(paramHal.collectorUdid) };
488         if (!GetLocalUdid(&collectorUdid)) {
489             IAM_LOGE("fill collector udid by local udid failed");
490             return RESULT_GENERAL_ERROR;
491         }
492     }
493     Uint8Array localUdid = { paramHal.localUdid, sizeof(paramHal.localUdid) };
494     if (!GetLocalUdid(&localUdid)) {
495         IAM_LOGE("GetLocalUdid failed");
496         return RESULT_GENERAL_ERROR;
497     }
498     return RESULT_SUCCESS;
499 }
500 
BeginAuthentication(uint64_t contextId,const HdiAuthParam & param,std::vector<HdiScheduleInfo> & infos)501 int32_t UserAuthInterfaceService::BeginAuthentication(uint64_t contextId, const HdiAuthParam &param,
502     std::vector<HdiScheduleInfo> &infos)
503 {
504     IAM_LOGI("start");
505     infos.clear();
506     AuthParamHal paramHal = {};
507     int32_t ret = CopyAuthParamToHal(contextId, param, paramHal);
508     if (ret != RESULT_SUCCESS) {
509         IAM_LOGE("copy CopyAuthParamToHal failed %{public}d", ret);
510         return ret;
511     }
512     std::lock_guard<std::mutex> lock(g_mutex);
513     LinkedList *schedulesGet = nullptr;
514     ret = GenerateSolutionFunc(paramHal, &schedulesGet);
515     if (ret != RESULT_SUCCESS) {
516         IAM_LOGE("generate solution failed %{public}d", ret);
517         return ret;
518     }
519     if (schedulesGet == nullptr) {
520         IAM_LOGE("get null schedule");
521         return RESULT_GENERAL_ERROR;
522     }
523     LinkedListNode *tempNode = schedulesGet->head;
524     while (tempNode != nullptr) {
525         if (tempNode->data == nullptr) {
526             IAM_LOGE("node data is invalid");
527             DestroyLinkedList(schedulesGet);
528             return RESULT_UNKNOWN;
529         }
530         HdiScheduleInfo temp = {};
531         auto coAuthSchedule = static_cast<CoAuthSchedule *>(tempNode->data);
532         if (!CopyAuthScheduleInfo(paramHal, coAuthSchedule, &temp)) {
533             infos.clear();
534             IAM_LOGE("copy schedule info failed");
535             DestroyLinkedList(schedulesGet);
536             return RESULT_GENERAL_ERROR;
537         }
538         infos.push_back(temp);
539         tempNode = tempNode->next;
540     }
541     DestroyLinkedList(schedulesGet);
542     return ret;
543 }
544 
GetAllUserInfo(std::vector<UserInfo> & userInfos)545 int32_t UserAuthInterfaceService::GetAllUserInfo(std::vector<UserInfo> &userInfos)
546 {
547     IAM_LOGI("GetAllUserInfo mock start");
548     static_cast<void>(userInfos);
549 
550     return RESULT_SUCCESS;
551 }
552 
CreateExecutorCommand(int32_t userId,HdiAuthResultInfo & info)553 static int32_t CreateExecutorCommand(int32_t userId, HdiAuthResultInfo &info)
554 {
555     LinkedList *executorSendMsg = nullptr;
556     AuthPropertyMode authPropMode;
557     if (info.result == RESULT_SUCCESS) {
558         authPropMode = PROPERTY_MODE_UNFREEZE;
559     } else if (info.remainAttempts == 0) {
560         authPropMode = PROPERTY_MODE_FREEZE;
561     } else {
562         return RESULT_SUCCESS;
563     }
564     ResultCode ret = GetExecutorMsgList(userId, authPropMode, &executorSendMsg);
565     if (ret != RESULT_SUCCESS) {
566         IAM_LOGE("get executor msg failed");
567         return ret;
568     }
569 
570     LinkedListNode *temp = executorSendMsg->head;
571     while (temp != nullptr) {
572         if (temp->data == nullptr) {
573             IAM_LOGE("list node is invalid");
574             DestroyLinkedList(executorSendMsg);
575             return RESULT_UNKNOWN;
576         }
577         auto nodeData = static_cast<ExecutorMsg *>(temp->data);
578         Buffer *nodeMsgBuffer = nodeData->msg;
579         if (!IsBufferValid(nodeMsgBuffer)) {
580             IAM_LOGE("node's buffer invalid");
581             DestroyLinkedList(executorSendMsg);
582             return RESULT_UNKNOWN;
583         }
584         HdiExecutorSendMsg msg = {};
585         msg.executorIndex = nodeData->executorIndex;
586         msg.commandId = static_cast<int32_t>(authPropMode);
587         msg.msg.resize(nodeMsgBuffer->contentSize);
588         if (memcpy_s(msg.msg.data(), msg.msg.size(), nodeMsgBuffer->buf, nodeMsgBuffer->contentSize) != EOK) {
589             IAM_LOGE("copy failed");
590             msg.msg.clear();
591             DestroyLinkedList(executorSendMsg);
592             return RESULT_BAD_COPY;
593         }
594         info.msgs.push_back(msg);
595         temp = temp->next;
596     }
597     DestroyLinkedList(executorSendMsg);
598     return RESULT_SUCCESS;
599 }
600 
CopyAuthResult(AuthResult & infoIn,UserAuthTokenHal & authTokenIn,HdiAuthResultInfo & infoOut,HdiEnrolledState & enrolledStateOut)601 static int32_t CopyAuthResult(AuthResult &infoIn, UserAuthTokenHal &authTokenIn, HdiAuthResultInfo &infoOut,
602     HdiEnrolledState &enrolledStateOut)
603 {
604     IAM_LOGI("start");
605     infoOut.result = infoIn.result;
606     infoOut.remainAttempts = infoIn.remainTimes;
607     infoOut.lockoutDuration = infoIn.freezingTime;
608     enrolledStateOut.credentialDigest = infoIn.credentialDigest;
609     enrolledStateOut.credentialCount = infoIn.credentialCount;
610     infoOut.pinExpiredInfo = infoIn.pinExpiredInfo;
611     if (infoOut.result == RESULT_SUCCESS) {
612         infoOut.userId = infoIn.userId;
613         infoOut.credentialId = infoIn.credentialId;
614         IAM_LOGI("matched userId: %{public}d, credentialId: %{public}s.",
615             infoOut.userId, GET_MASKED_STRING(infoOut.credentialId).c_str());
616         infoOut.token.resize(sizeof(UserAuthTokenHal));
617         if (memcpy_s(infoOut.token.data(), infoOut.token.size(), &authTokenIn, sizeof(UserAuthTokenHal)) != EOK) {
618                 IAM_LOGE("copy authToken failed");
619                 infoOut.token.clear();
620                 return RESULT_BAD_COPY;
621         }
622         if (infoIn.rootSecret != nullptr) {
623             infoOut.rootSecret.resize(infoIn.rootSecret->contentSize);
624             if (memcpy_s(infoOut.rootSecret.data(), infoOut.rootSecret.size(),
625                 infoIn.rootSecret->buf, infoIn.rootSecret->contentSize) != EOK) {
626                 IAM_LOGE("copy secret failed");
627                 infoOut.rootSecret.clear();
628                 infoOut.token.clear();
629                 return RESULT_BAD_COPY;
630             }
631         }
632     }
633     if (infoIn.remoteAuthResultMsg != nullptr) {
634         infoOut.remoteAuthResultMsg.resize(infoIn.remoteAuthResultMsg->contentSize);
635         if (memcpy_s(infoOut.remoteAuthResultMsg.data(), infoOut.remoteAuthResultMsg.size(),
636             infoIn.remoteAuthResultMsg->buf, infoIn.remoteAuthResultMsg->contentSize) != EOK) {
637             IAM_LOGE("copy remoteAuthResultMsg failed");
638             infoOut.remoteAuthResultMsg.clear();
639             infoOut.rootSecret.clear();
640             infoOut.token.clear();
641             return RESULT_BAD_COPY;
642         }
643     }
644     infoOut.userId = infoIn.userId;
645     IAM_LOGI("matched userId: %{public}d.", infoOut.userId);
646     return RESULT_SUCCESS;
647 }
648 
UpdateAuthenticationResultInner(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,HdiAuthResultInfo & info,HdiEnrolledState & enrolledState)649 static int32_t UpdateAuthenticationResultInner(uint64_t contextId,
650     const std::vector<uint8_t> &scheduleResult, HdiAuthResultInfo &info, HdiEnrolledState &enrolledState)
651 {
652     IAM_LOGI("start");
653     if (scheduleResult.size() == 0) {
654         IAM_LOGE("param is invalid");
655         DestroyContextbyId(contextId);
656         return RESULT_BAD_PARAM;
657     }
658     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
659     if (!IsBufferValid(scheduleResultBuffer)) {
660         IAM_LOGE("scheduleTokenBuffer is invalid");
661         DestroyContextbyId(contextId);
662         return RESULT_NO_MEMORY;
663     }
664     std::lock_guard<std::mutex> lock(g_mutex);
665     UserAuthTokenHal authTokenHal = {};
666     AuthResult authResult = {};
667     int32_t funcRet = RESULT_GENERAL_ERROR;
668     do {
669         int32_t ret = RequestAuthResultFunc(contextId, scheduleResultBuffer, &authTokenHal, &authResult);
670         DestoryBuffer(scheduleResultBuffer);
671         if (ret != RESULT_SUCCESS) {
672             IAM_LOGE("execute func failed");
673             break;
674         }
675         ret = CopyAuthResult(authResult, authTokenHal, info, enrolledState);
676         if (ret != RESULT_SUCCESS) {
677             IAM_LOGE("Copy auth result failed");
678             break;
679         }
680         if (authResult.authType != PIN_AUTH) {
681             IAM_LOGI("type not pin");
682         } else {
683             IAM_LOGI("type pin");
684             ret = CreateExecutorCommand(authResult.userId, info);
685             if (ret != RESULT_SUCCESS) {
686                 IAM_LOGE("create executor command failed");
687                 break;
688             }
689         }
690         funcRet = RESULT_SUCCESS;
691     } while (0);
692 
693     DestroyAuthResult(&authResult);
694     return funcRet;
695 }
696 
UpdateAuthenticationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,HdiAuthResultInfo & info,HdiEnrolledState & enrolledState)697 int32_t UserAuthInterfaceService::UpdateAuthenticationResult(uint64_t contextId,
698     const std::vector<uint8_t> &scheduleResult, HdiAuthResultInfo &info, HdiEnrolledState &enrolledState)
699 {
700     IAM_LOGI("start");
701     return UpdateAuthenticationResultInner(contextId, scheduleResult, info, enrolledState);
702 }
703 
CancelAuthentication(uint64_t contextId)704 int32_t UserAuthInterfaceService::CancelAuthentication(uint64_t contextId)
705 {
706     IAM_LOGI("start");
707     std::lock_guard<std::mutex> lock(g_mutex);
708     return DestroyContextbyId(contextId);
709 }
710 
BeginIdentification(uint64_t contextId,int32_t authType,const std::vector<uint8_t> & challenge,uint32_t executorSensorHint,HdiScheduleInfo & scheduleInfo)711 int32_t UserAuthInterfaceService::BeginIdentification(uint64_t contextId, int32_t authType,
712     const std::vector<uint8_t> &challenge, uint32_t executorSensorHint, HdiScheduleInfo &scheduleInfo)
713 {
714     IAM_LOGI("start");
715     if (authType == PIN) {
716         IAM_LOGE("param is invalid");
717         return RESULT_BAD_PARAM;
718     }
719     IdentifyParam param = {};
720     param.contextId = contextId;
721     param.authType = static_cast<uint32_t>(authType);
722     param.executorSensorHint = executorSensorHint;
723     if (!challenge.empty() && memcpy_s(param.challenge, CHALLENGE_LEN, challenge.data(), challenge.size()) != EOK) {
724         IAM_LOGE("challenge copy failed");
725         return RESULT_BAD_COPY;
726     }
727     std::lock_guard<std::mutex> lock(g_mutex);
728     LinkedList *scheduleGet = nullptr;
729     int32_t ret = DoIdentify(param, &scheduleGet);
730     if (ret != RESULT_SUCCESS) {
731         IAM_LOGE("generate solution failed");
732         return ret;
733     }
734     if (scheduleGet == nullptr) {
735         IAM_LOGE("get null schedule");
736         return RESULT_GENERAL_ERROR;
737     }
738     if (scheduleGet->head == nullptr || scheduleGet->head->data == nullptr) {
739         IAM_LOGE("scheduleGet is invalid");
740         DestroyLinkedList(scheduleGet);
741         return RESULT_UNKNOWN;
742     }
743     auto data = static_cast<CoAuthSchedule *>(scheduleGet->head->data);
744     if (!CopyScheduleInfo(data, &scheduleInfo)) {
745         IAM_LOGE("copy schedule failed");
746         ret = RESULT_BAD_COPY;
747     }
748     DestroyLinkedList(scheduleGet);
749     return ret;
750 }
751 
UpdateIdentificationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,IdentifyResultInfo & info)752 int32_t UserAuthInterfaceService::UpdateIdentificationResult(uint64_t contextId,
753     const std::vector<uint8_t> &scheduleResult, IdentifyResultInfo &info)
754 {
755     IAM_LOGI("start");
756     if (scheduleResult.size() == 0) {
757         IAM_LOGE("param is invalid");
758         return RESULT_BAD_PARAM;
759     }
760     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
761     if (!IsBufferValid(scheduleResultBuffer)) {
762         IAM_LOGE("scheduleTokenBuffer is invalid");
763         return RESULT_NO_MEMORY;
764     }
765     std::lock_guard<std::mutex> lock(g_mutex);
766     UserAuthTokenHal token = {};
767     int32_t ret = DoUpdateIdentify(contextId, scheduleResultBuffer, &info.userId, &token, &info.result);
768     DestoryBuffer(scheduleResultBuffer);
769     if (ret != RESULT_SUCCESS) {
770         IAM_LOGE("DoUpdateIdentify failed");
771         return ret;
772     }
773     if (info.result == RESULT_SUCCESS) {
774         info.token.resize(sizeof(UserAuthTokenHal));
775         if (memcpy_s(info.token.data(), info.token.size(), &token, sizeof(token)) != EOK) {
776             IAM_LOGE("copy authToken failed");
777             info.token.clear();
778             return RESULT_BAD_COPY;
779         }
780     }
781     return RESULT_SUCCESS;
782 }
783 
CancelIdentification(uint64_t contextId)784 int32_t UserAuthInterfaceService::CancelIdentification(uint64_t contextId)
785 {
786     IAM_LOGI("start");
787     std::lock_guard<std::mutex> lock(g_mutex);
788     return DestroyContextbyId(contextId);
789 }
790 
GetAvailableStatus(int32_t userId,int32_t authType,uint32_t authTrustLevel,int32_t & checkResult)791 int32_t UserAuthInterfaceService::GetAvailableStatus(int32_t userId, int32_t authType, uint32_t authTrustLevel,
792     int32_t &checkResult)
793 {
794     IAM_LOGI("start");
795     std::lock_guard<std::mutex> lock(g_mutex);
796     GetAvailableStatusFunc(userId, authType, authTrustLevel, &checkResult);
797     if (checkResult != RESULT_SUCCESS) {
798         IAM_LOGE("GetAvailableStatusFunc failed");
799     }
800     return RESULT_SUCCESS;
801 }
802 
GetValidSolution(int32_t userId,const std::vector<int32_t> & authTypes,uint32_t authTrustLevel,std::vector<int32_t> & validTypes)803 int32_t UserAuthInterfaceService::GetValidSolution(int32_t userId, const std::vector<int32_t> &authTypes,
804     uint32_t authTrustLevel, std::vector<int32_t> &validTypes)
805 {
806     IAM_LOGI("start userId:%{public}d authTrustLevel:%{public}u", userId, authTrustLevel);
807     int32_t result = RESULT_TYPE_NOT_SUPPORT;
808     validTypes.clear();
809     std::lock_guard<std::mutex> lock(g_mutex);
810     for (auto &authType : authTypes) {
811         int32_t checkRet = RESULT_GENERAL_ERROR;
812         GetAvailableStatusFunc(userId, authType, authTrustLevel, &checkRet);
813         if (checkRet == RESULT_PIN_EXPIRED) {
814             LOG_ERROR("pin is expired");
815             return RESULT_PIN_EXPIRED;
816         }
817         if (checkRet == RESULT_TRUST_LEVEL_NOT_SUPPORT) {
818             IAM_LOGE("GetAvailableStatus checkRet: %{public}d", checkRet);
819             result = checkRet;
820             continue;
821         }
822         if (checkRet != RESULT_SUCCESS) {
823             IAM_LOGE("authType does not support, authType:%{public}d, ret:%{public}d", authType, checkRet);
824             result = RESULT_NOT_ENROLLED;
825             continue;
826         }
827         IAM_LOGI("get valid authType:%{public}d", authType);
828         validTypes.push_back(authType);
829     }
830     if (validTypes.empty()) {
831         IAM_LOGE("no auth type valid");
832         return result;
833     }
834     return RESULT_SUCCESS;
835 }
836 
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)837 int32_t UserAuthInterfaceService::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
838 {
839     IAM_LOGI("start");
840     std::lock_guard<std::mutex> lock(g_mutex);
841     challenge.resize(CHALLENGE_LEN);
842     int32_t ret = OpenEditSession(userId, challenge.data(), challenge.size());
843     if (ret != RESULT_SUCCESS) {
844         IAM_LOGE("failed to open session");
845         challenge.clear();
846     }
847     return ret;
848 }
849 
CloseSession(int32_t userId)850 int32_t UserAuthInterfaceService::CloseSession(int32_t userId)
851 {
852     IAM_LOGI("start");
853     std::lock_guard<std::mutex> lock(g_mutex);
854     return CloseEditSession();
855 }
856 
BeginEnrollment(const std::vector<uint8_t> & authToken,const HdiEnrollParam & param,HdiScheduleInfo & info)857 int32_t UserAuthInterfaceService::BeginEnrollment(
858     const std::vector<uint8_t> &authToken, const HdiEnrollParam &param, HdiScheduleInfo &info)
859 {
860     IAM_LOGI("start");
861     if (authToken.size() != sizeof(UserAuthTokenHal) && authToken.size() != 0) {
862         IAM_LOGE("authToken len is invalid");
863         return RESULT_BAD_PARAM;
864     }
865     PermissionCheckParam checkParam = {};
866     if (authToken.size() == sizeof(UserAuthTokenHal) &&
867         memcpy_s(checkParam.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
868         return RESULT_BAD_COPY;
869     }
870     checkParam.authType = param.authType;
871     checkParam.userId = param.userId;
872     checkParam.executorSensorHint = param.executorSensorHint;
873     checkParam.userType = param.userType;
874     std::lock_guard<std::mutex> lock(g_mutex);
875     uint64_t scheduleId;
876     int32_t ret;
877     if (authToken.size() == sizeof(UserAuthTokenHal) && param.authType == PIN) {
878         ret = CheckUpdatePermission(checkParam, &scheduleId);
879         if (ret != RESULT_SUCCESS) {
880             IAM_LOGE("check update permission failed");
881             return ret;
882         }
883     } else {
884         ret = CheckEnrollPermission(checkParam, &scheduleId);
885         if (ret != RESULT_SUCCESS) {
886             IAM_LOGE("check enroll permission failed");
887             return ret;
888         }
889     }
890     const CoAuthSchedule *scheduleInfo = GetCoAuthSchedule(scheduleId);
891     if (scheduleInfo == nullptr) {
892         IAM_LOGE("get schedule info failed");
893         return RESULT_UNKNOWN;
894     }
895     if (!CopyScheduleInfo(scheduleInfo, &info)) {
896         IAM_LOGE("copy schedule info failed");
897         return RESULT_BAD_COPY;
898     }
899     ret = SetAttributeToExtraInfo(info, INVALID_CAPABILITY_LEVEL, scheduleId);
900     if (ret != RESULT_SUCCESS) {
901         IAM_LOGE("SetAttributeToExtraInfo failed");
902     }
903 
904     IAM_LOGI("end");
905     return ret;
906 }
907 
CancelEnrollment(int32_t userId)908 int32_t UserAuthInterfaceService::CancelEnrollment(int32_t userId)
909 {
910     IAM_LOGI("start");
911     std::lock_guard<std::mutex> lock(g_mutex);
912     BreakOffCoauthSchedule();
913     return RESULT_SUCCESS;
914 }
915 
CopyCredentialInfo(const CredentialInfoHal & in,HdiCredentialInfo & out)916 static void CopyCredentialInfo(const CredentialInfoHal &in, HdiCredentialInfo &out)
917 {
918     out.authType = static_cast<AuthType>(in.authType);
919     out.authSubType = in.credentialType;
920     out.credentialId = in.credentialId;
921     out.templateId = in.templateId;
922     out.executorMatcher = in.executorMatcher;
923     out.executorSensorHint = in.executorSensorHint;
924     out.executorIndex = QueryCredentialExecutorIndex(in.authType, in.executorSensorHint);
925 }
926 
GetUpdateResult(int32_t userId,HdiEnrollResultInfo & info,Buffer * scheduleResultBuffer)927 static int32_t GetUpdateResult(int32_t userId, HdiEnrollResultInfo &info, Buffer *scheduleResultBuffer)
928 {
929     UpdateCredentialOutput output = {};
930     int32_t ret = UpdateCredentialFunc(userId, scheduleResultBuffer, &output);
931     if (ret == RESULT_SUCCESS) {
932         /* Only update pin have oldRootSecret and rootSecret */
933         info.rootSecret.resize(ROOT_SECRET_LEN);
934         if (memcpy_s(info.rootSecret.data(), ROOT_SECRET_LEN, output.rootSecret->buf, ROOT_SECRET_LEN) != EOK) {
935             IAM_LOGE("failed to copy rootSecret");
936             ret = RESULT_BAD_COPY;
937             goto ERROR;
938         }
939         info.oldRootSecret.resize(ROOT_SECRET_LEN);
940         if (memcpy_s(info.oldRootSecret.data(), ROOT_SECRET_LEN, output.oldRootSecret->buf, ROOT_SECRET_LEN) != EOK) {
941             IAM_LOGE("failed to copy oldRootSecret");
942             ret = RESULT_BAD_COPY;
943             goto ERROR;
944         }
945         info.authToken.resize(AUTH_TOKEN_LEN);
946         if (memcpy_s(info.authToken.data(), AUTH_TOKEN_LEN, output.authToken->buf, AUTH_TOKEN_LEN) != EOK) {
947             IAM_LOGE("failed to copy authToken");
948             ret = RESULT_BAD_COPY;
949             goto ERROR;
950         }
951         info.credentialId = output.credentialId;
952         CopyCredentialInfo(output.deletedCredential, info.oldInfo);
953         goto EXIT;
954     }
955 
956 ERROR:
957     (void)memset_s(info.rootSecret.data(), info.rootSecret.size(), 0, info.rootSecret.size());
958     info.rootSecret.clear();
959     (void)memset_s(info.oldRootSecret.data(), info.oldRootSecret.size(), 0, info.oldRootSecret.size());
960     info.oldRootSecret.clear();
961     (void)memset_s(info.authToken.data(), info.authToken.size(), 0, info.authToken.size());
962     info.authToken.clear();
963 
964 EXIT:
965     DestoryBuffer(output.rootSecret);
966     DestoryBuffer(output.oldRootSecret);
967     DestoryBuffer(output.authToken);
968     return ret;
969 }
970 
GetEnrollResult(int32_t userId,HdiEnrollResultInfo & info,Buffer * scheduleResultBuffer)971 static int32_t GetEnrollResult(int32_t userId, HdiEnrollResultInfo &info, Buffer *scheduleResultBuffer)
972 {
973     Buffer *authToken = nullptr;
974     Buffer *rootSecret = nullptr;
975     int32_t ret = AddCredentialFunc(userId, scheduleResultBuffer, &info.credentialId, &rootSecret, &authToken);
976     if (ret == RESULT_SUCCESS) {
977         /* Only enroll pin have authToken and rootSecret */
978         if (authToken != nullptr) {
979             info.authToken.resize(authToken->contentSize);
980             if (memcpy_s(info.authToken.data(), info.authToken.size(), authToken->buf, authToken->contentSize) != EOK) {
981                 IAM_LOGE("failed to copy authToken");
982                 info.authToken.clear();
983                 DestoryBuffer(authToken);
984                 DestoryBuffer(rootSecret);
985                 return RESULT_BAD_COPY;
986             }
987         }
988         if (rootSecret != nullptr) {
989             info.rootSecret.resize(rootSecret->contentSize);
990             if (memcpy_s(info.rootSecret.data(), info.rootSecret.size(), rootSecret->buf,
991                 rootSecret->contentSize) != EOK) {
992                 IAM_LOGE("failed to copy rootSecret");
993                 info.rootSecret.clear();
994                 ret = RESULT_BAD_COPY;
995             }
996         }
997     }
998     DestoryBuffer(authToken);
999     DestoryBuffer(rootSecret);
1000     return ret;
1001 }
1002 
UpdateEnrollmentResult(int32_t userId,const std::vector<uint8_t> & scheduleResult,HdiEnrollResultInfo & info)1003 int32_t UserAuthInterfaceService::UpdateEnrollmentResult(int32_t userId, const std::vector<uint8_t> &scheduleResult,
1004     HdiEnrollResultInfo &info)
1005 {
1006     IAM_LOGI("start");
1007     if (scheduleResult.size() == 0) {
1008         IAM_LOGE("enrollToken is invalid");
1009         return RESULT_BAD_PARAM;
1010     }
1011     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
1012     if (scheduleResultBuffer == nullptr) {
1013         IAM_LOGE("scheduleTokenBuffer is null");
1014         return RESULT_NO_MEMORY;
1015     }
1016     std::lock_guard<std::mutex> lock(g_mutex);
1017     bool isUpdate;
1018     int32_t ret = GetIsUpdate(&isUpdate);
1019     if (ret != RESULT_SUCCESS) {
1020         IAM_LOGE("get isUpdate failed");
1021         DestoryBuffer(scheduleResultBuffer);
1022         return ret;
1023     }
1024     if (isUpdate) {
1025         ret = GetUpdateResult(userId, info, scheduleResultBuffer);
1026         if (ret != RESULT_SUCCESS) {
1027             IAM_LOGE("GetUpdateResult failed");
1028         }
1029     } else {
1030         ret = GetEnrollResult(userId, info, scheduleResultBuffer);
1031         if (ret != RESULT_SUCCESS) {
1032             IAM_LOGE("GetEnrollResult failed");
1033         }
1034     }
1035 
1036     DestoryBuffer(scheduleResultBuffer);
1037     return ret;
1038 }
1039 
DeleteCredential(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,CredentialInfo & info)1040 int32_t UserAuthInterfaceService::DeleteCredential(int32_t userId, uint64_t credentialId,
1041     const std::vector<uint8_t> &authToken, CredentialInfo &info)
1042 {
1043     IAM_LOGI("start");
1044     if (authToken.size() != sizeof(UserAuthTokenHal)) {
1045         IAM_LOGE("authToken len is invalid");
1046         return RESULT_BAD_PARAM;
1047     }
1048     std::lock_guard<std::mutex> lock(g_mutex);
1049     CredentialDeleteParam param = {};
1050     if (memcpy_s(param.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
1051         IAM_LOGE("param token copy failed");
1052         return RESULT_BAD_COPY;
1053     }
1054     param.userId = userId;
1055     param.credentialId = credentialId;
1056     CredentialInfoHal credentialInfoHal = {};
1057     int32_t ret = DeleteCredentialFunc(param, &credentialInfoHal);
1058     if (ret != RESULT_SUCCESS) {
1059         IAM_LOGE("delete credential failed");
1060         return ret;
1061     }
1062     CopyCredentialInfo(credentialInfoHal, info);
1063     return RESULT_SUCCESS;
1064 }
1065 
GetCredential(int32_t userId,int32_t authType,std::vector<CredentialInfo> & infos)1066 int32_t UserAuthInterfaceService::GetCredential(int32_t userId, int32_t authType, std::vector<CredentialInfo> &infos)
1067 {
1068     IAM_LOGI("start");
1069     std::lock_guard<std::mutex> lock(g_mutex);
1070     LinkedList *credList = nullptr;
1071     int32_t ret = QueryCredentialFunc(userId, authType, &credList);
1072     if (ret != RESULT_SUCCESS) {
1073         IAM_LOGE("query credential failed");
1074         return ret;
1075     }
1076     infos.reserve(credList->getSize(credList));
1077     LinkedListNode *temp = credList->head;
1078     while (temp != nullptr) {
1079         if (temp->data == nullptr) {
1080             IAM_LOGE("list node is invalid");
1081             DestroyLinkedList(credList);
1082             return RESULT_UNKNOWN;
1083         }
1084         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
1085         CredentialInfo credentialInfo = {};
1086         CopyCredentialInfo(*credentialHal, credentialInfo);
1087         infos.push_back(credentialInfo);
1088         temp = temp->next;
1089     }
1090     DestroyLinkedList(credList);
1091     return RESULT_SUCCESS;
1092 }
1093 
GetUserInfo(int32_t userId,uint64_t & secureUid,int32_t & pinSubType,std::vector<EnrolledInfo> & infos)1094 int32_t UserAuthInterfaceService::GetUserInfo(int32_t userId, uint64_t &secureUid, int32_t &pinSubType,
1095     std::vector<EnrolledInfo> &infos)
1096 {
1097     IAM_LOGI("start");
1098     std::lock_guard<std::mutex> lock(g_mutex);
1099     EnrolledInfoHal *enrolledInfoHals = nullptr;
1100     uint32_t num = 0;
1101     uint64_t pinSubTypeGet;
1102     int32_t ret = GetUserInfoFunc(userId, &secureUid, &pinSubTypeGet, &enrolledInfoHals, &num);
1103     if (ret != RESULT_SUCCESS) {
1104         IAM_LOGE("get user info failed");
1105         return ret;
1106     }
1107     pinSubType = static_cast<PinSubType>(pinSubTypeGet);
1108     for (uint32_t i = 0; i < num; ++i) {
1109         EnrolledInfo enrolledInfo = {};
1110         enrolledInfo.authType = static_cast<AuthType>(enrolledInfoHals[i].authType);
1111         enrolledInfo.enrolledId = enrolledInfoHals[i].enrolledId;
1112         infos.push_back(enrolledInfo);
1113     }
1114     free(enrolledInfoHals);
1115     return RESULT_SUCCESS;
1116 }
1117 
DeleteUser(int32_t userId,const std::vector<uint8_t> & authToken,std::vector<CredentialInfo> & deletedInfos,std::vector<uint8_t> & rootSecret)1118 int32_t UserAuthInterfaceService::DeleteUser(int32_t userId, const std::vector<uint8_t> &authToken,
1119     std::vector<CredentialInfo> &deletedInfos, std::vector<uint8_t> &rootSecret)
1120 {
1121     IAM_LOGI("start");
1122     if (authToken.size() != sizeof(UserAuthTokenHal)) {
1123         IAM_LOGE("authToken is invalid");
1124         return RESULT_BAD_PARAM;
1125     }
1126     UserAuthTokenHal authTokenStruct = {};
1127     if (memcpy_s(&authTokenStruct, sizeof(UserAuthTokenHal), &authToken[0], authToken.size()) != EOK) {
1128         IAM_LOGE("authTokenStruct copy failed");
1129         return RESULT_BAD_COPY;
1130     }
1131     int32_t ret = CheckIdmOperationToken(userId, &authTokenStruct);
1132     if (ret != RESULT_SUCCESS) {
1133         IAM_LOGE("failed to verify token");
1134         return RESULT_VERIFY_TOKEN_FAIL;
1135     }
1136     ret = EnforceDeleteUser(userId, deletedInfos);
1137     if (ret != RESULT_SUCCESS) {
1138         IAM_LOGE("oldRootSecret is invalid");
1139         return RESULT_GENERAL_ERROR;
1140     }
1141 
1142     rootSecret.resize(ROOT_SECRET_LEN);
1143     Buffer *oldRootSecret = GetCacheRootSecret(userId);
1144     if (!IsBufferValid(oldRootSecret)) {
1145         IAM_LOGE("get GetCacheRootSecret failed");
1146         return RESULT_SUCCESS;
1147     }
1148     if (memcpy_s(rootSecret.data(), rootSecret.size(), oldRootSecret->buf, oldRootSecret->contentSize) != EOK) {
1149         IAM_LOGE("rootSecret copy failed");
1150         ret = RESULT_BAD_COPY;
1151     }
1152 
1153     DestoryBuffer(oldRootSecret);
1154     return ret;
1155 }
1156 
EnforceDeleteUser(int32_t userId,std::vector<CredentialInfo> & deletedInfos)1157 int32_t UserAuthInterfaceService::EnforceDeleteUser(int32_t userId, std::vector<CredentialInfo> &deletedInfos)
1158 {
1159     IAM_LOGI("start");
1160     std::lock_guard<std::mutex> lock(g_mutex);
1161     LinkedList *credList = nullptr;
1162     int32_t ret = DeleteUserInfo(userId, &credList);
1163     if (ret != RESULT_SUCCESS) {
1164         IAM_LOGE("query credential failed");
1165         return ret;
1166     }
1167     RefreshValidTokenTime();
1168     LinkedListNode *temp = credList->head;
1169     while (temp != nullptr) {
1170         if (temp->data == nullptr) {
1171             IAM_LOGE("list node is invalid");
1172             DestroyLinkedList(credList);
1173             return RESULT_UNKNOWN;
1174         }
1175         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
1176         CredentialInfo credentialInfo = {};
1177         CopyCredentialInfo(*credentialHal, credentialInfo);
1178         deletedInfos.push_back(credentialInfo);
1179         temp = temp->next;
1180     }
1181     DestroyLinkedList(credList);
1182     return RESULT_SUCCESS;
1183 }
1184 
verifyExecutorRegisterInfo(const HdiExecutorRegisterInfo & in,ExecutorInfoHal & out)1185 static bool verifyExecutorRegisterInfo(const HdiExecutorRegisterInfo &in, ExecutorInfoHal &out)
1186 {
1187     Buffer *execInfoMsg = CreateBufferByData(&in.signedRemoteExecutorInfo[0], in.signedRemoteExecutorInfo.size());
1188     if (!IsBufferValid(execInfoMsg)) {
1189         IAM_LOGE("execInfoMsg is invalid");
1190         return false;
1191     }
1192 
1193     bool isOk = CheckRemoteExecutorInfo(execInfoMsg, &out);
1194     DestoryBuffer(execInfoMsg);
1195     return isOk;
1196 }
1197 
CopyExecutorInfo(const HdiExecutorRegisterInfo & in,ExecutorInfoHal & out)1198 static bool CopyExecutorInfo(const HdiExecutorRegisterInfo &in, ExecutorInfoHal &out)
1199 {
1200     out.authType = in.authType;
1201     out.executorMatcher = in.executorMatcher;
1202     out.esl = in.esl;
1203     out.maxTemplateAcl = in.maxTemplateAcl;
1204     out.executorRole = in.executorRole;
1205     out.executorSensorHint = in.executorSensorHint;
1206     if (memcpy_s(out.pubKey, PUBLIC_KEY_LEN, &in.publicKey[0], in.publicKey.size()) != EOK) {
1207         IAM_LOGE("memcpy failed");
1208         return false;
1209     }
1210 
1211     std::string deviceUdid = in.deviceUdid;
1212     if (deviceUdid.empty()) {
1213         deviceUdid = g_localUdid;
1214     }
1215 
1216     if (memcpy_s(out.deviceUdid, sizeof(out.deviceUdid), deviceUdid.c_str(), deviceUdid.length()) != EOK) {
1217         IAM_LOGE("memcpy failed");
1218         return false;
1219     }
1220 
1221     if (g_localUdid != deviceUdid) {
1222         IAM_LOGI("verify remote executor register info");
1223         if (!verifyExecutorRegisterInfo(in, out)) {
1224             IAM_LOGE("verifyExecutorRegisterInfo failed");
1225             return false;
1226         }
1227         IAM_LOGI("add remote executor authType %{public}d executorRole %{public}d", in.authType, in.executorRole);
1228     } else {
1229         IAM_LOGI("add local executor authType %{public}d executorRole %{public}d", in.authType, in.executorRole);
1230     }
1231     return true;
1232 }
1233 
ObtainReconciliationData(uint32_t authType,uint32_t sensorHint,std::vector<uint64_t> & templateIds)1234 static int32_t ObtainReconciliationData(uint32_t authType, uint32_t sensorHint, std::vector<uint64_t> &templateIds)
1235 {
1236     CredentialCondition condition = {};
1237     SetCredentialConditionAuthType(&condition, authType);
1238     SetCredentialConditionExecutorSensorHint(&condition, sensorHint);
1239     SetCredentiaConditionNeedCachePin(&condition);
1240     LinkedList *credList = QueryCredentialLimit(&condition);
1241     if (credList == nullptr) {
1242         IAM_LOGE("query credential failed");
1243         return RESULT_NOT_FOUND;
1244     }
1245     LinkedListNode *temp = credList->head;
1246     while (temp != nullptr) {
1247         if (temp->data == nullptr) {
1248             IAM_LOGE("list node is invalid");
1249             DestroyLinkedList(credList);
1250             return RESULT_UNKNOWN;
1251         }
1252         auto credentialInfo = static_cast<CredentialInfoHal *>(temp->data);
1253         templateIds.push_back(credentialInfo->templateId);
1254         temp = temp->next;
1255     }
1256     DestroyLinkedList(credList);
1257     return RESULT_SUCCESS;
1258 }
1259 
AddExecutor(const HdiExecutorRegisterInfo & info,uint64_t & index,std::vector<uint8_t> & publicKey,std::vector<uint64_t> & templateIds)1260 int32_t UserAuthInterfaceService::AddExecutor(const HdiExecutorRegisterInfo &info, uint64_t &index,
1261     std::vector<uint8_t> &publicKey, std::vector<uint64_t> &templateIds)
1262 {
1263     IAM_LOGI("start");
1264     if (info.publicKey.size() != PUBLIC_KEY_LEN) {
1265         IAM_LOGE("invalid info");
1266         return RESULT_BAD_PARAM;
1267     }
1268     templateIds.clear();
1269     const Buffer *frameworkPubKey = GetPubKey();
1270     if (!IsBufferValid(frameworkPubKey)) {
1271         IAM_LOGE("get public key failed");
1272         return RESULT_UNKNOWN;
1273     }
1274     publicKey.resize(PUBLIC_KEY_LEN);
1275     if (memcpy_s(&publicKey[0], publicKey.size(), frameworkPubKey->buf, frameworkPubKey->contentSize) != EOK) {
1276         IAM_LOGE("copy public key failed");
1277         publicKey.clear();
1278         return RESULT_UNKNOWN;
1279     }
1280     std::lock_guard<std::mutex> lock(g_mutex);
1281     ExecutorInfoHal executorInfoHal = {};
1282     bool copyRet = CopyExecutorInfo(info, executorInfoHal);
1283     if (!copyRet) {
1284         IAM_LOGE("copy executor info failed");
1285         return RESULT_UNKNOWN;
1286     }
1287     int32_t ret = RegisterExecutor(&executorInfoHal, &index);
1288     if (ret != RESULT_SUCCESS) {
1289         IAM_LOGE("register executor failed");
1290         return ret;
1291     }
1292     if (info.executorRole == ALL_IN_ONE) {
1293         return ObtainReconciliationData(executorInfoHal.authType, executorInfoHal.executorSensorHint, templateIds);
1294     }
1295     return RESULT_SUCCESS;
1296 }
1297 
DeleteExecutor(uint64_t index)1298 int32_t UserAuthInterfaceService::DeleteExecutor(uint64_t index)
1299 {
1300     IAM_LOGI("start");
1301     std::lock_guard<std::mutex> lock(g_mutex);
1302     return UnRegisterExecutor(index);
1303 }
1304 
GetAllExtUserInfo(std::vector<ExtUserInfo> & userInfos)1305 int32_t UserAuthInterfaceService::GetAllExtUserInfo(std::vector<ExtUserInfo> &userInfos)
1306 {
1307     IAM_LOGI("start");
1308     UserInfoResult *userInfoResult = (UserInfoResult *)Malloc(sizeof(UserInfoResult) * MAX_USER);
1309     if (userInfoResult == NULL) {
1310         IAM_LOGE("malloc failed");
1311         return RESULT_GENERAL_ERROR;
1312     }
1313     uint32_t userInfoCount = 0;
1314     ResultCode ret = QueryAllExtUserInfoFunc(userInfoResult, MAX_USER, &userInfoCount);
1315     if (ret != RESULT_SUCCESS) {
1316         Free(userInfoResult);
1317         IAM_LOGE("QueryAllExtUserInfoFunc failed");
1318         return RESULT_GENERAL_ERROR;
1319     }
1320 
1321     for (uint32_t i = 0; i < userInfoCount; i++) {
1322         ExtUserInfo info = {};
1323         info.userId = userInfoResult[i].userId;
1324         info.userInfo.secureUid = userInfoResult[i].secUid;
1325         info.userInfo.pinSubType = static_cast<PinSubType>(userInfoResult[i].pinSubType);
1326         for (uint32_t j = 0; j < userInfoResult[i].enrollNum; j++) {
1327             EnrolledInfo enrolledInfo = {};
1328             enrolledInfo.authType = static_cast<AuthType>(userInfoResult[i].enrolledInfo[j].authType);
1329             enrolledInfo.enrolledId = userInfoResult[i].enrolledInfo[j].enrolledId;
1330             info.userInfo.enrolledInfos.push_back(enrolledInfo);
1331         }
1332         userInfos.push_back(info);
1333     }
1334 
1335     Free(userInfoResult);
1336     return RESULT_SUCCESS;
1337 }
1338 
GetEnrolledState(int32_t userId,int32_t authType,HdiEnrolledState & enrolledState)1339 int32_t UserAuthInterfaceService::GetEnrolledState(int32_t userId, int32_t authType, HdiEnrolledState &enrolledState)
1340 {
1341     IAM_LOGI("start");
1342     EnrolledStateHal *enrolledStateHal = (EnrolledStateHal *) Malloc(sizeof(EnrolledStateHal));
1343     if (enrolledStateHal == NULL) {
1344         IAM_LOGE("malloc failed");
1345         return RESULT_GENERAL_ERROR;
1346     }
1347     int32_t ret = GetEnrolledStateFunc(userId, authType, enrolledStateHal);
1348     if (ret != RESULT_SUCCESS) {
1349         Free(enrolledStateHal);
1350         IAM_LOGE("GetEnrolledState failed");
1351         return ret;
1352     }
1353     enrolledState.credentialDigest = enrolledStateHal->credentialDigest;
1354     enrolledState.credentialCount = enrolledStateHal->credentialCount;
1355 
1356     Free(enrolledStateHal);
1357     return RESULT_SUCCESS;
1358 }
1359 
CheckReuseUnlockResult(const ReuseUnlockParam & param,ReuseUnlockInfo & info)1360 int32_t UserAuthInterfaceService::CheckReuseUnlockResult(const ReuseUnlockParam& param,
1361     ReuseUnlockInfo& info)
1362 {
1363     IAM_LOGI("start reuseMode: %{public}u, reuseDuration: %{public}" PRIu64 ".", param.reuseUnlockResultMode,
1364         param.reuseUnlockResultDuration);
1365     if (param.authTypes.empty() || param.authTypes.size() > MAX_AUTH_TYPE_LEN ||
1366         param.reuseUnlockResultDuration == 0 || param.reuseUnlockResultDuration > REUSED_UNLOCK_TOKEN_PERIOD ||
1367         (param.reuseUnlockResultMode != AUTH_TYPE_RELEVANT && param.reuseUnlockResultMode != AUTH_TYPE_IRRELEVANT &&
1368         param.reuseUnlockResultMode != CALLER_IRRELEVANT_AUTH_TYPE_RELEVANT &&
1369         param.reuseUnlockResultMode != CALLER_IRRELEVANT_AUTH_TYPE_IRRELEVANT)) {
1370         IAM_LOGE("checkReuseUnlockResult bad param");
1371         return RESULT_BAD_PARAM;
1372     }
1373     ReuseUnlockParamHal paramHal = {};
1374     paramHal.userId = param.baseParam.userId;
1375     paramHal.authTrustLevel = param.baseParam.authTrustLevel;
1376     paramHal.reuseUnlockResultDuration = param.reuseUnlockResultDuration;
1377     paramHal.reuseUnlockResultMode = param.reuseUnlockResultMode;
1378     if (!param.baseParam.challenge.empty() &&
1379         memcpy_s(paramHal.challenge, CHALLENGE_LEN,
1380             param.baseParam.challenge.data(), param.baseParam.challenge.size()) != EOK) {
1381         IAM_LOGE("challenge copy failed");
1382         return RESULT_BAD_COPY;
1383     }
1384     paramHal.authTypeSize = param.authTypes.size();
1385     for (uint32_t i = 0; i < param.authTypes.size(); i++) {
1386         paramHal.authTypes[i] = static_cast<uint32_t>(param.authTypes[i]);
1387     }
1388     ReuseUnlockResult reuseResult = {};
1389     int32_t ret = CheckReuseUnlockResultFunc(&paramHal, &reuseResult);
1390     if (ret != RESULT_SUCCESS) {
1391         info.token.clear();
1392         IAM_LOGE("check reuse unlock result failed, ret:%{public}d", ret);
1393         return ret;
1394     }
1395     info.authType = reuseResult.authType;
1396     info.enrolledState.credentialDigest = reuseResult.enrolledState.credentialDigest;
1397     info.enrolledState.credentialCount = reuseResult.enrolledState.credentialCount;
1398     info.token.resize(AUTH_TOKEN_LEN);
1399     if (memcpy_s(info.token.data(), info.token.size(), reuseResult.token, AUTH_TOKEN_LEN) != EOK) {
1400         IAM_LOGE("copy authToken failed");
1401         info.token.clear();
1402         return RESULT_BAD_COPY;
1403     }
1404     IAM_LOGI("check reuse unlock result finish success");
1405     return RESULT_SUCCESS;
1406 }
1407 
SendMessage(uint64_t scheduleId,int32_t srcRole,const std::vector<uint8_t> & msg)1408 int32_t UserAuthInterfaceService::SendMessage(uint64_t scheduleId, int32_t srcRole, const std::vector<uint8_t>& msg)
1409 {
1410     static_cast<void>(scheduleId);
1411     static_cast<void>(srcRole);
1412     static_cast<void>(msg);
1413     return HDF_SUCCESS;
1414 }
1415 
RegisterMessageCallback(const sptr<IMessageCallback> & messageCallback)1416 int32_t UserAuthInterfaceService::RegisterMessageCallback(const sptr<IMessageCallback>& messageCallback)
1417 {
1418     static_cast<void>(messageCallback);
1419     return HDF_SUCCESS;
1420 }
1421 
PrepareRemoteAuth(const std::string & remoteUdid)1422 int32_t UserAuthInterfaceService::PrepareRemoteAuth(const std::string &remoteUdid)
1423 {
1424     IAM_LOGI("PrepareRemoteAuth");
1425     return RESULT_SUCCESS;
1426 }
1427 
CopyHdiScheduleInfo(const ScheduleInfoParam * in,HdiScheduleInfo * out)1428 static bool CopyHdiScheduleInfo(const ScheduleInfoParam *in, HdiScheduleInfo *out)
1429 {
1430     IAM_LOGI("CopyHdiScheduleInfo start");
1431     out->executorIndexes.clear();
1432     out->templateIds.clear();
1433     out->executorMessages.clear();
1434     out->scheduleId = in->scheduleId;
1435     out->authType = static_cast<AuthType>(in->authType);
1436     out->executorMatcher = static_cast<uint32_t>(in->executorMatcher);
1437     out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
1438     out->executorIndexes.push_back(in->executorIndex);
1439     out->executorMessages.resize(1);
1440     out->executorMessages[0].resize(in->executorMessages->contentSize);
1441     if (memcpy_s(out->executorMessages[0].data(), out->executorMessages[0].size(),
1442         in->executorMessages->buf, in->executorMessages->contentSize) != EOK) {
1443         IAM_LOGE("copy executorMessages failed");
1444         out->executorMessages.clear();
1445         out->executorIndexes.clear();
1446         return false;
1447     }
1448     return true;
1449 }
1450 
DestroyScheduleInfoParam(ScheduleInfoParam * result)1451 static void DestroyScheduleInfoParam(ScheduleInfoParam *result)
1452 {
1453     if (result == NULL) {
1454         return;
1455     }
1456     if (result->executorMessages != NULL) {
1457         DestoryBuffer(result->executorMessages);
1458     }
1459     Free(result);
1460 }
1461 
GetLocalScheduleFromMessage(const std::string & remoteUdid,const std::vector<uint8_t> & message,HdiScheduleInfo & scheduleInfo)1462 int32_t UserAuthInterfaceService::GetLocalScheduleFromMessage(const std::string &remoteUdid,
1463     const std::vector<uint8_t> &message, HdiScheduleInfo& scheduleInfo)
1464 {
1465     IAM_LOGI("GetLocalScheduleFromMessage start");
1466     if ((g_localUdid.empty()) || (remoteUdid.empty()) || (message.size() == 0)) {
1467         IAM_LOGE("param is invalid");
1468         return RESULT_BAD_PARAM;
1469     }
1470     Buffer *messageBuffer = CreateBufferByData(&message[0], message.size());
1471     if (!IsBufferValid(messageBuffer)) {
1472         IAM_LOGE("messageBuffer is invalid");
1473         return RESULT_NO_MEMORY;
1474     }
1475     std::lock_guard<std::mutex> lock(g_mutex);
1476     ScheduleInfoParam *scheduleParam = (ScheduleInfoParam *)Malloc(sizeof(ScheduleInfoParam));
1477     if (scheduleParam == NULL) {
1478         IAM_LOGE("schedule is null");
1479         DestoryBuffer(messageBuffer);
1480         return RESULT_GENERAL_ERROR;
1481     }
1482 
1483     int32_t funcRet = RESULT_GENERAL_ERROR;
1484     int32_t ret = RESULT_GENERAL_ERROR;
1485     Uint8Array remoteUdidArray = {};
1486     if (memcpy_s(scheduleParam->localUdid, sizeof(scheduleParam->localUdid), g_localUdid.c_str(),
1487         g_localUdid.length()) != EOK) {
1488         IAM_LOGE("localUdid copy failed");
1489         goto FAIL;
1490     }
1491 
1492     if (memcpy_s(scheduleParam->remoteUdid, sizeof(scheduleParam->remoteUdid), remoteUdid.c_str(),
1493         remoteUdid.length()) != EOK) {
1494         IAM_LOGE("remoteUdid copy failed");
1495         goto FAIL;
1496     }
1497 
1498     remoteUdidArray = { scheduleParam->remoteUdid, sizeof(scheduleParam->remoteUdid) };
1499 
1500     ret = GenerateScheduleFunc(messageBuffer, remoteUdidArray, scheduleParam);
1501     if (ret != RESULT_SUCCESS) {
1502         IAM_LOGE("GenerateScheduleFunc failed");
1503         goto FAIL;
1504     }
1505     if (!CopyHdiScheduleInfo(scheduleParam, &scheduleInfo)) {
1506         IAM_LOGE("copy schedule info failed");
1507         goto FAIL;
1508     }
1509 
1510     funcRet = RESULT_SUCCESS;
1511 FAIL:
1512     DestoryBuffer(messageBuffer);
1513     DestroyScheduleInfoParam(scheduleParam);
1514     return funcRet;
1515 }
1516 
DestroyExecutorInfo(void * data)1517 static void DestroyExecutorInfo(void *data)
1518 {
1519     if (data == nullptr) {
1520         IAM_LOGE("data is null");
1521         return;
1522     }
1523     Free(data);
1524 }
1525 
GetSignedExecutorInfo(const std::vector<int32_t> & authTypes,int32_t executorRole,const std::string & remoteUdid,std::vector<uint8_t> & signedExecutorInfo)1526 int32_t UserAuthInterfaceService::GetSignedExecutorInfo(const std::vector<int32_t>& authTypes, int32_t executorRole,
1527     const std::string& remoteUdid, std::vector<uint8_t>& signedExecutorInfo)
1528 {
1529     IAM_LOGI("GetSignedExecutorInfo start");
1530     if ((g_localUdid.empty()) || (remoteUdid.empty()) || (authTypes.size() == 0)) {
1531         IAM_LOGE("param is invalid");
1532         return RESULT_BAD_PARAM;
1533     }
1534     ResultCode result = RESULT_GENERAL_ERROR;
1535     LinkedList *linkedList = CreateLinkedList(DestroyExecutorInfo);
1536     if (linkedList == NULL) {
1537         IAM_LOGE("create linkedList failed");
1538         return result;
1539     }
1540     std::lock_guard<std::mutex> lock(g_mutex);
1541     for (uint32_t i = 0; i < authTypes.size(); i++) {
1542         result = GetExecutorInfoLinkedList(authTypes[i], executorRole, linkedList);
1543         if (result != RESULT_SUCCESS) {
1544             IAM_LOGE("GetExecutorInfo failed");
1545             DestroyLinkedList(linkedList);
1546             return result;
1547         }
1548     }
1549     uint8_t remoteUdidData[UDID_LEN] = {};
1550     if (memcpy_s(remoteUdidData, UDID_LEN, remoteUdid.c_str(), remoteUdid.length()) != EOK) {
1551         IAM_LOGE("remoteUdidData copy failed");
1552         DestroyLinkedList(linkedList);
1553         return RESULT_BAD_COPY;
1554     }
1555 
1556     Uint8Array remoteUdidArray = { remoteUdidData, sizeof(remoteUdidData) };
1557     Buffer *signInfo = GetSignExecutorInfoFunc(remoteUdidArray, linkedList);
1558     if (!IsBufferValid(signInfo)) {
1559         IAM_LOGE("signInfo is invalid");
1560         DestroyLinkedList(linkedList);
1561         return RESULT_NO_MEMORY;
1562     }
1563     signedExecutorInfo.resize(signInfo->contentSize);
1564     if (memcpy_s(&signedExecutorInfo[0], signedExecutorInfo.size(), signInfo->buf, signInfo->contentSize) != EOK) {
1565         IAM_LOGE("sign copy failed");
1566         result = RESULT_BAD_COPY;
1567     }
1568     DestoryBuffer(signInfo);
1569     DestroyLinkedList(linkedList);
1570     return result;
1571 }
1572 
CopyHdiAuthResultInfo(const AuthResultParam * in,HdiAuthResultInfo * out,const std::vector<uint8_t> & message)1573 static bool CopyHdiAuthResultInfo(const AuthResultParam *in, HdiAuthResultInfo *out,
1574     const std::vector<uint8_t>& message)
1575 {
1576     IAM_LOGI("CopyHdiAuthResultInfo start");
1577     out->token.clear();
1578     out->rootSecret.clear();
1579     out->remoteAuthResultMsg.clear();
1580     out->result = in->result;
1581     out->lockoutDuration = in->lockoutDuration;
1582     out->remainAttempts = in->remainAttempts;
1583     out->userId = in->userId;
1584 
1585     out->token.resize(in->token->contentSize);
1586     if (memcpy_s(out->token.data(), out->token.size(), in->token->buf, in->token->contentSize) != EOK) {
1587         IAM_LOGE("copy token failed");
1588         return false;
1589     }
1590 
1591     out->remoteAuthResultMsg.resize(message.size());
1592     if (memcpy_s(out->remoteAuthResultMsg.data(), out->remoteAuthResultMsg.size(),
1593         message.data(), message.size()) != EOK) {
1594         IAM_LOGE("copy remoteAuthResultMsg failed");
1595         return false;
1596     }
1597     return true;
1598 }
1599 
DestroyAuthResultParam(AuthResultParam * result)1600 static void DestroyAuthResultParam(AuthResultParam *result)
1601 {
1602     if (result == NULL) {
1603         return;
1604     }
1605     if (result->token != NULL) {
1606         DestoryBuffer(result->token);
1607     }
1608     if (result->remoteAuthResultMsg != NULL) {
1609         DestoryBuffer(result->remoteAuthResultMsg);
1610     }
1611     Free(result);
1612 }
1613 
GetAuthResultFromMessage(const std::string & remoteUdid,const std::vector<uint8_t> & message,HdiAuthResultInfo & authResultInfo)1614 int32_t UserAuthInterfaceService::GetAuthResultFromMessage(const std::string& remoteUdid,
1615     const std::vector<uint8_t>& message, HdiAuthResultInfo& authResultInfo)
1616 {
1617     IAM_LOGI("GetAuthResultFromMessage start");
1618     if ((g_localUdid.empty()) || (remoteUdid.empty()) || (message.size() == 0)) {
1619         IAM_LOGE("param is invalid");
1620         return RESULT_BAD_PARAM;
1621     }
1622     Buffer *messageBuffer = CreateBufferByData(&message[0], message.size());
1623     if (!IsBufferValid(messageBuffer)) {
1624         IAM_LOGE("messageBuffer is invalid");
1625         return RESULT_NO_MEMORY;
1626     }
1627     std::lock_guard<std::mutex> lock(g_mutex);
1628     AuthResultParam *authResultParam = (AuthResultParam *)Malloc(sizeof(AuthResultParam));
1629     if (authResultParam == NULL) {
1630         IAM_LOGE("authResultParam is null");
1631         DestoryBuffer(messageBuffer);
1632         return RESULT_GENERAL_ERROR;
1633     }
1634 
1635     int32_t funcRet = RESULT_GENERAL_ERROR;
1636     int32_t ret = RESULT_GENERAL_ERROR;
1637     if (memcpy_s(authResultParam->localUdid, sizeof(authResultParam->localUdid), g_localUdid.c_str(),
1638         g_localUdid.length()) != EOK) {
1639         IAM_LOGE("localUdid copy failed");
1640         goto FAIL;
1641     }
1642 
1643     if (memcpy_s(authResultParam->remoteUdid, sizeof(authResultParam->remoteUdid), remoteUdid.c_str(),
1644         remoteUdid.length()) != EOK) {
1645         IAM_LOGE("remoteUdid copy failed");
1646         goto FAIL;
1647     }
1648 
1649     ret = GenerateAuthResultFunc(messageBuffer, authResultParam);
1650     if (ret != RESULT_SUCCESS) {
1651         IAM_LOGE("GenerateAuthResultFunc failed");
1652         goto FAIL;
1653     }
1654     if (!CopyHdiAuthResultInfo(authResultParam, &authResultInfo, message)) {
1655         IAM_LOGE("copy authResult info failed");
1656         goto FAIL;
1657     }
1658     ret = CreateExecutorCommand(authResultInfo.userId, authResultInfo);
1659     if (ret != RESULT_SUCCESS) {
1660         IAM_LOGE("CreateExecutorCommand failed");
1661         goto FAIL;
1662     }
1663 
1664     funcRet = RESULT_SUCCESS;
1665 FAIL:
1666     DestoryBuffer(messageBuffer);
1667     DestroyAuthResultParam(authResultParam);
1668     return ret;
1669 }
1670 
SetGlobalConfigParam(const HdiGlobalConfigParam & param)1671 int32_t UserAuthInterfaceService::SetGlobalConfigParam(const HdiGlobalConfigParam &param)
1672 {
1673     IAM_LOGI("start");
1674     if (param.type != PIN_EXPIRED_PERIOD) {
1675         IAM_LOGE("bad global config type");
1676         return RESULT_BAD_PARAM;
1677     }
1678     GlobalConfigParamHal paramHal = {};
1679     paramHal.type = PIN_EXPIRED_PERIOD;
1680     paramHal.value.pinExpiredPeriod = NO_CHECK_PIN_EXPIRED_PERIOD;
1681     if (param.value.pinExpiredPeriod > 0) {
1682         paramHal.value.pinExpiredPeriod = param.value.pinExpiredPeriod;
1683     }
1684 
1685     uint32_t ret = SetGlobalConfigParamFunc(&paramHal);
1686     if (ret != RESULT_SUCCESS) {
1687         IAM_LOGE("SetGlobalConfigParamFunc failed");
1688     }
1689     return ret;
1690 }
1691 
GetCredentialById(uint64_t credentialId,HdiCredentialInfo & info)1692 int32_t UserAuthInterfaceService::GetCredentialById(uint64_t credentialId, HdiCredentialInfo &info)
1693 {
1694     IAM_LOGI("start");
1695     std::lock_guard<std::mutex> lock(g_mutex);
1696     LinkedList *credList = nullptr;
1697     int32_t ret = QueryCredentialByIdFunc(credentialId, &credList);
1698     if (ret != RESULT_SUCCESS || credList == NULL) {
1699         IAM_LOGE("query credential failed");
1700         return RESULT_GENERAL_ERROR;
1701     }
1702     if (credList->head == NULL || credList->head->data == NULL) {
1703         IAM_LOGE("credential is null");
1704         DestroyLinkedList(credList);
1705         return RESULT_NOT_ENROLLED;
1706     }
1707     auto credentialHal = static_cast<CredentialInfoHal *>(credList->head->data);
1708     CopyCredentialInfo(*credentialHal, info);
1709     DestroyLinkedList(credList);
1710     return RESULT_SUCCESS;
1711 }
1712 } // Userauth
1713 } // HDI
1714 } // OHOS