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 #include "authentication_impl.h"
16
17 #include "hdi_wrapper.h"
18 #include "iam_hitrace_helper.h"
19 #include "iam_logger.h"
20 #include "schedule_node_helper.h"
21
22 #define LOG_TAG "USER_AUTH_SA"
23 namespace OHOS {
24 namespace UserIam {
25 namespace UserAuth {
AuthenticationImpl(uint64_t contextId,const AuthenticationPara & authPara)26 AuthenticationImpl::AuthenticationImpl(uint64_t contextId, const AuthenticationPara &authPara)
27 : contextId_(contextId), authPara_(authPara)
28 {
29 }
30
~AuthenticationImpl()31 AuthenticationImpl::~AuthenticationImpl()
32 {
33 Cancel();
34 }
35
SetLatestError(int32_t error)36 void AuthenticationImpl::SetLatestError(int32_t error)
37 {
38 if (error != ResultCode::SUCCESS) {
39 latestError_ = error;
40 }
41 }
42
GetLatestError() const43 int32_t AuthenticationImpl::GetLatestError() const
44 {
45 return latestError_;
46 }
47
SetExecutor(uint32_t executorIndex)48 void AuthenticationImpl::SetExecutor(uint32_t executorIndex)
49 {
50 executorIndex_ = executorIndex;
51 }
52
SetChallenge(const std::vector<uint8_t> & challenge)53 void AuthenticationImpl::SetChallenge(const std::vector<uint8_t> &challenge)
54 {
55 challenge_ = challenge;
56 }
57
SetAccessTokenId(uint32_t tokenId)58 void AuthenticationImpl::SetAccessTokenId(uint32_t tokenId)
59 {
60 tokenId_ = tokenId;
61 }
62
SetEndAfterFirstFail(bool endAfterFirstFail)63 void AuthenticationImpl::SetEndAfterFirstFail(bool endAfterFirstFail)
64 {
65 endAfterFirstFail_ = endAfterFirstFail;
66 }
67
SetCollectorUdid(std::string & collectorUdid)68 void AuthenticationImpl::SetCollectorUdid(std::string &collectorUdid)
69 {
70 collectorUdid_ = collectorUdid;
71 }
72
GetAccessTokenId() const73 uint32_t AuthenticationImpl::GetAccessTokenId() const
74 {
75 return tokenId_;
76 }
77
GetUserId() const78 int32_t AuthenticationImpl::GetUserId() const
79 {
80 return authPara_.userId;
81 }
82
GetAuthType() const83 int32_t AuthenticationImpl::GetAuthType() const
84 {
85 return authPara_.authType;
86 }
87
GetAuthExecutorMsgs() const88 std::vector<Authentication::AuthExecutorMsg> AuthenticationImpl::GetAuthExecutorMsgs() const
89 {
90 return authExecutorMsgs_;
91 }
92
Start(std::vector<std::shared_ptr<ScheduleNode>> & scheduleList,std::shared_ptr<ScheduleNodeCallback> callback)93 bool AuthenticationImpl::Start(std::vector<std::shared_ptr<ScheduleNode>> &scheduleList,
94 std::shared_ptr<ScheduleNodeCallback> callback)
95 {
96 IAM_LOGI("UserId:%{public}d AuthType:%{public}d ATL:%{public}u authIntent:%{public}d",
97 authPara_.userId, authPara_.authType, authPara_.atl, authPara_.authIntent);
98 auto hdi = HdiWrapper::GetHdiInstance();
99 if (!hdi) {
100 IAM_LOGE("bad hdi");
101 return false;
102 }
103 HdiAuthParam param = {
104 .baseParam = {
105 .userId = authPara_.userId,
106 .authTrustLevel = authPara_.atl,
107 .executorSensorHint = executorSensorHint,
108 .challenge = challenge_,
109 .callerName = authPara_.callerName,
110 .callerType = authPara_.callerType,
111 .apiVersion = authPara_.sdkVersion,
112 },
113 .authType = authPara_.authType,
114 .authIntent = authPara_.authIntent,
115 .isOsAccountVerified = authPara_.isOsAccountVerified,
116 .collectorUdid = collectorUdid_,
117 };
118 std::vector<HdiScheduleInfo> infos;
119 IamHitraceHelper traceHelper("hdi BeginAuthentication");
120 auto result = hdi->BeginAuthentication(contextId_, param, infos);
121 if (result != HDF_SUCCESS) {
122 IAM_LOGE("hdi BeginAuthentication failed, err is %{public}d", result);
123 SetLatestError(result);
124 return false;
125 }
126 if (infos.empty()) {
127 IAM_LOGE("hdi BeginAuthentication failed, infos is empty");
128 return false;
129 }
130
131 ScheduleNodeHelper::NodeOptionalPara para;
132 para.tokenId = tokenId_;
133 para.endAfterFirstFail = endAfterFirstFail_;
134 para.collectorTokenId = authPara_.collectorTokenId;
135 para.authIntent = authPara_.authIntent;
136 para.userId = authPara_.userId;
137
138 if (!ScheduleNodeHelper::BuildFromHdi(infos, callback, scheduleList, para)) {
139 IAM_LOGE("BuildFromHdi failed");
140 return false;
141 }
142
143 running_ = true;
144 return true;
145 }
146
Update(const std::vector<uint8_t> & scheduleResult,AuthResultInfo & resultInfo)147 bool AuthenticationImpl::Update(const std::vector<uint8_t> &scheduleResult, AuthResultInfo &resultInfo)
148 {
149 auto hdi = HdiWrapper::GetHdiInstance();
150 if (!hdi) {
151 IAM_LOGE("bad hdi");
152 return false;
153 }
154
155 HdiAuthResultInfo info;
156 HdiEnrolledState enrolledState;
157 auto result = hdi->UpdateAuthenticationResult(contextId_, scheduleResult, info, enrolledState);
158 if (result != HDF_SUCCESS) {
159 IAM_LOGE("hdi UpdateAuthenticationResult failed, err is %{public}d", result);
160 SetLatestError(result);
161 }
162
163 for (auto &[executorIndex, commandId, msg] : info.msgs) {
164 Authentication::AuthExecutorMsg authExecutorMsg = {executorIndex, commandId, msg};
165 authExecutorMsgs_.emplace_back(authExecutorMsg);
166 }
167
168 resultInfo.result = static_cast<decltype(resultInfo.result)>(info.result);
169 resultInfo.freezingTime = info.lockoutDuration;
170 resultInfo.remainTimes = info.remainAttempts;
171 resultInfo.token = info.token;
172 resultInfo.rootSecret = info.rootSecret;
173 resultInfo.pinExpiredInfo = info.pinExpiredInfo;
174 resultInfo.credentialDigest = enrolledState.credentialDigest;
175 resultInfo.credentialCount = enrolledState.credentialCount;
176 resultInfo.sdkVersion = authPara_.sdkVersion;
177 resultInfo.userId = info.userId;
178 resultInfo.remoteAuthResultMsg = info.remoteAuthResultMsg;
179 resultInfo.credentialId = info.credentialId;
180
181 if (resultInfo.result != SUCCESS) {
182 SetLatestError(resultInfo.result);
183 }
184
185 return result == HDF_SUCCESS && resultInfo.result == SUCCESS;
186 }
187
Cancel()188 bool AuthenticationImpl::Cancel()
189 {
190 if (!running_) {
191 return false;
192 }
193 running_ = false;
194
195 auto hdi = HdiWrapper::GetHdiInstance();
196 if (!hdi) {
197 IAM_LOGE("bad hdi");
198 return false;
199 }
200
201 auto result = hdi->CancelAuthentication(contextId_);
202 if (result != HDF_SUCCESS) {
203 IAM_LOGE("hdi CancelAuthentication failed, err is %{public}d", result);
204 SetLatestError(result);
205 return false;
206 }
207 return true;
208 }
209 } // namespace UserAuth
210 } // namespace UserIam
211 } // namespace OHOS