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