• 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 "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 &para)
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 &para,
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