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