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
GetAuthExecutorMsgs() const83 std::vector<Authentication::AuthExecutorMsg> AuthenticationImpl::GetAuthExecutorMsgs() const
84 {
85 return authExecutorMsgs_;
86 }
87
Start(std::vector<std::shared_ptr<ScheduleNode>> & scheduleList,std::shared_ptr<ScheduleNodeCallback> callback)88 bool AuthenticationImpl::Start(std::vector<std::shared_ptr<ScheduleNode>> &scheduleList,
89 std::shared_ptr<ScheduleNodeCallback> callback)
90 {
91 IAM_LOGI("UserId:%{public}d AuthType:%{public}d ATL:%{public}u authIntent:%{public}d",
92 authPara_.userId, authPara_.authType, authPara_.atl, authPara_.authIntent);
93 auto hdi = HdiWrapper::GetHdiInstance();
94 if (!hdi) {
95 IAM_LOGE("bad hdi");
96 return false;
97 }
98 HdiAuthParam param = {
99 .baseParam = {
100 .userId = authPara_.userId,
101 .authTrustLevel = authPara_.atl,
102 .executorSensorHint = executorSensorHint,
103 .challenge = challenge_,
104 .callerName = authPara_.callerName,
105 .callerType = authPara_.callerType,
106 .apiVersion = authPara_.sdkVersion,
107 },
108 .authType = authPara_.authType,
109 .authIntent = authPara_.authIntent,
110 .isOsAccountVerified = authPara_.isOsAccountVerified,
111 .collectorUdid = collectorUdid_,
112 };
113 std::vector<HdiScheduleInfo> infos;
114 IamHitraceHelper traceHelper("hdi BeginAuthentication");
115 auto result = hdi->BeginAuthentication(contextId_, param, infos);
116 if (result != HDF_SUCCESS) {
117 IAM_LOGE("hdi BeginAuthentication failed, err is %{public}d", result);
118 SetLatestError(result);
119 return false;
120 }
121 if (infos.empty()) {
122 IAM_LOGE("hdi BeginAuthentication failed, infos is empty");
123 return false;
124 }
125
126 ScheduleNodeHelper::NodeOptionalPara para;
127 para.tokenId = tokenId_;
128 para.endAfterFirstFail = endAfterFirstFail_;
129 para.collectorTokenId = authPara_.collectorTokenId;
130 para.authIntent = authPara_.authIntent;
131 para.userId = authPara_.userId;
132
133 if (!ScheduleNodeHelper::BuildFromHdi(infos, callback, scheduleList, para)) {
134 IAM_LOGE("BuildFromHdi failed");
135 return false;
136 }
137
138 running_ = true;
139 return true;
140 }
141
Update(const std::vector<uint8_t> & scheduleResult,AuthResultInfo & resultInfo)142 bool AuthenticationImpl::Update(const std::vector<uint8_t> &scheduleResult, AuthResultInfo &resultInfo)
143 {
144 auto hdi = HdiWrapper::GetHdiInstance();
145 if (!hdi) {
146 IAM_LOGE("bad hdi");
147 return false;
148 }
149
150 HdiAuthResultInfo info;
151 HdiEnrolledState enrolledState;
152 auto result = hdi->UpdateAuthenticationResult(contextId_, scheduleResult, info, enrolledState);
153 if (result != HDF_SUCCESS) {
154 IAM_LOGE("hdi UpdateAuthenticationResult failed, err is %{public}d", result);
155 SetLatestError(result);
156 }
157
158 for (auto &[executorIndex, commandId, msg] : info.msgs) {
159 Authentication::AuthExecutorMsg authExecutorMsg = {executorIndex, commandId, msg};
160 authExecutorMsgs_.emplace_back(authExecutorMsg);
161 }
162
163 resultInfo.result = static_cast<decltype(resultInfo.result)>(info.result);
164 resultInfo.freezingTime = info.lockoutDuration;
165 resultInfo.remainTimes = info.remainAttempts;
166 resultInfo.token = info.token;
167 resultInfo.rootSecret = info.rootSecret;
168 resultInfo.pinExpiredInfo = info.pinExpiredInfo;
169 resultInfo.credentialDigest = enrolledState.credentialDigest;
170 resultInfo.credentialCount = enrolledState.credentialCount;
171 resultInfo.sdkVersion = authPara_.sdkVersion;
172 resultInfo.userId = info.userId;
173 resultInfo.remoteAuthResultMsg = info.remoteAuthResultMsg;
174 resultInfo.credentialId = info.credentialId;
175
176 if (resultInfo.result != SUCCESS) {
177 SetLatestError(resultInfo.result);
178 }
179
180 return result == HDF_SUCCESS && resultInfo.result == SUCCESS;
181 }
182
Cancel()183 bool AuthenticationImpl::Cancel()
184 {
185 if (!running_) {
186 return false;
187 }
188 running_ = false;
189
190 auto hdi = HdiWrapper::GetHdiInstance();
191 if (!hdi) {
192 IAM_LOGE("bad hdi");
193 return false;
194 }
195
196 auto result = hdi->CancelAuthentication(contextId_);
197 if (result != HDF_SUCCESS) {
198 IAM_LOGE("hdi CancelAuthentication failed, err is %{public}d", result);
199 SetLatestError(result);
200 return false;
201 }
202 return true;
203 }
204 } // namespace UserAuth
205 } // namespace UserIam
206 } // namespace OHOS