• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_2/user_auth_interface_service.h"
17 
18 #include <mutex>
19 #include <hdf_base.h>
20 #include "securec.h"
21 #include <set>
22 
23 #include "iam_logger.h"
24 #include "iam_ptr.h"
25 
26 #include "useriam_common.h"
27 #include "auth_level.h"
28 #include "buffer.h"
29 #include "coauth_funcs.h"
30 #include "identify_funcs.h"
31 #include "idm_database.h"
32 #include "idm_session.h"
33 #include "ed25519_key.h"
34 #include "user_auth_hdi.h"
35 #include "user_auth_funcs.h"
36 #include "user_idm_funcs.h"
37 #include "enroll_specification_check.h"
38 
39 #define LOG_LABEL OHOS::UserIam::Common::LABEL_USER_AUTH_HDI
40 
41 namespace OHOS {
42 namespace HDI {
43 namespace UserAuth {
44 namespace {
45 static std::mutex g_mutex;
46 constexpr uint32_t INVALID_CAPABILITY_LEVEL = 100;
47 constexpr uint32_t AUTH_TRUST_LEVEL_SYS = 1;
48 }
49 
UserAuthInterfaceImplGetInstance(void)50 extern "C" IUserAuthInterface *UserAuthInterfaceImplGetInstance(void)
51 {
52     auto userAuthInterfaceService = new (std::nothrow) UserAuthInterfaceService();
53     if (userAuthInterfaceService == nullptr) {
54         IAM_LOGE("userAuthInterfaceService is nullptr");
55         return nullptr;
56     }
57     std::lock_guard<std::mutex> lock(g_mutex);
58     OHOS::UserIam::Common::Init();
59     return userAuthInterfaceService;
60 }
61 
Init()62 int32_t UserAuthInterfaceService::Init()
63 {
64     IAM_LOGI("start");
65     std::lock_guard<std::mutex> lock(g_mutex);
66     OHOS::UserIam::Common::Close();
67     return OHOS::UserIam::Common::Init();
68 }
69 
CopyScheduleInfoV1_1(const CoAuthSchedule * in,ScheduleInfoV1_1 * out)70 static bool CopyScheduleInfoV1_1(const CoAuthSchedule *in, ScheduleInfoV1_1 *out)
71 {
72     IAM_LOGI("start");
73     if (in->executorSize == 0 || (in->templateIds.data == NULL && in->templateIds.len != 0)) {
74         IAM_LOGE("executorSize is zero");
75         return false;
76     }
77     out->executors.clear();
78     out->templateIds.clear();
79     out->scheduleId = in->scheduleId;
80     out->authType = static_cast<AuthType>(in->authType);
81     for (uint32_t i = 0; i < in->templateIds.len; ++i) {
82         out->templateIds.push_back(in->templateIds.data[i]);
83     }
84     out->executorMatcher = static_cast<uint32_t>(in->executors[0].executorMatcher);
85     out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
86     for (uint32_t i = 0; i < in->executorSize; ++i) {
87         ExecutorInfo temp = {};
88         temp.executorIndex = in->executors[i].executorIndex;
89         temp.info.authType = static_cast<AuthType>(in->executors[i].authType);
90         temp.info.executorRole = static_cast<ExecutorRole>(in->executors[i].executorRole);
91         temp.info.executorSensorHint = in->executors[i].executorSensorHint;
92         temp.info.executorMatcher = static_cast<uint32_t>(in->executors[i].executorMatcher);
93         temp.info.esl = static_cast<ExecutorSecureLevel>(in->executors[i].esl);
94         temp.info.publicKey.resize(PUBLIC_KEY_LEN);
95         if (memcpy_s(&temp.info.publicKey[0], temp.info.publicKey.size(),
96             in->executors[i].pubKey, PUBLIC_KEY_LEN) != EOK) {
97             IAM_LOGE("copy failed");
98             out->executors.clear();
99             out->templateIds.clear();
100             return false;
101         }
102         out->executors.push_back(temp);
103     }
104     out->extraInfo = {};
105     return true;
106 }
107 
SetAttributeToExtraInfo(ScheduleInfoV1_1 & info,uint32_t capabilityLevel,uint64_t scheduleId)108 static int32_t SetAttributeToExtraInfo(ScheduleInfoV1_1 &info, uint32_t capabilityLevel, uint64_t scheduleId)
109 {
110     Attribute *attribute = CreateEmptyAttribute();
111     IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
112 
113     ResultCode ret = RESULT_GENERAL_ERROR;
114     do {
115         Uint64Array templateIdsIn = {info.templateIds.data(), info.templateIds.size()};
116         if (SetAttributeUint64Array(attribute, AUTH_TEMPLATE_ID_LIST, templateIdsIn) != RESULT_SUCCESS) {
117             IAM_LOGE("SetAttributeUint64Array templateIdsIn failed");
118             break;
119         }
120         if (capabilityLevel != INVALID_CAPABILITY_LEVEL &&
121             SetAttributeUint32(attribute, AUTH_CAPABILITY_LEVEL, capabilityLevel) != RESULT_SUCCESS) {
122             IAM_LOGE("SetAttributeUint32 capabilityLevel failed");
123             break;
124         }
125         if (SetAttributeUint64(attribute, AUTH_SCHEDULE_ID, scheduleId) != RESULT_SUCCESS) {
126             IAM_LOGE("SetAttributeUint64 scheduleId failed");
127             break;
128         }
129         info.extraInfo.resize(MAX_EXECUTOR_MSG_LEN);
130         Uint8Array retExtraInfo = { info.extraInfo.data(), MAX_EXECUTOR_MSG_LEN };
131         if (GetAttributeExecutorMsg(attribute, true, &retExtraInfo) != RESULT_SUCCESS) {
132             IAM_LOGE("GetAttributeExecutorMsg failed");
133             info.extraInfo.clear();
134             break;
135         }
136         info.extraInfo.resize(retExtraInfo.len);
137         ret = RESULT_SUCCESS;
138     } while (0);
139 
140     FreeAttribute(&attribute);
141     return ret;
142 }
143 
GetCapabilityLevel(int32_t userId,ScheduleInfoV1_1 & info,uint32_t & capabilityLevel)144 static int32_t GetCapabilityLevel(int32_t userId, ScheduleInfoV1_1 &info, uint32_t &capabilityLevel)
145 {
146     capabilityLevel = INVALID_CAPABILITY_LEVEL;
147     LinkedList *credList = nullptr;
148     int32_t ret = QueryCredentialFunc(userId, info.authType, &credList);
149     if (ret != RESULT_SUCCESS) {
150         IAM_LOGE("query credential failed");
151         return ret;
152     }
153     LinkedListNode *temp = credList->head;
154     while (temp != nullptr) {
155         if (temp->data == nullptr) {
156             IAM_LOGE("list node is invalid");
157             DestroyLinkedList(credList);
158             return RESULT_UNKNOWN;
159         }
160         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
161         // Only the lowest acl is returned
162         capabilityLevel = (capabilityLevel < credentialHal->capabilityLevel) ?
163             capabilityLevel : credentialHal->capabilityLevel;
164         temp = temp->next;
165     }
166 
167     DestroyLinkedList(credList);
168     return RESULT_SUCCESS;
169 }
170 
SetArrayAttributeToExtraInfo(int32_t userId,std::vector<ScheduleInfoV1_1> & infos)171 static int32_t SetArrayAttributeToExtraInfo(int32_t userId, std::vector<ScheduleInfoV1_1> &infos)
172 {
173     for (auto &info : infos) {
174         uint32_t capabilityLevel = INVALID_CAPABILITY_LEVEL;
175         int32_t result = GetCapabilityLevel(userId, info, capabilityLevel);
176         if (result != RESULT_SUCCESS) {
177             IAM_LOGE("GetCapabilityLevel fail");
178             return result;
179         }
180         result = SetAttributeToExtraInfo(info, capabilityLevel, info.scheduleId);
181         if (result != RESULT_SUCCESS) {
182             IAM_LOGE("SetAttributeToExtraInfo fail");
183             return result;
184         }
185     }
186 
187     return RESULT_SUCCESS;
188 }
189 
CopyScheduleInfoV1_1ToV1_0(const ScheduleInfoV1_1 & in,ScheduleInfo & out)190 static void CopyScheduleInfoV1_1ToV1_0(const ScheduleInfoV1_1 &in, ScheduleInfo &out)
191 {
192     out.scheduleId = in.scheduleId;
193     out.templateIds = in.templateIds;
194     out.authType = in.authType;
195     out.executorMatcher = in.executorMatcher;
196     out.scheduleMode = in.scheduleMode;
197     for (auto &inInfo : in.executors) {
198         ExecutorInfo outInfo = {};
199         outInfo.executorIndex = inInfo.executorIndex;
200         outInfo.info.authType = inInfo.info.authType;
201         outInfo.info.executorRole = inInfo.info.executorRole;
202         outInfo.info.executorSensorHint = inInfo.info.executorSensorHint;
203         outInfo.info.executorMatcher = inInfo.info.executorMatcher;
204         outInfo.info.esl = inInfo.info.esl;
205         outInfo.info.publicKey = inInfo.info.publicKey;
206         out.executors.push_back(outInfo);
207     }
208 }
209 
CopyScheduleInfosV1_1ToV1_0(const std::vector<ScheduleInfoV1_1> & in,std::vector<ScheduleInfo> & out)210 static void CopyScheduleInfosV1_1ToV1_0(const std::vector<ScheduleInfoV1_1> &in, std::vector<ScheduleInfo> &out)
211 {
212     for (auto &inInfo : in) {
213         ScheduleInfo outInfo;
214         CopyScheduleInfoV1_1ToV1_0(inInfo, outInfo);
215         out.push_back(outInfo);
216     }
217 }
218 
CopyAuthSolutionV1_2ToV1_0(const AuthSolutionV1_2 & in,AuthSolution & out)219 static int32_t CopyAuthSolutionV1_2ToV1_0(const AuthSolutionV1_2 &in, AuthSolution &out)
220 {
221     out.userId = in.userId;
222     out.authTrustLevel = in.authTrustLevel;
223     out.authType = in.authType;
224     out.executorSensorHint = in.executorSensorHint;
225     out.challenge = std::move(in.challenge);
226     return RESULT_SUCCESS;
227 }
228 
BeginAuthentication(uint64_t contextId,const AuthSolution & param,std::vector<ScheduleInfo> & infos)229 int32_t UserAuthInterfaceService::BeginAuthentication(uint64_t contextId, const AuthSolution &param,
230     std::vector<ScheduleInfo> &infos)
231 {
232     IAM_LOGI("start");
233     std::vector<ScheduleInfoV1_1> infosV1_1;
234     int32_t ret = BeginAuthenticationV1_1(contextId, param, infosV1_1);
235     CopyScheduleInfosV1_1ToV1_0(infosV1_1, infos);
236     return ret;
237 }
238 
BeginAuthenticationV1_2(uint64_t contextId,const AuthSolutionV1_2 & paramV1_2,std::vector<ScheduleInfoV1_1> & infos)239 int32_t UserAuthInterfaceService::BeginAuthenticationV1_2(uint64_t contextId, const AuthSolutionV1_2 &paramV1_2,
240     std::vector<ScheduleInfoV1_1> &infos)
241 {
242     IAM_LOGI("start");
243     AuthSolution param;
244     int32_t ret = CopyAuthSolutionV1_2ToV1_0(paramV1_2, param);
245     if (ret != RESULT_SUCCESS) {
246         IAM_LOGE("AuthSolution copy failed");
247         return ret;
248     }
249     ret = BeginAuthenticationV1_1(contextId, param, infos);
250     return ret;
251 }
252 
BeginAuthenticationV1_1(uint64_t contextId,const AuthSolution & param,std::vector<ScheduleInfoV1_1> & infos)253 int32_t UserAuthInterfaceService::BeginAuthenticationV1_1(
254     uint64_t contextId, const AuthSolution &param, std::vector<ScheduleInfoV1_1> &infos)
255 {
256     IAM_LOGI("start");
257     infos.clear();
258     AuthSolutionHal solutionIn = {};
259     solutionIn.contextId = contextId;
260     solutionIn.userId = param.userId;
261     solutionIn.authType = static_cast<uint32_t>(param.authType);
262     solutionIn.authTrustLevel = param.authTrustLevel;
263     if (!param.challenge.empty() && memcpy_s(solutionIn.challenge, CHALLENGE_LEN, param.challenge.data(),
264         param.challenge.size()) != EOK) {
265         IAM_LOGE("challenge copy failed");
266         return RESULT_BAD_COPY;
267     }
268     std::lock_guard<std::mutex> lock(g_mutex);
269     LinkedList *schedulesGet = nullptr;
270     int32_t ret = GenerateSolutionFunc(solutionIn, &schedulesGet);
271     if (ret != RESULT_SUCCESS) {
272         IAM_LOGE("generate solution failed %{public}d", ret);
273         return ret;
274     }
275     if (schedulesGet == nullptr) {
276         IAM_LOGE("get null schedule");
277         return RESULT_GENERAL_ERROR;
278     }
279     LinkedListNode *tempNode = schedulesGet->head;
280     while (tempNode != nullptr) {
281         if (tempNode->data == nullptr) {
282             IAM_LOGE("node data is invalid");
283             DestroyLinkedList(schedulesGet);
284             return RESULT_UNKNOWN;
285         }
286         ScheduleInfoV1_1 temp = {};
287         auto coAuthSchedule = static_cast<CoAuthSchedule *>(tempNode->data);
288         if (!CopyScheduleInfoV1_1(coAuthSchedule, &temp)) {
289             infos.clear();
290             IAM_LOGE("copy schedule info failed");
291             DestroyLinkedList(schedulesGet);
292             return RESULT_GENERAL_ERROR;
293         }
294         infos.push_back(temp);
295         tempNode = tempNode->next;
296     }
297     ret = SetArrayAttributeToExtraInfo(solutionIn.userId, infos);
298     if (ret != RESULT_SUCCESS) {
299         IAM_LOGE("SetArrayAttributeToExtraInfo fail");
300     }
301     DestroyLinkedList(schedulesGet);
302     return ret;
303 }
304 
GetAllUserInfo(std::vector<UserInfo> & userInfos)305 int32_t UserAuthInterfaceService::GetAllUserInfo(std::vector<UserInfo> &userInfos)
306 {
307     IAM_LOGI("GetAllUserInfo mock start");
308     static_cast<void>(userInfos);
309 
310     return RESULT_SUCCESS;
311 }
312 
CreateExecutorCommand(int32_t userId,AuthResultInfo & info)313 static int32_t CreateExecutorCommand(int32_t userId, AuthResultInfo &info)
314 {
315     LinkedList *executorSendMsg = nullptr;
316     AuthPropertyMode authPropMode;
317     if (info.result == RESULT_SUCCESS) {
318         authPropMode = PROPERTY_MODE_UNFREEZE;
319     } else if (info.remainAttempts == 0) {
320         authPropMode = PROPERTY_MODE_FREEZE;
321     } else {
322         return RESULT_SUCCESS;
323     }
324     ResultCode ret = GetExecutorMsgList(userId, authPropMode, &executorSendMsg);
325     if (ret != RESULT_SUCCESS) {
326         IAM_LOGE("get executor msg failed");
327         return ret;
328     }
329 
330     LinkedListNode *temp = executorSendMsg->head;
331     while (temp != nullptr) {
332         if (temp->data == nullptr) {
333             IAM_LOGE("list node is invalid");
334             DestroyLinkedList(executorSendMsg);
335             return RESULT_UNKNOWN;
336         }
337         auto nodeData = static_cast<ExecutorMsg *>(temp->data);
338         Buffer *nodeMsgBuffer = nodeData->msg;
339         if (!IsBufferValid(nodeMsgBuffer)) {
340             IAM_LOGE("node's buffer invalid");
341             DestroyLinkedList(executorSendMsg);
342             return RESULT_UNKNOWN;
343         }
344         ExecutorSendMsg msg = {};
345         msg.executorIndex = nodeData->executorIndex;
346         msg.commandId = static_cast<int32_t>(authPropMode);
347         msg.msg.resize(nodeMsgBuffer->contentSize);
348         if (memcpy_s(msg.msg.data(), msg.msg.size(), nodeMsgBuffer->buf, nodeMsgBuffer->contentSize) != EOK) {
349             IAM_LOGE("copy failed");
350             msg.msg.clear();
351             DestroyLinkedList(executorSendMsg);
352             return RESULT_BAD_COPY;
353         }
354         info.msgs.push_back(msg);
355         temp = temp->next;
356     }
357     DestroyLinkedList(executorSendMsg);
358     return RESULT_SUCCESS;
359 }
360 
CopyAuthResult(AuthResult & infoIn,UserAuthTokenHal & authTokenIn,AuthResultInfo & infoOut)361 static int32_t CopyAuthResult(AuthResult &infoIn, UserAuthTokenHal &authTokenIn, AuthResultInfo &infoOut)
362 {
363     infoOut.result = infoIn.result;
364     infoOut.remainAttempts = infoIn.remainTimes;
365     infoOut.lockoutDuration = infoIn.freezingTime;
366     if (infoOut.result == RESULT_SUCCESS) {
367         infoOut.token.resize(sizeof(UserAuthTokenHal));
368         if (memcpy_s(infoOut.token.data(), infoOut.token.size(), &authTokenIn, sizeof(UserAuthTokenHal)) != EOK) {
369             IAM_LOGE("copy authToken failed");
370             infoOut.token.clear();
371             return RESULT_BAD_COPY;
372         }
373         if (infoIn.rootSecret != nullptr) {
374             infoOut.rootSecret.resize(infoIn.rootSecret->contentSize);
375             if (memcpy_s(infoOut.rootSecret.data(), infoOut.rootSecret.size(),
376                 infoIn.rootSecret->buf, infoIn.rootSecret->contentSize) != EOK) {
377                 IAM_LOGE("copy secret failed");
378                 infoOut.rootSecret.clear();
379                 infoOut.token.clear();
380                 return RESULT_BAD_COPY;
381             }
382         }
383     }
384     DestoryBuffer(infoIn.rootSecret);
385     return RESULT_SUCCESS;
386 }
387 
UpdateAuthenticationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,AuthResultInfo & info)388 int32_t UserAuthInterfaceService::UpdateAuthenticationResult(uint64_t contextId,
389     const std::vector<uint8_t> &scheduleResult, AuthResultInfo &info)
390 {
391     IAM_LOGI("start");
392     if (scheduleResult.size() == 0) {
393         IAM_LOGE("param is invalid");
394         DestoryContextbyId(contextId);
395         return RESULT_BAD_PARAM;
396     }
397     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
398     if (!IsBufferValid(scheduleResultBuffer)) {
399         IAM_LOGE("scheduleTokenBuffer is invalid");
400         DestoryContextbyId(contextId);
401         return RESULT_NO_MEMORY;
402     }
403     std::lock_guard<std::mutex> lock(g_mutex);
404     UserAuthTokenHal authTokenHal = {};
405     AuthResult authResult = {};
406     int32_t ret = RequestAuthResultFunc(contextId, scheduleResultBuffer, &authTokenHal, &authResult);
407     DestoryBuffer(scheduleResultBuffer);
408     if (ret != RESULT_SUCCESS) {
409         IAM_LOGE("execute func failed");
410         return ret;
411     }
412     ret = CopyAuthResult(authResult, authTokenHal, info);
413     if (ret != RESULT_SUCCESS) {
414         IAM_LOGE("Copy auth result failed");
415         return ret;
416     }
417     if (authResult.authType != PIN_AUTH) {
418         IAM_LOGI("type not pin");
419         return RESULT_SUCCESS;
420     }
421     IAM_LOGI("type pin");
422     return CreateExecutorCommand(authResult.userId, info);
423 }
424 
CancelAuthentication(uint64_t contextId)425 int32_t UserAuthInterfaceService::CancelAuthentication(uint64_t contextId)
426 {
427     IAM_LOGI("start");
428     std::lock_guard<std::mutex> lock(g_mutex);
429     return DestoryContextbyId(contextId);
430 }
431 
BeginIdentification(uint64_t contextId,AuthType authType,const std::vector<uint8_t> & challenge,uint32_t executorSensorHint,ScheduleInfo & scheduleInfo)432 int32_t UserAuthInterfaceService::BeginIdentification(uint64_t contextId, AuthType authType,
433     const std::vector<uint8_t> &challenge, uint32_t executorSensorHint, ScheduleInfo &scheduleInfo)
434 {
435     IAM_LOGI("start");
436     ScheduleInfoV1_1 infoV1_1;
437     int32_t ret = BeginIdentificationV1_1(contextId, authType, challenge, executorSensorHint, infoV1_1);
438     CopyScheduleInfoV1_1ToV1_0(infoV1_1, scheduleInfo);
439     return ret;
440 }
441 
BeginIdentificationV1_1(uint64_t contextId,AuthType authType,const std::vector<uint8_t> & challenge,uint32_t executorSensorHint,ScheduleInfoV1_1 & scheduleInfo)442 int32_t UserAuthInterfaceService::BeginIdentificationV1_1(uint64_t contextId, AuthType authType,
443     const std::vector<uint8_t> &challenge, uint32_t executorSensorHint, ScheduleInfoV1_1 &scheduleInfo)
444 {
445     IAM_LOGI("start");
446     if (authType == PIN) {
447         IAM_LOGE("param is invalid");
448         return RESULT_BAD_PARAM;
449     }
450     IdentifyParam param = {};
451     param.contextId = contextId;
452     param.authType = static_cast<uint32_t>(authType);
453     param.executorSensorHint = executorSensorHint;
454     if (!challenge.empty() && memcpy_s(param.challenge, CHALLENGE_LEN, challenge.data(), challenge.size()) != EOK) {
455         IAM_LOGE("challenge copy failed");
456         return RESULT_BAD_COPY;
457     }
458     std::lock_guard<std::mutex> lock(g_mutex);
459     LinkedList *scheduleGet = nullptr;
460     int32_t ret = DoIdentify(param, &scheduleGet);
461     if (ret != RESULT_SUCCESS) {
462         IAM_LOGE("generate solution failed");
463         return ret;
464     }
465     if (scheduleGet == nullptr) {
466         IAM_LOGE("get null schedule");
467         return RESULT_GENERAL_ERROR;
468     }
469     if (scheduleGet->head == nullptr || scheduleGet->head->data == nullptr) {
470         IAM_LOGE("scheduleGet is invalid");
471         DestroyLinkedList(scheduleGet);
472         return RESULT_UNKNOWN;
473     }
474     auto data = static_cast<CoAuthSchedule *>(scheduleGet->head->data);
475     if (!CopyScheduleInfoV1_1(data, &scheduleInfo)) {
476         IAM_LOGE("copy schedule failed");
477         ret = RESULT_BAD_COPY;
478     }
479     DestroyLinkedList(scheduleGet);
480     return ret;
481 }
482 
UpdateIdentificationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,IdentifyResultInfo & info)483 int32_t UserAuthInterfaceService::UpdateIdentificationResult(uint64_t contextId,
484     const std::vector<uint8_t> &scheduleResult, IdentifyResultInfo &info)
485 {
486     IAM_LOGI("start");
487     if (scheduleResult.size() == 0) {
488         IAM_LOGE("param is invalid");
489         return RESULT_BAD_PARAM;
490     }
491     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
492     if (!IsBufferValid(scheduleResultBuffer)) {
493         IAM_LOGE("scheduleTokenBuffer is invalid");
494         return RESULT_NO_MEMORY;
495     }
496     std::lock_guard<std::mutex> lock(g_mutex);
497     UserAuthTokenHal token = {};
498     int32_t ret = DoUpdateIdentify(contextId, scheduleResultBuffer, &info.userId, &token, &info.result);
499     DestoryBuffer(scheduleResultBuffer);
500     if (ret != RESULT_SUCCESS) {
501         IAM_LOGE("DoUpdateIdentify failed");
502         return ret;
503     }
504     if (info.result == RESULT_SUCCESS) {
505         info.token.resize(sizeof(UserAuthTokenHal));
506         if (memcpy_s(info.token.data(), info.token.size(), &token, sizeof(token)) != EOK) {
507             IAM_LOGE("copy authToken failed");
508             info.token.clear();
509             return RESULT_BAD_COPY;
510         }
511     }
512     return RESULT_SUCCESS;
513 }
514 
CancelIdentification(uint64_t contextId)515 int32_t UserAuthInterfaceService::CancelIdentification(uint64_t contextId)
516 {
517     IAM_LOGI("start");
518     std::lock_guard<std::mutex> lock(g_mutex);
519     return DestoryContextbyId(contextId);
520 }
521 
GetAuthTrustLevel(int32_t userId,AuthType authType,uint32_t & authTrustLevel)522 int32_t UserAuthInterfaceService::GetAuthTrustLevel(int32_t userId, AuthType authType, uint32_t &authTrustLevel)
523 {
524     IAM_LOGI("start");
525     std::lock_guard<std::mutex> lock(g_mutex);
526     int32_t ret = SingleAuthTrustLevel(userId, authType, &authTrustLevel);
527     return ret;
528 }
529 
GetValidSolution(int32_t userId,const std::vector<AuthType> & authTypes,uint32_t authTrustLevel,std::vector<AuthType> & validTypes)530 int32_t UserAuthInterfaceService::GetValidSolution(int32_t userId, const std::vector<AuthType> &authTypes,
531     uint32_t authTrustLevel, std::vector<AuthType> &validTypes)
532 {
533     IAM_LOGI("start userId:%{public}d authTrustLevel:%{public}u", userId, authTrustLevel);
534     int32_t result = RESULT_TYPE_NOT_SUPPORT;
535     validTypes.clear();
536     std::lock_guard<std::mutex> lock(g_mutex);
537     for (auto &authType : authTypes) {
538         uint32_t supportedAtl = AUTH_TRUST_LEVEL_SYS;
539         int32_t ret = SingleAuthTrustLevel(userId, authType, &supportedAtl);
540         if (ret != RESULT_SUCCESS) {
541             IAM_LOGE("authType does not support, authType:%{public}d, ret:%{public}d", authType, ret);
542             result = RESULT_NOT_ENROLLED;
543             continue;
544         }
545         if (authTrustLevel > supportedAtl) {
546             IAM_LOGE("authTrustLevel does not support, authType:%{public}d, supportedAtl:%{public}u",
547                 authType, supportedAtl);
548             result = RESULT_TRUST_LEVEL_NOT_SUPPORT;
549             continue;
550         }
551         IAM_LOGI("get valid authType:%{public}d", authType);
552         validTypes.push_back(authType);
553     }
554     if (validTypes.empty()) {
555         IAM_LOGE("no auth type valid");
556         return result;
557     }
558     return RESULT_SUCCESS;
559 }
560 
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)561 int32_t UserAuthInterfaceService::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
562 {
563     IAM_LOGI("start");
564     std::lock_guard<std::mutex> lock(g_mutex);
565     challenge.resize(CHALLENGE_LEN);
566     int32_t ret = OpenEditSession(userId, challenge.data(), challenge.size());
567     if (ret != RESULT_SUCCESS) {
568         IAM_LOGE("failed to open session");
569         challenge.clear();
570     }
571     return ret;
572 }
573 
CloseSession(int32_t userId)574 int32_t UserAuthInterfaceService::CloseSession(int32_t userId)
575 {
576     IAM_LOGI("start");
577     std::lock_guard<std::mutex> lock(g_mutex);
578     return CloseEditSession();
579 }
580 
BeginEnrollmentV1_2(int32_t userId,const std::vector<uint8_t> & authToken,const EnrollParamV1_2 & paramV1_2,ScheduleInfoV1_1 & infoV1_1)581 int32_t UserAuthInterfaceService::BeginEnrollmentV1_2(int32_t userId, const std::vector<uint8_t> &authToken,
582     const EnrollParamV1_2 &paramV1_2, ScheduleInfoV1_1 &infoV1_1)
583 {
584     IAM_LOGI("start");
585     EnrollParam param;
586     param.authType = paramV1_2.authType;
587     param.executorSensorHint = paramV1_2.executorSensorHint;
588     return BeginEnrollmentV1_1(userId, authToken, param, infoV1_1);
589 }
590 
591 
BeginEnrollment(int32_t userId,const std::vector<uint8_t> & authToken,const EnrollParam & param,ScheduleInfo & info)592 int32_t UserAuthInterfaceService::BeginEnrollment(int32_t userId, const std::vector<uint8_t> &authToken,
593     const EnrollParam &param, ScheduleInfo &info)
594 {
595     IAM_LOGI("start");
596     ScheduleInfoV1_1 infoV1_1;
597     int32_t ret = BeginEnrollmentV1_1(userId, authToken, param, infoV1_1);
598     CopyScheduleInfoV1_1ToV1_0(infoV1_1, info);
599     return ret;
600 }
601 
BeginEnrollmentV1_1(int32_t userId,const std::vector<uint8_t> & authToken,const EnrollParam & param,ScheduleInfoV1_1 & info)602 int32_t UserAuthInterfaceService::BeginEnrollmentV1_1(
603     int32_t userId, const std::vector<uint8_t> &authToken, const EnrollParam &param, ScheduleInfoV1_1 &info)
604 {
605     IAM_LOGI("start");
606     if (authToken.size() != sizeof(UserAuthTokenHal) && authToken.size() != 0) {
607         IAM_LOGE("authToken len is invalid");
608         return RESULT_BAD_PARAM;
609     }
610     PermissionCheckParam checkParam = {};
611     if (authToken.size() == sizeof(UserAuthTokenHal) &&
612         memcpy_s(checkParam.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
613         return RESULT_BAD_COPY;
614     }
615     checkParam.authType = param.authType;
616     checkParam.userId = userId;
617     checkParam.executorSensorHint = param.executorSensorHint;
618     std::lock_guard<std::mutex> lock(g_mutex);
619     uint64_t scheduleId;
620     int32_t ret;
621     if (authToken.size() == sizeof(UserAuthTokenHal) && param.authType == PIN) {
622         ret = CheckUpdatePermission(checkParam, &scheduleId);
623         if (ret != RESULT_SUCCESS) {
624             IAM_LOGE("check update permission failed");
625             return ret;
626         }
627     } else {
628         ret = CheckEnrollPermission(checkParam, &scheduleId);
629         if (ret != RESULT_SUCCESS) {
630             IAM_LOGE("check enroll permission failed");
631             return ret;
632         }
633     }
634     const CoAuthSchedule *scheduleInfo = GetCoAuthSchedule(scheduleId);
635     if (scheduleInfo == nullptr) {
636         IAM_LOGE("get schedule info failed");
637         return RESULT_UNKNOWN;
638     }
639     if (!CopyScheduleInfoV1_1(scheduleInfo, &info)) {
640         IAM_LOGE("copy schedule info failed");
641         return RESULT_BAD_COPY;
642     }
643     ret = SetAttributeToExtraInfo(info, INVALID_CAPABILITY_LEVEL, scheduleId);
644     if (ret != RESULT_SUCCESS) {
645         IAM_LOGE("SetAttributeToExtraInfo failed");
646     }
647 
648     IAM_LOGI("end");
649     return ret;
650 }
651 
CancelEnrollment(int32_t userId)652 int32_t UserAuthInterfaceService::CancelEnrollment(int32_t userId)
653 {
654     IAM_LOGI("start");
655     std::lock_guard<std::mutex> lock(g_mutex);
656     BreakOffCoauthSchedule();
657     return RESULT_SUCCESS;
658 }
659 
CopyCredentialInfo(const CredentialInfoHal & in,CredentialInfo & out)660 static void CopyCredentialInfo(const CredentialInfoHal &in, CredentialInfo &out)
661 {
662     out.authType = static_cast<AuthType>(in.authType);
663     out.credentialId = in.credentialId;
664     out.templateId = in.templateId;
665     out.executorMatcher = in.executorMatcher;
666     out.executorSensorHint = in.executorSensorHint;
667     out.executorIndex = QueryCredentialExecutorIndex(in.authType, in.executorSensorHint);
668 }
669 
UpdateEnrollmentResult(int32_t userId,const std::vector<uint8_t> & scheduleResult,EnrollResultInfo & info)670 int32_t UserAuthInterfaceService::UpdateEnrollmentResult(int32_t userId, const std::vector<uint8_t> &scheduleResult,
671     EnrollResultInfo &info)
672 {
673     IAM_LOGI("start");
674     if (scheduleResult.size() == 0) {
675         IAM_LOGE("enrollToken is invalid");
676         return RESULT_BAD_PARAM;
677     }
678     Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
679     if (scheduleResultBuffer == nullptr) {
680         IAM_LOGE("scheduleTokenBuffer is null");
681         return RESULT_NO_MEMORY;
682     }
683     std::lock_guard<std::mutex> lock(g_mutex);
684     bool isUpdate;
685     int32_t ret = GetIsUpdate(&isUpdate);
686     if (ret != RESULT_SUCCESS) {
687         IAM_LOGE("get isUpdate failed");
688         DestoryBuffer(scheduleResultBuffer);
689         return ret;
690     }
691     Buffer *rootSecret = nullptr;
692     if (isUpdate) {
693         CredentialInfoHal oldCredentialHal = {};
694         ret = UpdateCredentialFunc(userId, scheduleResultBuffer, &info.credentialId, &oldCredentialHal, &rootSecret);
695         CopyCredentialInfo(oldCredentialHal, info.oldInfo);
696     } else {
697         ret = AddCredentialFunc(userId, scheduleResultBuffer, &info.credentialId, &rootSecret);
698     }
699     if (rootSecret != nullptr) {
700         info.rootSecret.resize(rootSecret->contentSize);
701         if (memcpy_s(info.rootSecret.data(), info.rootSecret.size(), rootSecret->buf, rootSecret->contentSize) != EOK) {
702             IAM_LOGE("failed to copy rootSecret");
703             info.rootSecret.clear();
704             ret = RESULT_BAD_COPY;
705         }
706         DestoryBuffer(rootSecret);
707     }
708     DestoryBuffer(scheduleResultBuffer);
709     return ret;
710 }
711 
DeleteCredential(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,CredentialInfo & info)712 int32_t UserAuthInterfaceService::DeleteCredential(int32_t userId, uint64_t credentialId,
713     const std::vector<uint8_t> &authToken, CredentialInfo &info)
714 {
715     IAM_LOGI("start");
716     if (authToken.size() != sizeof(UserAuthTokenHal)) {
717         IAM_LOGE("authToken len is invalid");
718         return RESULT_BAD_PARAM;
719     }
720     std::lock_guard<std::mutex> lock(g_mutex);
721     CredentialDeleteParam param = {};
722     if (memcpy_s(param.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
723         IAM_LOGE("param token copy failed");
724         return RESULT_BAD_COPY;
725     }
726     param.userId = userId;
727     param.credentialId = credentialId;
728     CredentialInfoHal credentialInfoHal = {};
729     int32_t ret = DeleteCredentialFunc(param, &credentialInfoHal);
730     if (ret != RESULT_SUCCESS) {
731         IAM_LOGE("delete failed");
732         return ret;
733     }
734     CopyCredentialInfo(credentialInfoHal, info);
735     return RESULT_SUCCESS;
736 }
737 
GetCredential(int32_t userId,AuthType authType,std::vector<CredentialInfo> & infos)738 int32_t UserAuthInterfaceService::GetCredential(int32_t userId, AuthType authType, std::vector<CredentialInfo> &infos)
739 {
740     IAM_LOGI("start");
741     std::lock_guard<std::mutex> lock(g_mutex);
742     LinkedList *credList = nullptr;
743     int32_t ret = QueryCredentialFunc(userId, authType, &credList);
744     if (ret != RESULT_SUCCESS) {
745         IAM_LOGE("query credential failed");
746         return ret;
747     }
748     infos.reserve(credList->getSize(credList));
749     LinkedListNode *temp = credList->head;
750     while (temp != nullptr) {
751         if (temp->data == nullptr) {
752             IAM_LOGE("list node is invalid");
753             DestroyLinkedList(credList);
754             return RESULT_UNKNOWN;
755         }
756         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
757         CredentialInfo credentialInfo = {};
758         CopyCredentialInfo(*credentialHal, credentialInfo);
759         infos.push_back(credentialInfo);
760         temp = temp->next;
761     }
762     DestroyLinkedList(credList);
763     return RESULT_SUCCESS;
764 }
765 
GetUserInfo(int32_t userId,uint64_t & secureUid,PinSubType & pinSubType,std::vector<EnrolledInfo> & infos)766 int32_t UserAuthInterfaceService::GetUserInfo(int32_t userId, uint64_t &secureUid, PinSubType &pinSubType,
767     std::vector<EnrolledInfo> &infos)
768 {
769     IAM_LOGI("start");
770     std::lock_guard<std::mutex> lock(g_mutex);
771     EnrolledInfoHal *enrolledInfoHals = nullptr;
772     uint32_t num = 0;
773     uint64_t pinSubTypeGet;
774     int32_t ret = GetUserInfoFunc(userId, &secureUid, &pinSubTypeGet, &enrolledInfoHals, &num);
775     if (ret != RESULT_SUCCESS) {
776         IAM_LOGE("get user info failed");
777         return ret;
778     }
779     pinSubType = static_cast<PinSubType>(pinSubTypeGet);
780     for (uint32_t i = 0; i < num; ++i) {
781         EnrolledInfo enrolledInfo = {};
782         enrolledInfo.authType = static_cast<AuthType>(enrolledInfoHals[i].authType);
783         enrolledInfo.enrolledId = enrolledInfoHals[i].enrolledId;
784         infos.push_back(enrolledInfo);
785     }
786     free(enrolledInfoHals);
787     return RESULT_SUCCESS;
788 }
789 
DeleteUser(int32_t userId,const std::vector<uint8_t> & authToken,std::vector<CredentialInfo> & deletedInfos)790 int32_t UserAuthInterfaceService::DeleteUser(int32_t userId, const std::vector<uint8_t> &authToken,
791     std::vector<CredentialInfo> &deletedInfos)
792 {
793     IAM_LOGI("start");
794     if (authToken.size() != sizeof(UserAuthTokenHal)) {
795         IAM_LOGE("authToken is invalid");
796         return RESULT_BAD_PARAM;
797     }
798     UserAuthTokenHal authTokenStruct = {};
799     if (memcpy_s(&authTokenStruct, sizeof(UserAuthTokenHal), &authToken[0], authToken.size()) != EOK) {
800         IAM_LOGE("authTokenStruct copy failed");
801         return RESULT_BAD_COPY;
802     }
803     int32_t ret = CheckIdmOperationToken(userId, &authTokenStruct);
804     if (ret != RESULT_SUCCESS) {
805         IAM_LOGE("failed to verify token");
806         return RESULT_VERIFY_TOKEN_FAIL;
807     }
808     return EnforceDeleteUser(userId, deletedInfos);
809 }
810 
EnforceDeleteUser(int32_t userId,std::vector<CredentialInfo> & deletedInfos)811 int32_t UserAuthInterfaceService::EnforceDeleteUser(int32_t userId, std::vector<CredentialInfo> &deletedInfos)
812 {
813     IAM_LOGI("start");
814     std::lock_guard<std::mutex> lock(g_mutex);
815     LinkedList *credList = nullptr;
816     int32_t ret = DeleteUserInfo(userId, &credList);
817     if (ret != RESULT_SUCCESS) {
818         IAM_LOGE("query credential failed");
819         return ret;
820     }
821     RefreshValidTokenTime();
822     LinkedListNode *temp = credList->head;
823     while (temp != nullptr) {
824         if (temp->data == nullptr) {
825             IAM_LOGE("list node is invalid");
826             DestroyLinkedList(credList);
827             return RESULT_UNKNOWN;
828         }
829         auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
830         CredentialInfo credentialInfo = {};
831         CopyCredentialInfo(*credentialHal, credentialInfo);
832         deletedInfos.push_back(credentialInfo);
833         temp = temp->next;
834     }
835     DestroyLinkedList(credList);
836     return RESULT_SUCCESS;
837 }
838 
CopyExecutorInfo(const ExecutorRegisterInfo & in,ExecutorInfoHal & out)839 static bool CopyExecutorInfo(const ExecutorRegisterInfo &in, ExecutorInfoHal &out)
840 {
841     out.authType = in.authType;
842     out.executorMatcher = in.executorMatcher;
843     out.esl = in.esl;
844     out.executorRole = in.executorRole;
845     out.executorSensorHint = in.executorSensorHint;
846     if (memcpy_s(out.pubKey, PUBLIC_KEY_LEN, &in.publicKey[0], in.publicKey.size()) != EOK) {
847         IAM_LOGE("memcpy failed");
848         return false;
849     }
850     return true;
851 }
852 
ObtainReconciliationData(uint32_t authType,uint32_t sensorHint,std::vector<uint64_t> & templateIds)853 static int32_t ObtainReconciliationData(uint32_t authType, uint32_t sensorHint, std::vector<uint64_t> &templateIds)
854 {
855     CredentialCondition condition = {};
856     SetCredentialConditionAuthType(&condition, authType);
857     SetCredentialConditionExecutorSensorHint(&condition, sensorHint);
858     LinkedList *credList = QueryCredentialLimit(&condition);
859     if (credList == nullptr) {
860         IAM_LOGE("query credential failed");
861         return RESULT_NOT_FOUND;
862     }
863     LinkedListNode *temp = credList->head;
864     while (temp != nullptr) {
865         if (temp->data == nullptr) {
866             IAM_LOGE("list node is invalid");
867             DestroyLinkedList(credList);
868             return RESULT_UNKNOWN;
869         }
870         auto credentialInfo = static_cast<CredentialInfoHal *>(temp->data);
871         templateIds.push_back(credentialInfo->templateId);
872         temp = temp->next;
873     }
874     DestroyLinkedList(credList);
875     return RESULT_SUCCESS;
876 }
877 
AddExecutor(const ExecutorRegisterInfo & info,uint64_t & index,std::vector<uint8_t> & publicKey,std::vector<uint64_t> & templateIds)878 int32_t UserAuthInterfaceService::AddExecutor(const ExecutorRegisterInfo &info, uint64_t &index,
879     std::vector<uint8_t> &publicKey, std::vector<uint64_t> &templateIds)
880 {
881     IAM_LOGI("start");
882     if (info.publicKey.size() != PUBLIC_KEY_LEN) {
883         IAM_LOGE("invalid info");
884         return RESULT_BAD_PARAM;
885     }
886     templateIds.clear();
887     const Buffer *frameworkPubKey = GetPubKey();
888     if (!IsBufferValid(frameworkPubKey)) {
889         IAM_LOGE("get public key failed");
890         return RESULT_UNKNOWN;
891     }
892     publicKey.resize(PUBLIC_KEY_LEN);
893     if (memcpy_s(&publicKey[0], publicKey.size(), frameworkPubKey->buf, frameworkPubKey->contentSize) != EOK) {
894         IAM_LOGE("copy public key failed");
895         publicKey.clear();
896         return RESULT_UNKNOWN;
897     }
898     std::lock_guard<std::mutex> lock(g_mutex);
899     ExecutorInfoHal executorInfoHal = {};
900     CopyExecutorInfo(info, executorInfoHal);
901     int32_t ret = RegisterExecutor(&executorInfoHal, &index);
902     if (ret != RESULT_SUCCESS) {
903         IAM_LOGE("register executor failed");
904         return ret;
905     }
906     if (info.executorRole == VERIFIER || info.executorRole == ALL_IN_ONE) {
907         return ObtainReconciliationData(executorInfoHal.authType, executorInfoHal.executorSensorHint, templateIds);
908     }
909     return RESULT_SUCCESS;
910 }
911 
DeleteExecutor(uint64_t index)912 int32_t UserAuthInterfaceService::DeleteExecutor(uint64_t index)
913 {
914     IAM_LOGI("start");
915     std::lock_guard<std::mutex> lock(g_mutex);
916     return UnRegisterExecutor(index);
917 }
918 
GetAllExtUserInfo(std::vector<ExtUserInfo> & userInfos)919 int32_t UserAuthInterfaceService::GetAllExtUserInfo(std::vector<ExtUserInfo> &userInfos)
920 {
921     IAM_LOGI("start");
922     UserInfoResult *userInfoResult = (UserInfoResult *)Malloc(sizeof(UserInfoResult) * MAX_USER);
923     if (userInfoResult == NULL) {
924         IAM_LOGE("malloc failed");
925         return RESULT_GENERAL_ERROR;
926     }
927     uint32_t userInfoCount = 0;
928     ResultCode ret = QueryAllExtUserInfoFunc(userInfoResult, MAX_USER, &userInfoCount);
929     if (ret != RESULT_SUCCESS) {
930         Free(userInfoResult);
931         IAM_LOGE("QueryAllExtUserInfoFunc failed");
932         return RESULT_GENERAL_ERROR;
933     }
934 
935     for (uint32_t i = 0; i < userInfoCount; i++) {
936         ExtUserInfo info = {};
937         info.userId = userInfoResult[i].userId;
938         info.userInfo.secureUid = userInfoResult[i].secUid;
939         info.userInfo.pinSubType = static_cast<PinSubType>(userInfoResult[i].pinSubType);
940         for (uint32_t j = 0; j < userInfoResult[i].enrollNum; j++) {
941             EnrolledInfo enrolledInfo = {};
942             enrolledInfo.authType = static_cast<AuthType>(userInfoResult[i].enrolledInfo[j].authType);
943             enrolledInfo.enrolledId = userInfoResult[i].enrolledInfo[j].enrolledId;
944             info.userInfo.enrolledInfos.push_back(enrolledInfo);
945         }
946         userInfos.push_back(info);
947     }
948 
949     Free(userInfoResult);
950     return RESULT_SUCCESS;
951 }
952 } // Userauth
953 } // HDI
954 } // OHOS
955