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 "v3_0/user_auth_interface_service.h"
17
18 #include <cinttypes>
19 #include <mutex>
20 #include <hdf_base.h>
21 #include "securec.h"
22 #include <set>
23 #include <string>
24
25 #include "iam_logger.h"
26 #include "iam_para2str.h"
27 #include "iam_ptr.h"
28
29 #include "adaptor_time.h"
30 #include "useriam_common.h"
31 #include "auth_level.h"
32 #include "buffer.h"
33 #include "coauth_funcs.h"
34 #include "executor_message.h"
35 #include "hmac_key.h"
36 #include "identify_funcs.h"
37 #include "idm_database.h"
38 #include "idm_session.h"
39 #include "ed25519_key.h"
40 #include "udid_manager.h"
41 #include "user_auth_hdi.h"
42 #include "user_auth_funcs.h"
43 #include "user_idm_funcs.h"
44 #include "user_sign_centre.h"
45 #include "enroll_specification_check.h"
46
47 #undef LOG_TAG
48 #define LOG_TAG "USER_AUTH_HDI"
49
50 namespace OHOS {
51 namespace HDI {
52 namespace UserAuth {
53 namespace {
54 static std::mutex g_mutex;
55 static std::string g_localUdid;
56 constexpr uint32_t INVALID_CAPABILITY_LEVEL = 100;
57 const std::string SETTRINGS_NAME = "settings";
58 constexpr uint32_t MAX_TOKEN_ALLOWABLE_DURATION = 24 * 60 * 60 * 1000;
59
60 enum UserAuthCallerType : int32_t {
61 TOKEN_INVALID = -1,
62 TOKEN_HAP = 0,
63 TOKEN_NATIVE,
64 };
65 const uint32_t PUBLIC_KEY_STR_LEN = 33;
FormatHexString(uint8_t * data,int32_t dataSize,char * outBuffer,int32_t outBufferSize)66 void FormatHexString(uint8_t* data, int32_t dataSize, char* outBuffer, int32_t outBufferSize)
67 {
68 int32_t writeIndex = 0;
69 do {
70 for (int i = 0; i < dataSize; i++) {
71 int ret = sprintf_s(outBuffer + writeIndex, outBufferSize - writeIndex, "%X", data[i]);
72 if (ret < 0) {
73 writeIndex = 0;
74 break;
75 }
76 writeIndex += ret;
77 }
78 } while (0);
79
80 if (writeIndex == 0) {
81 memset_s(outBuffer, outBufferSize, 0, outBufferSize);
82 }
83 }
84 } // namespace
85
86 using namespace std;
87
UserAuthInterfaceImplGetInstance(void)88 extern "C" IUserAuthInterface *UserAuthInterfaceImplGetInstance(void)
89 {
90 auto userAuthInterfaceService = new (std::nothrow) UserAuthInterfaceService();
91 if (userAuthInterfaceService == nullptr) {
92 IAM_LOGE("userAuthInterfaceService is nullptr");
93 return nullptr;
94 }
95 std::lock_guard<std::mutex> lock(g_mutex);
96 OHOS::UserIam::Common::Init();
97 return userAuthInterfaceService;
98 }
99
Init(const std::string & deviceUdid)100 int32_t UserAuthInterfaceService::Init(const std::string &deviceUdid)
101 {
102 IAM_LOGI("start");
103 std::lock_guard<std::mutex> lock(g_mutex);
104 g_localUdid = deviceUdid;
105 bool ret = SetLocalUdid(g_localUdid.c_str());
106 IF_TRUE_LOGE_AND_RETURN_VAL(!ret, HDF_FAILURE);
107 OHOS::UserIam::Common::Close();
108 return OHOS::UserIam::Common::Init();
109 }
110
CopyScheduleInfo(const CoAuthSchedule * in,HdiScheduleInfo * out)111 static bool CopyScheduleInfo(const CoAuthSchedule *in, HdiScheduleInfo *out)
112 {
113 IAM_LOGI("start");
114 if (in->executorSize == 0 || (in->templateIds.data == NULL && in->templateIds.len != 0)) {
115 IAM_LOGE("executorSize is zero");
116 return false;
117 }
118 out->executorIndexes.clear();
119 out->templateIds.clear();
120 out->scheduleId = in->scheduleId;
121 out->authType = static_cast<AuthType>(in->authType);
122 for (uint32_t i = 0; i < in->templateIds.len; ++i) {
123 out->templateIds.push_back(in->templateIds.data[i]);
124 }
125 out->executorMatcher = static_cast<uint32_t>(in->executors[0].executorMatcher);
126 out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
127 for (uint32_t i = 0; i < in->executorSize; ++i) {
128 out->executorIndexes.push_back(in->executors[i].executorIndex);
129 }
130 out->executorMessages.clear();
131 return true;
132 }
133
SetAttributeToCoAuthExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array publicKey,Attribute * attribute)134 static int32_t SetAttributeToCoAuthExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info,
135 Uint8Array publicKey, Attribute *attribute)
136 {
137 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
138
139 if (SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, info.scheduleId) != RESULT_SUCCESS) {
140 IAM_LOGE("SetAttributeUint64 scheduleId failed");
141 return RESULT_GENERAL_ERROR;
142 }
143
144 Uint8Array localUdidIn = { paramHal.localUdid, sizeof(paramHal.localUdid) };
145 if (SetAttributeUint8Array(attribute, ATTR_VERIFIER_UDID, localUdidIn) != RESULT_SUCCESS) {
146 IAM_LOGE("SetAttributeUint8Array verifierUdid failed");
147 return RESULT_GENERAL_ERROR;
148 }
149 if (SetAttributeUint8Array(attribute, ATTR_LOCAL_UDID, localUdidIn) != RESULT_SUCCESS) {
150 IAM_LOGE("SetAttributeUint8Array localUdid failed");
151 return RESULT_GENERAL_ERROR;
152 }
153 Uint8Array peerUdidIn = { paramHal.collectorUdid, sizeof(paramHal.collectorUdid) };
154 if (SetAttributeUint8Array(attribute, ATTR_COLLECTOR_UDID, peerUdidIn) != RESULT_SUCCESS) {
155 IAM_LOGE("SetAttributeUint8Array collectorUdid failed");
156 return RESULT_GENERAL_ERROR;
157 }
158 if (SetAttributeUint8Array(attribute, ATTR_PEER_UDID, peerUdidIn) != RESULT_SUCCESS) {
159 IAM_LOGE("SetAttributeUint8Array peerUdid failed");
160 return RESULT_GENERAL_ERROR;
161 }
162 char publicKeyStrBuffer[PUBLIC_KEY_STR_LEN] = {0};
163 FormatHexString(&publicKey.data[0], publicKey.len, publicKeyStrBuffer, PUBLIC_KEY_STR_LEN);
164 IAM_LOGI("public key: %{public}s", publicKeyStrBuffer);
165 if (SetAttributeUint8Array(attribute, ATTR_PUBLIC_KEY, publicKey) != RESULT_SUCCESS) {
166 IAM_LOGE("SetAttributeUint8Array publicKey failed");
167 return RESULT_GENERAL_ERROR;
168 }
169 Uint8Array challenge = { paramHal.challenge, CHALLENGE_LEN };
170 if (SetAttributeUint8Array(attribute, ATTR_CHALLENGE, challenge) != RESULT_SUCCESS) {
171 IAM_LOGE("SetAttributeUint8Array challenge failed");
172 return RESULT_GENERAL_ERROR;
173 }
174
175 return RESULT_SUCCESS;
176 }
177
SetAttributeToCollectorExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array publicKey,Uint8Array * retExtraInfo)178 static int32_t SetAttributeToCollectorExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info,
179 Uint8Array publicKey, Uint8Array *retExtraInfo)
180 {
181 Attribute *attribute = CreateEmptyAttribute();
182 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
183
184 ResultCode ret = RESULT_GENERAL_ERROR;
185 do {
186 if (SetAttributeUint32(attribute, ATTR_TYPE, paramHal.authType) != RESULT_SUCCESS) {
187 IAM_LOGE("SetAttributeUint32 authType failed");
188 break;
189 }
190 if (SetAttributeUint32(attribute, ATTR_EXECUTOR_MATCHER, info.executorMatcher) != RESULT_SUCCESS) {
191 IAM_LOGE("SetAttributeUint64 executorMatcher failed");
192 break;
193 }
194 if (SetAttributeInt32(attribute, ATTR_SCHEDULE_MODE, info.scheduleMode) != RESULT_SUCCESS) {
195 IAM_LOGE("SetAttributeUint64 scheduleMode failed");
196 break;
197 }
198 if (SetAttributeUint32(attribute, ATTR_EXECUTOR_ROLE, COLLECTOR) != RESULT_SUCCESS) {
199 IAM_LOGE("SetAttributeUint32 executorRole failed");
200 break;
201 }
202 if (SetAttributeToCoAuthExecMsg(paramHal, info, publicKey, attribute) != RESULT_SUCCESS) {
203 IAM_LOGE("SetAttributeToCoAuthExecMsg failed");
204 break;
205 }
206
207 SignParam signParam = {
208 .needSignature = true,
209 .keyType = KEY_TYPE_CROSS_DEVICE,
210 .peerUdid = { paramHal.collectorUdid, sizeof(paramHal.collectorUdid) }
211 };
212 if (GetAttributeExecutorMsg(attribute, retExtraInfo, signParam) != RESULT_SUCCESS) {
213 IAM_LOGE("GetAttributeExecutorMsg failed");
214 break;
215 }
216 ret = RESULT_SUCCESS;
217 } while (0);
218
219 FreeAttribute(&attribute);
220 return ret;
221 }
222
GetCapabilityLevel(int32_t userId,HdiScheduleInfo & info,uint32_t & capabilityLevel)223 static int32_t GetCapabilityLevel(int32_t userId, HdiScheduleInfo &info, uint32_t &capabilityLevel)
224 {
225 capabilityLevel = INVALID_CAPABILITY_LEVEL;
226 LinkedList *credList = nullptr;
227 int32_t ret = QueryCredentialFunc(userId, info.authType, &credList);
228 if (ret != RESULT_SUCCESS) {
229 IAM_LOGE("query credential failed");
230 return ret;
231 }
232 LinkedListNode *temp = credList->head;
233 while (temp != nullptr) {
234 if (temp->data == nullptr) {
235 IAM_LOGE("list node is invalid");
236 DestroyLinkedList(credList);
237 return RESULT_UNKNOWN;
238 }
239 auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
240 // Only the lowest acl is returned
241 capabilityLevel = (capabilityLevel < credentialHal->capabilityLevel) ?
242 capabilityLevel : credentialHal->capabilityLevel;
243 temp = temp->next;
244 }
245
246 DestroyLinkedList(credList);
247 return RESULT_SUCCESS;
248 }
249
GetExpiredSysTime(AuthParamHal paramHal)250 static uint64_t GetExpiredSysTime(AuthParamHal paramHal)
251 {
252 UserAuthContext *context = GetContext(paramHal.contextId);
253 if (context == NULL) {
254 IAM_LOGE("context is null");
255 return NO_CHECK_PIN_EXPIRED_PERIOD;
256 }
257
258 if (!context->isExpiredReturnSuccess) {
259 return context->authExpiredSysTime;
260 }
261
262 return NO_CHECK_PIN_EXPIRED_PERIOD;
263 }
264
SetAttributeToVerifierExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array publicKey,Uint8Array * retExtraInfo)265 static int32_t SetAttributeToVerifierExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info,
266 Uint8Array publicKey, Uint8Array *retExtraInfo)
267 {
268 Attribute *attribute = CreateEmptyAttribute();
269 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
270
271 ResultCode ret = RESULT_GENERAL_ERROR;
272 do {
273 Uint64Array templateIdsIn = {info.templateIds.data(), info.templateIds.size()};
274 if (SetAttributeUint64Array(attribute, ATTR_TEMPLATE_ID_LIST, templateIdsIn) != RESULT_SUCCESS) {
275 IAM_LOGE("SetAttributeUint64Array templateIdsIn failed");
276 break;
277 }
278 uint32_t capabilityLevel = INVALID_CAPABILITY_LEVEL;
279 int32_t result = GetCapabilityLevel(paramHal.userId, info, capabilityLevel);
280 if (result != RESULT_SUCCESS) {
281 IAM_LOGE("GetCapabilityLevel fail");
282 return result;
283 }
284 if (capabilityLevel != INVALID_CAPABILITY_LEVEL &&
285 SetAttributeUint32(attribute, ATTR_CAPABILITY_LEVEL, capabilityLevel) != RESULT_SUCCESS) {
286 IAM_LOGE("SetAttributeUint32 capabilityLevel failed");
287 break;
288 }
289 if (SetAttributeUint64(attribute, ATTR_EXPIRED_SYS_TIME, GetExpiredSysTime(paramHal)) != RESULT_SUCCESS) {
290 IAM_LOGE("SetAttributeUint64 authExpiredSysTime failed");
291 break;
292 }
293 if (SetAttributeToCoAuthExecMsg(paramHal, info, publicKey, attribute) != RESULT_SUCCESS) {
294 IAM_LOGE("SetAttributeToCoAuthExecMsg failed");
295 break;
296 }
297
298 SignParam signParam = { .needSignature = true, .keyType = KEY_TYPE_EXECUTOR };
299 if (GetAttributeExecutorMsg(attribute, retExtraInfo, signParam) != RESULT_SUCCESS) {
300 IAM_LOGE("GetAttributeExecutorMsg failed");
301 break;
302 }
303 ret = RESULT_SUCCESS;
304 } while (0);
305
306 FreeAttribute(&attribute);
307 return ret;
308 }
309
SetAttributeToExtraInfo(HdiScheduleInfo & info,uint32_t capabilityLevel,uint64_t scheduleId)310 static int32_t SetAttributeToExtraInfo(HdiScheduleInfo &info, uint32_t capabilityLevel, uint64_t scheduleId)
311 {
312 Attribute *attribute = CreateEmptyAttribute();
313 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
314
315 ResultCode ret = RESULT_GENERAL_ERROR;
316 do {
317 Uint64Array templateIdsIn = {info.templateIds.data(), info.templateIds.size()};
318 if (SetAttributeUint64Array(attribute, ATTR_TEMPLATE_ID_LIST, templateIdsIn) != RESULT_SUCCESS) {
319 IAM_LOGE("SetAttributeUint64Array templateIdsIn failed");
320 break;
321 }
322 if (capabilityLevel != INVALID_CAPABILITY_LEVEL &&
323 SetAttributeUint32(attribute, ATTR_CAPABILITY_LEVEL, capabilityLevel) != RESULT_SUCCESS) {
324 IAM_LOGE("SetAttributeUint32 capabilityLevel failed");
325 break;
326 }
327 if (SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, scheduleId) != RESULT_SUCCESS) {
328 IAM_LOGE("SetAttributeUint64 scheduleId failed");
329 break;
330 }
331
332 info.executorMessages.resize(1);
333 info.executorMessages[0].resize(MAX_EXECUTOR_MSG_LEN);
334 Uint8Array retExtraInfo = { info.executorMessages[0].data(), MAX_EXECUTOR_MSG_LEN };
335 SignParam signParam = { .needSignature = true, .keyType = KEY_TYPE_EXECUTOR };
336 if (GetAttributeExecutorMsg(attribute, &retExtraInfo, signParam) != RESULT_SUCCESS) {
337 IAM_LOGE("GetAttributeExecutorMsg failed");
338 info.executorMessages.clear();
339 break;
340 }
341 info.executorMessages[0].resize(retExtraInfo.len);
342 ret = RESULT_SUCCESS;
343 } while (0);
344
345 FreeAttribute(&attribute);
346 return ret;
347 }
348
SetAttributeToAllInOneExecMsg(AuthParamHal paramHal,HdiScheduleInfo & info,Uint8Array * retExtraInfo)349 static int32_t SetAttributeToAllInOneExecMsg(AuthParamHal paramHal, HdiScheduleInfo &info, Uint8Array *retExtraInfo)
350 {
351 uint32_t capabilityLevel = INVALID_CAPABILITY_LEVEL;
352 int32_t result = GetCapabilityLevel(paramHal.userId, info, capabilityLevel);
353 if (result != RESULT_SUCCESS) {
354 IAM_LOGE("GetCapabilityLevel fail");
355 return result;
356 }
357
358 Attribute *attribute = CreateEmptyAttribute();
359 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == nullptr, RESULT_GENERAL_ERROR);
360
361 ResultCode ret = RESULT_GENERAL_ERROR;
362 do {
363 Uint64Array templateIdsIn = {info.templateIds.data(), info.templateIds.size()};
364 if (SetAttributeUint64Array(attribute, ATTR_TEMPLATE_ID_LIST, templateIdsIn) != RESULT_SUCCESS) {
365 IAM_LOGE("SetAttributeUint64Array templateIdsIn failed");
366 break;
367 }
368 if (capabilityLevel != INVALID_CAPABILITY_LEVEL &&
369 SetAttributeUint32(attribute, ATTR_CAPABILITY_LEVEL, capabilityLevel) != RESULT_SUCCESS) {
370 IAM_LOGE("SetAttributeUint32 capabilityLevel failed");
371 break;
372 }
373 if (SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, info.scheduleId) != RESULT_SUCCESS) {
374 IAM_LOGE("SetAttributeUint64 scheduleId failed");
375 break;
376 }
377
378 if (SetAttributeUint64(attribute, ATTR_EXPIRED_SYS_TIME, GetExpiredSysTime(paramHal)) != RESULT_SUCCESS) {
379 IAM_LOGE("SetAttributeUint64 authExpiredSysTime failed");
380 break;
381 }
382
383 Uint8Array challenge = { paramHal.challenge, CHALLENGE_LEN };
384 if (SetAttributeUint8Array(attribute, ATTR_CHALLENGE, challenge) != RESULT_SUCCESS) {
385 IAM_LOGE("SetAttributeUint8Array challenge failed");
386 break;
387 }
388
389 SignParam signParam = { .needSignature = true, .keyType = KEY_TYPE_EXECUTOR };
390 if (GetAttributeExecutorMsg(attribute, retExtraInfo, signParam) != RESULT_SUCCESS) {
391 IAM_LOGE("GetAttributeExecutorMsg failed");
392 break;
393 }
394 ret = RESULT_SUCCESS;
395 } while (0);
396
397 FreeAttribute(&attribute);
398 return ret;
399 }
400
GetAuthExecutorMsg(uint32_t executorRole,AuthParamHal paramHal,Uint8Array publicKey,HdiScheduleInfo & info,Uint8Array * retMsg)401 static int32_t GetAuthExecutorMsg(uint32_t executorRole, AuthParamHal paramHal,
402 Uint8Array publicKey, HdiScheduleInfo &info, Uint8Array *retMsg)
403 {
404 if (executorRole == COLLECTOR) {
405 if (SetAttributeToCollectorExecMsg(paramHal, info, publicKey, retMsg) != RESULT_SUCCESS) {
406 IAM_LOGE("SetAttributeToCollectorExecMsg failed");
407 return RESULT_GENERAL_ERROR;
408 }
409 } else if (executorRole == VERIFIER) {
410 if (SetAttributeToVerifierExecMsg(paramHal, info, publicKey, retMsg) != RESULT_SUCCESS) {
411 IAM_LOGE("SetAttributeToVerifierExecMsg failed");
412 return RESULT_GENERAL_ERROR;
413 }
414 } else if (executorRole == ALL_IN_ONE) {
415 if (SetAttributeToAllInOneExecMsg(paramHal, info, retMsg) != RESULT_SUCCESS) {
416 IAM_LOGE("SetAttributeToAllInOneExecMsg fail");
417 return RESULT_GENERAL_ERROR;
418 }
419 } else {
420 IAM_LOGE("Unsupported executorRole %{public}u", executorRole);
421 return RESULT_GENERAL_ERROR;
422 }
423 return RESULT_SUCCESS;
424 }
425
CopyAuthScheduleInfo(AuthParamHal paramHal,const CoAuthSchedule * in,HdiScheduleInfo * out)426 static bool CopyAuthScheduleInfo(AuthParamHal paramHal, const CoAuthSchedule *in, HdiScheduleInfo *out)
427 {
428 IAM_LOGI("CopyAuthScheduleInfo start");
429 if (in->executorSize == 0 || (in->templateIds.data == NULL && in->templateIds.len != 0)) {
430 IAM_LOGE("executorSize is zero");
431 return false;
432 }
433 out->executorIndexes.clear();
434 out->templateIds.clear();
435 out->scheduleId = in->scheduleId;
436 out->authType = static_cast<AuthType>(in->authType);
437 for (uint32_t i = 0; i < in->templateIds.len; ++i) {
438 out->templateIds.push_back(in->templateIds.data[i]);
439 }
440 out->executorMatcher = static_cast<uint32_t>(in->executors[0].executorMatcher);
441 out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
442
443 out->executorIndexes.resize(in->executorSize);
444 out->executorMessages.resize(in->executorSize);
445 for (uint32_t i = 0; i < in->executorSize; ++i) {
446 out->executorIndexes[i] = in->executors[i].executorIndex;
447 out->executorMessages[i].resize(MAX_EXECUTOR_MSG_LEN);
448 Uint8Array retExtraInfo = { out->executorMessages[i].data(), MAX_EXECUTOR_MSG_LEN };
449 uint32_t executorRoleTemp = static_cast<ExecutorRole>(in->executors[i].executorRole);
450 Uint8Array publicKeyInfo = { (uint8_t *)in->executors[1 - i].pubKey, PUBLIC_KEY_LEN };
451 if (GetAuthExecutorMsg(executorRoleTemp, paramHal, publicKeyInfo, *out, &retExtraInfo) != RESULT_SUCCESS) {
452 IAM_LOGE("GetAuthExecutorMsg failed");
453 out->executorIndexes.clear();
454 out->templateIds.clear();
455 out->executorMessages.clear();
456 return false;
457 }
458 out->executorMessages[i].resize(retExtraInfo.len);
459 }
460 return true;
461 }
462
CopyAuthParamToHal(uint64_t contextId,const HdiAuthParam & param,AuthParamHal & paramHal)463 static int32_t CopyAuthParamToHal(uint64_t contextId, const HdiAuthParam ¶m,
464 AuthParamHal ¶mHal)
465 {
466 paramHal.contextId = contextId;
467 paramHal.userId = param.baseParam.userId;
468 paramHal.authType = static_cast<int32_t>(param.authType);
469 paramHal.authTrustLevel = param.baseParam.authTrustLevel;
470 if (!param.baseParam.challenge.empty() && memcpy_s(paramHal.challenge, CHALLENGE_LEN,
471 param.baseParam.challenge.data(), param.baseParam.challenge.size()) != EOK) {
472 IAM_LOGE("challenge copy failed");
473 return RESULT_BAD_COPY;
474 }
475 paramHal.authIntent = param.authIntent;
476 paramHal.isExpiredReturnSuccess = false;
477 if (param.baseParam.callerType == TOKEN_HAP &&
478 (param.baseParam.callerName.find(SETTRINGS_NAME) != std::string::npos ||
479 param.authIntent == HdiAuthIntent::UNLOCK)) {
480 paramHal.isExpiredReturnSuccess = true;
481 }
482 if (!param.collectorUdid.empty()) {
483 if (memcpy_s(paramHal.collectorUdid, sizeof(paramHal.collectorUdid),
484 (uint8_t *)param.collectorUdid.c_str(), param.collectorUdid.length()) != EOK) {
485 IAM_LOGE("collectorUdid copy failed");
486 return RESULT_BAD_COPY;
487 }
488 } else {
489 Uint8Array collectorUdid = { paramHal.collectorUdid, sizeof(paramHal.collectorUdid) };
490 if (!GetLocalUdid(&collectorUdid)) {
491 IAM_LOGE("fill collector udid by local udid failed");
492 return RESULT_GENERAL_ERROR;
493 }
494 }
495 Uint8Array localUdid = { paramHal.localUdid, sizeof(paramHal.localUdid) };
496 if (!GetLocalUdid(&localUdid)) {
497 IAM_LOGE("GetLocalUdid failed");
498 return RESULT_GENERAL_ERROR;
499 }
500 return RESULT_SUCCESS;
501 }
502
BeginAuthentication(uint64_t contextId,const HdiAuthParam & param,std::vector<HdiScheduleInfo> & infos)503 int32_t UserAuthInterfaceService::BeginAuthentication(uint64_t contextId, const HdiAuthParam ¶m,
504 std::vector<HdiScheduleInfo> &infos)
505 {
506 IAM_LOGI("start");
507 infos.clear();
508 AuthParamHal paramHal = {};
509 int32_t ret = CopyAuthParamToHal(contextId, param, paramHal);
510 if (ret != RESULT_SUCCESS) {
511 IAM_LOGE("copy CopyAuthParamToHal failed %{public}d", ret);
512 return ret;
513 }
514 std::lock_guard<std::mutex> lock(g_mutex);
515 LinkedList *schedulesGet = nullptr;
516 ret = GenerateSolutionFunc(paramHal, &schedulesGet);
517 if (ret != RESULT_SUCCESS) {
518 IAM_LOGE("generate solution failed %{public}d", ret);
519 return ret;
520 }
521 if (schedulesGet == nullptr) {
522 IAM_LOGE("get null schedule");
523 return RESULT_GENERAL_ERROR;
524 }
525 LinkedListNode *tempNode = schedulesGet->head;
526 while (tempNode != nullptr) {
527 if (tempNode->data == nullptr) {
528 IAM_LOGE("node data is invalid");
529 DestroyLinkedList(schedulesGet);
530 return RESULT_UNKNOWN;
531 }
532 HdiScheduleInfo temp = {};
533 auto coAuthSchedule = static_cast<CoAuthSchedule *>(tempNode->data);
534 if (!CopyAuthScheduleInfo(paramHal, coAuthSchedule, &temp)) {
535 infos.clear();
536 IAM_LOGE("copy schedule info failed");
537 DestroyLinkedList(schedulesGet);
538 return RESULT_GENERAL_ERROR;
539 }
540 infos.push_back(temp);
541 tempNode = tempNode->next;
542 }
543 DestroyLinkedList(schedulesGet);
544 return ret;
545 }
546
GetAllUserInfo(std::vector<UserInfo> & userInfos)547 int32_t UserAuthInterfaceService::GetAllUserInfo(std::vector<UserInfo> &userInfos)
548 {
549 IAM_LOGI("GetAllUserInfo mock start");
550 static_cast<void>(userInfos);
551
552 return RESULT_SUCCESS;
553 }
554
CreateExecutorCommand(int32_t userId,HdiAuthResultInfo & info)555 static int32_t CreateExecutorCommand(int32_t userId, HdiAuthResultInfo &info)
556 {
557 LinkedList *executorSendMsg = nullptr;
558 AuthPropertyMode authPropMode;
559 if (info.result == RESULT_SUCCESS) {
560 authPropMode = PROPERTY_MODE_UNFREEZE;
561 } else if (info.remainAttempts == 0) {
562 authPropMode = PROPERTY_MODE_FREEZE;
563 } else {
564 return RESULT_SUCCESS;
565 }
566 ResultCode ret = GetExecutorMsgList(userId, authPropMode, &executorSendMsg);
567 if (ret != RESULT_SUCCESS) {
568 IAM_LOGE("get executor msg failed");
569 return ret;
570 }
571
572 LinkedListNode *temp = executorSendMsg->head;
573 while (temp != nullptr) {
574 if (temp->data == nullptr) {
575 IAM_LOGE("list node is invalid");
576 DestroyLinkedList(executorSendMsg);
577 return RESULT_UNKNOWN;
578 }
579 auto nodeData = static_cast<ExecutorMsg *>(temp->data);
580 Buffer *nodeMsgBuffer = nodeData->msg;
581 if (!IsBufferValid(nodeMsgBuffer)) {
582 IAM_LOGE("node's buffer invalid");
583 DestroyLinkedList(executorSendMsg);
584 return RESULT_UNKNOWN;
585 }
586 HdiExecutorSendMsg msg = {};
587 msg.executorIndex = nodeData->executorIndex;
588 msg.commandId = static_cast<int32_t>(authPropMode);
589 msg.msg.resize(nodeMsgBuffer->contentSize);
590 if (memcpy_s(msg.msg.data(), msg.msg.size(), nodeMsgBuffer->buf, nodeMsgBuffer->contentSize) != EOK) {
591 IAM_LOGE("copy failed");
592 msg.msg.clear();
593 DestroyLinkedList(executorSendMsg);
594 return RESULT_BAD_COPY;
595 }
596 info.msgs.push_back(msg);
597 temp = temp->next;
598 }
599 DestroyLinkedList(executorSendMsg);
600 return RESULT_SUCCESS;
601 }
602
CopyAuthResult(AuthResult & infoIn,UserAuthTokenHal & authTokenIn,HdiAuthResultInfo & infoOut,HdiEnrolledState & enrolledStateOut)603 static int32_t CopyAuthResult(AuthResult &infoIn, UserAuthTokenHal &authTokenIn, HdiAuthResultInfo &infoOut,
604 HdiEnrolledState &enrolledStateOut)
605 {
606 IAM_LOGI("start");
607 infoOut.result = infoIn.result;
608 infoOut.remainAttempts = infoIn.remainTimes;
609 infoOut.lockoutDuration = infoIn.freezingTime;
610 enrolledStateOut.credentialDigest = infoIn.credentialDigest;
611 enrolledStateOut.credentialCount = infoIn.credentialCount;
612 infoOut.pinExpiredInfo = infoIn.pinExpiredInfo;
613 if (infoOut.result == RESULT_SUCCESS) {
614 infoOut.userId = infoIn.userId;
615 infoOut.credentialId = infoIn.credentialId;
616 IAM_LOGI("matched userId: %{public}d, credentialId: %{public}s.",
617 infoOut.userId, GET_MASKED_STRING(infoOut.credentialId).c_str());
618 infoOut.token.resize(sizeof(UserAuthTokenHal));
619 if (memcpy_s(infoOut.token.data(), infoOut.token.size(), &authTokenIn, sizeof(UserAuthTokenHal)) != EOK) {
620 IAM_LOGE("copy authToken failed");
621 infoOut.token.clear();
622 return RESULT_BAD_COPY;
623 }
624 if (infoIn.rootSecret != nullptr) {
625 infoOut.rootSecret.resize(infoIn.rootSecret->contentSize);
626 if (memcpy_s(infoOut.rootSecret.data(), infoOut.rootSecret.size(),
627 infoIn.rootSecret->buf, infoIn.rootSecret->contentSize) != EOK) {
628 IAM_LOGE("copy secret failed");
629 infoOut.rootSecret.clear();
630 infoOut.token.clear();
631 return RESULT_BAD_COPY;
632 }
633 }
634 }
635 if (infoIn.remoteAuthResultMsg != nullptr) {
636 infoOut.remoteAuthResultMsg.resize(infoIn.remoteAuthResultMsg->contentSize);
637 if (memcpy_s(infoOut.remoteAuthResultMsg.data(), infoOut.remoteAuthResultMsg.size(),
638 infoIn.remoteAuthResultMsg->buf, infoIn.remoteAuthResultMsg->contentSize) != EOK) {
639 IAM_LOGE("copy remoteAuthResultMsg failed");
640 infoOut.remoteAuthResultMsg.clear();
641 infoOut.rootSecret.clear();
642 infoOut.token.clear();
643 return RESULT_BAD_COPY;
644 }
645 }
646 infoOut.userId = infoIn.userId;
647 IAM_LOGI("matched userId: %{public}d.", infoOut.userId);
648 return RESULT_SUCCESS;
649 }
650
UpdateAuthenticationResultInner(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,HdiAuthResultInfo & info,HdiEnrolledState & enrolledState)651 static int32_t UpdateAuthenticationResultInner(uint64_t contextId,
652 const std::vector<uint8_t> &scheduleResult, HdiAuthResultInfo &info, HdiEnrolledState &enrolledState)
653 {
654 IAM_LOGI("start");
655 if (scheduleResult.size() == 0) {
656 IAM_LOGE("param is invalid");
657 DestroyContextbyId(contextId);
658 return RESULT_BAD_PARAM;
659 }
660 Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
661 if (!IsBufferValid(scheduleResultBuffer)) {
662 IAM_LOGE("scheduleTokenBuffer is invalid");
663 DestroyContextbyId(contextId);
664 return RESULT_NO_MEMORY;
665 }
666 std::lock_guard<std::mutex> lock(g_mutex);
667 UserAuthTokenHal authTokenHal = {};
668 AuthResult authResult = {};
669 int32_t funcRet = RESULT_GENERAL_ERROR;
670 do {
671 int32_t ret = RequestAuthResultFunc(contextId, scheduleResultBuffer, &authTokenHal, &authResult);
672 DestoryBuffer(scheduleResultBuffer);
673 if (ret != RESULT_SUCCESS) {
674 IAM_LOGE("execute func failed");
675 break;
676 }
677 ret = CopyAuthResult(authResult, authTokenHal, info, enrolledState);
678 if (ret != RESULT_SUCCESS) {
679 IAM_LOGE("Copy auth result failed");
680 break;
681 }
682 if (authResult.authType != PIN_AUTH) {
683 IAM_LOGI("type not pin");
684 } else {
685 IAM_LOGI("type pin");
686 ret = CreateExecutorCommand(authResult.userId, info);
687 if (ret != RESULT_SUCCESS) {
688 IAM_LOGE("create executor command failed");
689 break;
690 }
691 }
692 funcRet = RESULT_SUCCESS;
693 } while (0);
694
695 DestroyAuthResult(&authResult);
696 return funcRet;
697 }
698
UpdateAuthenticationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,HdiAuthResultInfo & info,HdiEnrolledState & enrolledState)699 int32_t UserAuthInterfaceService::UpdateAuthenticationResult(uint64_t contextId,
700 const std::vector<uint8_t> &scheduleResult, HdiAuthResultInfo &info, HdiEnrolledState &enrolledState)
701 {
702 IAM_LOGI("start");
703 return UpdateAuthenticationResultInner(contextId, scheduleResult, info, enrolledState);
704 }
705
CancelAuthentication(uint64_t contextId)706 int32_t UserAuthInterfaceService::CancelAuthentication(uint64_t contextId)
707 {
708 IAM_LOGI("start");
709 std::lock_guard<std::mutex> lock(g_mutex);
710 return DestroyContextbyId(contextId);
711 }
712
BeginIdentification(uint64_t contextId,int32_t authType,const std::vector<uint8_t> & challenge,uint32_t executorSensorHint,HdiScheduleInfo & scheduleInfo)713 int32_t UserAuthInterfaceService::BeginIdentification(uint64_t contextId, int32_t authType,
714 const std::vector<uint8_t> &challenge, uint32_t executorSensorHint, HdiScheduleInfo &scheduleInfo)
715 {
716 IAM_LOGI("start");
717 if (authType == PIN) {
718 IAM_LOGE("param is invalid");
719 return RESULT_BAD_PARAM;
720 }
721 IdentifyParam param = {};
722 param.contextId = contextId;
723 param.authType = static_cast<uint32_t>(authType);
724 param.executorSensorHint = executorSensorHint;
725 if (!challenge.empty() && memcpy_s(param.challenge, CHALLENGE_LEN, challenge.data(), challenge.size()) != EOK) {
726 IAM_LOGE("challenge copy failed");
727 return RESULT_BAD_COPY;
728 }
729 std::lock_guard<std::mutex> lock(g_mutex);
730 LinkedList *scheduleGet = nullptr;
731 int32_t ret = DoIdentify(param, &scheduleGet);
732 if (ret != RESULT_SUCCESS) {
733 IAM_LOGE("generate solution failed");
734 return ret;
735 }
736 if (scheduleGet == nullptr) {
737 IAM_LOGE("get null schedule");
738 return RESULT_GENERAL_ERROR;
739 }
740 if (scheduleGet->head == nullptr || scheduleGet->head->data == nullptr) {
741 IAM_LOGE("scheduleGet is invalid");
742 DestroyLinkedList(scheduleGet);
743 return RESULT_UNKNOWN;
744 }
745 auto data = static_cast<CoAuthSchedule *>(scheduleGet->head->data);
746 if (!CopyScheduleInfo(data, &scheduleInfo)) {
747 IAM_LOGE("copy schedule failed");
748 ret = RESULT_BAD_COPY;
749 }
750 DestroyLinkedList(scheduleGet);
751 return ret;
752 }
753
UpdateIdentificationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,IdentifyResultInfo & info)754 int32_t UserAuthInterfaceService::UpdateIdentificationResult(uint64_t contextId,
755 const std::vector<uint8_t> &scheduleResult, IdentifyResultInfo &info)
756 {
757 IAM_LOGI("start");
758 if (scheduleResult.size() == 0) {
759 IAM_LOGE("param is invalid");
760 return RESULT_BAD_PARAM;
761 }
762 Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
763 if (!IsBufferValid(scheduleResultBuffer)) {
764 IAM_LOGE("scheduleTokenBuffer is invalid");
765 return RESULT_NO_MEMORY;
766 }
767 std::lock_guard<std::mutex> lock(g_mutex);
768 UserAuthTokenHal token = {};
769 int32_t ret = DoUpdateIdentify(contextId, scheduleResultBuffer, &info.userId, &token, &info.result);
770 DestoryBuffer(scheduleResultBuffer);
771 if (ret != RESULT_SUCCESS) {
772 IAM_LOGE("DoUpdateIdentify failed");
773 return ret;
774 }
775 if (info.result == RESULT_SUCCESS) {
776 info.token.resize(sizeof(UserAuthTokenHal));
777 if (memcpy_s(info.token.data(), info.token.size(), &token, sizeof(token)) != EOK) {
778 IAM_LOGE("copy authToken failed");
779 info.token.clear();
780 return RESULT_BAD_COPY;
781 }
782 }
783 return RESULT_SUCCESS;
784 }
785
CancelIdentification(uint64_t contextId)786 int32_t UserAuthInterfaceService::CancelIdentification(uint64_t contextId)
787 {
788 IAM_LOGI("start");
789 std::lock_guard<std::mutex> lock(g_mutex);
790 return DestroyContextbyId(contextId);
791 }
792
GetAvailableStatus(int32_t userId,int32_t authType,uint32_t authTrustLevel,int32_t & checkResult)793 int32_t UserAuthInterfaceService::GetAvailableStatus(int32_t userId, int32_t authType, uint32_t authTrustLevel,
794 int32_t &checkResult)
795 {
796 IAM_LOGI("start");
797 std::lock_guard<std::mutex> lock(g_mutex);
798 checkResult = GetAvailableStatusFunc(userId, authType, authTrustLevel);
799 if (checkResult != RESULT_SUCCESS) {
800 IAM_LOGE("GetAvailableStatusFunc failed");
801 }
802 return RESULT_SUCCESS;
803 }
804
GetValidSolution(int32_t userId,const std::vector<int32_t> & authTypes,uint32_t authTrustLevel,std::vector<int32_t> & validTypes)805 int32_t UserAuthInterfaceService::GetValidSolution(int32_t userId, const std::vector<int32_t> &authTypes,
806 uint32_t authTrustLevel, std::vector<int32_t> &validTypes)
807 {
808 IAM_LOGI("start userId:%{public}d authTrustLevel:%{public}u", userId, authTrustLevel);
809 static int32_t resultPriority[] = {RESULT_GENERAL_ERROR, RESULT_TYPE_NOT_SUPPORT, RESULT_TRUST_LEVEL_NOT_SUPPORT,
810 RESULT_NOT_ENROLLED, RESULT_PIN_EXPIRED};
811 int32_t result = RESULT_GENERAL_ERROR;
812 validTypes.clear();
813 std::lock_guard<std::mutex> lock(g_mutex);
814 for (auto &authType : authTypes) {
815 int32_t checkRet = GetAvailableStatusFunc(userId, authType, authTrustLevel);
816 if (checkRet == RESULT_SUCCESS) {
817 IAM_LOGI("get valid authType:%{public}d", authType);
818 validTypes.push_back(authType);
819 continue;
820 }
821 bool isResultFound = false;
822 for (uint32_t i = 0; i < sizeof(resultPriority) / sizeof(int32_t); i++) {
823 if (resultPriority[i] == result) {
824 isResultFound = true;
825 }
826 if (resultPriority[i] == checkRet && isResultFound) {
827 IAM_LOGI("checkRet:%{public}d higher priority than result:%{public}d", checkRet, result);
828 result = checkRet;
829 break;
830 }
831 }
832 }
833 if (validTypes.empty()) {
834 IAM_LOGE("no auth type valid");
835 return result;
836 }
837 return RESULT_SUCCESS;
838 }
839
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)840 int32_t UserAuthInterfaceService::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
841 {
842 IAM_LOGI("start");
843 std::lock_guard<std::mutex> lock(g_mutex);
844 challenge.resize(CHALLENGE_LEN);
845 int32_t ret = OpenEditSession(userId, challenge.data(), challenge.size());
846 if (ret != RESULT_SUCCESS) {
847 IAM_LOGE("failed to open session");
848 challenge.clear();
849 }
850 return ret;
851 }
852
CloseSession(int32_t userId)853 int32_t UserAuthInterfaceService::CloseSession(int32_t userId)
854 {
855 IAM_LOGI("start");
856 std::lock_guard<std::mutex> lock(g_mutex);
857 return CloseEditSession();
858 }
859
BeginEnrollment(const std::vector<uint8_t> & authToken,const HdiEnrollParam & param,HdiScheduleInfo & info)860 int32_t UserAuthInterfaceService::BeginEnrollment(
861 const std::vector<uint8_t> &authToken, const HdiEnrollParam ¶m, HdiScheduleInfo &info)
862 {
863 IAM_LOGI("start");
864 if (authToken.size() != sizeof(UserAuthTokenHal) && authToken.size() != 0) {
865 IAM_LOGE("authToken len is invalid");
866 return RESULT_BAD_PARAM;
867 }
868 PermissionCheckParam checkParam = {};
869 if (authToken.size() == sizeof(UserAuthTokenHal) &&
870 memcpy_s(checkParam.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
871 return RESULT_BAD_COPY;
872 }
873 checkParam.authType = param.authType;
874 checkParam.userId = param.userId;
875 checkParam.executorSensorHint = param.executorSensorHint;
876 checkParam.userType = param.userType;
877 std::lock_guard<std::mutex> lock(g_mutex);
878 uint64_t scheduleId;
879 int32_t ret;
880 if (authToken.size() == sizeof(UserAuthTokenHal) && param.authType == PIN) {
881 ret = CheckUpdatePermission(checkParam, &scheduleId);
882 if (ret != RESULT_SUCCESS) {
883 IAM_LOGE("check update permission failed");
884 return ret;
885 }
886 } else {
887 ret = CheckEnrollPermission(checkParam, &scheduleId);
888 if (ret != RESULT_SUCCESS) {
889 IAM_LOGE("check enroll permission failed");
890 return ret;
891 }
892 }
893 const CoAuthSchedule *scheduleInfo = GetCoAuthSchedule(scheduleId);
894 if (scheduleInfo == nullptr) {
895 IAM_LOGE("get schedule info failed");
896 return RESULT_UNKNOWN;
897 }
898 if (!CopyScheduleInfo(scheduleInfo, &info)) {
899 IAM_LOGE("copy schedule info failed");
900 return RESULT_BAD_COPY;
901 }
902 ret = SetAttributeToExtraInfo(info, INVALID_CAPABILITY_LEVEL, scheduleId);
903 if (ret != RESULT_SUCCESS) {
904 IAM_LOGE("SetAttributeToExtraInfo failed");
905 }
906
907 IAM_LOGI("end");
908 return ret;
909 }
910
CancelEnrollment(int32_t userId)911 int32_t UserAuthInterfaceService::CancelEnrollment(int32_t userId)
912 {
913 IAM_LOGI("start");
914 std::lock_guard<std::mutex> lock(g_mutex);
915 BreakOffCoauthSchedule();
916 return RESULT_SUCCESS;
917 }
918
CopyCredentialInfo(const CredentialInfoHal & in,HdiCredentialInfo & out)919 static void CopyCredentialInfo(const CredentialInfoHal &in, HdiCredentialInfo &out)
920 {
921 out.authType = static_cast<AuthType>(in.authType);
922 out.authSubType = in.credentialType;
923 out.credentialId = in.credentialId;
924 out.templateId = in.templateId;
925 out.executorMatcher = in.executorMatcher;
926 out.executorSensorHint = in.executorSensorHint;
927 out.executorIndex = QueryCredentialExecutorIndex(in.authType, in.executorSensorHint);
928 }
929
GetUpdateResult(int32_t userId,HdiEnrollResultInfo & info,Buffer * scheduleResultBuffer)930 static int32_t GetUpdateResult(int32_t userId, HdiEnrollResultInfo &info, Buffer *scheduleResultBuffer)
931 {
932 UpdateCredentialOutput output = {};
933 int32_t ret = UpdateCredentialFunc(userId, scheduleResultBuffer, &output);
934 if (ret == RESULT_SUCCESS) {
935 /* Only update pin have oldRootSecret and rootSecret */
936 info.rootSecret.resize(ROOT_SECRET_LEN);
937 if (memcpy_s(info.rootSecret.data(), ROOT_SECRET_LEN, output.rootSecret->buf, ROOT_SECRET_LEN) != EOK) {
938 IAM_LOGE("failed to copy rootSecret");
939 ret = RESULT_BAD_COPY;
940 goto ERROR;
941 }
942 info.oldRootSecret.resize(ROOT_SECRET_LEN);
943 if (memcpy_s(info.oldRootSecret.data(), ROOT_SECRET_LEN, output.oldRootSecret->buf, ROOT_SECRET_LEN) != EOK) {
944 IAM_LOGE("failed to copy oldRootSecret");
945 ret = RESULT_BAD_COPY;
946 goto ERROR;
947 }
948 info.authToken.resize(AUTH_TOKEN_LEN);
949 if (memcpy_s(info.authToken.data(), AUTH_TOKEN_LEN, output.authToken->buf, AUTH_TOKEN_LEN) != EOK) {
950 IAM_LOGE("failed to copy authToken");
951 ret = RESULT_BAD_COPY;
952 goto ERROR;
953 }
954 info.credentialId = output.credentialId;
955 CopyCredentialInfo(output.deletedCredential, info.oldInfo);
956 goto EXIT;
957 }
958
959 ERROR:
960 (void)memset_s(info.rootSecret.data(), info.rootSecret.size(), 0, info.rootSecret.size());
961 info.rootSecret.clear();
962 (void)memset_s(info.oldRootSecret.data(), info.oldRootSecret.size(), 0, info.oldRootSecret.size());
963 info.oldRootSecret.clear();
964 (void)memset_s(info.authToken.data(), info.authToken.size(), 0, info.authToken.size());
965 info.authToken.clear();
966
967 EXIT:
968 DestoryBuffer(output.rootSecret);
969 DestoryBuffer(output.oldRootSecret);
970 DestoryBuffer(output.authToken);
971 return ret;
972 }
973
GetEnrollResult(int32_t userId,HdiEnrollResultInfo & info,Buffer * scheduleResultBuffer)974 static int32_t GetEnrollResult(int32_t userId, HdiEnrollResultInfo &info, Buffer *scheduleResultBuffer)
975 {
976 Buffer *authToken = nullptr;
977 Buffer *rootSecret = nullptr;
978 int32_t ret = AddCredentialFunc(userId, scheduleResultBuffer, &info.credentialId, &rootSecret, &authToken);
979 if (ret == RESULT_SUCCESS) {
980 /* Only enroll pin have authToken and rootSecret */
981 if (authToken != nullptr) {
982 info.authToken.resize(authToken->contentSize);
983 if (memcpy_s(info.authToken.data(), info.authToken.size(), authToken->buf, authToken->contentSize) != EOK) {
984 IAM_LOGE("failed to copy authToken");
985 info.authToken.clear();
986 DestoryBuffer(authToken);
987 DestoryBuffer(rootSecret);
988 return RESULT_BAD_COPY;
989 }
990 }
991 if (rootSecret != nullptr) {
992 info.rootSecret.resize(rootSecret->contentSize);
993 if (memcpy_s(info.rootSecret.data(), info.rootSecret.size(), rootSecret->buf,
994 rootSecret->contentSize) != EOK) {
995 IAM_LOGE("failed to copy rootSecret");
996 info.rootSecret.clear();
997 ret = RESULT_BAD_COPY;
998 }
999 }
1000 }
1001 DestoryBuffer(authToken);
1002 DestoryBuffer(rootSecret);
1003 return ret;
1004 }
1005
UpdateEnrollmentResult(int32_t userId,const std::vector<uint8_t> & scheduleResult,HdiEnrollResultInfo & info)1006 int32_t UserAuthInterfaceService::UpdateEnrollmentResult(int32_t userId, const std::vector<uint8_t> &scheduleResult,
1007 HdiEnrollResultInfo &info)
1008 {
1009 IAM_LOGI("start");
1010 if (scheduleResult.size() == 0) {
1011 IAM_LOGE("enrollToken is invalid");
1012 return RESULT_BAD_PARAM;
1013 }
1014 Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
1015 if (scheduleResultBuffer == nullptr) {
1016 IAM_LOGE("scheduleTokenBuffer is null");
1017 return RESULT_NO_MEMORY;
1018 }
1019 std::lock_guard<std::mutex> lock(g_mutex);
1020 bool isUpdate;
1021 int32_t ret = GetIsUpdate(&isUpdate);
1022 if (ret != RESULT_SUCCESS) {
1023 IAM_LOGE("get isUpdate failed");
1024 DestoryBuffer(scheduleResultBuffer);
1025 return ret;
1026 }
1027 if (isUpdate) {
1028 ret = GetUpdateResult(userId, info, scheduleResultBuffer);
1029 if (ret != RESULT_SUCCESS) {
1030 IAM_LOGE("GetUpdateResult failed");
1031 }
1032 } else {
1033 ret = GetEnrollResult(userId, info, scheduleResultBuffer);
1034 if (ret != RESULT_SUCCESS) {
1035 IAM_LOGE("GetEnrollResult failed");
1036 }
1037 }
1038
1039 DestoryBuffer(scheduleResultBuffer);
1040 return ret;
1041 }
1042
DeleteCredential(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,CredentialInfo & info)1043 int32_t UserAuthInterfaceService::DeleteCredential(int32_t userId, uint64_t credentialId,
1044 const std::vector<uint8_t> &authToken, CredentialInfo &info)
1045 {
1046 IAM_LOGI("start");
1047 if (authToken.size() != sizeof(UserAuthTokenHal)) {
1048 IAM_LOGE("authToken len is invalid");
1049 return RESULT_BAD_PARAM;
1050 }
1051 std::lock_guard<std::mutex> lock(g_mutex);
1052 CredentialDeleteParam param = {};
1053 if (memcpy_s(param.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
1054 IAM_LOGE("param token copy failed");
1055 return RESULT_BAD_COPY;
1056 }
1057 param.userId = userId;
1058 param.credentialId = credentialId;
1059 CredentialInfoHal credentialInfoHal = {};
1060 int32_t ret = DeleteCredentialFunc(param, &credentialInfoHal);
1061 if (ret != RESULT_SUCCESS) {
1062 IAM_LOGE("delete credential failed");
1063 return ret;
1064 }
1065 CopyCredentialInfo(credentialInfoHal, info);
1066 return RESULT_SUCCESS;
1067 }
1068
GetCredential(int32_t userId,int32_t authType,std::vector<CredentialInfo> & infos)1069 int32_t UserAuthInterfaceService::GetCredential(int32_t userId, int32_t authType, std::vector<CredentialInfo> &infos)
1070 {
1071 IAM_LOGI("start");
1072 std::lock_guard<std::mutex> lock(g_mutex);
1073 LinkedList *credList = nullptr;
1074 int32_t ret = QueryCredentialFunc(userId, authType, &credList);
1075 if (ret != RESULT_SUCCESS) {
1076 IAM_LOGE("query credential failed");
1077 return ret;
1078 }
1079 infos.reserve(credList->getSize(credList));
1080 LinkedListNode *temp = credList->head;
1081 while (temp != nullptr) {
1082 if (temp->data == nullptr) {
1083 IAM_LOGE("list node is invalid");
1084 DestroyLinkedList(credList);
1085 return RESULT_UNKNOWN;
1086 }
1087 auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
1088 CredentialInfo credentialInfo = {};
1089 CopyCredentialInfo(*credentialHal, credentialInfo);
1090 infos.push_back(credentialInfo);
1091 temp = temp->next;
1092 }
1093 DestroyLinkedList(credList);
1094 return RESULT_SUCCESS;
1095 }
1096
GetUserInfo(int32_t userId,uint64_t & secureUid,int32_t & pinSubType,std::vector<EnrolledInfo> & infos)1097 int32_t UserAuthInterfaceService::GetUserInfo(int32_t userId, uint64_t &secureUid, int32_t &pinSubType,
1098 std::vector<EnrolledInfo> &infos)
1099 {
1100 IAM_LOGI("start");
1101 std::lock_guard<std::mutex> lock(g_mutex);
1102 EnrolledInfoHal *enrolledInfoHals = nullptr;
1103 uint32_t num = 0;
1104 uint64_t pinSubTypeGet;
1105 int32_t ret = GetUserInfoFunc(userId, &secureUid, &pinSubTypeGet, &enrolledInfoHals, &num);
1106 if (ret == RESULT_NOT_FOUND) {
1107 IAM_LOGE("user not found");
1108 return RESULT_SUCCESS;
1109 }
1110 if (ret != RESULT_SUCCESS) {
1111 IAM_LOGE("get user info failed");
1112 return ret;
1113 }
1114 pinSubType = static_cast<PinSubType>(pinSubTypeGet);
1115 for (uint32_t i = 0; i < num; ++i) {
1116 EnrolledInfo enrolledInfo = {};
1117 enrolledInfo.authType = static_cast<AuthType>(enrolledInfoHals[i].authType);
1118 enrolledInfo.enrolledId = enrolledInfoHals[i].enrolledId;
1119 infos.push_back(enrolledInfo);
1120 }
1121 free(enrolledInfoHals);
1122 return RESULT_SUCCESS;
1123 }
1124
DeleteUser(int32_t userId,const std::vector<uint8_t> & authToken,std::vector<CredentialInfo> & deletedInfos,std::vector<uint8_t> & rootSecret)1125 int32_t UserAuthInterfaceService::DeleteUser(int32_t userId, const std::vector<uint8_t> &authToken,
1126 std::vector<CredentialInfo> &deletedInfos, std::vector<uint8_t> &rootSecret)
1127 {
1128 IAM_LOGI("start");
1129 if (authToken.size() != sizeof(UserAuthTokenHal)) {
1130 IAM_LOGE("authToken is invalid");
1131 return RESULT_VERIFY_TOKEN_FAIL;
1132 }
1133 UserAuthTokenHal authTokenStruct = {};
1134 if (memcpy_s(&authTokenStruct, sizeof(UserAuthTokenHal), &authToken[0], authToken.size()) != EOK) {
1135 IAM_LOGE("authTokenStruct copy failed");
1136 return RESULT_BAD_COPY;
1137 }
1138 int32_t ret = CheckIdmOperationToken(userId, &authTokenStruct);
1139 if (ret != RESULT_SUCCESS) {
1140 IAM_LOGE("failed to verify token");
1141 return RESULT_VERIFY_TOKEN_FAIL;
1142 }
1143 ret = EnforceDeleteUser(userId, deletedInfos);
1144 if (ret != RESULT_SUCCESS) {
1145 IAM_LOGE("oldRootSecret is invalid");
1146 return RESULT_GENERAL_ERROR;
1147 }
1148
1149 rootSecret.resize(ROOT_SECRET_LEN);
1150 Buffer *oldRootSecret = GetCacheRootSecret(userId);
1151 if (!IsBufferValid(oldRootSecret)) {
1152 IAM_LOGE("get GetCacheRootSecret failed");
1153 return RESULT_SUCCESS;
1154 }
1155 if (memcpy_s(rootSecret.data(), rootSecret.size(), oldRootSecret->buf, oldRootSecret->contentSize) != EOK) {
1156 IAM_LOGE("rootSecret copy failed");
1157 ret = RESULT_BAD_COPY;
1158 }
1159
1160 DestoryBuffer(oldRootSecret);
1161 return ret;
1162 }
1163
EnforceDeleteUser(int32_t userId,std::vector<CredentialInfo> & deletedInfos)1164 int32_t UserAuthInterfaceService::EnforceDeleteUser(int32_t userId, std::vector<CredentialInfo> &deletedInfos)
1165 {
1166 IAM_LOGI("start");
1167 std::lock_guard<std::mutex> lock(g_mutex);
1168 LinkedList *credList = nullptr;
1169 int32_t ret = DeleteUserInfo(userId, &credList);
1170 if (ret != RESULT_SUCCESS) {
1171 IAM_LOGE("query credential failed");
1172 return ret;
1173 }
1174 RefreshValidTokenTime();
1175 LinkedListNode *temp = credList->head;
1176 while (temp != nullptr) {
1177 if (temp->data == nullptr) {
1178 IAM_LOGE("list node is invalid");
1179 DestroyLinkedList(credList);
1180 return RESULT_UNKNOWN;
1181 }
1182 auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
1183 CredentialInfo credentialInfo = {};
1184 CopyCredentialInfo(*credentialHal, credentialInfo);
1185 deletedInfos.push_back(credentialInfo);
1186 temp = temp->next;
1187 }
1188 DestroyLinkedList(credList);
1189 return RESULT_SUCCESS;
1190 }
1191
verifyExecutorRegisterInfo(const HdiExecutorRegisterInfo & in,ExecutorInfoHal & out)1192 static bool verifyExecutorRegisterInfo(const HdiExecutorRegisterInfo &in, ExecutorInfoHal &out)
1193 {
1194 Buffer *execInfoMsg = CreateBufferByData(&in.signedRemoteExecutorInfo[0], in.signedRemoteExecutorInfo.size());
1195 if (!IsBufferValid(execInfoMsg)) {
1196 IAM_LOGE("execInfoMsg is invalid");
1197 return false;
1198 }
1199
1200 bool isOk = CheckRemoteExecutorInfo(execInfoMsg, &out);
1201 DestoryBuffer(execInfoMsg);
1202 return isOk;
1203 }
1204
CopyExecutorInfo(const HdiExecutorRegisterInfo & in,ExecutorInfoHal & out)1205 static bool CopyExecutorInfo(const HdiExecutorRegisterInfo &in, ExecutorInfoHal &out)
1206 {
1207 out.authType = in.authType;
1208 out.executorMatcher = in.executorMatcher;
1209 out.esl = in.esl;
1210 out.maxTemplateAcl = in.maxTemplateAcl;
1211 out.executorRole = in.executorRole;
1212 out.executorSensorHint = in.executorSensorHint;
1213 if (memcpy_s(out.pubKey, PUBLIC_KEY_LEN, &in.publicKey[0], in.publicKey.size()) != EOK) {
1214 IAM_LOGE("memcpy failed");
1215 return false;
1216 }
1217
1218 std::string deviceUdid = in.deviceUdid;
1219 if (deviceUdid.empty()) {
1220 deviceUdid = g_localUdid;
1221 }
1222
1223 if (memcpy_s(out.deviceUdid, sizeof(out.deviceUdid), deviceUdid.c_str(), deviceUdid.length()) != EOK) {
1224 IAM_LOGE("memcpy failed");
1225 return false;
1226 }
1227
1228 if (g_localUdid != deviceUdid) {
1229 IAM_LOGI("verify remote executor register info");
1230 if (!verifyExecutorRegisterInfo(in, out)) {
1231 IAM_LOGE("verifyExecutorRegisterInfo failed");
1232 return false;
1233 }
1234 IAM_LOGI("add remote executor authType %{public}d executorRole %{public}d", in.authType, in.executorRole);
1235 } else {
1236 IAM_LOGI("add local executor authType %{public}d executorRole %{public}d", in.authType, in.executorRole);
1237 }
1238 return true;
1239 }
1240
ObtainReconciliationData(uint32_t authType,uint32_t sensorHint,std::vector<uint64_t> & templateIds)1241 static int32_t ObtainReconciliationData(uint32_t authType, uint32_t sensorHint, std::vector<uint64_t> &templateIds)
1242 {
1243 CredentialCondition condition = {};
1244 SetCredentialConditionAuthType(&condition, authType);
1245 SetCredentialConditionExecutorSensorHint(&condition, sensorHint);
1246 SetCredentiaConditionNeedCachePin(&condition);
1247 LinkedList *credList = QueryCredentialLimit(&condition);
1248 if (credList == nullptr) {
1249 IAM_LOGE("query credential failed");
1250 return RESULT_NOT_FOUND;
1251 }
1252 LinkedListNode *temp = credList->head;
1253 while (temp != nullptr) {
1254 if (temp->data == nullptr) {
1255 IAM_LOGE("list node is invalid");
1256 DestroyLinkedList(credList);
1257 return RESULT_UNKNOWN;
1258 }
1259 auto credentialInfo = static_cast<CredentialInfoHal *>(temp->data);
1260 templateIds.push_back(credentialInfo->templateId);
1261 temp = temp->next;
1262 }
1263 DestroyLinkedList(credList);
1264 return RESULT_SUCCESS;
1265 }
1266
AddExecutor(const HdiExecutorRegisterInfo & info,uint64_t & index,std::vector<uint8_t> & publicKey,std::vector<uint64_t> & templateIds)1267 int32_t UserAuthInterfaceService::AddExecutor(const HdiExecutorRegisterInfo &info, uint64_t &index,
1268 std::vector<uint8_t> &publicKey, std::vector<uint64_t> &templateIds)
1269 {
1270 IAM_LOGI("start");
1271 if (info.publicKey.size() != PUBLIC_KEY_LEN) {
1272 IAM_LOGE("invalid info");
1273 return RESULT_BAD_PARAM;
1274 }
1275 templateIds.clear();
1276 const Buffer *frameworkPubKey = GetPubKey();
1277 if (!IsBufferValid(frameworkPubKey)) {
1278 IAM_LOGE("get public key failed");
1279 return RESULT_UNKNOWN;
1280 }
1281 publicKey.resize(PUBLIC_KEY_LEN);
1282 if (memcpy_s(&publicKey[0], publicKey.size(), frameworkPubKey->buf, frameworkPubKey->contentSize) != EOK) {
1283 IAM_LOGE("copy public key failed");
1284 publicKey.clear();
1285 return RESULT_UNKNOWN;
1286 }
1287 std::lock_guard<std::mutex> lock(g_mutex);
1288 ExecutorInfoHal executorInfoHal = {};
1289 bool copyRet = CopyExecutorInfo(info, executorInfoHal);
1290 if (!copyRet) {
1291 IAM_LOGE("copy executor info failed");
1292 return RESULT_UNKNOWN;
1293 }
1294 int32_t ret = RegisterExecutor(&executorInfoHal, &index);
1295 if (ret != RESULT_SUCCESS) {
1296 IAM_LOGE("register executor failed");
1297 return ret;
1298 }
1299 if (info.executorRole == ALL_IN_ONE) {
1300 return ObtainReconciliationData(executorInfoHal.authType, executorInfoHal.executorSensorHint, templateIds);
1301 }
1302 return RESULT_SUCCESS;
1303 }
1304
DeleteExecutor(uint64_t index)1305 int32_t UserAuthInterfaceService::DeleteExecutor(uint64_t index)
1306 {
1307 IAM_LOGI("start");
1308 std::lock_guard<std::mutex> lock(g_mutex);
1309 return UnRegisterExecutor(index);
1310 }
1311
GetAllExtUserInfo(std::vector<ExtUserInfo> & userInfos)1312 int32_t UserAuthInterfaceService::GetAllExtUserInfo(std::vector<ExtUserInfo> &userInfos)
1313 {
1314 IAM_LOGI("start");
1315 UserInfoResult *userInfoResult = (UserInfoResult *)Malloc(sizeof(UserInfoResult) * MAX_USER);
1316 if (userInfoResult == NULL) {
1317 IAM_LOGE("malloc failed");
1318 return RESULT_GENERAL_ERROR;
1319 }
1320 uint32_t userInfoCount = 0;
1321 ResultCode ret = QueryAllExtUserInfoFunc(userInfoResult, MAX_USER, &userInfoCount);
1322 if (ret != RESULT_SUCCESS) {
1323 Free(userInfoResult);
1324 IAM_LOGE("QueryAllExtUserInfoFunc failed");
1325 return RESULT_GENERAL_ERROR;
1326 }
1327
1328 for (uint32_t i = 0; i < userInfoCount; i++) {
1329 ExtUserInfo info = {};
1330 info.userId = userInfoResult[i].userId;
1331 info.userInfo.secureUid = userInfoResult[i].secUid;
1332 info.userInfo.pinSubType = static_cast<PinSubType>(userInfoResult[i].pinSubType);
1333 for (uint32_t j = 0; j < userInfoResult[i].enrollNum; j++) {
1334 EnrolledInfo enrolledInfo = {};
1335 enrolledInfo.authType = static_cast<AuthType>(userInfoResult[i].enrolledInfo[j].authType);
1336 enrolledInfo.enrolledId = userInfoResult[i].enrolledInfo[j].enrolledId;
1337 info.userInfo.enrolledInfos.push_back(enrolledInfo);
1338 }
1339 userInfos.push_back(info);
1340 }
1341
1342 Free(userInfoResult);
1343 return RESULT_SUCCESS;
1344 }
1345
GetEnrolledState(int32_t userId,int32_t authType,HdiEnrolledState & enrolledState)1346 int32_t UserAuthInterfaceService::GetEnrolledState(int32_t userId, int32_t authType, HdiEnrolledState &enrolledState)
1347 {
1348 IAM_LOGI("start");
1349 EnrolledStateHal *enrolledStateHal = (EnrolledStateHal *) Malloc(sizeof(EnrolledStateHal));
1350 if (enrolledStateHal == NULL) {
1351 IAM_LOGE("malloc failed");
1352 return RESULT_GENERAL_ERROR;
1353 }
1354 int32_t ret = GetEnrolledStateFunc(userId, authType, enrolledStateHal);
1355 if (ret != RESULT_SUCCESS) {
1356 Free(enrolledStateHal);
1357 IAM_LOGE("GetEnrolledState failed");
1358 return ret;
1359 }
1360 enrolledState.credentialDigest = enrolledStateHal->credentialDigest;
1361 enrolledState.credentialCount = enrolledStateHal->credentialCount;
1362
1363 Free(enrolledStateHal);
1364 return RESULT_SUCCESS;
1365 }
1366
CheckReuseUnlockResult(const ReuseUnlockParam & param,ReuseUnlockInfo & info)1367 int32_t UserAuthInterfaceService::CheckReuseUnlockResult(const ReuseUnlockParam& param,
1368 ReuseUnlockInfo& info)
1369 {
1370 IAM_LOGI("start reuseMode: %{public}u, reuseDuration: %{public}" PRIu64 ".", param.reuseUnlockResultMode,
1371 param.reuseUnlockResultDuration);
1372 if (param.authTypes.empty() || param.authTypes.size() > MAX_AUTH_TYPE_LEN ||
1373 param.reuseUnlockResultDuration == 0 || param.reuseUnlockResultDuration > REUSED_UNLOCK_TOKEN_PERIOD ||
1374 (param.reuseUnlockResultMode != AUTH_TYPE_RELEVANT && param.reuseUnlockResultMode != AUTH_TYPE_IRRELEVANT &&
1375 param.reuseUnlockResultMode != CALLER_IRRELEVANT_AUTH_TYPE_RELEVANT &&
1376 param.reuseUnlockResultMode != CALLER_IRRELEVANT_AUTH_TYPE_IRRELEVANT)) {
1377 IAM_LOGE("checkReuseUnlockResult bad param");
1378 return RESULT_BAD_PARAM;
1379 }
1380 ReuseUnlockParamHal paramHal = {};
1381 paramHal.userId = param.baseParam.userId;
1382 paramHal.authTrustLevel = param.baseParam.authTrustLevel;
1383 paramHal.reuseUnlockResultDuration = param.reuseUnlockResultDuration;
1384 paramHal.reuseUnlockResultMode = param.reuseUnlockResultMode;
1385 if (!param.baseParam.challenge.empty() &&
1386 memcpy_s(paramHal.challenge, CHALLENGE_LEN,
1387 param.baseParam.challenge.data(), param.baseParam.challenge.size()) != EOK) {
1388 IAM_LOGE("challenge copy failed");
1389 return RESULT_BAD_COPY;
1390 }
1391 paramHal.authTypeSize = param.authTypes.size();
1392 for (uint32_t i = 0; i < param.authTypes.size(); i++) {
1393 paramHal.authTypes[i] = static_cast<uint32_t>(param.authTypes[i]);
1394 }
1395 ReuseUnlockResult reuseResult = {};
1396 int32_t ret = CheckReuseUnlockResultFunc(¶mHal, &reuseResult);
1397 if (ret != RESULT_SUCCESS) {
1398 info.token.clear();
1399 IAM_LOGE("check reuse unlock result failed, ret:%{public}d", ret);
1400 return ret;
1401 }
1402 info.authType = reuseResult.authType;
1403 info.enrolledState.credentialDigest = reuseResult.enrolledState.credentialDigest;
1404 info.enrolledState.credentialCount = reuseResult.enrolledState.credentialCount;
1405 info.token.resize(AUTH_TOKEN_LEN);
1406 if (memcpy_s(info.token.data(), info.token.size(), reuseResult.token, AUTH_TOKEN_LEN) != EOK) {
1407 IAM_LOGE("copy authToken failed");
1408 info.token.clear();
1409 return RESULT_BAD_COPY;
1410 }
1411 IAM_LOGI("check reuse unlock result finish success");
1412 return RESULT_SUCCESS;
1413 }
1414
SendMessage(uint64_t scheduleId,int32_t srcRole,const std::vector<uint8_t> & msg)1415 int32_t UserAuthInterfaceService::SendMessage(uint64_t scheduleId, int32_t srcRole, const std::vector<uint8_t>& msg)
1416 {
1417 static_cast<void>(scheduleId);
1418 static_cast<void>(srcRole);
1419 static_cast<void>(msg);
1420 return HDF_SUCCESS;
1421 }
1422
RegisterMessageCallback(const sptr<IMessageCallback> & messageCallback)1423 int32_t UserAuthInterfaceService::RegisterMessageCallback(const sptr<IMessageCallback>& messageCallback)
1424 {
1425 static_cast<void>(messageCallback);
1426 return HDF_SUCCESS;
1427 }
1428
PrepareRemoteAuth(const std::string & remoteUdid)1429 int32_t UserAuthInterfaceService::PrepareRemoteAuth(const std::string &remoteUdid)
1430 {
1431 IAM_LOGI("PrepareRemoteAuth");
1432 return RESULT_SUCCESS;
1433 }
1434
CopyHdiScheduleInfo(const ScheduleInfoParam * in,HdiScheduleInfo * out)1435 static bool CopyHdiScheduleInfo(const ScheduleInfoParam *in, HdiScheduleInfo *out)
1436 {
1437 IAM_LOGI("CopyHdiScheduleInfo start");
1438 out->executorIndexes.clear();
1439 out->templateIds.clear();
1440 out->executorMessages.clear();
1441 out->scheduleId = in->scheduleId;
1442 out->authType = static_cast<AuthType>(in->authType);
1443 out->executorMatcher = static_cast<uint32_t>(in->executorMatcher);
1444 out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
1445 out->executorIndexes.push_back(in->executorIndex);
1446 out->executorMessages.resize(1);
1447 out->executorMessages[0].resize(in->executorMessages->contentSize);
1448 if (memcpy_s(out->executorMessages[0].data(), out->executorMessages[0].size(),
1449 in->executorMessages->buf, in->executorMessages->contentSize) != EOK) {
1450 IAM_LOGE("copy executorMessages failed");
1451 out->executorMessages.clear();
1452 out->executorIndexes.clear();
1453 return false;
1454 }
1455 return true;
1456 }
1457
DestroyScheduleInfoParam(ScheduleInfoParam * result)1458 static void DestroyScheduleInfoParam(ScheduleInfoParam *result)
1459 {
1460 if (result == NULL) {
1461 return;
1462 }
1463 if (result->executorMessages != NULL) {
1464 DestoryBuffer(result->executorMessages);
1465 }
1466 Free(result);
1467 }
1468
GetLocalScheduleFromMessage(const std::string & remoteUdid,const std::vector<uint8_t> & message,HdiScheduleInfo & scheduleInfo)1469 int32_t UserAuthInterfaceService::GetLocalScheduleFromMessage(const std::string &remoteUdid,
1470 const std::vector<uint8_t> &message, HdiScheduleInfo& scheduleInfo)
1471 {
1472 IAM_LOGI("GetLocalScheduleFromMessage start");
1473 if ((g_localUdid.empty()) || (remoteUdid.empty()) || (message.size() == 0)) {
1474 IAM_LOGE("param is invalid");
1475 return RESULT_BAD_PARAM;
1476 }
1477 Buffer *messageBuffer = CreateBufferByData(&message[0], message.size());
1478 if (!IsBufferValid(messageBuffer)) {
1479 IAM_LOGE("messageBuffer is invalid");
1480 return RESULT_NO_MEMORY;
1481 }
1482 std::lock_guard<std::mutex> lock(g_mutex);
1483 ScheduleInfoParam *scheduleParam = (ScheduleInfoParam *)Malloc(sizeof(ScheduleInfoParam));
1484 if (scheduleParam == NULL) {
1485 IAM_LOGE("schedule is null");
1486 DestoryBuffer(messageBuffer);
1487 return RESULT_GENERAL_ERROR;
1488 }
1489
1490 int32_t funcRet = RESULT_GENERAL_ERROR;
1491 int32_t ret = RESULT_GENERAL_ERROR;
1492 Uint8Array remoteUdidArray = {};
1493 if (memcpy_s(scheduleParam->localUdid, sizeof(scheduleParam->localUdid), g_localUdid.c_str(),
1494 g_localUdid.length()) != EOK) {
1495 IAM_LOGE("localUdid copy failed");
1496 goto FAIL;
1497 }
1498
1499 if (memcpy_s(scheduleParam->remoteUdid, sizeof(scheduleParam->remoteUdid), remoteUdid.c_str(),
1500 remoteUdid.length()) != EOK) {
1501 IAM_LOGE("remoteUdid copy failed");
1502 goto FAIL;
1503 }
1504
1505 remoteUdidArray = { scheduleParam->remoteUdid, sizeof(scheduleParam->remoteUdid) };
1506
1507 ret = GenerateScheduleFunc(messageBuffer, remoteUdidArray, scheduleParam);
1508 if (ret != RESULT_SUCCESS) {
1509 IAM_LOGE("GenerateScheduleFunc failed");
1510 goto FAIL;
1511 }
1512 if (!CopyHdiScheduleInfo(scheduleParam, &scheduleInfo)) {
1513 IAM_LOGE("copy schedule info failed");
1514 goto FAIL;
1515 }
1516
1517 funcRet = RESULT_SUCCESS;
1518 FAIL:
1519 DestoryBuffer(messageBuffer);
1520 DestroyScheduleInfoParam(scheduleParam);
1521 return funcRet;
1522 }
1523
DestroyExecutorInfo(void * data)1524 static void DestroyExecutorInfo(void *data)
1525 {
1526 if (data == nullptr) {
1527 IAM_LOGE("data is null");
1528 return;
1529 }
1530 Free(data);
1531 }
1532
GetSignedExecutorInfo(const std::vector<int32_t> & authTypes,int32_t executorRole,const std::string & remoteUdid,std::vector<uint8_t> & signedExecutorInfo)1533 int32_t UserAuthInterfaceService::GetSignedExecutorInfo(const std::vector<int32_t>& authTypes, int32_t executorRole,
1534 const std::string& remoteUdid, std::vector<uint8_t>& signedExecutorInfo)
1535 {
1536 IAM_LOGI("GetSignedExecutorInfo start");
1537 if ((g_localUdid.empty()) || (remoteUdid.empty()) || (authTypes.size() == 0)) {
1538 IAM_LOGE("param is invalid");
1539 return RESULT_BAD_PARAM;
1540 }
1541 ResultCode result = RESULT_GENERAL_ERROR;
1542 LinkedList *linkedList = CreateLinkedList(DestroyExecutorInfo);
1543 if (linkedList == NULL) {
1544 IAM_LOGE("create linkedList failed");
1545 return result;
1546 }
1547 std::lock_guard<std::mutex> lock(g_mutex);
1548 for (uint32_t i = 0; i < authTypes.size(); i++) {
1549 result = GetExecutorInfoLinkedList(authTypes[i], executorRole, linkedList);
1550 if (result != RESULT_SUCCESS) {
1551 IAM_LOGE("GetExecutorInfo failed");
1552 DestroyLinkedList(linkedList);
1553 return result;
1554 }
1555 }
1556 uint8_t remoteUdidData[UDID_LEN] = {};
1557 if (memcpy_s(remoteUdidData, UDID_LEN, remoteUdid.c_str(), remoteUdid.length()) != EOK) {
1558 IAM_LOGE("remoteUdidData copy failed");
1559 DestroyLinkedList(linkedList);
1560 return RESULT_BAD_COPY;
1561 }
1562
1563 Uint8Array remoteUdidArray = { remoteUdidData, sizeof(remoteUdidData) };
1564 Buffer *signInfo = GetSignExecutorInfoFunc(remoteUdidArray, linkedList);
1565 if (!IsBufferValid(signInfo)) {
1566 IAM_LOGE("signInfo is invalid");
1567 DestroyLinkedList(linkedList);
1568 return RESULT_NO_MEMORY;
1569 }
1570 signedExecutorInfo.resize(signInfo->contentSize);
1571 if (memcpy_s(&signedExecutorInfo[0], signedExecutorInfo.size(), signInfo->buf, signInfo->contentSize) != EOK) {
1572 IAM_LOGE("sign copy failed");
1573 result = RESULT_BAD_COPY;
1574 }
1575 DestoryBuffer(signInfo);
1576 DestroyLinkedList(linkedList);
1577 return result;
1578 }
1579
CopyHdiAuthResultInfo(const AuthResultParam * in,HdiAuthResultInfo * out,const std::vector<uint8_t> & message)1580 static bool CopyHdiAuthResultInfo(const AuthResultParam *in, HdiAuthResultInfo *out,
1581 const std::vector<uint8_t>& message)
1582 {
1583 IAM_LOGI("CopyHdiAuthResultInfo start");
1584 out->token.clear();
1585 out->rootSecret.clear();
1586 out->remoteAuthResultMsg.clear();
1587 out->result = in->result;
1588 out->lockoutDuration = in->lockoutDuration;
1589 out->remainAttempts = in->remainAttempts;
1590 out->userId = in->userId;
1591
1592 out->token.resize(in->token->contentSize);
1593 if (memcpy_s(out->token.data(), out->token.size(), in->token->buf, in->token->contentSize) != EOK) {
1594 IAM_LOGE("copy token failed");
1595 return false;
1596 }
1597
1598 out->remoteAuthResultMsg.resize(message.size());
1599 if (memcpy_s(out->remoteAuthResultMsg.data(), out->remoteAuthResultMsg.size(),
1600 message.data(), message.size()) != EOK) {
1601 IAM_LOGE("copy remoteAuthResultMsg failed");
1602 return false;
1603 }
1604 return true;
1605 }
1606
DestroyAuthResultParam(AuthResultParam * result)1607 static void DestroyAuthResultParam(AuthResultParam *result)
1608 {
1609 if (result == NULL) {
1610 return;
1611 }
1612 if (result->token != NULL) {
1613 DestoryBuffer(result->token);
1614 }
1615 if (result->remoteAuthResultMsg != NULL) {
1616 DestoryBuffer(result->remoteAuthResultMsg);
1617 }
1618 Free(result);
1619 }
1620
GetAuthResultFromMessage(const std::string & remoteUdid,const std::vector<uint8_t> & message,HdiAuthResultInfo & authResultInfo)1621 int32_t UserAuthInterfaceService::GetAuthResultFromMessage(const std::string& remoteUdid,
1622 const std::vector<uint8_t>& message, HdiAuthResultInfo& authResultInfo)
1623 {
1624 IAM_LOGI("GetAuthResultFromMessage start");
1625 if ((g_localUdid.empty()) || (remoteUdid.empty()) || (message.size() == 0)) {
1626 IAM_LOGE("param is invalid");
1627 return RESULT_BAD_PARAM;
1628 }
1629 Buffer *messageBuffer = CreateBufferByData(&message[0], message.size());
1630 if (!IsBufferValid(messageBuffer)) {
1631 IAM_LOGE("messageBuffer is invalid");
1632 return RESULT_NO_MEMORY;
1633 }
1634 std::lock_guard<std::mutex> lock(g_mutex);
1635 AuthResultParam *authResultParam = (AuthResultParam *)Malloc(sizeof(AuthResultParam));
1636 if (authResultParam == NULL) {
1637 IAM_LOGE("authResultParam is null");
1638 DestoryBuffer(messageBuffer);
1639 return RESULT_GENERAL_ERROR;
1640 }
1641
1642 int32_t funcRet = RESULT_GENERAL_ERROR;
1643 int32_t ret = RESULT_GENERAL_ERROR;
1644 if (memcpy_s(authResultParam->localUdid, sizeof(authResultParam->localUdid), g_localUdid.c_str(),
1645 g_localUdid.length()) != EOK) {
1646 IAM_LOGE("localUdid copy failed");
1647 goto FAIL;
1648 }
1649
1650 if (memcpy_s(authResultParam->remoteUdid, sizeof(authResultParam->remoteUdid), remoteUdid.c_str(),
1651 remoteUdid.length()) != EOK) {
1652 IAM_LOGE("remoteUdid copy failed");
1653 goto FAIL;
1654 }
1655
1656 ret = GenerateAuthResultFunc(messageBuffer, authResultParam);
1657 if (ret != RESULT_SUCCESS) {
1658 IAM_LOGE("GenerateAuthResultFunc failed");
1659 goto FAIL;
1660 }
1661 if (!CopyHdiAuthResultInfo(authResultParam, &authResultInfo, message)) {
1662 IAM_LOGE("copy authResult info failed");
1663 goto FAIL;
1664 }
1665 ret = CreateExecutorCommand(authResultInfo.userId, authResultInfo);
1666 if (ret != RESULT_SUCCESS) {
1667 IAM_LOGE("CreateExecutorCommand failed");
1668 goto FAIL;
1669 }
1670
1671 funcRet = RESULT_SUCCESS;
1672 FAIL:
1673 DestoryBuffer(messageBuffer);
1674 DestroyAuthResultParam(authResultParam);
1675 return ret;
1676 }
1677
CopyGlobalConfigParam(const HdiGlobalConfigParam & param,GlobalConfigParamHal & paramHal)1678 static int32_t CopyGlobalConfigParam(const HdiGlobalConfigParam ¶m, GlobalConfigParamHal ¶mHal)
1679 {
1680 switch (param.type) {
1681 case PIN_EXPIRED_PERIOD:
1682 paramHal.value.pinExpiredPeriod = NO_CHECK_PIN_EXPIRED_PERIOD;
1683 if (param.value.pinExpiredPeriod > 0) {
1684 paramHal.value.pinExpiredPeriod = param.value.pinExpiredPeriod;
1685 }
1686 break;
1687 case ENABLE_STATUS:
1688 paramHal.value.enableStatus = param.value.enableStatus;
1689 break;
1690 default:
1691 IAM_LOGE("bad global config type");
1692 return RESULT_BAD_PARAM;
1693 }
1694 paramHal.type = static_cast<GlobalConfigTypeHal>(param.type);
1695
1696 for (uint32_t i = 0; i < param.userIds.size(); i++) {
1697 paramHal.userIds[i] = param.userIds[i];
1698 }
1699 paramHal.userIdNum = param.userIds.size();
1700 for (uint32_t i = 0; i < param.authTypes.size(); i++) {
1701 paramHal.authTypes[i] = static_cast<uint32_t>(param.authTypes[i]);
1702 }
1703 paramHal.authTypeNum = param.authTypes.size();
1704 return RESULT_SUCCESS;
1705 }
1706
SetGlobalConfigParam(const HdiGlobalConfigParam & param)1707 int32_t UserAuthInterfaceService::SetGlobalConfigParam(const HdiGlobalConfigParam ¶m)
1708 {
1709 IAM_LOGI("start, global config type is %{public}d, userIds size %{public}zu, authTypes size %{public}zu",
1710 param.type, param.userIds.size(), param.authTypes.size());
1711 if (param.authTypes.size() > MAX_AUTH_TYPE_LEN || param.authTypes.size() == 0 ||
1712 param.userIds.size() > MAX_USER) {
1713 IAM_LOGE("SetGlobalConfigParam bad param");
1714 return RESULT_BAD_PARAM;
1715 }
1716 GlobalConfigParamHal paramHal = {};
1717 int32_t ret = CopyGlobalConfigParam(param, paramHal);
1718 if (ret != RESULT_SUCCESS) {
1719 IAM_LOGE("CopyGlobalConfigParam failed");
1720 return ret;
1721 }
1722
1723 ret = SetGlobalConfigParamFunc(¶mHal);
1724 if (ret != RESULT_SUCCESS) {
1725 IAM_LOGE("SetGlobalConfigParamFunc failed");
1726 }
1727 return ret;
1728 }
1729
GetCredentialById(uint64_t credentialId,HdiCredentialInfo & info)1730 int32_t UserAuthInterfaceService::GetCredentialById(uint64_t credentialId, HdiCredentialInfo &info)
1731 {
1732 IAM_LOGI("start");
1733 std::lock_guard<std::mutex> lock(g_mutex);
1734 LinkedList *credList = nullptr;
1735 int32_t ret = QueryCredentialByIdFunc(credentialId, &credList);
1736 if (ret != RESULT_SUCCESS || credList == NULL) {
1737 IAM_LOGE("query credential failed");
1738 return RESULT_GENERAL_ERROR;
1739 }
1740 if (credList->head == NULL || credList->head->data == NULL) {
1741 IAM_LOGE("credential is null");
1742 DestroyLinkedList(credList);
1743 return RESULT_NOT_ENROLLED;
1744 }
1745 auto credentialHal = static_cast<CredentialInfoHal *>(credList->head->data);
1746 CopyCredentialInfo(*credentialHal, info);
1747 DestroyLinkedList(credList);
1748 return RESULT_SUCCESS;
1749 }
1750
CopyAuthTokenPlainHal(const UserAuthTokenPlainHal & tokenIn,HdiUserAuthTokenPlain & tokenOut)1751 static bool CopyAuthTokenPlainHal(const UserAuthTokenPlainHal &tokenIn, HdiUserAuthTokenPlain &tokenOut)
1752 {
1753 tokenOut.userId = tokenIn.tokenDataToEncrypt.userId;
1754 tokenOut.challenge.resize(CHALLENGE_LEN);
1755 if (tokenOut.challenge.size() != 0 && memcpy_s(tokenOut.challenge.data(), CHALLENGE_LEN,
1756 tokenIn.tokenDataPlain.challenge, CHALLENGE_LEN) != EOK) {
1757 IAM_LOGE("copy challenge fail");
1758 return RESULT_BAD_COPY;
1759 }
1760 uint64_t currentTime = GetSystemTime();
1761 if (currentTime < tokenIn.tokenDataPlain.time) {
1762 LOG_ERROR("bad time, current:%" PRIu64 ", tokenTime:%" PRIu64, currentTime, tokenIn.tokenDataPlain.time);
1763 return RESULT_GENERAL_ERROR;
1764 }
1765 tokenOut.timeInterval = currentTime - tokenIn.tokenDataPlain.time;
1766 tokenOut.authTrustLevel = tokenIn.tokenDataPlain.authTrustLevel;
1767 tokenOut.authType = tokenIn.tokenDataPlain.authType;
1768 tokenOut.authMode = tokenIn.tokenDataPlain.authMode;
1769 tokenOut.securityLevel = tokenIn.tokenDataPlain.securityLevel;
1770 tokenOut.tokenType = tokenIn.tokenDataPlain.tokenType;
1771 tokenOut.secureUid = tokenIn.tokenDataToEncrypt.secureUid;
1772 tokenOut.enrolledId = tokenIn.tokenDataToEncrypt.enrolledId;
1773 tokenOut.credentialId = tokenIn.tokenDataToEncrypt.credentialId;
1774 tokenOut.collectorUdid.resize(UDID_LEN);
1775 if (tokenOut.collectorUdid.length() != 0 && memcpy_s(tokenOut.collectorUdid.data(), UDID_LEN,
1776 tokenIn.tokenDataToEncrypt.collectorUdid, UDID_LEN) != EOK) {
1777 IAM_LOGE("copy collectorUdid fail");
1778 return RESULT_BAD_COPY;
1779 }
1780 tokenOut.verifierUdid.resize(UDID_LEN);
1781 if (tokenOut.verifierUdid.length() != 0 && memcpy_s(tokenOut.verifierUdid.data(), UDID_LEN,
1782 tokenIn.tokenDataToEncrypt.verifierUdid, UDID_LEN) != EOK) {
1783 IAM_LOGE("copy verifierUdid fail");
1784 return RESULT_BAD_COPY;
1785 }
1786 return RESULT_SUCCESS;
1787 }
1788
ConvertResultCode(const int32_t in)1789 static int32_t ConvertResultCode(const int32_t in)
1790 {
1791 static const std::map<ResultCode, InnerKitResultCode> data = {
1792 {ResultCode::RESULT_TOKEN_TIMEOUT, InnerKitResultCode::INNER_RESULT_AUTH_TOKEN_EXPIRED},
1793 {ResultCode::RESULT_VERIFY_TOKEN_FAIL, InnerKitResultCode::INNER_RESULT_AUTH_TOKEN_CHECK_FAILED},
1794 };
1795 auto iter = data.find(static_cast<ResultCode>(in));
1796 if (iter != data.end()) {
1797 return iter->second;
1798 }
1799 return in;
1800 }
1801
GetRootSecret(const UserAuthTokenPlainHal & token,std::vector<uint8_t> & rootSecret)1802 static void GetRootSecret(const UserAuthTokenPlainHal &token, std::vector<uint8_t> &rootSecret)
1803 {
1804 rootSecret.resize(0);
1805 if (CheckSessionTimeout() != RESULT_SUCCESS) {
1806 LOG_ERROR("CheckSessionTimeout fail");
1807 return;
1808 }
1809 if (!IsValidTokenTime(token.tokenDataPlain.time)) {
1810 LOG_ERROR("check token time failed, token is invalid");
1811 return;
1812 }
1813 if (CheckChallenge(token.tokenDataPlain.challenge, CHALLENGE_LEN) != RESULT_SUCCESS) {
1814 LOG_ERROR("check challenge failed, token is invalid");
1815 return;
1816 }
1817 if (token.tokenDataPlain.authType != PIN_AUTH) {
1818 LOG_ERROR("token authType is not pin");
1819 return;
1820 }
1821
1822 Buffer *rootSecretBuffer = GetCacheRootSecret(token.tokenDataToEncrypt.userId);
1823 if (!IsBufferValid(rootSecretBuffer)) {
1824 IAM_LOGE("get GetCacheRootSecret failed");
1825 DestoryBuffer(rootSecretBuffer);
1826 return;
1827 }
1828 rootSecret.resize(ROOT_SECRET_LEN);
1829 if (memcpy_s(rootSecret.data(), rootSecret.size(), rootSecretBuffer->buf, rootSecretBuffer->contentSize) != EOK) {
1830 IAM_LOGE("rootSecret copy failed");
1831 (void)memset_s(rootSecret.data(), rootSecret.size(), 0, rootSecret.size());
1832 rootSecret.clear();
1833 }
1834
1835 DestoryBuffer(rootSecretBuffer);
1836 return;
1837 }
1838
VerifyAuthToken(const std::vector<uint8_t> & tokenIn,uint64_t allowableDuration,HdiUserAuthTokenPlain & tokenPlainOut,std::vector<uint8_t> & rootSecret)1839 int32_t UserAuthInterfaceService::VerifyAuthToken(const std::vector<uint8_t> &tokenIn, uint64_t allowableDuration,
1840 HdiUserAuthTokenPlain &tokenPlainOut, std::vector<uint8_t> &rootSecret)
1841 {
1842 IAM_LOGI("start, allowableDuration:%{public}" PRIu64, allowableDuration);
1843 if (tokenIn.size() != sizeof(UserAuthTokenHal) || tokenIn.data() == NULL ||
1844 allowableDuration > MAX_TOKEN_ALLOWABLE_DURATION) {
1845 IAM_LOGE("VerifyAuthToken bad param");
1846 return RESULT_BAD_PARAM;
1847 }
1848 UserAuthTokenPlainHal tokenPlain = {};
1849 int32_t result = UserAuthTokenVerify((UserAuthTokenHal *)(tokenIn.data()), allowableDuration, &tokenPlain);
1850 if (result != RESULT_SUCCESS) {
1851 IAM_LOGE("UserAuthTokenVerify failed");
1852 return ConvertResultCode(result);
1853 }
1854 GetRootSecret(tokenPlain, rootSecret);
1855 result = CopyAuthTokenPlainHal(tokenPlain, tokenPlainOut);
1856 if (result != RESULT_SUCCESS) {
1857 IAM_LOGE("CopyAuthTokenPlainHal failed");
1858 return result;
1859 }
1860 return result;
1861 }
1862 } // Userauth
1863 } // HDI
1864 } // OHOS