• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "v1_0/user_auth_interface_service.h"
17 
18 #include <mutex>
19 #include <hdf_base.h>
20 #include "securec.h"
21 
22 #include "iam_logger.h"
23 #include "iam_ptr.h"
24 
25 #include "useriam_common.h"
26 #include "auth_level.h"
27 #include "buffer.h"
28 #include "coauth_funcs.h"
29 #include "identify_funcs.h"
30 #include "idm_database.h"
31 #include "idm_session.h"
32 #include "ed25519_key.h"
33 #include "user_auth_funcs.h"
34 #include "user_idm_funcs.h"
35 #include "enroll_specification_check.h"
36 
37 #define LOG_LABEL OHOS::UserIam::Common::LABEL_USER_AUTH_HDI
38 
39 namespace OHOS {
40 namespace HDI {
41 namespace UserAuth {
42 namespace V1_0 {
43 namespace {
44 static std::mutex g_mutex;
45 }
46 
UserAuthInterfaceImplGetInstance(void)47 extern "C" IUserAuthInterface *UserAuthInterfaceImplGetInstance(void)
48 {
49     auto userAuthInterfaceService = new (std::nothrow) UserAuthInterfaceService();
50     if (userAuthInterfaceService == nullptr) {
51         IAM_LOGE("userAuthInterfaceService is nullptr");
52         return nullptr;
53     }
54     std::lock_guard<std::mutex> lock(g_mutex);
55     OHOS::UserIam::Common::Init();
56     return userAuthInterfaceService;
57 }
58 
Init()59 int32_t UserAuthInterfaceService::Init()
60 {
61     IAM_LOGI("start");
62     std::lock_guard<std::mutex> lock(g_mutex);
63     OHOS::UserIam::Common::Close();
64     return OHOS::UserIam::Common::Init();
65 }
66 
CopyScheduleInfo(const CoAuthSchedule * in,ScheduleInfo * out)67 static bool CopyScheduleInfo(const CoAuthSchedule *in, ScheduleInfo *out)
68 {
69     IAM_LOGI("start");
70     if (in->executorSize == 0) {
71         IAM_LOGE("executorSize is zero");
72         return false;
73     }
74     out->executors.clear();
75     out->templateIds.clear();
76     out->scheduleId = in->scheduleId;
77     out->authType = static_cast<AuthType>(in->authType);
78     for (uint32_t i = 0; i < in->templateIds.num; ++i) {
79         out->templateIds.push_back(in->templateIds.value[i]);
80     }
81     out->executorMatcher = static_cast<uint32_t>(in->executors[0].executorMatcher);
82     out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
83     for (uint32_t i = 0; i < in->executorSize; ++i) {
84         ExecutorInfo temp = {};
85         temp.executorIndex = in->executors[i].executorIndex;
86         temp.info.authType = static_cast<AuthType>(in->executors[i].authType);
87         temp.info.executorRole = static_cast<ExecutorRole>(in->executors[i].executorRole);
88         temp.info.executorSensorHint = in->executors[i].executorSensorHint;
89         temp.info.executorMatcher = static_cast<uint32_t>(in->executors[i].executorMatcher);
90         temp.info.esl = static_cast<ExecutorSecureLevel>(in->executors[i].esl);
91         temp.info.publicKey.resize(PUBLIC_KEY_LEN);
92         if (memcpy_s(&temp.info.publicKey[0], temp.info.publicKey.size(),
93             in->executors[i].pubKey, PUBLIC_KEY_LEN) != EOK) {
94             IAM_LOGE("copy failed");
95             out->executors.clear();
96             out->templateIds.clear();
97             return false;
98         }
99         out->executors.push_back(temp);
100     }
101     return true;
102 }
103 
BeginAuthentication(uint64_t contextId,const AuthSolution & param,std::vector<ScheduleInfo> & infos)104 int32_t UserAuthInterfaceService::BeginAuthentication(uint64_t contextId, const AuthSolution &param,
105     std::vector<ScheduleInfo> &infos)
106 {
107     IAM_LOGI("start");
108     infos.clear();
109     AuthSolutionHal solutionIn = {};
110     solutionIn.contextId = contextId;
111     solutionIn.userId = param.userId;
112     solutionIn.authType = static_cast<uint32_t>(param.authType);
113     solutionIn.authTrustLevel = param.authTrustLevel;
114     if (!param.challenge.empty() && memcpy_s(solutionIn.challenge, CHALLENGE_LEN, param.challenge.data(),
115         param.challenge.size()) != EOK) {
116         IAM_LOGE("challenge copy failed");
117         return RESULT_BAD_COPY;
118     }
119     std::lock_guard<std::mutex> lock(g_mutex);
120     LinkedList *schedulesGet = nullptr;
121     int32_t ret = GenerateSolutionFunc(solutionIn, &schedulesGet);
122     if (ret != RESULT_SUCCESS) {
123         IAM_LOGE("generate solution failed %{public}d", ret);
124         return ret;
125     }
126     if (schedulesGet == nullptr) {
127         IAM_LOGE("get null schedule");
128         return RESULT_GENERAL_ERROR;
129     }
130     LinkedListNode *tempNode = schedulesGet->head;
131     while (tempNode != nullptr) {
132         if (tempNode->data == nullptr) {
133             IAM_LOGE("node data is invalid");
134             DestroyLinkedList(schedulesGet);
135             return RESULT_UNKNOWN;
136         }
137         ScheduleInfo temp = {};
138         auto coAuthSchedule = static_cast<CoAuthSchedule *>(tempNode->data);
139         if (!CopyScheduleInfo(coAuthSchedule, &temp)) {
140             infos.clear();
141             ret = RESULT_GENERAL_ERROR;
142             break;
143         }
144         infos.push_back(temp);
145         tempNode = tempNode->next;
146     }
147     DestroyLinkedList(schedulesGet);
148     return ret;
149 }
150 
CreateExecutorCommand(AuthResultInfo & info)151 static int32_t CreateExecutorCommand(AuthResultInfo &info)
152 {
153     LinkedList *executorSendMsg = nullptr;
154     int32_t ret = RESULT_GENERAL_ERROR;
155     if (info.result == RESULT_SUCCESS) {
156         ret = GetExecutorMsgList(PROPERMODE_UNLOCK, &executorSendMsg);
157         if (ret != RESULT_SUCCESS) {
158             IAM_LOGE("get unlock msg failed");
159             return ret;
160         }
161     } else if (info.remainAttempts == 0) {
162         ret = GetExecutorMsgList(PROPERMODE_LOCK, &executorSendMsg);
163         if (ret != RESULT_SUCCESS) {
164             IAM_LOGE("get lock msg failed");
165             return ret;
166         }
167     } else {
168         return RESULT_SUCCESS;
169     }
170     LinkedListNode *temp = executorSendMsg->head;
171     while (temp != NULL) {
172         if (temp->data == NULL) {
173             IAM_LOGE("list node is invalid");
174             DestroyLinkedList(executorSendMsg);
175             return RESULT_UNKNOWN;
176         }
177         auto nodeData = static_cast<ExecutorMsg *>(temp->data);
178         Buffer *nodeMsgBuffer = nodeData->msg;
179         if (!IsBufferValid(nodeMsgBuffer)) {
180             IAM_LOGE("node's buffer invalid");
181             DestroyLinkedList(executorSendMsg);
182             return RESULT_UNKNOWN;
183         }
184         ExecutorSendMsg msg = {};
185         msg.executorIndex = nodeData->executorIndex;
186         msg.msg.resize(nodeMsgBuffer->contentSize);
187         if (memcpy_s(msg.msg.data(), msg.msg.size(), nodeMsgBuffer->buf, nodeMsgBuffer->contentSize) != EOK) {
188             IAM_LOGE("copy failed");
189             msg.msg.clear();
190             DestroyLinkedList(executorSendMsg);
191             return RESULT_BAD_COPY;
192         }
193         info.msgs.push_back(msg);
194         temp = temp->next;
195     }
196     DestroyLinkedList(executorSendMsg);
197     return RESULT_SUCCESS;
198 }
199 
UpdateAuthenticationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,AuthResultInfo & info)200 int32_t UserAuthInterfaceService::UpdateAuthenticationResult(uint64_t contextId,
201     const std::vector<uint8_t> &scheduleResult, AuthResultInfo &info)
202 {
203     IAM_LOGI("start");
204     if (scheduleResult.size() == 0) {
205         IAM_LOGE("param is invalid");
206         DestoryContextbyId(contextId);
207         return RESULT_BAD_PARAM;
208     }
209     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
210     if (!IsBufferValid(scheduleResultBuffer)) {
211         IAM_LOGE("scheduleTokenBuffer is invalid");
212         DestoryContextbyId(contextId);
213         return RESULT_NO_MEMORY;
214     }
215     std::lock_guard<std::mutex> lock(g_mutex);
216     UserAuthTokenHal authTokenHal = {};
217     AuthResult authResult = {};
218     int32_t ret = RequestAuthResultFunc(contextId, scheduleResultBuffer, &authTokenHal, &authResult);
219     DestoryBuffer(scheduleResultBuffer);
220     if (ret != RESULT_SUCCESS) {
221         IAM_LOGE("execute func failed");
222         return ret;
223     }
224     info.result = authResult.result;
225     info.remainAttempts = authResult.remainTimes;
226     info.lockoutDuration = authResult.freezingTime;
227     if (info.result == RESULT_SUCCESS) {
228         info.token.resize(sizeof(UserAuthTokenHal));
229         if (memcpy_s(info.token.data(), info.token.size(), &authTokenHal, sizeof(authTokenHal)) != EOK) {
230             IAM_LOGE("copy authToken failed");
231             info.token.clear();
232             return RESULT_BAD_COPY;
233         }
234         if (authResult.rootSecret != NULL) {
235             info.rootSecret.resize(authResult.rootSecret->contentSize);
236             if (memcpy_s(info.rootSecret.data(), info.rootSecret.size(),
237                 authResult.rootSecret->buf, authResult.rootSecret->contentSize) != EOK) {
238                 IAM_LOGE("copy secret failed");
239                 info.rootSecret.clear();
240                 info.token.clear();
241                 return RESULT_BAD_COPY;
242             }
243         }
244     }
245     DestoryBuffer(authResult.rootSecret);
246     if (authTokenHal.authType != PIN_AUTH) {
247         IAM_LOGI("type not pin");
248         return RESULT_SUCCESS;
249     }
250     IAM_LOGI("type pin");
251     return CreateExecutorCommand(info);
252 }
253 
CancelAuthentication(uint64_t contextId)254 int32_t UserAuthInterfaceService::CancelAuthentication(uint64_t contextId)
255 {
256     IAM_LOGI("start");
257     std::lock_guard<std::mutex> lock(g_mutex);
258     return DestoryContextbyId(contextId);
259 }
260 
BeginIdentification(uint64_t contextId,AuthType authType,const std::vector<uint8_t> & challenge,uint32_t executorSensorHint,ScheduleInfo & scheduleInfo)261 int32_t UserAuthInterfaceService::BeginIdentification(uint64_t contextId, AuthType authType,
262     const std::vector<uint8_t> &challenge, uint32_t executorSensorHint, ScheduleInfo &scheduleInfo)
263 {
264     IAM_LOGI("start");
265     if (authType == PIN) {
266         IAM_LOGE("param is invalid");
267         return RESULT_BAD_PARAM;
268     }
269     IdentifyParam param = {};
270     param.contextId = contextId;
271     param.authType = static_cast<uint32_t>(authType);
272     param.executorSensorHint = executorSensorHint;
273     if (!challenge.empty() && memcpy_s(param.challenge, CHALLENGE_LEN, challenge.data(), challenge.size()) != EOK) {
274         IAM_LOGE("challenge copy failed");
275         return RESULT_BAD_COPY;
276     }
277     std::lock_guard<std::mutex> lock(g_mutex);
278     LinkedList *scheduleGet = nullptr;
279     int32_t ret = DoIdentify(param, &scheduleGet);
280     if (ret != RESULT_SUCCESS) {
281         IAM_LOGE("generate solution failed");
282         return ret;
283     }
284     if (scheduleGet == nullptr) {
285         IAM_LOGE("get null schedule");
286         return RESULT_GENERAL_ERROR;
287     }
288     if (scheduleGet->head == nullptr || scheduleGet->head->data == nullptr) {
289         IAM_LOGE("scheduleGet is invalid");
290         DestroyLinkedList(scheduleGet);
291         return RESULT_UNKNOWN;
292     }
293     auto data = static_cast<CoAuthSchedule *>(scheduleGet->head->data);
294     if (!CopyScheduleInfo(data, &scheduleInfo)) {
295         IAM_LOGE("copy schedule failed");
296         ret = RESULT_BAD_COPY;
297     }
298     DestroyLinkedList(scheduleGet);
299     return ret;
300 }
301 
UpdateIdentificationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,IdentifyResultInfo & info)302 int32_t UserAuthInterfaceService::UpdateIdentificationResult(uint64_t contextId,
303     const std::vector<uint8_t> &scheduleResult, IdentifyResultInfo &info)
304 {
305     IAM_LOGI("start");
306     if (scheduleResult.size() == 0) {
307         IAM_LOGE("param is invalid");
308         return RESULT_BAD_PARAM;
309     }
310     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
311     if (!IsBufferValid(scheduleResultBuffer)) {
312         IAM_LOGE("scheduleTokenBuffer is invalid");
313         return RESULT_NO_MEMORY;
314     }
315     std::lock_guard<std::mutex> lock(g_mutex);
316     UserAuthTokenHal token = {};
317     int32_t ret = DoUpdateIdentify(contextId, scheduleResultBuffer, &info.userId, &token, &info.result);
318     DestoryBuffer(scheduleResultBuffer);
319     if (ret != RESULT_SUCCESS) {
320         IAM_LOGE("DoUpdateIdentify failed");
321         return ret;
322     }
323     if (info.result == RESULT_SUCCESS) {
324         info.token.resize(sizeof(UserAuthTokenHal));
325         if (memcpy_s(info.token.data(), info.token.size(), &token, sizeof(token)) != EOK) {
326             IAM_LOGE("copy authToken failed");
327             info.token.clear();
328             return RESULT_BAD_COPY;
329         }
330     }
331     return RESULT_SUCCESS;
332 }
333 
CancelIdentification(uint64_t contextId)334 int32_t UserAuthInterfaceService::CancelIdentification(uint64_t contextId)
335 {
336     IAM_LOGI("start");
337     std::lock_guard<std::mutex> lock(g_mutex);
338     return DestoryContextbyId(contextId);
339 }
340 
GetAuthTrustLevel(int32_t userId,AuthType authType,uint32_t & authTrustLevel)341 int32_t UserAuthInterfaceService::GetAuthTrustLevel(int32_t userId, AuthType authType, uint32_t &authTrustLevel)
342 {
343     IAM_LOGI("start");
344     std::lock_guard<std::mutex> lock(g_mutex);
345     int32_t ret = SingleAuthTrustLevel(userId, authType, &authTrustLevel);
346     return ret;
347 }
348 
GetValidSolution(int32_t userId,const std::vector<AuthType> & authTypes,uint32_t authTrustLevel,std::vector<AuthType> & validTypes)349 int32_t UserAuthInterfaceService::GetValidSolution(int32_t userId, const std::vector<AuthType> &authTypes,
350     uint32_t authTrustLevel, std::vector<AuthType> &validTypes)
351 {
352     IAM_LOGI("start");
353     return RESULT_SUCCESS;
354 }
355 
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)356 int32_t UserAuthInterfaceService::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
357 {
358     IAM_LOGI("start");
359     std::lock_guard<std::mutex> lock(g_mutex);
360     challenge.resize(CHALLENGE_LEN);
361     int32_t ret = OpenEditSession(userId, challenge.data(), challenge.size());
362     if (ret != RESULT_SUCCESS) {
363         IAM_LOGE("failed to open session");
364         challenge.clear();
365     }
366     return ret;
367 }
368 
CloseSession(int32_t userId)369 int32_t UserAuthInterfaceService::CloseSession(int32_t userId)
370 {
371     IAM_LOGI("start");
372     std::lock_guard<std::mutex> lock(g_mutex);
373     return CloseEditSession();
374 }
375 
BeginEnrollment(int32_t userId,const std::vector<uint8_t> & authToken,const EnrollParam & param,ScheduleInfo & info)376 int32_t UserAuthInterfaceService::BeginEnrollment(int32_t userId, const std::vector<uint8_t> &authToken,
377     const EnrollParam &param, ScheduleInfo &info)
378 {
379     IAM_LOGI("start");
380     if (authToken.size() != sizeof(UserAuthTokenHal) && authToken.size() != 0) {
381         IAM_LOGE("authToken len is invalid");
382         return RESULT_BAD_PARAM;
383     }
384     PermissionCheckParam checkParam = {};
385     if (authToken.size() == sizeof(UserAuthTokenHal) &&
386         memcpy_s(checkParam.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
387         return RESULT_BAD_COPY;
388     }
389     checkParam.authType = param.authType;
390     checkParam.userId = userId;
391     checkParam.executorSensorHint = param.executorSensorHint;
392     std::lock_guard<std::mutex> lock(g_mutex);
393     uint64_t scheduleId;
394     int32_t ret;
395     if (authToken.size() == sizeof(UserAuthTokenHal) && param.authType == PIN) {
396         ret = CheckUpdatePermission(checkParam, &scheduleId);
397         if (ret != RESULT_SUCCESS) {
398             IAM_LOGE("check update permission failed");
399             return ret;
400         }
401     } else {
402         ret = CheckEnrollPermission(checkParam, &scheduleId);
403         if (ret != RESULT_SUCCESS) {
404             IAM_LOGE("check enroll permission failed");
405             return ret;
406         }
407     }
408     const CoAuthSchedule *scheduleInfo = GetCoAuthSchedule(scheduleId);
409     if (scheduleInfo == NULL) {
410         IAM_LOGE("get schedule info failed");
411         return RESULT_UNKNOWN;
412     }
413     if (!CopyScheduleInfo(scheduleInfo, &info)) {
414         IAM_LOGE("copy schedule info failed");
415         return RESULT_BAD_COPY;
416     }
417     return ret;
418 }
419 
CancelEnrollment(int32_t userId)420 int32_t UserAuthInterfaceService::CancelEnrollment(int32_t userId)
421 {
422     IAM_LOGI("start");
423     std::lock_guard<std::mutex> lock(g_mutex);
424     BreakOffCoauthSchedule();
425     return RESULT_SUCCESS;
426 }
427 
CopyCredentialInfo(const CredentialInfoHal & in,CredentialInfo & out)428 static void CopyCredentialInfo(const CredentialInfoHal &in, CredentialInfo &out)
429 {
430     out.authType = static_cast<AuthType>(in.authType);
431     out.credentialId = in.credentialId;
432     out.templateId = in.templateId;
433     out.executorMatcher = in.executorMatcher;
434     out.executorSensorHint = in.executorSensorHint;
435     out.executorIndex = QueryCredentialExecutorIndex(in.authType, in.executorSensorHint);
436 }
437 
UpdateEnrollmentResult(int32_t userId,const std::vector<uint8_t> & scheduleResult,EnrollResultInfo & info)438 int32_t UserAuthInterfaceService::UpdateEnrollmentResult(int32_t userId, const std::vector<uint8_t> &scheduleResult,
439     EnrollResultInfo &info)
440 {
441     IAM_LOGI("start");
442     if (scheduleResult.size() == 0) {
443         IAM_LOGE("enrollToken is invalid");
444         return RESULT_BAD_PARAM;
445     }
446     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
447     if (scheduleResultBuffer == nullptr) {
448         IAM_LOGE("scheduleTokenBuffer is null");
449         return RESULT_NO_MEMORY;
450     }
451     std::lock_guard<std::mutex> lock(g_mutex);
452     bool isUpdate;
453     int32_t ret = GetIsUpdate(&isUpdate);
454     if (ret != RESULT_SUCCESS) {
455         IAM_LOGE("get isUpdate failed");
456         DestoryBuffer(scheduleResultBuffer);
457         return ret;
458     }
459     Buffer *rootSecret = NULL;
460     if (isUpdate) {
461         CredentialInfoHal oldCredentialHal = {};
462         ret = UpdateCredentialFunc(userId, scheduleResultBuffer, &info.credentialId, &oldCredentialHal, &rootSecret);
463         CopyCredentialInfo(oldCredentialHal, info.oldInfo);
464     } else {
465         ret = AddCredentialFunc(userId, scheduleResultBuffer, &info.credentialId, &rootSecret);
466     }
467     if (rootSecret != NULL) {
468         info.rootSecret.resize(rootSecret->contentSize);
469         if (memcpy_s(info.rootSecret.data(), info.rootSecret.size(), rootSecret->buf, rootSecret->contentSize) != EOK) {
470             IAM_LOGE("failed to copy rootSecret");
471             info.rootSecret.clear();
472             ret = RESULT_BAD_COPY;
473         }
474         DestoryBuffer(rootSecret);
475     }
476     DestoryBuffer(scheduleResultBuffer);
477     return ret;
478 }
479 
DeleteCredential(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,CredentialInfo & info)480 int32_t UserAuthInterfaceService::DeleteCredential(int32_t userId, uint64_t credentialId,
481     const std::vector<uint8_t> &authToken, CredentialInfo &info)
482 {
483     IAM_LOGI("start");
484     if (authToken.size() != sizeof(UserAuthTokenHal)) {
485         IAM_LOGE("authToken len is invalid");
486         return RESULT_BAD_PARAM;
487     }
488     std::lock_guard<std::mutex> lock(g_mutex);
489     CredentialDeleteParam param = {};
490     if (memcpy_s(param.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
491         IAM_LOGE("param token copy failed");
492         return RESULT_BAD_COPY;
493     }
494     param.userId = userId;
495     param.credentialId = credentialId;
496     CredentialInfoHal credentialInfoHal = {};
497     int32_t ret = DeleteCredentialFunc(param, &credentialInfoHal);
498     if (ret != RESULT_SUCCESS) {
499         IAM_LOGE("delete failed");
500         return ret;
501     }
502     CopyCredentialInfo(credentialInfoHal, info);
503     return RESULT_SUCCESS;
504 }
505 
GetCredential(int32_t userId,AuthType authType,std::vector<CredentialInfo> & infos)506 int32_t UserAuthInterfaceService::GetCredential(int32_t userId, AuthType authType, std::vector<CredentialInfo> &infos)
507 {
508     IAM_LOGI("start");
509     std::lock_guard<std::mutex> lock(g_mutex);
510     LinkedList *credList = nullptr;
511     int32_t ret = QueryCredentialFunc(userId, authType, &credList);
512     if (ret != RESULT_SUCCESS) {
513         IAM_LOGE("query credential failed");
514         return ret;
515     }
516     infos.reserve(credList->getSize(credList));
517     LinkedListNode *temp = credList->head;
518     while (temp != nullptr) {
519         if (temp->data == NULL) {
520             IAM_LOGE("list node is invalid");
521             DestroyLinkedList(credList);
522             return RESULT_UNKNOWN;
523         }
524         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
525         CredentialInfo credentialInfo = {};
526         CopyCredentialInfo(*credentialHal, credentialInfo);
527         infos.push_back(credentialInfo);
528         temp = temp->next;
529     }
530     DestroyLinkedList(credList);
531     return RESULT_SUCCESS;
532 }
533 
GetUserInfo(int32_t userId,uint64_t & secureUid,PinSubType & pinSubType,std::vector<EnrolledInfo> & infos)534 int32_t UserAuthInterfaceService::GetUserInfo(int32_t userId, uint64_t &secureUid, PinSubType &pinSubType,
535     std::vector<EnrolledInfo> &infos)
536 {
537     IAM_LOGI("start");
538     std::lock_guard<std::mutex> lock(g_mutex);
539     EnrolledInfoHal *enrolledInfoHals = nullptr;
540     uint32_t num = 0;
541     uint64_t pinSubTypeGet;
542     int32_t ret = GetUserInfoFunc(userId, &secureUid, &pinSubTypeGet, &enrolledInfoHals, &num);
543     if (ret != RESULT_SUCCESS) {
544         IAM_LOGE("get user info failed");
545         return ret;
546     }
547     pinSubType = static_cast<PinSubType>(pinSubTypeGet);
548     for (uint32_t i = 0; i < num; ++i) {
549         EnrolledInfo enrolledInfo = {};
550         enrolledInfo.authType = static_cast<AuthType>(enrolledInfoHals[i].authType);
551         enrolledInfo.enrolledId = enrolledInfoHals[i].enrolledId;
552         infos.push_back(enrolledInfo);
553     }
554     free(enrolledInfoHals);
555     return RESULT_SUCCESS;
556 }
557 
DeleteUser(int32_t userId,const std::vector<uint8_t> & authToken,std::vector<CredentialInfo> & deletedInfos)558 int32_t UserAuthInterfaceService::DeleteUser(int32_t userId, const std::vector<uint8_t> &authToken,
559     std::vector<CredentialInfo> &deletedInfos)
560 {
561     IAM_LOGI("start");
562     if (authToken.size() != sizeof(UserAuthTokenHal)) {
563         IAM_LOGE("authToken is invalid");
564         return RESULT_BAD_PARAM;
565     }
566     UserAuthTokenHal authTokenStruct = {};
567     if (memcpy_s(&authTokenStruct, sizeof(UserAuthTokenHal), &authToken[0], authToken.size()) != EOK) {
568         IAM_LOGE("authTokenStruct copy failed");
569         return RESULT_BAD_COPY;
570     }
571     int32_t ret = CheckIdmOperationToken(userId, &authTokenStruct);
572     if (ret != RESULT_SUCCESS) {
573         IAM_LOGE("failed to verify token");
574         return RESULT_BAD_SIGN;
575     }
576     return EnforceDeleteUser(userId, deletedInfos);
577 }
578 
EnforceDeleteUser(int32_t userId,std::vector<CredentialInfo> & deletedInfos)579 int32_t UserAuthInterfaceService::EnforceDeleteUser(int32_t userId, std::vector<CredentialInfo> &deletedInfos)
580 {
581     IAM_LOGI("start");
582     std::lock_guard<std::mutex> lock(g_mutex);
583     LinkedList *credList = nullptr;
584     int32_t ret = DeleteUserInfo(userId, &credList);
585     if (ret != RESULT_SUCCESS) {
586         IAM_LOGE("query credential failed");
587         return ret;
588     }
589     RefreshValidTokenTime();
590     LinkedListNode *temp = credList->head;
591     while (temp != NULL) {
592         if (temp->data == NULL) {
593             IAM_LOGE("list node is invalid");
594             DestroyLinkedList(credList);
595             return RESULT_UNKNOWN;
596         }
597         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
598         CredentialInfo credentialInfo = {};
599         CopyCredentialInfo(*credentialHal, credentialInfo);
600         deletedInfos.push_back(credentialInfo);
601         temp = temp->next;
602     }
603     DestroyLinkedList(credList);
604     return RESULT_SUCCESS;
605 }
606 
CopyExecutorInfo(const ExecutorRegisterInfo & in,ExecutorInfoHal & out)607 static bool CopyExecutorInfo(const ExecutorRegisterInfo &in, ExecutorInfoHal &out)
608 {
609     out.authType = in.authType;
610     out.executorMatcher = in.executorMatcher;
611     out.esl = in.esl;
612     out.executorRole = in.executorRole;
613     out.executorSensorHint = in.executorSensorHint;
614     if (memcpy_s(out.pubKey, PUBLIC_KEY_LEN, &in.publicKey[0], in.publicKey.size()) != EOK) {
615         IAM_LOGE("memcpy failed");
616         return false;
617     }
618     return true;
619 }
620 
ObtainReconciliationData(uint32_t authType,uint32_t sensorHint,std::vector<uint64_t> & templateIds)621 static int32_t ObtainReconciliationData(uint32_t authType, uint32_t sensorHint, std::vector<uint64_t> &templateIds)
622 {
623     CredentialCondition condition = {};
624     SetCredentialConditionAuthType(&condition, authType);
625     SetCredentialConditionExecutorSensorHint(&condition, sensorHint);
626     LinkedList *credList = QueryCredentialLimit(&condition);
627     if (credList == NULL) {
628         IAM_LOGE("query credential failed");
629         return RESULT_NOT_FOUND;
630     }
631     LinkedListNode *temp = credList->head;
632     while (temp != NULL) {
633         if (temp->data == NULL) {
634             IAM_LOGE("list node is invalid");
635             DestroyLinkedList(credList);
636             return RESULT_UNKNOWN;
637         }
638         auto credentialInfo = static_cast<CredentialInfoHal *>(temp->data);
639         templateIds.push_back(credentialInfo->templateId);
640         temp = temp->next;
641     }
642     DestroyLinkedList(credList);
643     return RESULT_SUCCESS;
644 }
645 
AddExecutor(const ExecutorRegisterInfo & info,uint64_t & index,std::vector<uint8_t> & publicKey,std::vector<uint64_t> & templateIds)646 int32_t UserAuthInterfaceService::AddExecutor(const ExecutorRegisterInfo &info, uint64_t &index,
647     std::vector<uint8_t> &publicKey, std::vector<uint64_t> &templateIds)
648 {
649     IAM_LOGI("start");
650     if (info.publicKey.size() != PUBLIC_KEY_LEN) {
651         IAM_LOGE("invalid info");
652         return RESULT_BAD_PARAM;
653     }
654     templateIds.clear();
655     const Buffer *frameworkPubKey = GetPubKey();
656     if (!IsBufferValid(frameworkPubKey)) {
657         IAM_LOGE("get public key failed");
658         return RESULT_UNKNOWN;
659     }
660     publicKey.resize(PUBLIC_KEY_LEN);
661     if (memcpy_s(&publicKey[0], publicKey.size(), frameworkPubKey->buf, frameworkPubKey->contentSize) != EOK) {
662         IAM_LOGE("copy public key failed");
663         publicKey.clear();
664         return RESULT_UNKNOWN;
665     }
666     std::lock_guard<std::mutex> lock(g_mutex);
667     ExecutorInfoHal executorInfoHal = {};
668     CopyExecutorInfo(info, executorInfoHal);
669     int32_t ret = RegisterExecutor(&executorInfoHal, &index);
670     if (ret != RESULT_SUCCESS) {
671         IAM_LOGE("register executor failed");
672         return ret;
673     }
674     if (info.executorRole == VERIFIER || info.executorRole == ALL_IN_ONE) {
675         return ObtainReconciliationData(executorInfoHal.authType, executorInfoHal.executorSensorHint, templateIds);
676     }
677     return RESULT_SUCCESS;
678 }
679 
DeleteExecutor(uint64_t index)680 int32_t UserAuthInterfaceService::DeleteExecutor(uint64_t index)
681 {
682     IAM_LOGI("start");
683     std::lock_guard<std::mutex> lock(g_mutex);
684     return UnRegisterExecutor(index);
685 }
686 } // V1_0
687 } // Userauth
688 } // HDI
689 } // OHOS
690