1 /*
2 * Copyright (c) 2023-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 "auth_widget_helper.h"
17
18 #include <cinttypes>
19 #include "securec.h"
20
21 #include "iam_check.h"
22 #include "iam_logger.h"
23 #include "resource_node_pool.h"
24 #include "user_idm_database.h"
25 #include "widget_client.h"
26
27 #define LOG_TAG "USER_AUTH_SA"
28
29 namespace OHOS {
30 namespace UserIam {
31 namespace UserAuth {
32
InitWidgetContextParam(const AuthParamInner &authParam, std::vector<AuthType> &validType, const WidgetParam &widgetParam, ContextFactory::AuthWidgetContextPara ¶)33 bool AuthWidgetHelper::InitWidgetContextParam(const AuthParamInner &authParam, std::vector<AuthType> &validType,
34 const WidgetParam &widgetParam, ContextFactory::AuthWidgetContextPara ¶)
35 {
36 for (auto &authType : validType) {
37 ContextFactory::AuthProfile profile;
38 if (!GetUserAuthProfile(para.userId, authType, profile)) {
39 IAM_LOGE("get user auth profile failed");
40 return false;
41 }
42 para.authProfileMap[authType] = profile;
43 if (authType == AuthType::PIN) {
44 WidgetClient::Instance().SetPinSubType(static_cast<PinSubType>(profile.pinSubType));
45 } else if (authType == AuthType::FINGERPRINT) {
46 WidgetClient::Instance().SetSensorInfo(profile.sensorInfo);
47 }
48 }
49 para.challenge = std::move(authParam.challenge);
50 para.authTypeList = std::move(validType);
51 para.atl = authParam.authTrustLevel;
52 para.widgetParam = widgetParam;
53 if (widgetParam.windowMode == WindowModeType::UNKNOWN_WINDOW_MODE) {
54 para.widgetParam.windowMode = WindowModeType::DIALOG_BOX;
55 }
56 return true;
57 }
58
GetUserAuthProfile(int32_t userId, const AuthType &authType, ContextFactory::AuthProfile &profile)59 bool AuthWidgetHelper::GetUserAuthProfile(int32_t userId, const AuthType &authType,
60 ContextFactory::AuthProfile &profile)
61 {
62 Attributes values;
63 auto credentialInfos = UserIdmDatabase::Instance().GetCredentialInfo(userId, authType);
64 if (credentialInfos.empty() || credentialInfos[0] == nullptr) {
65 IAM_LOGE("user %{public}d has no credential type %{public}d", userId, authType);
66 return false;
67 }
68 uint64_t executorIndex = credentialInfos[0]->GetExecutorIndex();
69 auto resourceNode = ResourceNodePool::Instance().Select(executorIndex).lock();
70 if (resourceNode == nullptr) {
71 IAM_LOGE("resourceNode is nullptr");
72 return false;
73 }
74
75 std::vector<uint64_t> templateIds;
76 templateIds.reserve(credentialInfos.size());
77 for (auto &info : credentialInfos) {
78 if (info == nullptr) {
79 IAM_LOGE("info is null");
80 continue;
81 }
82 templateIds.push_back(info->GetTemplateId());
83 }
84 std::vector<uint32_t> uint32Keys = {
85 Attributes::ATTR_SENSOR_INFO,
86 Attributes::ATTR_REMAIN_TIMES,
87 Attributes::ATTR_FREEZING_TIME
88 };
89 if (authType == AuthType::PIN) {
90 uint32Keys.push_back(Attributes::ATTR_PIN_SUB_TYPE);
91 }
92
93 Attributes attr;
94 attr.SetInt32Value(Attributes::ATTR_AUTH_TYPE, authType);
95 attr.SetUint32Value(Attributes::ATTR_PROPERTY_MODE, PROPERTY_MODE_GET);
96 attr.SetUint64ArrayValue(Attributes::ATTR_TEMPLATE_ID_LIST, templateIds);
97 attr.SetUint32ArrayValue(Attributes::ATTR_KEY_LIST, uint32Keys);
98 int32_t result = resourceNode->GetProperty(attr, values);
99 if (result != SUCCESS) {
100 IAM_LOGE("failed to get property, result = %{public}d", result);
101 return false;
102 }
103 return ParseAttributes(values, authType, profile);
104 }
105
ParseAttributes(const Attributes &values, const AuthType &authType, ContextFactory::AuthProfile &profile)106 bool AuthWidgetHelper::ParseAttributes(const Attributes &values, const AuthType &authType,
107 ContextFactory::AuthProfile &profile)
108 {
109 if (authType == AuthType::PIN) {
110 if (!values.GetInt32Value(Attributes::ATTR_PIN_SUB_TYPE, profile.pinSubType)) {
111 IAM_LOGE("get ATTR_PIN_SUB_TYPE failed");
112 return false;
113 }
114 }
115 if (!values.GetStringValue(Attributes::ATTR_SENSOR_INFO, profile.sensorInfo)) {
116 IAM_LOGE("get ATTR_SENSOR_INFO failed");
117 return false;
118 }
119 if (!values.GetInt32Value(Attributes::ATTR_REMAIN_TIMES, profile.remainTimes)) {
120 IAM_LOGE("get ATTR_REMAIN_TIMES failed");
121 return false;
122 }
123 if (!values.GetInt32Value(Attributes::ATTR_FREEZING_TIME, profile.freezingTime)) {
124 IAM_LOGE("get ATTR_FREEZING_TIME failed");
125 return false;
126 }
127 return true;
128 }
129
CheckValidSolution(int32_t userId, const std::vector<AuthType> &authTypeList, const AuthTrustLevel &atl, std::vector<AuthType> &validTypeList)130 int32_t AuthWidgetHelper::CheckValidSolution(int32_t userId,
131 const std::vector<AuthType> &authTypeList, const AuthTrustLevel &atl, std::vector<AuthType> &validTypeList)
132 {
133 IAM_LOGI("start userId:%{public}d atl:%{public}u typeSize:%{public}zu", userId, atl, authTypeList.size());
134 auto hdi = HdiWrapper::GetHdiInstance();
135 if (hdi == nullptr) {
136 IAM_LOGE("hdi interface is nullptr");
137 return GENERAL_ERROR;
138 }
139 std::vector<int32_t> inputAuthType;
140 std::vector<int32_t> validTypes;
141 uint32_t inputAtl = atl;
142 for (auto &type : authTypeList) {
143 inputAuthType.emplace_back(static_cast<int32_t>(type));
144 }
145 int32_t result = hdi->GetValidSolution(userId, inputAuthType, inputAtl, validTypes);
146 if (result != SUCCESS) {
147 IAM_LOGE("GetValidSolution failed result:%{public}d userId:%{public}d", result, userId);
148 return result;
149 }
150 validTypeList.clear();
151 for (auto &type : validTypes) {
152 IAM_LOGI("get valid authType:%{public}d", type);
153 validTypeList.emplace_back(static_cast<AuthType>(type));
154 }
155 return result;
156 }
157
SetReuseUnlockResult(int32_t apiVersion, const HdiReuseUnlockInfo &info, Attributes &extraInfo)158 int32_t AuthWidgetHelper::SetReuseUnlockResult(int32_t apiVersion, const HdiReuseUnlockInfo &info,
159 Attributes &extraInfo)
160 {
161 bool setSignatureResult = extraInfo.SetUint8ArrayValue(Attributes::ATTR_SIGNATURE, info.token);
162 IF_FALSE_LOGE_AND_RETURN_VAL(setSignatureResult == true, GENERAL_ERROR);
163 bool setAuthTypeResult = extraInfo.SetInt32Value(Attributes::ATTR_AUTH_TYPE,
164 static_cast<int32_t>(info.authType));
165 IF_FALSE_LOGE_AND_RETURN_VAL(setAuthTypeResult == true, GENERAL_ERROR);
166 bool setResultCodeRet = extraInfo.SetInt32Value(Attributes::ATTR_RESULT_CODE, SUCCESS);
167 IF_FALSE_LOGE_AND_RETURN_VAL(setResultCodeRet == true, GENERAL_ERROR);
168 uint64_t credentialDigest = info.enrolledState.credentialDigest;
169 if (apiVersion < INNER_API_VERSION_10000) {
170 credentialDigest = info.enrolledState.credentialDigest & UINT16_MAX;
171 }
172 bool setCredentialDigestRet = extraInfo.SetUint64Value(Attributes::ATTR_CREDENTIAL_DIGEST, credentialDigest);
173 IF_FALSE_LOGE_AND_RETURN_VAL(setCredentialDigestRet == true, GENERAL_ERROR);
174 bool setCredentialCountRet = extraInfo.SetUint16Value(Attributes::ATTR_CREDENTIAL_COUNT,
175 info.enrolledState.credentialCount);
176 IF_FALSE_LOGE_AND_RETURN_VAL(setCredentialCountRet == true, GENERAL_ERROR);
177 return SUCCESS;
178 }
179
CheckReuseUnlockResult(const ContextFactory::AuthWidgetContextPara ¶, const AuthParamInner &authParam, Attributes &extraInfo)180 int32_t AuthWidgetHelper::CheckReuseUnlockResult(const ContextFactory::AuthWidgetContextPara ¶,
181 const AuthParamInner &authParam, Attributes &extraInfo)
182 {
183 IAM_LOGI("start userId:%{public}d, reuseMode:%{public}u, reuseDuration: %{public}" PRIu64 ".",
184 para.userId, authParam.reuseUnlockResult.reuseMode, authParam.reuseUnlockResult.reuseDuration);
185 if (!authParam.reuseUnlockResult.isReuse || authParam.reuseUnlockResult.reuseDuration == 0 ||
186 authParam.reuseUnlockResult.reuseDuration > MAX_ALLOWABLE_REUSE_DURATION ||
187 (authParam.reuseUnlockResult.reuseMode != AUTH_TYPE_RELEVANT &&
188 authParam.reuseUnlockResult.reuseMode != AUTH_TYPE_IRRELEVANT)) {
189 IAM_LOGE("CheckReuseUnlockResult invalid param");
190 return INVALID_PARAMETERS;
191 }
192 auto hdi = HdiWrapper::GetHdiInstance();
193 if (hdi == nullptr) {
194 IAM_LOGE("hdi interface is nullptr");
195 return GENERAL_ERROR;
196 }
197
198 HdiReuseUnlockParam unlockParam = {};
199 unlockParam.baseParam.userId = para.userId;
200 unlockParam.baseParam.authTrustLevel = authParam.authTrustLevel;
201 for (auto &type : authParam.authTypes) {
202 unlockParam.authTypes.emplace_back(static_cast<HdiAuthType>(type));
203 }
204 unlockParam.baseParam.challenge = authParam.challenge;
205 unlockParam.baseParam.callerName = para.callerName;
206 unlockParam.baseParam.callerType = para.callerType;
207 unlockParam.baseParam.apiVersion = para.sdkVersion;
208 unlockParam.reuseUnlockResultMode = authParam.reuseUnlockResult.reuseMode;
209 unlockParam.reuseUnlockResultDuration = authParam.reuseUnlockResult.reuseDuration;
210
211 HdiReuseUnlockInfo reuseResultInfo = {};
212 int32_t result = hdi->CheckReuseUnlockResult(unlockParam, reuseResultInfo);
213 if (result != SUCCESS) {
214 IAM_LOGE("CheckReuseUnlockResult failed result:%{public}d userId:%{public}d", result, para.userId);
215 return result;
216 }
217
218 return SetReuseUnlockResult(para.sdkVersion, reuseResultInfo, extraInfo);
219 }
220 } // namespace UserAuth
221 } // namespace UserIam
222 } // namespace OHOS