1 /*
2 * Copyright (C) 2022-2024 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 "user_idm_funcs.h"
17
18 #include "securec.h"
19
20 #include "adaptor_log.h"
21 #include "adaptor_memory.h"
22 #include "adaptor_time.h"
23 #include "coauth.h"
24 #include "enroll_specification_check.h"
25 #include "executor_message.h"
26 #include "idm_database.h"
27 #include "udid_manager.h"
28
29 #ifdef IAM_TEST_ENABLE
30 #define IAM_STATIC
31 #else
32 #define IAM_STATIC static
33 #endif
34
SetScheduleParam(const PermissionCheckParam * param,ScheduleType scheduleType,ScheduleParam * scheduleParam)35 IAM_STATIC ResultCode SetScheduleParam(const PermissionCheckParam *param, ScheduleType scheduleType,
36 ScheduleParam *scheduleParam)
37 {
38 scheduleParam->associateId.userId = param->userId;
39 scheduleParam->authType = param->authType;
40 scheduleParam->userType = param->userType;
41 scheduleParam->scheduleMode = (scheduleType == SCHEDULE_TYPE_ABANDON) ?
42 SCHEDULE_MODE_ABANDON : SCHEDULE_MODE_ENROLL;
43 scheduleParam->collectorSensorHint = param->executorSensorHint;
44
45 Uint8Array localUdid = { scheduleParam->localUdid, UDID_LEN };
46 bool getLocalUdidRet = GetLocalUdid(&localUdid);
47 if (!getLocalUdidRet) {
48 LOG_ERROR("get udid failed");
49 return RESULT_GENERAL_ERROR;
50 }
51 return RESULT_SUCCESS;
52 }
53
GetEnrollTemplateIdList(ScheduleParam * scheduleParam,const PermissionCheckParam * param)54 IAM_STATIC ResultCode GetEnrollTemplateIdList(ScheduleParam *scheduleParam, const PermissionCheckParam *param)
55 {
56 LinkedList *credList = NULL;
57 if (GetCredentialListByAuthType(param->userId, param->authType, &credList) != RESULT_SUCCESS) {
58 LOG_ERROR("query credential failed");
59 return RESULT_GENERAL_ERROR;
60 }
61 uint64_t templateIdsBuffer[MAX_CREDENTIAL_OUTPUT];
62 uint32_t len = 0;
63 LinkedListNode *temp = credList->head;
64 while (temp != NULL) {
65 if (temp->data == NULL) {
66 LOG_ERROR("list node is invalid");
67 DestroyLinkedList(credList);
68 return RESULT_GENERAL_ERROR;
69 }
70 CredentialInfoHal *credentialHal = (CredentialInfoHal *)(temp->data);
71 if (len >= MAX_CREDENTIAL_OUTPUT) {
72 LOG_ERROR("len out of bound");
73 DestroyLinkedList(credList);
74 return RESULT_GENERAL_ERROR;
75 }
76 templateIdsBuffer[len] = credentialHal->templateId;
77 ++len;
78 temp = temp->next;
79 }
80
81 scheduleParam->templateIds = CreateUint64ArrayByData(templateIdsBuffer, len);
82 DestroyLinkedList(credList);
83 return RESULT_SUCCESS;
84 }
85
CopyTemplateIds(LinkedList * credList,uint64_t * templateIdsBuffer,uint32_t tempalteIdsMaxLen,uint32_t * templateIdsLen)86 IAM_STATIC ResultCode CopyTemplateIds(LinkedList *credList, uint64_t *templateIdsBuffer,
87 uint32_t tempalteIdsMaxLen, uint32_t *templateIdsLen)
88 {
89 uint32_t len = *templateIdsLen;
90 LinkedListNode *temp = credList->head;
91 while (temp != NULL) {
92 if (temp->data == NULL) {
93 LOG_ERROR("list node is invalid");
94 return RESULT_GENERAL_ERROR;
95 }
96 CredentialInfoHal *credentialHal = (CredentialInfoHal *)(temp->data);
97 if (len >= MAX_CREDENTIAL_OUTPUT) {
98 LOG_ERROR("len out of bound");
99 return RESULT_GENERAL_ERROR;
100 }
101 templateIdsBuffer[len] = credentialHal->templateId;
102 ++len;
103 temp = temp->next;
104 }
105 *templateIdsLen = len;
106 return RESULT_SUCCESS;
107 }
108
GetAbandonTemplateIdList(ScheduleParam * scheduleParam,const PermissionCheckParam * param)109 IAM_STATIC ResultCode GetAbandonTemplateIdList(ScheduleParam *scheduleParam, const PermissionCheckParam *param)
110 {
111 uint64_t templateIdsBuffer[MAX_CREDENTIAL_OUTPUT];
112 uint32_t len = 0;
113 LinkedList *currCredList = NULL;
114 LinkedList *cacheCredList = NULL;
115 PinChangeScence pinChangeScence = GetPinChangeScence(param->userId);
116 if (pinChangeScence == PIN_RESET_SCENCE) {
117 if (GetCredentialListByAbandonFlag(param->userId, param->authType, &currCredList) != RESULT_SUCCESS) {
118 LOG_ERROR("query abandon credential failed");
119 goto FAIL;
120 }
121 } else {
122 if (GetCredentialListByAuthType(param->userId, param->authType, &currCredList) != RESULT_SUCCESS) {
123 LOG_ERROR("query current credential failed");
124 goto FAIL;
125 }
126 }
127
128 if (GetCredentialListByCachePin(param->userId, &cacheCredList) != RESULT_SUCCESS) {
129 LOG_ERROR("query current credential failed");
130 goto FAIL;
131 }
132
133 if (currCredList != NULL &&
134 CopyTemplateIds(currCredList, templateIdsBuffer, MAX_CREDENTIAL_OUTPUT, &len) != RESULT_SUCCESS) {
135 LOG_ERROR("copy current credential failed");
136 goto FAIL;
137 }
138
139 if (cacheCredList != NULL &&
140 CopyTemplateIds(cacheCredList, templateIdsBuffer, MAX_CREDENTIAL_OUTPUT, &len) != RESULT_SUCCESS) {
141 LOG_ERROR("copy cache credential failed");
142 goto FAIL;
143 }
144 scheduleParam->templateIds = CreateUint64ArrayByData(templateIdsBuffer, len);
145 FAIL:
146 DestroyLinkedList(currCredList);
147 DestroyLinkedList(cacheCredList);
148 return RESULT_SUCCESS;
149 }
150
GetTemplateIdList(ScheduleParam * scheduleParam,const PermissionCheckParam * param,ScheduleType scheduleType)151 IAM_STATIC ResultCode GetTemplateIdList(ScheduleParam *scheduleParam, const PermissionCheckParam *param,
152 ScheduleType scheduleType)
153 {
154 switch (scheduleType) {
155 case SCHEDULE_TYPE_ENROLL:
156 case SCHEDULE_TYPE_UPDATE: {
157 return GetEnrollTemplateIdList(scheduleParam, param);
158 }
159 case SCHEDULE_TYPE_ABANDON: {
160 return GetAbandonTemplateIdList(scheduleParam, param);
161 }
162 default: {
163 LOG_ERROR("scheduleType:%{public}d", scheduleType);
164 }
165 }
166 return RESULT_GENERAL_ERROR;
167 }
168
GenerateIdmSchedule(const PermissionCheckParam * param,ScheduleType scheduleType)169 IAM_STATIC CoAuthSchedule *GenerateIdmSchedule(const PermissionCheckParam *param, ScheduleType scheduleType)
170 {
171 ResultCode ret = RESULT_SUCCESS;
172 ScheduleParam scheduleParam = {};
173 if (SetScheduleParam(param, scheduleType, &scheduleParam) != RESULT_SUCCESS) {
174 LOG_ERROR("SetScheduleParam failed");
175 return NULL;
176 }
177
178 if (scheduleParam.collectorSensorHint != INVALID_SENSOR_HINT) {
179 ResultCode ret = QueryCollecterMatcher(scheduleParam.authType, scheduleParam.collectorSensorHint,
180 &scheduleParam.executorMatcher);
181 if (ret != RESULT_SUCCESS) {
182 LOG_ERROR("QueryCollecterMatcher failed");
183 return NULL;
184 }
185 }
186
187 ret = GetTemplateIdList(&scheduleParam, param, scheduleType);
188 if (ret != RESULT_SUCCESS) {
189 LOG_ERROR("GetTemplateIdList failed");
190 DestroyUint64Array(&(scheduleParam.templateIds));
191 return NULL;
192 }
193 CoAuthSchedule *coAuthSchedule = GenerateSchedule(&scheduleParam);
194 if (coAuthSchedule == NULL) {
195 LOG_ERROR("GenerateSchedule failed");
196 DestroyUint64Array(&(scheduleParam.templateIds));
197 return NULL;
198 }
199 DestroyUint64Array(&(scheduleParam.templateIds));
200 return coAuthSchedule;
201 }
202
GenerateCoAuthSchedule(PermissionCheckParam * param,ScheduleType scheduleType)203 CoAuthSchedule *GenerateCoAuthSchedule(PermissionCheckParam *param, ScheduleType scheduleType)
204 {
205 CoAuthSchedule *enrollSchedule = GenerateIdmSchedule(param, scheduleType);
206 if (enrollSchedule == NULL) {
207 LOG_ERROR("enrollSchedule malloc failed");
208 return NULL;
209 }
210 ResultCode ret = AddCoAuthSchedule(enrollSchedule);
211 if (ret != RESULT_SUCCESS) {
212 LOG_ERROR("add coauth schedule failed");
213 goto EXIT;
214 }
215 ret = AssociateCoauthSchedule(enrollSchedule->scheduleId, param->authType, scheduleType);
216 if (ret != RESULT_SUCCESS) {
217 LOG_ERROR("idm associate coauth schedule failed");
218 RemoveCoAuthSchedule(enrollSchedule->scheduleId);
219 goto EXIT;
220 }
221 return enrollSchedule;
222
223 EXIT:
224 DestroyCoAuthSchedule(enrollSchedule);
225 return NULL;
226 }
227
CheckEnrollPermission(PermissionCheckParam * param)228 ResultCode CheckEnrollPermission(PermissionCheckParam *param)
229 {
230 if (!GetEnableStatus(param->userId, param->authType)) {
231 LOG_ERROR("authType is not support %{public}d", param->authType);
232 return RESULT_TYPE_NOT_SUPPORT;
233 }
234 ResultCode ret = IsValidUserType(param->userType);
235 if (ret != RESULT_SUCCESS) {
236 LOG_ERROR("userType is invalid");
237 return ret;
238 }
239 ret = CheckSessionValid(param->userId);
240 if (ret != RESULT_SUCCESS) {
241 LOG_ERROR("session is invalid");
242 return ret;
243 }
244 UserAuthTokenHal *authToken = (UserAuthTokenHal *)param->token;
245 ret = CheckSpecification(param->userId, param->authType);
246 if (ret != RESULT_SUCCESS) {
247 LOG_ERROR("check specification failed, authType is %{public}u, ret is %{public}d", param->authType, ret);
248 return ret;
249 }
250 if (param->authType != PIN_AUTH) {
251 ret = CheckIdmOperationToken(param->userId, authToken);
252 if (ret != RESULT_SUCCESS) {
253 LOG_ERROR("a valid token is required");
254 return RESULT_VERIFY_TOKEN_FAIL;
255 }
256 }
257 return RESULT_SUCCESS;
258 }
259
CheckUpdatePermission(PermissionCheckParam * param)260 ResultCode CheckUpdatePermission(PermissionCheckParam *param)
261 {
262 if (param->authType != PIN_AUTH) {
263 LOG_ERROR("param is invalid");
264 return RESULT_BAD_PARAM;
265 }
266 if (!GetEnableStatus(param->userId, param->authType)) {
267 LOG_ERROR("authType is not support %{public}d", param->authType);
268 return RESULT_TYPE_NOT_SUPPORT;
269 }
270 ResultCode ret = CheckSessionValid(param->userId);
271 if (ret != RESULT_SUCCESS) {
272 LOG_ERROR("session is invalid");
273 return ret;
274 }
275 ret = CheckSpecification(param->userId, param->authType);
276 if (ret != RESULT_EXCEED_LIMIT) {
277 LOG_ERROR("no pin or exception, authType is %{public}u, ret is %{public}d", param->authType, ret);
278 return ret;
279 }
280 UserAuthTokenHal *authToken = (UserAuthTokenHal *)param->token;
281 ret = CheckIdmOperationToken(param->userId, authToken);
282 if (ret != RESULT_SUCCESS) {
283 LOG_ERROR("a valid token is required");
284 return RESULT_VERIFY_TOKEN_FAIL;
285 }
286
287 return RESULT_SUCCESS;
288 }
289
GetInfoFromResult(CredentialInfoHal * credentialInfo,const ExecutorResultInfo * result,const CoAuthSchedule * schedule)290 IAM_STATIC void GetInfoFromResult(CredentialInfoHal *credentialInfo, const ExecutorResultInfo *result,
291 const CoAuthSchedule *schedule)
292 {
293 credentialInfo->authType = schedule->authType;
294 credentialInfo->templateId = result->templateId;
295 credentialInfo->capabilityLevel = result->capabilityLevel;
296 credentialInfo->executorSensorHint = GetScheduleVerifierSensorHint(schedule);
297 credentialInfo->executorMatcher = schedule->executors[0].executorMatcher;
298 credentialInfo->credentialType = result->authSubType;
299 credentialInfo->isAbandoned = false;
300 credentialInfo->abandonedSysTime = 0;
301 }
302
GetCredentialInfoFromSchedule(const ExecutorResultInfo * executorInfo,CredentialInfoHal * credentialInfo,const CoAuthSchedule * schedule)303 IAM_STATIC ResultCode GetCredentialInfoFromSchedule(const ExecutorResultInfo *executorInfo,
304 CredentialInfoHal *credentialInfo, const CoAuthSchedule *schedule)
305 {
306 uint64_t currentScheduleId;
307 uint32_t scheduleAuthType;
308 ResultCode ret = GetEnrollScheduleInfo(¤tScheduleId, &scheduleAuthType);
309 if (ret != RESULT_SUCCESS || executorInfo->scheduleId != currentScheduleId) {
310 LOG_ERROR("schedule is mismatch, ret:%{public}d", ret);
311 return RESULT_GENERAL_ERROR;
312 }
313 ret = CheckSessionTimeout();
314 if (ret != RESULT_SUCCESS) {
315 LOG_ERROR("idm session is time out");
316 return ret;
317 }
318 GetInfoFromResult(credentialInfo, executorInfo, schedule);
319 return RESULT_SUCCESS;
320 }
321
GetEnrollTokenDataPlain(const CredentialInfoHal * credentialInfo,TokenDataPlain * dataPlain)322 IAM_STATIC ResultCode GetEnrollTokenDataPlain(const CredentialInfoHal *credentialInfo, TokenDataPlain *dataPlain)
323 {
324 ResultCode ret = GetChallenge(dataPlain->challenge, CHALLENGE_LEN);
325 if (ret != RESULT_SUCCESS) {
326 LOG_ERROR("get challenge fail");
327 return ret;
328 }
329
330 dataPlain->time = GetSystemTime();
331 dataPlain->authTrustLevel = ATL3;
332 dataPlain->authType = credentialInfo->authType;
333 dataPlain->authMode = SCHEDULE_MODE_ENROLL;
334 return RESULT_SUCCESS;
335 }
336
GetEnrollTokenDataToEncrypt(const CredentialInfoHal * credentialInfo,int32_t userId,TokenDataToEncrypt * data)337 IAM_STATIC ResultCode GetEnrollTokenDataToEncrypt(const CredentialInfoHal *credentialInfo, int32_t userId,
338 TokenDataToEncrypt *data)
339 {
340 data->userId = userId;
341 uint64_t secureUid;
342 ResultCode ret = GetSecureUid(userId, &secureUid);
343 if (ret != RESULT_SUCCESS) {
344 LOG_ERROR("get secure uid failed");
345 return ret;
346 }
347 data->secureUid = secureUid;
348 EnrolledInfoHal enrolledInfo = {};
349 ret = GetEnrolledInfoAuthType(userId, credentialInfo->authType, &enrolledInfo);
350 if (ret != RESULT_SUCCESS) {
351 LOG_ERROR("get enrolled info failed");
352 return ret;
353 }
354 data->enrolledId = enrolledInfo.enrolledId;
355 data->credentialId = credentialInfo->credentialId;
356 return RESULT_SUCCESS;
357 }
358
GetAuthTokenForPinEnroll(const CredentialInfoHal * credentialInfo,int32_t userId)359 IAM_STATIC Buffer *GetAuthTokenForPinEnroll(const CredentialInfoHal *credentialInfo, int32_t userId)
360 {
361 UserAuthTokenPlainHal tokenPlain = {};
362 ResultCode ret = GetEnrollTokenDataPlain(credentialInfo, &(tokenPlain.tokenDataPlain));
363 if (ret != RESULT_SUCCESS) {
364 LOG_ERROR("GetEnrollTokenDataPlain fail");
365 return NULL;
366 }
367 ret = GetEnrollTokenDataToEncrypt(credentialInfo, userId, &(tokenPlain.tokenDataToEncrypt));
368 if (ret != RESULT_SUCCESS) {
369 LOG_ERROR("GetEnrollTokenDataToEncrypt fail");
370 return NULL;
371 }
372
373 UserAuthTokenHal authTokenHal = {};
374 ret = UserAuthTokenSign(&tokenPlain, &authTokenHal);
375 if (ret != RESULT_SUCCESS) {
376 LOG_ERROR("generate pin enroll authToken fail");
377 return NULL;
378 }
379 Buffer *authToken = CreateBufferByData((uint8_t *)(&authTokenHal), sizeof(UserAuthTokenHal));
380 if (!IsBufferValid(authToken)) {
381 LOG_ERROR("create authToken buffer fail");
382 return NULL;
383 }
384
385 return authToken;
386 }
387
ProcessAddPinCredential(int32_t userId,const CredentialInfoHal * credentialInfo,const ExecutorResultInfo * executorResultInfo,Buffer ** rootSecret,Buffer ** authToken)388 IAM_STATIC ResultCode ProcessAddPinCredential(int32_t userId, const CredentialInfoHal *credentialInfo,
389 const ExecutorResultInfo *executorResultInfo, Buffer **rootSecret, Buffer **authToken)
390 {
391 ResultCode ret = SetPinSubType(userId, executorResultInfo->authSubType);
392 if (ret != RESULT_SUCCESS) {
393 LOG_ERROR("set pin sub type failed");
394 return ret;
395 }
396 *rootSecret = CopyBuffer(executorResultInfo->rootSecret);
397 if ((*rootSecret) == NULL) {
398 LOG_ERROR("copy rootSecret fail");
399 return RESULT_NO_MEMORY;
400 }
401 *authToken = GetAuthTokenForPinEnroll(credentialInfo, userId);
402 if (!IsBufferValid(*authToken)) {
403 LOG_ERROR("authToken is invalid");
404 DestoryBuffer(*rootSecret);
405 *rootSecret = NULL;
406 return RESULT_NO_MEMORY;
407 }
408
409 return RESULT_SUCCESS;
410 }
411
AddCredentialFunc(int32_t userId,const Buffer * scheduleResult,uint64_t * credentialId,Buffer ** rootSecret,Buffer ** authToken)412 ResultCode AddCredentialFunc(
413 int32_t userId, const Buffer *scheduleResult, uint64_t *credentialId, Buffer **rootSecret, Buffer **authToken)
414 {
415 if (!IsBufferValid(scheduleResult) || credentialId == NULL || rootSecret == NULL || authToken == NULL) {
416 LOG_ERROR("param is null");
417 return RESULT_BAD_PARAM;
418 }
419 int32_t sessionUserId;
420 ResultCode ret = GetUserId(&sessionUserId);
421 if (ret != RESULT_SUCCESS || sessionUserId != userId) {
422 LOG_ERROR("userId mismatch");
423 return RESULT_UNKNOWN;
424 }
425 ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
426 if (executorResultInfo == NULL) {
427 LOG_ERROR("executorResultInfo is null");
428 return RESULT_UNKNOWN;
429 }
430 const CoAuthSchedule *schedule = GetCoAuthSchedule(executorResultInfo->scheduleId);
431 if (schedule == NULL) {
432 LOG_ERROR("schedule is null");
433 ret = RESULT_GENERAL_ERROR;
434 goto EXIT;
435 }
436 CredentialInfoHal credentialInfo;
437 ret = GetCredentialInfoFromSchedule(executorResultInfo, &credentialInfo, schedule);
438 if (ret != RESULT_SUCCESS) {
439 LOG_ERROR("failed to get credential info result");
440 goto EXIT;
441 }
442 ret = AddCredentialInfo(userId, &credentialInfo, schedule->userType);
443 if (ret != RESULT_SUCCESS) {
444 LOG_ERROR("add credential failed");
445 goto EXIT;
446 }
447 *credentialId = credentialInfo.credentialId;
448 if (credentialInfo.authType != PIN_AUTH) {
449 goto EXIT;
450 }
451 ret = ProcessAddPinCredential(userId, &credentialInfo, executorResultInfo, rootSecret, authToken);
452 if (ret != RESULT_SUCCESS) {
453 LOG_ERROR("ProcessAddPinCredential fail");
454 goto EXIT;
455 }
456
457 EXIT:
458 DestroyExecutorResultInfo(executorResultInfo);
459 return ret;
460 }
461
GenerateAbandonSchedule(CredentialDeleteParam param,CoAuthSchedule * info)462 static ResultCode GenerateAbandonSchedule(CredentialDeleteParam param, CoAuthSchedule *info)
463 {
464 PermissionCheckParam checkParam = {};
465 if (memcpy_s(checkParam.token, AUTH_TOKEN_LEN, param.token, AUTH_TOKEN_LEN) != EOK) {
466 LOG_ERROR("bad copy");
467 return RESULT_BAD_COPY;
468 }
469
470 checkParam.userId = param.userId;
471 checkParam.authType = PIN_AUTH;
472 CoAuthSchedule *scheduleInfo = GenerateCoAuthSchedule(&checkParam, SCHEDULE_TYPE_ABANDON);
473 if (scheduleInfo == NULL) {
474 LOG_ERROR("get schedule info failed");
475 BreakOffCoauthSchedule();
476 return RESULT_UNKNOWN;
477 }
478
479 if (memcpy_s(info, sizeof(CoAuthSchedule), scheduleInfo, sizeof(CoAuthSchedule)) != EOK) {
480 LOG_ERROR("bad copy");
481 DestroyCoAuthSchedule(scheduleInfo);
482 BreakOffCoauthSchedule();
483 return RESULT_BAD_COPY;
484 }
485
486 return RESULT_SUCCESS;
487 }
488
DeleteCredentialFunc(CredentialDeleteParam param,OperateResult * operateResult)489 ResultCode DeleteCredentialFunc(CredentialDeleteParam param, OperateResult *operateResult)
490 {
491 if (operateResult == NULL) {
492 LOG_ERROR("param is null");
493 return RESULT_BAD_PARAM;
494 }
495 UserAuthTokenHal token;
496 if (memcpy_s(&token, sizeof(UserAuthTokenHal), param.token, AUTH_TOKEN_LEN) != EOK) {
497 LOG_ERROR("token copy failed");
498 return RESULT_BAD_COPY;
499 }
500 ResultCode ret = CheckIdmOperationToken(param.userId, &token);
501 if (ret != RESULT_SUCCESS) {
502 LOG_ERROR("token is invalid");
503 return RESULT_VERIFY_TOKEN_FAIL;
504 }
505
506 CredentialInfoHal credentialInfo = {};
507 ret = GetCredentialByUserIdAndCredId(param.userId, param.credentialId, &credentialInfo);
508 if (ret != RESULT_SUCCESS) {
509 LOG_ERROR("GetCredentialByUserIdAndCredId failed, ret:%d", ret);
510 return ret;
511 }
512
513 if (credentialInfo.authType == PIN_AUTH && !credentialInfo.isAbandoned) {
514 operateResult->operateType = ABANDON_CREDENTIAL;
515 return GenerateAbandonSchedule(param, &(operateResult->scheduleInfo));
516 }
517 operateResult->operateType = DELETE_CREDENTIAL;
518 operateResult->credentialCount = 0;
519 ret = DeleteCredentialInfo(param.userId, param.credentialId, &(operateResult->credentialInfos[0]));
520 if (ret != RESULT_SUCCESS) {
521 LOG_ERROR("delete database info failed");
522 return RESULT_BAD_SIGN;
523 }
524 operateResult->credentialCount++;
525
526 return RESULT_SUCCESS;
527 }
528
QueryCredentialFunc(int32_t userId,uint32_t authType,LinkedList ** creds)529 ResultCode QueryCredentialFunc(int32_t userId, uint32_t authType, LinkedList **creds)
530 {
531 if (creds == NULL) {
532 LOG_ERROR("creds is null");
533 return RESULT_BAD_PARAM;
534 }
535 CredentialCondition condition = {};
536 SetCredentialConditionUserId(&condition, userId);
537 if (authType != DEFAULT_AUTH_TYPE) {
538 SetCredentialConditionAuthType(&condition, authType);
539 }
540 SetCredentialConditionNeedAbandonPin(&condition);
541 *creds = QueryCredentialLimit(&condition);
542 if (*creds == NULL) {
543 LOG_ERROR("query credential failed");
544 return RESULT_UNKNOWN;
545 }
546 LOG_INFO("query credential success");
547 return RESULT_SUCCESS;
548 }
549
GetUserInfoFunc(int32_t userId,uint64_t * secureUid,uint64_t * pinSubType,EnrolledInfoHal ** enrolledInfoArray,uint32_t * enrolledNum)550 ResultCode GetUserInfoFunc(int32_t userId, uint64_t *secureUid, uint64_t *pinSubType,
551 EnrolledInfoHal **enrolledInfoArray, uint32_t *enrolledNum)
552 {
553 if (secureUid == NULL || pinSubType == NULL || enrolledInfoArray == NULL || enrolledNum == NULL) {
554 LOG_ERROR("param is null");
555 return RESULT_BAD_PARAM;
556 }
557 ResultCode ret = GetSecureUid(userId, secureUid);
558 if (ret != RESULT_SUCCESS) {
559 LOG_ERROR("get secureUid failed");
560 return ret;
561 }
562 ret = GetPinSubType(userId, pinSubType);
563 if (ret != RESULT_SUCCESS) {
564 LOG_ERROR("get pinSubType failed");
565 return ret;
566 }
567 return GetEnrolledInfo(userId, enrolledInfoArray, enrolledNum);
568 }
569
GetDeletedCredential(int32_t userId,CredentialInfoHal * deletedCredential)570 IAM_STATIC ResultCode GetDeletedCredential(int32_t userId, CredentialInfoHal *deletedCredential)
571 {
572 CredentialCondition condition = {};
573 SetCredentialConditionAuthType(&condition, PIN_AUTH);
574 SetCredentialConditionUserId(&condition, userId);
575 LinkedList *credList = QueryCredentialLimit(&condition);
576 if (credList == NULL || credList->head == NULL || credList->head->data == NULL) {
577 LOG_ERROR("query credential failed");
578 DestroyLinkedList(credList);
579 return RESULT_UNKNOWN;
580 }
581 if (credList->getSize(credList) != MAX_NUMBER_OF_PIN_PER_USER) {
582 LOG_ERROR("pin num is invalid");
583 DestroyLinkedList(credList);
584 return RESULT_UNKNOWN;
585 }
586 *deletedCredential = *((CredentialInfoHal *)credList->head->data);
587 DestroyLinkedList(credList);
588 return RESULT_SUCCESS;
589 }
590
CheckResultValid(uint64_t scheduleId,int32_t userId)591 IAM_STATIC ResultCode CheckResultValid(uint64_t scheduleId, int32_t userId)
592 {
593 uint64_t currentScheduleId;
594 uint32_t scheduleAuthType;
595 ResultCode ret = GetEnrollScheduleInfo(¤tScheduleId, &scheduleAuthType);
596 if (ret != RESULT_SUCCESS || scheduleId != currentScheduleId) {
597 LOG_ERROR("schedule is mismatch");
598 return RESULT_GENERAL_ERROR;
599 }
600 ret = CheckSessionTimeout();
601 if (ret != RESULT_SUCCESS) {
602 LOG_ERROR("idm session is time out");
603 return ret;
604 }
605 int32_t userIdGet;
606 ret = GetUserId(&userIdGet);
607 if (ret != RESULT_SUCCESS || userId != userIdGet) {
608 LOG_ERROR("check userId failed");
609 return RESULT_REACH_LIMIT;
610 }
611 if (scheduleAuthType != PIN_AUTH) {
612 LOG_ERROR("only pin is allowed to be updated");
613 return RESULT_UNKNOWN;
614 }
615 return RESULT_SUCCESS;
616 }
617
GetUpdateCredentialOutput(int32_t userId,const Buffer * rootSecret,const CredentialInfoHal * credentialInfo,UpdateCredentialOutput * output)618 IAM_STATIC ResultCode GetUpdateCredentialOutput(int32_t userId, const Buffer *rootSecret,
619 const CredentialInfoHal *credentialInfo, UpdateCredentialOutput *output)
620 {
621 if (credentialInfo->authType != PIN_AUTH && credentialInfo->authType != DEFAULT_AUTH_TYPE) {
622 LOG_ERROR("bad authType");
623 return RESULT_GENERAL_ERROR;
624 }
625 CredentialInfoHal credInfo = (*credentialInfo);
626 credInfo.authType = PIN_AUTH;
627
628 output->credentialId = credInfo.credentialId;
629 output->rootSecret = CopyBuffer(rootSecret);
630 if (!IsBufferValid(output->rootSecret)) {
631 LOG_ERROR("copy rootSecret fail");
632 goto ERROR;
633 }
634 output->oldRootSecret = CopyBuffer(GetCurRootSecret(userId));
635 if (!IsBufferValid(output->oldRootSecret)) {
636 LOG_ERROR("GetCurRootSecret fail");
637 goto ERROR;
638 }
639 output->authToken = GetAuthTokenForPinEnroll(&credInfo, userId);
640 if (!IsBufferValid(output->authToken)) {
641 LOG_ERROR("authToken is invalid");
642 goto ERROR;
643 }
644 return RESULT_SUCCESS;
645
646 ERROR:
647 DestoryBuffer(output->rootSecret);
648 output->rootSecret = NULL;
649 DestoryBuffer(output->oldRootSecret);
650 output->oldRootSecret = NULL;
651 DestoryBuffer(output->authToken);
652 output->authToken = NULL;
653 return RESULT_NO_MEMORY;
654 }
655
UpdateCredentialFunc(int32_t userId,const Buffer * scheduleResult,UpdateCredentialOutput * output)656 ResultCode UpdateCredentialFunc(int32_t userId, const Buffer *scheduleResult, UpdateCredentialOutput *output)
657 {
658 if (!IsBufferValid(scheduleResult) || output == NULL) {
659 LOG_ERROR("param is invalid");
660 return RESULT_BAD_PARAM;
661 }
662 ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
663 if (executorResultInfo == NULL) {
664 LOG_ERROR("executorResultInfo is null");
665 return RESULT_UNKNOWN;
666 }
667 ResultCode ret = CheckResultValid(executorResultInfo->scheduleId, userId);
668 if (ret != RESULT_SUCCESS) {
669 LOG_ERROR("check result failed");
670 goto EXIT;
671 }
672 ret = GetDeletedCredential(userId, &(output->deletedCredential));
673 if (ret != RESULT_SUCCESS) {
674 LOG_ERROR("get old credential failed");
675 goto EXIT;
676 }
677 const CoAuthSchedule *schedule = GetCoAuthSchedule(executorResultInfo->scheduleId);
678 if (schedule == NULL) {
679 LOG_ERROR("schedule is null");
680 ret = RESULT_UNKNOWN;
681 goto EXIT;
682 }
683 CredentialInfoHal credentialInfo;
684 GetInfoFromResult(&credentialInfo, executorResultInfo, schedule);
685 ret = AddCredentialInfo(userId, &credentialInfo, schedule->userType);
686 if (ret != RESULT_SUCCESS) {
687 LOG_ERROR("failed to add credential");
688 goto EXIT;
689 }
690 ret = GetUpdateCredentialOutput(userId, executorResultInfo->rootSecret, &credentialInfo, output);
691 if (ret != RESULT_SUCCESS) {
692 LOG_ERROR("GetUpdateCredentialOutputRootSecret fail");
693 goto EXIT;
694 }
695 ret = SetNewRootSecret(userId, executorResultInfo->rootSecret);
696 if (ret != RESULT_SUCCESS) {
697 LOG_ERROR("SetNewRootSecret fail");
698 goto EXIT;
699 }
700 EXIT:
701 DestroyExecutorResultInfo(executorResultInfo);
702 return ret;
703 }
704
QueryAllExtUserInfoFunc(UserInfoResult * userInfos,uint32_t userInfolen,uint32_t * userInfoCount)705 ResultCode QueryAllExtUserInfoFunc(UserInfoResult *userInfos, uint32_t userInfolen, uint32_t *userInfoCount)
706 {
707 ResultCode ret = GetAllExtUserInfo(userInfos, userInfolen, userInfoCount);
708 if (ret != RESULT_SUCCESS) {
709 LOG_ERROR("GetAllExtUserInfo failed");
710 return RESULT_BAD_PARAM;
711 }
712
713 return RESULT_SUCCESS;
714 }
QueryCredentialByIdFunc(uint64_t credentialId,LinkedList ** creds)715 ResultCode QueryCredentialByIdFunc(uint64_t credentialId, LinkedList **creds)
716 {
717 if (creds == NULL) {
718 LOG_ERROR("creds is null");
719 return RESULT_BAD_PARAM;
720 }
721 CredentialCondition condition = {};
722 SetCredentialConditionCredentialId(&condition, credentialId);
723 SetCredentialConditionNeedCachePin(&condition);
724 SetCredentialConditionNeedAbandonPin(&condition);
725 *creds = QueryCredentialLimit(&condition);
726 if (*creds == NULL) {
727 LOG_ERROR("query credential failed");
728 return RESULT_UNKNOWN;
729 }
730 LOG_INFO("query credential success");
731 return RESULT_SUCCESS;
732 }
733
UpdateAbandonResultInnerFunc(int32_t userId,uint64_t scheduleId,bool * isDelete,CredentialInfoHal * credentialInfo)734 ResultCode UpdateAbandonResultInnerFunc(int32_t userId, uint64_t scheduleId,
735 bool *isDelete, CredentialInfoHal *credentialInfo)
736 {
737 const CoAuthSchedule *schedule = GetCoAuthSchedule(scheduleId);
738 if (schedule == NULL) {
739 LOG_ERROR("schedule is null");
740 return RESULT_GENERAL_ERROR;
741 }
742
743 PinChangeScence pinChangeScence = GetPinChangeScence(userId);
744 if (pinChangeScence == PIN_RESET_SCENCE) {
745 return UpdateAbandonResultForReset(userId, isDelete, credentialInfo);
746 } else {
747 return UpdateAbandonResultForUpdate(userId, isDelete, credentialInfo);
748 }
749
750 LOG_ERROR("UpdateAbandonResultInnerFunc fail, pinChangeScence:%d", pinChangeScence);
751 return RESULT_GENERAL_ERROR;
752 }
753
UpdateAbandonResultFunc(int32_t userId,const Buffer * scheduleResult,bool * isDelete,CredentialInfoHal * credentialInfo)754 ResultCode UpdateAbandonResultFunc(int32_t userId, const Buffer *scheduleResult,
755 bool *isDelete, CredentialInfoHal *credentialInfo)
756 {
757 if (!IsBufferValid(scheduleResult) || isDelete == NULL || credentialInfo == NULL) {
758 LOG_ERROR("query credential failed");
759 return RESULT_BAD_PARAM;
760 }
761
762 ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
763 if (executorResultInfo == NULL) {
764 LOG_ERROR("executorResultInfo is null");
765 return RESULT_UNKNOWN;
766 }
767
768 ResultCode ret = RESULT_GENERAL_ERROR;
769 if (executorResultInfo->result != RESULT_SUCCESS) {
770 LOG_ERROR("executorResultInfo result is %d", executorResultInfo->result);
771 goto EXIT;
772 }
773
774 ret = UpdateAbandonResultInnerFunc(userId, executorResultInfo->scheduleId, isDelete, credentialInfo);
775 if (ret != RESULT_SUCCESS) {
776 LOG_ERROR("UpdateAbandonResultInnerFunc fali, ret:%d", ret);
777 goto EXIT;
778 }
779 EXIT:
780 DestroyExecutorResultInfo(executorResultInfo);
781 return ret;
782 }
783
ClearUnavailableCredentialFunc(int32_t userId,CredentialInfoHal * credentialInfo)784 ResultCode ClearUnavailableCredentialFunc(int32_t userId, CredentialInfoHal *credentialInfo)
785 {
786 if (CheckSessionValid(userId) == RESULT_SUCCESS) {
787 LOG_ERROR("session is vliad, expired pin delay delete");
788 return RESULT_SUCCESS;
789 }
790 return ClearAbandonExpiredCredential(userId, credentialInfo);
791 }