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