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 WidgetParamInner & widgetParam,ContextFactory::AuthWidgetContextPara & para)33 bool AuthWidgetHelper::InitWidgetContextParam(const AuthParamInner &authParam, std::vector<AuthType> &validType,
34 const WidgetParamInner &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 || authType == AuthType::PRIVATE_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 std::vector<std::shared_ptr<CredentialInfoInterface>> credentialInfos;
64 int32_t ret = UserIdmDatabase::Instance().GetCredentialInfo(userId, authType, credentialInfos);
65 if (ret != SUCCESS) {
66 IAM_LOGE("get credential fail, ret:%{public}d, userId:%{public}d, authType:%{public}d", ret,
67 userId, authType);
68 return false;
69 }
70 if (credentialInfos.empty() || credentialInfos[0] == nullptr) {
71 IAM_LOGE("user %{public}d has no credential type %{public}d", userId, authType);
72 return false;
73 }
74 uint64_t executorIndex = credentialInfos[0]->GetExecutorIndex();
75 auto resourceNode = ResourceNodePool::Instance().Select(executorIndex).lock();
76 if (resourceNode == nullptr) {
77 IAM_LOGE("resourceNode is nullptr");
78 return false;
79 }
80 std::vector<uint64_t> templateIds;
81 templateIds.reserve(credentialInfos.size());
82 for (auto &info : credentialInfos) {
83 if (info == nullptr) {
84 IAM_LOGE("info is null");
85 continue;
86 }
87 templateIds.push_back(info->GetTemplateId());
88 }
89 std::vector<uint32_t> uint32Keys = {
90 Attributes::ATTR_REMAIN_TIMES,
91 Attributes::ATTR_FREEZING_TIME
92 };
93 if (authType == AuthType::PIN || authType == AuthType::PRIVATE_PIN) {
94 uint32Keys.push_back(Attributes::ATTR_PIN_SUB_TYPE);
95 }
96 if (authType == AuthType::FINGERPRINT) {
97 uint32Keys.push_back(Attributes::ATTR_SENSOR_INFO);
98 }
99 Attributes attr;
100 attr.SetInt32Value(Attributes::ATTR_AUTH_TYPE, authType);
101 attr.SetUint32Value(Attributes::ATTR_PROPERTY_MODE, PROPERTY_MODE_GET);
102 attr.SetUint64ArrayValue(Attributes::ATTR_TEMPLATE_ID_LIST, templateIds);
103 attr.SetUint32ArrayValue(Attributes::ATTR_KEY_LIST, uint32Keys);
104 int32_t result = resourceNode->GetProperty(attr, values);
105 if (result != SUCCESS) {
106 IAM_LOGE("failed to get property, result = %{public}d", result);
107 return false;
108 }
109 return ParseAttributes(values, authType, profile);
110 }
111
ParseAttributes(const Attributes & values,const AuthType & authType,ContextFactory::AuthProfile & profile)112 bool AuthWidgetHelper::ParseAttributes(const Attributes &values, const AuthType &authType,
113 ContextFactory::AuthProfile &profile)
114 {
115 if (authType == AuthType::PIN || authType == AuthType::PRIVATE_PIN) {
116 if (!values.GetInt32Value(Attributes::ATTR_PIN_SUB_TYPE, profile.pinSubType)) {
117 IAM_LOGE("get ATTR_PIN_SUB_TYPE failed");
118 return false;
119 }
120 }
121 if (authType == AuthType::FINGERPRINT && (!values.GetStringValue(Attributes::ATTR_SENSOR_INFO,
122 profile.sensorInfo))) {
123 IAM_LOGE("get ATTR_SENSOR_INFO failed");
124 return false;
125 }
126 if (!values.GetInt32Value(Attributes::ATTR_REMAIN_TIMES, profile.remainTimes)) {
127 IAM_LOGE("get ATTR_REMAIN_TIMES failed");
128 return false;
129 }
130 if (!values.GetInt32Value(Attributes::ATTR_FREEZING_TIME, profile.freezingTime)) {
131 IAM_LOGE("get ATTR_FREEZING_TIME failed");
132 return false;
133 }
134 return true;
135 }
136
CheckValidSolution(int32_t userId,const std::vector<AuthType> & authTypeList,const AuthTrustLevel & atl,std::vector<AuthType> & validTypeList)137 int32_t AuthWidgetHelper::CheckValidSolution(int32_t userId,
138 const std::vector<AuthType> &authTypeList, const AuthTrustLevel &atl, std::vector<AuthType> &validTypeList)
139 {
140 IAM_LOGI("start userId:%{public}d atl:%{public}u typeSize:%{public}zu", userId, atl, authTypeList.size());
141 auto hdi = HdiWrapper::GetHdiInstance();
142 if (hdi == nullptr) {
143 IAM_LOGE("hdi interface is nullptr");
144 return GENERAL_ERROR;
145 }
146 std::vector<int32_t> inputAuthType;
147 std::vector<int32_t> validTypes;
148 uint32_t inputAtl = atl;
149 for (auto &type : authTypeList) {
150 inputAuthType.emplace_back(static_cast<int32_t>(type));
151 }
152 int32_t result = hdi->GetValidSolution(userId, inputAuthType, inputAtl, validTypes);
153 if (result != SUCCESS) {
154 IAM_LOGE("GetValidSolution failed result:%{public}d userId:%{public}d", result, userId);
155 return result;
156 }
157 validTypeList.clear();
158 for (auto &type : validTypes) {
159 IAM_LOGI("get valid authType:%{public}d", type);
160 validTypeList.emplace_back(static_cast<AuthType>(type));
161 }
162 return result;
163 }
164
SetReuseUnlockResult(int32_t apiVersion,const HdiReuseUnlockInfo & info,Attributes & extraInfo)165 int32_t AuthWidgetHelper::SetReuseUnlockResult(int32_t apiVersion, const HdiReuseUnlockInfo &info,
166 Attributes &extraInfo)
167 {
168 bool setSignatureResult = extraInfo.SetUint8ArrayValue(Attributes::ATTR_SIGNATURE, info.token);
169 IF_FALSE_LOGE_AND_RETURN_VAL(setSignatureResult == true, GENERAL_ERROR);
170 bool setAuthTypeResult = extraInfo.SetInt32Value(Attributes::ATTR_AUTH_TYPE,
171 static_cast<int32_t>(info.authType));
172 IF_FALSE_LOGE_AND_RETURN_VAL(setAuthTypeResult == true, GENERAL_ERROR);
173 bool setResultCodeRet = extraInfo.SetInt32Value(Attributes::ATTR_RESULT_CODE, SUCCESS);
174 IF_FALSE_LOGE_AND_RETURN_VAL(setResultCodeRet == true, GENERAL_ERROR);
175 uint64_t credentialDigest = info.enrolledState.credentialDigest;
176 if (apiVersion < INNER_API_VERSION_10000) {
177 credentialDigest = info.enrolledState.credentialDigest & UINT16_MAX;
178 }
179 bool setCredentialDigestRet = extraInfo.SetUint64Value(Attributes::ATTR_CREDENTIAL_DIGEST, credentialDigest);
180 IF_FALSE_LOGE_AND_RETURN_VAL(setCredentialDigestRet == true, GENERAL_ERROR);
181 bool setCredentialCountRet = extraInfo.SetUint16Value(Attributes::ATTR_CREDENTIAL_COUNT,
182 info.enrolledState.credentialCount);
183 IF_FALSE_LOGE_AND_RETURN_VAL(setCredentialCountRet == true, GENERAL_ERROR);
184 return SUCCESS;
185 }
186
CheckReuseUnlockResult(const ContextFactory::AuthWidgetContextPara & para,const AuthParamInner & authParam,Attributes & extraInfo)187 int32_t AuthWidgetHelper::CheckReuseUnlockResult(const ContextFactory::AuthWidgetContextPara ¶,
188 const AuthParamInner &authParam, Attributes &extraInfo)
189 {
190 IAM_LOGI("start userId:%{public}d, reuseMode:%{public}u, reuseDuration: %{public}" PRIu64 ".",
191 para.userId, authParam.reuseUnlockResult.reuseMode, authParam.reuseUnlockResult.reuseDuration);
192 if (!authParam.reuseUnlockResult.isReuse || authParam.reuseUnlockResult.reuseDuration == 0 ||
193 authParam.reuseUnlockResult.reuseDuration > MAX_ALLOWABLE_REUSE_DURATION ||
194 (authParam.reuseUnlockResult.reuseMode != AUTH_TYPE_RELEVANT &&
195 authParam.reuseUnlockResult.reuseMode != AUTH_TYPE_IRRELEVANT &&
196 authParam.reuseUnlockResult.reuseMode != CALLER_IRRELEVANT_AUTH_TYPE_RELEVANT &&
197 authParam.reuseUnlockResult.reuseMode != CALLER_IRRELEVANT_AUTH_TYPE_IRRELEVANT)) {
198 IAM_LOGE("CheckReuseUnlockResult invalid param");
199 return INVALID_PARAMETERS;
200 }
201 auto hdi = HdiWrapper::GetHdiInstance();
202 if (hdi == nullptr) {
203 IAM_LOGE("hdi interface is nullptr");
204 return GENERAL_ERROR;
205 }
206
207 HdiReuseUnlockParam unlockParam = {};
208 unlockParam.baseParam.userId = para.userId;
209 unlockParam.baseParam.authTrustLevel = authParam.authTrustLevel;
210 for (auto &type : authParam.authTypes) {
211 unlockParam.authTypes.emplace_back(static_cast<HdiAuthType>(type));
212 }
213 unlockParam.baseParam.challenge = authParam.challenge;
214 unlockParam.baseParam.callerName = para.callerName;
215 unlockParam.baseParam.callerType = para.callerType;
216 unlockParam.baseParam.apiVersion = para.sdkVersion;
217 unlockParam.reuseUnlockResultMode = authParam.reuseUnlockResult.reuseMode;
218 unlockParam.reuseUnlockResultDuration = authParam.reuseUnlockResult.reuseDuration;
219
220 HdiReuseUnlockInfo reuseResultInfo = {};
221 int32_t result = hdi->CheckReuseUnlockResult(unlockParam, reuseResultInfo);
222 if (result != SUCCESS) {
223 IAM_LOGE("CheckReuseUnlockResult failed result:%{public}d userId:%{public}d", result, para.userId);
224 return result;
225 }
226
227 return SetReuseUnlockResult(para.sdkVersion, reuseResultInfo, extraInfo);
228 }
229 } // namespace UserAuth
230 } // namespace UserIam
231 } // namespace OHOS