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