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 ¶m,
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 ¶mV1_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 ¶m, 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 ¶mV1_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 ¶m, 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 ¶m, 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