• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_manager.h"
17 #include "deviceprofile_connector.h"
18 #include "dm_anonymous.h"
19 #include "dm_auth_context.h"
20 #include "dm_auth_message_processor.h"
21 #include "dm_auth_state_machine.h"
22 #include "dm_auth_state.h"
23 #include "dm_auth_state_machine.h"
24 #include "dm_crypto.h"
25 #include "dm_dialog_manager.h"
26 #include "dm_log.h"
27 #include "dm_negotiate_process.h"
28 #include "dm_random.h"
29 #include "hichain_auth_connector.h"
30 #include "multiple_user_connector.h"
31 #include "service_info_profile.h"
32 
33 #ifdef SUPPORT_MSDP
34 #include "spatial_location_callback_impl.h"
35 #include "spatial_awareness_mgr_client.h"
36 #endif
37 
38 namespace OHOS {
39 namespace DistributedHardware {
40 
41 constexpr int32_t MAX_AUTH_INPUT_PIN_FAIL_TIMES = 3;
42 constexpr int32_t GET_ULTRASONIC_PIN_TIMEOUT = 4;
43 constexpr int32_t MIN_PIN_CODE = 100000;
44 constexpr int32_t MAX_PIN_CODE = 999999;
45 constexpr const char* UNVALID_CREDTID = "invalidCredId";
46 
ShowAuthInfoDialog(std::shared_ptr<DmAuthContext> context)47 int32_t AuthSinkStatePinAuthComm::ShowAuthInfoDialog(std::shared_ptr<DmAuthContext> context)
48 {
49     LOGI("AuthSinkConfirmState::ShowAuthInfoDialog start");
50     if (DmAuthState::IsScreenLocked()) {
51         LOGE("AuthSinkConfirmState::ShowAuthInfoDialog screen is locked.");
52         context->reason = ERR_DM_BIND_USER_CANCEL;
53         context->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL);
54         return STOP_BIND;
55     }
56 
57     DmDialogManager::GetInstance().ShowPinDialog(context->pinCode);
58     std::string pinCodeHash = GetAnonyString(Crypto::Sha256(context->pinCode));
59     LOGI("ShowAuthInfoDialog pinCodeHash: %{public}s", pinCodeHash.c_str());
60     context->timer->StartTimer(std::string(SESSION_HEARTBEAT_TIMEOUT_TASK),
61         DmAuthState::GetTaskTimeout(context, SESSION_HEARTBEAT_TIMEOUT_TASK, SESSION_HEARTBEAT_TIMEOUT),
62         [context] (std::string name) {
63             AuthSinkStatePinAuthComm::HandleSessionHeartbeat(context, name);
64         });
65     return DM_OK;
66 }
67 
HandleSessionHeartbeat(std::shared_ptr<DmAuthContext> context,std::string name)68 void AuthSinkStatePinAuthComm::HandleSessionHeartbeat(std::shared_ptr<DmAuthContext> context, std::string name)
69 {
70     context->timer->DeleteTimer(std::string(SESSION_HEARTBEAT_TIMEOUT_TASK));
71     if (context->successFinished) {
72         return;
73     }
74 
75     LOGI("DmAuthManager::HandleSessionHeartbeat name %{public}s", name.c_str());
76     JsonObject jsonObj;
77     jsonObj[TAG_SESSION_HEARTBEAT] = TAG_SESSION_HEARTBEAT;
78     std::string message = jsonObj.Dump();
79     context->softbusConnector->GetSoftbusSession()->SendHeartbeatData(context->sessionId, message);
80 
81     context->timer->StartTimer(std::string(SESSION_HEARTBEAT_TIMEOUT_TASK),
82         DmAuthState::GetTaskTimeout(context, SESSION_HEARTBEAT_TIMEOUT_TASK, SESSION_HEARTBEAT_TIMEOUT),
83         [context] (std::string name) {
84             AuthSinkStatePinAuthComm::HandleSessionHeartbeat(context, name);
85         });
86 
87     LOGI("DmAuthManager::HandleSessionHeartbeat complete.");
88 }
89 
IsPinCodeValid(int32_t numpin)90 bool AuthSinkStatePinAuthComm::IsPinCodeValid(int32_t numpin)
91 {
92     if (numpin < MIN_PIN_CODE || numpin > MAX_PIN_CODE) {
93         return false;
94     }
95     return true;
96 }
97 
IsPinCodeValid(const std::string & strpin)98 bool AuthSinkStatePinAuthComm::IsPinCodeValid(const std::string& strpin)
99 {
100     if (strpin.empty()) {
101         return false;
102     }
103     for (size_t i = 0; i < strpin.length(); i++) {
104         if (!isdigit(strpin[i])) {
105             return false;
106         }
107     }
108     int32_t pinnum = std::atoi(strpin.c_str());
109     return IsPinCodeValid(pinnum);
110 }
111 
IsAuthCodeReady(std::shared_ptr<DmAuthContext> context)112 bool AuthSinkStatePinAuthComm::IsAuthCodeReady(std::shared_ptr<DmAuthContext> context)
113 {
114     if (context->importAuthCode.empty() || context->importPkgName.empty()) {
115         LOGE("AuthSinkStatePinAuthComm::IsAuthCodeReady, auth code not ready with authCode %{public}s and "
116             "pkgName %{public}s.", GetAnonyString(context->importAuthCode).c_str(), context->importPkgName.c_str());
117         return false;
118     }
119     if (context->pkgName != context->importPkgName) {
120         LOGE("AuthSinkStatePinAuthComm::IsAuthCodeReady pkgName %{public}s not supported with "
121             "import pkgName %{public}s.", context->pkgName.c_str(), context->importPkgName.c_str());
122         return false;
123     }
124     return true;
125 }
126 
GeneratePincode(std::shared_ptr<DmAuthContext> context)127 void AuthSinkStatePinAuthComm::GeneratePincode(std::shared_ptr<DmAuthContext> context)
128 {
129     int32_t pinCode = GenRandInt(MIN_PIN_CODE, MAX_PIN_CODE);
130     context->pinCode = std::to_string(pinCode);
131     std::string pinCodeHash = GetAnonyString(Crypto::Sha256(context->pinCode));
132     LOGI("GeneratePincode pinCodeHash: %{public}s", pinCodeHash.c_str());
133 }
134 
GetStateType()135 DmAuthStateType AuthSrcPinAuthStartState::GetStateType()
136 {
137     return DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE;
138 }
139 
Action(std::shared_ptr<DmAuthContext> context)140 int32_t AuthSrcPinAuthStartState::Action(std::shared_ptr<DmAuthContext> context)
141 {
142     LOGI("AuthSrcPinAuthStartState::Action start");
143     // auth pincode
144     auto ret = context->hiChainAuthConnector->AuthCredentialPinCode(context->accesser.userId, context->requestId,
145         context->pinCode);
146     if (ret != DM_OK) {
147         LOGE("AuthSrcPinAuthStartState::AuthDevice call AuthCredentialPinCode failed.");
148         return ret;
149     }
150     // wait for onTransmit from hiChain
151     auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT);
152     if (retEvent == DmEventType::ON_TRANSMIT) {
153         // send 120 msg
154         context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_PIN_AUTH_START, context);
155         return DM_OK;
156     } else if (retEvent == DmEventType::ON_ERROR) {
157         LOGI("AuthSrcPinAuthStartState::AuthDevice ON_ERROR failed, maybe retry.");
158         return DM_OK;
159     }
160 
161     return STOP_BIND;
162 }
163 
GetStateType()164 DmAuthStateType AuthSinkPinAuthStartState::GetStateType()
165 {
166     return DmAuthStateType::AUTH_SINK_PIN_AUTH_START_STATE;
167 }
168 
Action(std::shared_ptr<DmAuthContext> context)169 int32_t AuthSinkPinAuthStartState::Action(std::shared_ptr<DmAuthContext> context)
170 {
171     LOGI("AuthSinkPinAuthStartState::Action start");
172     context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK));
173     if (!context->pinNegotiateStarted) {
174         context->pinNegotiateStarted = true;
175         context->timer->StartTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK),
176             DmAuthState::GetTaskTimeout(context, WAIT_PIN_AUTH_TIMEOUT_TASK, PIN_AUTH_TIMEOUT),
177             [context] (std::string name) {
178                 HandleAuthenticateTimeout(context, name);
179             });
180     }
181 
182     // Stop the abnormal authentication process
183     if (context->authTypeList.empty() ||
184         (context->confirmOperation != UiAction::USER_OPERATION_TYPE_ALLOW_AUTH &&
185         context->confirmOperation != UiAction::USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS)) {
186         LOGE("AuthSinkPinAuthStartState::Action invalid parameter.");
187         return ERR_DM_INPUT_PARA_INVALID;
188     }
189     std::string pinCodeHash = GetAnonyString(Crypto::Sha256(context->pinCode));
190     LOGI("AuthSinkPinAuthStartState pinCodeHash: %{public}s", pinCodeHash.c_str());
191     // process pincode auth
192     auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData);
193     if (ret != DM_OK) {
194         LOGE("AuthSinkPinAuthStartState::Action call ProcessCredData err.");
195         return ret;
196     }
197     // wait for onTransmit from hiChain
198     auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT);
199     if (retEvent == DmEventType::ON_TRANSMIT) {
200         // send 130 msg
201         context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_PIN_AUTH_START, context);
202         return DM_OK;
203     }
204     if (retEvent == DmEventType::ON_ERROR) {
205         LOGI("AuthSinkPinAuthStartState::AuthDevice ON_ERROR failed, maybe retry.");
206         return DM_OK;
207     }
208     return STOP_BIND;
209 }
210 
GetStateType()211 DmAuthStateType AuthSrcPinAuthMsgNegotiateState::GetStateType()
212 {
213     return DmAuthStateType::AUTH_SRC_PIN_AUTH_MSG_NEGOTIATE_STATE;
214 }
215 
Action(std::shared_ptr<DmAuthContext> context)216 int32_t AuthSrcPinAuthMsgNegotiateState::Action(std::shared_ptr<DmAuthContext> context)
217 {
218     LOGI("AuthSrcPinAuthMsgNegotiateState::Action start");
219     auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData);
220     if (context->authType == AUTH_TYPE_PIN_ULTRASONIC && context->ultrasonicInfo == DM_Ultrasonic_Forward) {
221         context->timer->DeleteTimer(std::string(GET_ULTRASONIC_PIN_TIMEOUT_TASK));
222     }
223     if (ret != DM_OK) {
224         LOGE("AuthSrcPinAuthMsgNegotiateState::Action call ProcessCredData err.");
225         return ret;
226     }
227     // wait for onTransmit from hiChain
228     auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT);
229     if (retEvent == DmEventType::ON_TRANSMIT) {
230         // send 121 msg
231         context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_PIN_AUTH_MSG_NEGOTIATE, context);
232         return DM_OK;
233     }
234     if (retEvent == DmEventType::ON_ERROR) {
235         LOGI("AuthSrcPinAuthMsgNegotiateState::AuthDevice ON_ERROR failed, maybe retry.");
236         return DM_OK;
237     }
238     LOGE("AuthSrcPinAuthMsgNegotiateState::Action failed.");
239     return STOP_BIND;
240 }
241 
GetStateType()242 DmAuthStateType AuthSinkPinAuthMsgNegotiateState::GetStateType()
243 {
244     return DmAuthStateType::AUTH_SINK_PIN_AUTH_MSG_NEGOTIATE_STATE;
245 }
246 
Action(std::shared_ptr<DmAuthContext> context)247 int32_t AuthSinkPinAuthMsgNegotiateState::Action(std::shared_ptr<DmAuthContext> context)
248 {
249     LOGI("AuthSinkPinAuthMsgNegotiateState::Action start");
250     auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData);
251     if (ret != DM_OK) {
252         LOGE("AuthSinkPinAuthMsgNegotiateState::Action call ProcessCredData err.");
253         return ret;
254     }
255     // wait for onTransmit from hiChain
256     auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT);
257     if (retEvent == DmEventType::ON_TRANSMIT) {
258         // send 131 msg
259         context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_PIN_AUTH_MSG_NEGOTIATE, context);
260     } else if (retEvent == DmEventType::ON_ERROR) {
261         LOGI("AuthSinkPinAuthMsgNegotiateState::AuthDevice WAIT ON_TRANSMIT ON_ERROR failed, maybe retry.");
262         return DM_OK;
263     } else {
264         return STOP_BIND;
265     }
266 
267     retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_SESSION_KEY_RETURNED);
268     if (retEvent == DmEventType::ON_SESSION_KEY_RETURNED) {
269         retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_FINISH);
270         if (retEvent == DmEventType::ON_FINISH || retEvent == DmEventType::ON_ERROR) {
271             context->timer->DeleteTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK));
272             context->authStateMachine->TransitionTo(std::make_shared<AuthSinkPinAuthDoneState>());
273             return DM_OK;
274         }
275     }  else if (retEvent == DmEventType::ON_ERROR) {
276         LOGI("AuthSinkPinAuthMsgNegotiateState::AuthDevice WAIT ON_SESSION_KEY_RETURNED ON_ERROR failed, maybe retry.");
277         return DM_OK;
278     }
279     LOGE("AuthSinkPinAuthMsgNegotiateState::AuthDevice failed.");
280     return STOP_BIND;
281 }
282 
GetStateType()283 DmAuthStateType AuthSinkPinAuthDoneState::GetStateType()
284 {
285     return DmAuthStateType::AUTH_SINK_PIN_AUTH_DONE_STATE;
286 }
287 
Action(std::shared_ptr<DmAuthContext> context)288 int32_t AuthSinkPinAuthDoneState::Action(std::shared_ptr<DmAuthContext> context)
289 {
290     LOGI("AuthSinkPinAuthDoneState Action");
291     GetSessionKey(context);
292     return DM_OK;
293 }
294 
GetStateType()295 DmAuthStateType AuthSrcPinAuthDoneState::GetStateType()
296 {
297     return DmAuthStateType::AUTH_SRC_PIN_AUTH_DONE_STATE;
298 }
299 
Action(std::shared_ptr<DmAuthContext> context)300 int32_t AuthSrcPinAuthDoneState::Action(std::shared_ptr<DmAuthContext> context)
301 {
302     LOGI("AuthSrcPinAuthDoneState::Action start");
303     std::string onTransmitData = context->transmitData;
304     if (context->hiChainAuthConnector->ProcessCredData(context->requestId, onTransmitData) != DM_OK) {
305         LOGE("AuthSrcPinAuthDoneState::Action failed, processCredData failed.");
306         return ERR_DM_FAILED;
307     }
308 
309     // wait for ON_SESSION_KEY_RETURNED from hichain
310     DmEventType ret = context->authStateMachine->WaitExpectEvent(ON_SESSION_KEY_RETURNED);
311     if (ret != ON_SESSION_KEY_RETURNED) {
312         if (ret == ON_ERROR) {
313             LOGE("AuthSrcPinAuthDoneState::Action, ON_SESSION_KEY_RETURNED event not arriverd, maybe retry.");
314             return DM_OK;
315         } else {
316             LOGE("AuthSrcPinAuthDoneState::Action failed, ON_SESSION_KEY_RETURNED event failed, other event arriverd.");
317             return ERR_DM_FAILED;
318         }
319     }
320 
321     // wait for ON_FINISH from hichain
322     ret = context->authStateMachine->WaitExpectEvent(ON_FINISH);
323     if (ret == ON_FINISH) {
324         LOGI("AuthSrcPinAuthDoneState::Action wait ON_FINISH done");
325         context->timer->DeleteTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK));
326         return DM_OK;
327     } else if (ret == ON_ERROR) {
328         return DM_OK;
329         LOGE("AuthSrcPinAuthDoneState::Action, ON_FINISH event not arriverd, maybe retry.");
330     }
331 
332     return ERR_DM_FAILED;
333 }
334 
GetStateType()335 DmAuthStateType AuthSrcPinNegotiateStartState::GetStateType()
336 {
337     return DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_START_STATE;
338 }
339 
NegotiatePinAuth(std::shared_ptr<DmAuthContext> context,bool firstTime)340 int32_t AuthSrcPinNegotiateStartState::NegotiatePinAuth(std::shared_ptr<DmAuthContext> context, bool firstTime)
341 {
342     if (firstTime) {
343         if (context->authTypeList.empty()) {
344             LOGE("authTypeList empty");
345             context->reason = ERR_DM_AUTH_REJECT;
346             return ERR_DM_AUTH_REJECT;
347         }
348         context->currentAuthTypeIdx = 0;
349         context->authType = context->authTypeList[0];
350     } else {
351         if (context->authType == DmAuthType::AUTH_TYPE_PIN &&
352             context->inputPinAuthFailTimes < MAX_AUTH_INPUT_PIN_FAIL_TIMES) {
353             LOGI("input pin auth err, retry");
354         } else {
355             // try to fallback to next auth type
356             if (context->currentAuthTypeIdx + 1 >= context->authTypeList.size()) {
357                 LOGE("all auth type failed");
358                 context->reason = ERR_DM_BIND_PIN_CODE_ERROR;
359                 return ERR_DM_BIND_PIN_CODE_ERROR;
360             }
361             context->currentAuthTypeIdx++;
362             context->authType = context->authTypeList[context->currentAuthTypeIdx];
363         }
364     }
365 
366     // restart pin auth timer
367     context->timer->DeleteTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK));
368     context->timer->StartTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK),
369         DmAuthState::GetTaskTimeout(context, WAIT_PIN_AUTH_TIMEOUT_TASK, PIN_AUTH_TIMEOUT),
370         [context] (std::string name) {
371             HandleAuthenticateTimeout(context, name);
372         });
373     if (DmAuthState::IsImportAuthCodeCompatibility(context->authType)) {
374         if (AuthSinkStatePinAuthComm::IsAuthCodeReady(context)) {
375             context->authStateMachine->TransitionTo(std::make_shared<AuthSrcPinAuthStartState>());
376         } else {
377             context->reason = ERR_DM_INPUT_PARA_INVALID;
378             return ERR_DM_FAILED;
379         }
380     } else if (context->authType == DmAuthType::AUTH_TYPE_PIN) {
381         context->authStateMachine->TransitionTo(std::make_shared<AuthSrcPinInputState>());
382     } else if (context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC &&
383         context->ultrasonicInfo == DM_Ultrasonic_Forward) {
384             context->authStateMachine->TransitionTo(std::make_shared<AuthSrcForwardUltrasonicStartState>());
385     } else if (context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC &&
386         context->ultrasonicInfo == DM_Ultrasonic_Reverse) {
387             context->authStateMachine->TransitionTo(std::make_shared<AuthSrcReverseUltrasonicStartState>());
388     } else {
389         LOGE("authType not support.");
390         return ERR_DM_FAILED;
391     }
392     return DM_OK;
393 }
394 
Action(std::shared_ptr<DmAuthContext> context)395 int32_t AuthSrcPinNegotiateStartState::Action(std::shared_ptr<DmAuthContext> context)
396 {
397     CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
398     if (!context->pinNegotiateStarted) {
399         int32_t ret = NegotiateProcess::GetInstance().HandleNegotiateResult(context);
400         if (ret != DM_OK) {
401             LOGE("HandleNegotiateResult failed ret %{public}d", ret);
402             context->reason = ret;
403             return ret;
404         }
405     }
406     if (!IsNeedBind(context) && !IsNeedAgreeCredential(context) && IsNeedAuth(context)) {
407         return ProcessCredAuth(context);
408     }
409     if (IsNeedBind(context)) {
410         return ProcessPinBind(context);
411     }
412     if (!IsNeedBind(context) && !IsNeedAgreeCredential(context) && !IsNeedAuth(context)) {
413         context->reason = DM_BIND_TRUST_TARGET;
414         context->authStateMachine->TransitionTo(std::make_shared<AuthSrcFinishState>());
415         return DM_OK;
416     }
417     context->reason = ERR_DM_CAPABILITY_NEGOTIATE_FAILED;
418     return ERR_DM_FAILED;
419 }
420 
ProcessCredAuth(std::shared_ptr<DmAuthContext> context)421 int32_t AuthSrcPinNegotiateStartState::ProcessCredAuth(std::shared_ptr<DmAuthContext> context)
422 {
423     CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
424     JsonObject accesserCredTypeList;
425     accesserCredTypeList.Parse(context->accesser.credTypeList);
426     if (accesserCredTypeList.IsDiscarded()) {
427         LOGE("CredTypeList invalid");
428         context->reason = ERR_DM_CAPABILITY_NEGOTIATE_FAILED;
429         return ERR_DM_FAILED;
430     }
431     if (accesserCredTypeList.Contains("identicalCredType")) {
432         context->confirmOperation = UiAction::USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS;
433         context->accesser.transmitCredentialId = GetCredIdByCredType(context, DM_IDENTICAL_ACCOUNT);
434     } else if (accesserCredTypeList.Contains("shareCredType")) {
435         context->confirmOperation = UiAction::USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS;
436         context->accesser.transmitCredentialId = GetCredIdByCredType(context, DM_SHARE);
437     } else if (accesserCredTypeList.Contains("pointTopointCredType")) {
438         context->accesser.transmitCredentialId = GetCredIdByCredType(context, DM_POINT_TO_POINT);
439     } else if (accesserCredTypeList.Contains("lnnCredType")) {
440         context->accesser.lnnCredentialId = GetCredIdByCredType(context, DM_LNN);
441     } else {
442         LOGE("credTypeList invalid.");
443     }
444     context->authStateMachine->TransitionTo(std::make_shared<AuthSrcCredentialAuthStartState>());
445     return DM_OK;
446 }
447 
GetCredIdByCredType(std::shared_ptr<DmAuthContext> context,int32_t credType)448 std::string AuthSrcPinNegotiateStartState::GetCredIdByCredType(std::shared_ptr<DmAuthContext> context, int32_t credType)
449 {
450     LOGI("credType %{public}d.", credType);
451     CHECK_NULL_RETURN(context, UNVALID_CREDTID);
452     if (context->accesser.credentialInfos.find(credType) != context->accesser.credentialInfos.end()) {
453         LOGE("invalid credType.");
454         return UNVALID_CREDTID;
455     }
456     std::string credInfoStr = context->accesser.credentialInfos[credType];
457     JsonObject credInfoJson;
458     credInfoJson.Parse(credInfoStr);
459     if (credInfoJson.IsDiscarded() || !credInfoJson.Contains(FILED_CRED_ID) ||
460         !credInfoJson[FILED_CRED_ID].IsNumberInteger()) {
461         LOGE("credInfoStr invalid.");
462         return UNVALID_CREDTID;
463     }
464     return credInfoJson[FILED_CRED_ID].Get<std::string>();
465 }
466 
ProcessPinBind(std::shared_ptr<DmAuthContext> context)467 int32_t AuthSrcPinNegotiateStartState::ProcessPinBind(std::shared_ptr<DmAuthContext> context)
468 {
469     CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
470     if (!context->pinNegotiateStarted) {
471         context->pinNegotiateStarted = true;
472         CHECK_NULL_RETURN(context->timer, ERR_DM_POINT_NULL);
473         context->timer->DeleteTimer(std::string(CONFIRM_TIMEOUT_TASK));
474         // import pin code auth always excute
475         if (DmAuthState::IsImportAuthCodeCompatibility(context->authType) &&
476             (!context->authTypeList.empty()) &&
477             DmAuthState::IsImportAuthCodeCompatibility(context->authTypeList[0])) {
478             return NegotiatePinAuth(context, true);
479         } else if (context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC) {
480             return NegotiatePinAuth(context, true);
481         } else {
482             return NegotiatePinAuth(context, false);
483         }
484     } else {
485         return NegotiatePinAuth(context, false);
486     }
487     return ERR_DM_FAILED;
488 }
489 
GetStateType()490 DmAuthStateType AuthSrcPinInputState::GetStateType()
491 {
492     return DmAuthStateType::AUTH_SRC_PIN_INPUT_STATE;
493 }
494 
ShowStartAuthDialog(std::shared_ptr<DmAuthContext> context)495 int32_t AuthSrcPinInputState::ShowStartAuthDialog(std::shared_ptr<DmAuthContext> context)
496 {
497     LOGI("AuthSrcPinInputState::ShowStartAuthDialog start.");
498     if (DmAuthState::IsScreenLocked()) {
499         LOGE("AuthSrcPinInputState screen is locked.");
500         context->reason = ERR_DM_BIND_USER_CANCEL;
501         return STOP_BIND;
502     }
503 
504     context->listener->OnAuthResult(context->processInfo, context->peerTargetId.deviceId, context->accessee.tokenIdHash,
505         static_cast<int32_t>(STATUS_DM_SHOW_PIN_INPUT_UI), DM_OK);
506     context->listener->OnBindResult(context->processInfo, context->peerTargetId,
507         DM_OK, static_cast<int32_t>(STATUS_DM_SHOW_PIN_INPUT_UI), "");
508     DmDialogManager::GetInstance().ShowInputDialog(context->accessee.deviceName);
509     LOGI("AuthSrcPinInputState::ShowStartAuthDialog end.");
510     return DM_OK;
511 }
512 
Action(std::shared_ptr<DmAuthContext> context)513 int32_t AuthSrcPinInputState::Action(std::shared_ptr<DmAuthContext> context)
514 {
515     LOGI("AuthSrcPinInputState::Action start");
516     CHECK_NULL_RETURN(context, STOP_BIND);
517     if (context->inputPinAuthFailTimes == 0) {
518         auto ret = ShowStartAuthDialog(context);
519         if (ret != DM_OK) {
520             return ret;
521         }
522     } else {
523         // clear input pin box, and show try again
524         CHECK_NULL_RETURN(context->authUiStateMgr, STOP_BIND);
525         context->authUiStateMgr->UpdateUiState(DmUiStateMsg::MSG_PIN_CODE_ERROR);
526     }
527 
528     CHECK_NULL_RETURN(context->authStateMachine, STOP_BIND);
529     LOGI("AuthSrcPinInputState::Action waitting user operation");
530     // wait for user operation
531     if (DmEventType::ON_USER_OPERATION !=
532         context->authStateMachine->WaitExpectEvent(DmEventType::ON_USER_OPERATION)) {
533         LOGI("AuthSrcPinInputState::Action wait ON_USER_OPERATION err");
534         return STOP_BIND;
535     }
536 
537     if (context->pinInputResult != USER_OPERATION_TYPE_DONE_PINCODE_INPUT) {
538         LOGE("AuthSrcPinInputState::Action not USER_OPERATION_TYPE_DONE_PINCODE_INPUT err");
539         return STOP_BIND;
540     }
541     context->authStateMachine->TransitionTo(std::make_shared<AuthSrcPinAuthStartState>());
542     return DM_OK;
543 }
544 
GetStateType()545 DmAuthStateType AuthSinkPinNegotiateStartState::GetStateType()
546 {
547     return DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_START_STATE;
548 }
549 
Action(std::shared_ptr<DmAuthContext> context)550 int32_t AuthSinkPinNegotiateStartState::Action(std::shared_ptr<DmAuthContext> context)
551 {
552     if (!context->pinNegotiateStarted) {
553         context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK));
554         context->pinNegotiateStarted = true;
555     } else {
556         if (context->authType == DmAuthType::AUTH_TYPE_PIN &&
557             context->inputPinAuthFailTimes < MAX_AUTH_INPUT_PIN_FAIL_TIMES) {
558             LOGI("AuthSinkPinNegotiateStartState::Action input pin auth err, retry");
559         } else {
560             // try to fallback to next auth type
561             auto idx = context->currentAuthTypeIdx;
562             if (idx + 1 >= context->authTypeList.size()) {
563                 LOGE("AuthSinkPinNegotiateStartState::Action all auth type failed");
564                 context->reason = ERR_DM_BIND_PIN_CODE_ERROR;
565                 return ERR_DM_BIND_PIN_CODE_ERROR;
566             }
567             ++idx;
568             context->currentAuthTypeIdx = idx;
569             context->authType = context->authTypeList[idx];
570         }
571     }
572     // restart pin auth timer
573     context->timer->DeleteTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK));
574     context->timer->StartTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK),
575         DmAuthState::GetTaskTimeout(context, WAIT_PIN_AUTH_TIMEOUT_TASK, PIN_AUTH_TIMEOUT),
576         [context] (std::string name) {
577             HandleAuthenticateTimeout(context, name);
578         });
579     if (DmAuthState::IsImportAuthCodeCompatibility(context->authType)) {
580         LOGI("AuthSinkPinNegotiateStartState::Action import auth code");
581     } else if (context->authType == DmAuthType::AUTH_TYPE_PIN) {
582         LOGI("AuthSinkPinNegotiateStartState::Action input pin");
583         context->authStateMachine->TransitionTo(std::make_shared<AuthSinkPinDisplayState>());
584     } else if (context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC) {
585         LOGI("AuthSinkPinNegotiateStartState::Action ultrasonic pin");
586     } else {
587         LOGE("AuthSinkPinNegotiateStartState::Action authType not support");
588         return ERR_DM_FAILED;
589     }
590     return DM_OK;
591 }
592 
GetStateType()593 DmAuthStateType AuthSinkPinDisplayState::GetStateType()
594 {
595     return DmAuthStateType::AUTH_SINK_PIN_DISPLAY_STATE;
596 }
597 
Action(std::shared_ptr<DmAuthContext> context)598 int32_t AuthSinkPinDisplayState::Action(std::shared_ptr<DmAuthContext> context)
599 {
600     if (context->inputPinAuthFailTimes == 0) {
601         // gen pincode
602         AuthSinkStatePinAuthComm::GeneratePincode(context);
603         // show pincode
604         return AuthSinkStatePinAuthComm::ShowAuthInfoDialog(context);
605     }
606     return DM_OK;
607 }
608 
GetStateType()609 DmAuthStateType AuthSrcReverseUltrasonicStartState::GetStateType()
610 {
611     return DmAuthStateType::AUTH_SRC_REVERSE_ULTRASONIC_START_STATE;
612 }
613 
Action(std::shared_ptr<DmAuthContext> context)614 int32_t AuthSrcReverseUltrasonicStartState::Action(std::shared_ptr<DmAuthContext> context)
615 {
616     LOGI("AuthSrcReverseUltrasonicStartState::Action start");
617     context->timer->StartTimer(std::string(GET_ULTRASONIC_PIN_TIMEOUT_TASK),
618         GET_ULTRASONIC_PIN_TIMEOUT, [context] (std::string name) {
619             LOGI("AuthSrcReverseUltrasonicStartState::Action timeout");
620             context->authStateMachine->TransitionTo(std::make_shared<AuthSrcPinNegotiateStartState>());
621             return DM_OK;
622         });
623     context->pinCode = std::to_string(GenRandInt(MIN_PIN_CODE, MAX_PIN_CODE));
624     std::string ultraPinCode = context->pinCode;
625 #ifdef SUPPORT_MSDP
626     Msdp::SpatialAwarenessMgrClient::GetInstance().SetPinCode(ultraPinCode);
627 #endif
628     context->reply = DM_OK;
629     context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REVERSE_ULTRASONIC_START, context);
630     return DM_OK;
631 }
632 
GetStateType()633 DmAuthStateType AuthSrcReverseUltrasonicDoneState::GetStateType()
634 {
635     return DmAuthStateType::AUTH_SRC_REVERSE_ULTRASONIC_DONE_STATE;
636 }
637 
Action(std::shared_ptr<DmAuthContext> context)638 int32_t AuthSrcReverseUltrasonicDoneState::Action(std::shared_ptr<DmAuthContext> context)
639 {
640     LOGI("AuthSrcReverseUltrasonicDoneState::Action Start.");
641     context->timer->DeleteTimer(std::string(GET_ULTRASONIC_PIN_TIMEOUT_TASK));
642     int32_t osAccountId = MultipleUserConnector::GetCurrentAccountUserID();
643     auto ret = context->hiChainAuthConnector->AuthCredentialPinCode(osAccountId, context->requestId,
644         context->pinCode);
645     if (ret != DM_OK) {
646         LOGE("AuthSrcPinAuthStartState::AuthDevice failed.");
647         return ret;
648     }
649     auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT);
650     if (retEvent == DmEventType::ON_TRANSMIT) {
651         context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_PIN_AUTH_START, context);
652         return DM_OK;
653     } else if (retEvent == DmEventType::ON_ERROR) {
654         LOGI("AuthSrcReverseUltrasonicDoneState::AuthDevice ON_ERROR failed.");
655         context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_PIN_AUTH_START, context);
656         context->authStateMachine->TransitionTo(std::make_shared<AuthSrcPinNegotiateStartState>());
657         return DM_OK;
658     }
659     return STOP_BIND;
660 }
661 
GetStateType()662 DmAuthStateType AuthSrcForwardUltrasonicStartState::GetStateType()
663 {
664     return DmAuthStateType::AUTH_SRC_FORWARD_ULTRASONIC_START_STATE;
665 }
666 
Action(std::shared_ptr<DmAuthContext> context)667 int32_t AuthSrcForwardUltrasonicStartState::Action(std::shared_ptr<DmAuthContext> context)
668 {
669     LOGI("AuthSrcForwardUltrasonicStartState::Action Start.");
670     context->reply = DM_OK;
671     context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_FORWARD_ULTRASONIC_START, context);
672     LOGI("AuthSrcForwardUltrasonicStartState::Action End.");
673     return DM_OK;
674 }
675 
GetStateType()676 DmAuthStateType AuthSrcForwardUltrasonicDoneState::GetStateType()
677 {
678     return DmAuthStateType::AUTH_SRC_FORWARD_ULTRASONIC_DONE_STATE;
679 }
680 
Action(std::shared_ptr<DmAuthContext> context)681 int32_t AuthSrcForwardUltrasonicDoneState::Action(std::shared_ptr<DmAuthContext> context)
682 {
683     LOGI("AuthSrcForwardUltrasonicDoneState::Action Start.");
684     context->timer->StartTimer(std::string(GET_ULTRASONIC_PIN_TIMEOUT_TASK),
685         GET_ULTRASONIC_PIN_TIMEOUT, [context] (std::string name) {
686             LOGI("AuthSrcForwardUltrasonicDoneState timeout.");
687 #ifdef SUPPORT_MSDP
688             Msdp::SpatialAwarenessMgrClient::GetInstance().UnregisterPinCallback();
689 #endif
690             context->authStateMachine->NotifyEventFinish(DmEventType::ON_ULTRASONIC_PIN_TIMEOUT);
691         });
692 #ifdef SUPPORT_MSDP
693     sptr<SpatialLocationCallbackImpl> callback = new(std::nothrow) SpatialLocationCallbackImpl(context);
694     Msdp::SpatialAwarenessMgrClient::GetInstance().RegisterPinCallback(callback);
695 #endif
696     auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_ULTRASONIC_PIN_CHANGED);
697     if (retEvent == DmEventType::ON_ULTRASONIC_PIN_CHANGED) {
698 #ifdef SUPPORT_MSDP
699         Msdp::SpatialAwarenessMgrClient::GetInstance().UnregisterPinCallback();
700 #endif
701         auto ret = context->hiChainAuthConnector->AuthCredentialPinCode(context->accesser.userId, context->requestId,
702             context->pinCode);
703         if (ret != DM_OK) {
704             LOGE("OnPinCodeChanged failed.");
705             return STOP_BIND;
706         }
707         auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT);
708         if (retEvent == DmEventType::ON_TRANSMIT) {
709             LOGI("OnPinCodeChanged ON_TRANSMIT.");
710             context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_PIN_AUTH_START, context);
711             return DM_OK;
712         } else if (retEvent == DmEventType::ON_ERROR) {
713             LOGI("OnPinCodeChanged ON_ERROR failed.");
714             context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_PIN_AUTH_START, context);
715             context->authStateMachine->TransitionTo(std::make_shared<AuthSrcPinNegotiateStartState>());
716             return DM_OK;
717         }
718     } else if (retEvent == DmEventType::ON_ULTRASONIC_PIN_TIMEOUT) {
719         context->authStateMachine->TransitionTo(std::make_shared<AuthSrcPinNegotiateStartState>());
720         return DM_OK;
721     }
722     return STOP_BIND;
723 }
724 
GetStateType()725 DmAuthStateType AuthSinkReverseUltrasonicStartState::GetStateType()
726 {
727     return DmAuthStateType::AUTH_SINK_REVERSE_ULTRASONIC_START_STATE;
728 }
729 
Action(std::shared_ptr<DmAuthContext> context)730 int32_t AuthSinkReverseUltrasonicStartState::Action(std::shared_ptr<DmAuthContext> context)
731 {
732     LOGI("AuthSinkReverseUltrasonicStartState::Action Start.");
733     context->timer->StartTimer(std::string(GET_ULTRASONIC_PIN_TIMEOUT_TASK),
734         GET_ULTRASONIC_PIN_TIMEOUT, [context] (std::string name) {
735             LOGI("AuthSinkReverseUltrasonicStartState timeout.");
736 #ifdef SUPPORT_MSDP
737             Msdp::SpatialAwarenessMgrClient::GetInstance().UnregisterPinCallback();
738 #endif
739             context->authStateMachine->NotifyEventFinish(DmEventType::ON_ULTRASONIC_PIN_TIMEOUT);
740         });
741 #ifdef SUPPORT_MSDP
742     sptr<SpatialLocationCallbackImpl> callback = new(std::nothrow) SpatialLocationCallbackImpl(context);
743     Msdp::SpatialAwarenessMgrClient::GetInstance().RegisterPinCallback(callback);
744 #endif
745     auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_ULTRASONIC_PIN_CHANGED);
746     if (retEvent == DmEventType::ON_ULTRASONIC_PIN_CHANGED) {
747 #ifdef SUPPORT_MSDP
748         Msdp::SpatialAwarenessMgrClient::GetInstance().UnregisterPinCallback();
749 #endif
750         context->reply = DM_OK;
751         context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REVERSE_ULTRASONIC_DONE, context);
752         LOGI("OnPinCodeChanged End.");
753         return DM_OK;
754     } else if (retEvent == DmEventType::ON_ULTRASONIC_PIN_TIMEOUT) {
755         context->authStateMachine->TransitionTo(std::make_shared<AuthSinkPinNegotiateStartState>());
756         return DM_OK;
757     }
758     return STOP_BIND;
759 }
760 
GetStateType()761 DmAuthStateType AuthSinkReverseUltrasonicDoneState::GetStateType()
762 {
763     return DmAuthStateType::AUTH_SINK_REVERSE_ULTRASONIC_DONE_STATE;
764 }
765 
Action(std::shared_ptr<DmAuthContext> context)766 int32_t AuthSinkReverseUltrasonicDoneState::Action(std::shared_ptr<DmAuthContext> context)
767 {
768     LOGI("AuthSinkReverseUltrasonicDoneState::Action Start.");
769     context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK));
770     context->timer->DeleteTimer(std::string(GET_ULTRASONIC_PIN_TIMEOUT_TASK));
771     context->pinNegotiateStarted = true;
772     auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData);
773     if (ret != DM_OK) {
774         LOGE("AuthSinkPinAuthStartState::Action call ProcessCredData err");
775         return ret;
776     }
777     auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT);
778     if (retEvent == DmEventType::ON_TRANSMIT) {
779         LOGI("AuthSrcPinAuthStartState::AuthDevice ON_TRANSMIT.");
780         context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_PIN_AUTH_START, context);
781         return DM_OK;
782     }
783     if (retEvent == DmEventType::ON_ERROR) {
784         LOGI("AuthSrcPinAuthStartState::AuthDevice ON_ERROR failed.");
785         context->authStateMachine->TransitionTo(std::make_shared<AuthSinkPinNegotiateStartState>());
786         return DM_OK;
787     }
788     return STOP_BIND;
789 }
790 
GetStateType()791 DmAuthStateType AuthSinkForwardUltrasonicStartState::GetStateType()
792 {
793     return DmAuthStateType::AUTH_SINK_FORWARD_ULTRASONIC_START_STATE;
794 }
795 
Action(std::shared_ptr<DmAuthContext> context)796 int32_t AuthSinkForwardUltrasonicStartState::Action(std::shared_ptr<DmAuthContext> context)
797 {
798     LOGI("AuthSinkForwardUltrasonicStartState::Action Start.");
799     context->timer->StartTimer(std::string(GET_ULTRASONIC_PIN_TIMEOUT_TASK),
800         GET_ULTRASONIC_PIN_TIMEOUT, [context] (std::string name) {
801             LOGI("AuthSinkForwardUltrasonicStartState timeout.");
802             context->authStateMachine->TransitionTo(std::make_shared<AuthSinkPinNegotiateStartState>());
803             return DM_OK;
804         });
805     context->pinCode = std::to_string(GenRandInt(MIN_PIN_CODE, MAX_PIN_CODE));
806     std::string ultraPinCode = context->pinCode;
807 #ifdef SUPPORT_MSDP
808     Msdp::SpatialAwarenessMgrClient::GetInstance().SetPinCode(ultraPinCode);
809 #endif
810     context->reply = DM_OK;
811     context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_FORWARD_ULTRASONIC_NEGOTIATE, context);
812     LOGI("AuthSinkForwardUltrasonicStartState::Action End.");
813     return DM_OK;
814 }
815 
GetStateType()816 DmAuthStateType AuthSinkForwardUltrasonicDoneState::GetStateType()
817 {
818     return DmAuthStateType::AUTH_SINK_FORWARD_ULTRASONIC_DONE_STATE;
819 }
820 
Action(std::shared_ptr<DmAuthContext> context)821 int32_t AuthSinkForwardUltrasonicDoneState::Action(std::shared_ptr<DmAuthContext> context)
822 {
823     LOGI("AuthSinkForwardUltrasonicDoneState::Action Start.");
824     context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK));
825     context->timer->DeleteTimer(std::string(GET_ULTRASONIC_PIN_TIMEOUT_TASK));
826     context->pinNegotiateStarted = true;
827     auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData);
828     if (ret != DM_OK) {
829         LOGE("AuthSinkForwardUltrasonicDoneState::Action call ProcessCredData err");
830         return ret;
831     }
832     auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT);
833     if (retEvent == DmEventType::ON_TRANSMIT) {
834         LOGI("AuthSinkForwardUltrasonicDoneState::AuthDevice ON_TRANSMIT.");
835         context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_PIN_AUTH_START, context);
836         return DM_OK;
837     }
838     if (retEvent == DmEventType::ON_ERROR) {
839         LOGI("AuthSinkForwardUltrasonicDoneState::AuthDevice ON_ERROR failed.");
840         context->authStateMachine->TransitionTo(std::make_shared<AuthSinkPinNegotiateStartState>());
841         return DM_OK;
842     }
843     return STOP_BIND;
844 }
845 } // namespace DistributedHardware
846 } // namespace OHOS