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