* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <memory>
#include "app_manager_3rd.h"
#include "business_event.h"
#include "distributed_device_profile_client.h"
#include "softbus_common.h"
#include "system_ability_definition.h"
#include "iservice_registry.h"
#include "parameter.h"
#include "ipc_skeleton.h"
#include "multiple_user_connector_3rd.h"
#include "dm_constants_3rd.h"
#include "dm_crypto_3rd.h"
#include "dm_log_3rd.h"
#include "dm_timer_3rd.h"
#include "device_manager_data_struct_3rd.h"
#include "dm_anonymous_3rd.h"
#include "dm_auth_state_machine_cred.h"
#include "dm_auth_context_cred.h"
#include "dm_auth_message_processor_cred.h"
#include "dm_auth_state_cred.h"
#include "json_object.h"
namespace OHOS {
namespace DistributedHardware {
namespace {
}
AuthManagerCred::AuthManagerCred(std::shared_ptr<SoftbusConnector3rd> softbusConnector,
std::shared_ptr<IDeviceManagerServiceListener3rd> listener,
std::shared_ptr<HiChainAuthConnector3rd> hiChainAuthConnector)
{
LOGI("AuthManagerCred constructor");
context_ = std::make_shared<DmAuthCredContext>();
context_->listener = listener;
context_->softbusConnector = softbusConnector;
context_->hiChainAuthConnector = hiChainAuthConnector;
context_->accesser.dmVersion = DM_CURRENT_VERSION;
context_->accessee.dmVersion = DM_CURRENT_VERSION;
context_->timer = std::make_shared<DmTimer3rd>();
context_->authMessageProcessor = std::make_shared<DmAuthMessageProcessorCred>();
}
AuthManagerCred::~AuthManagerCred()
{
if (context_ != nullptr) {
if (context_->authStateMachine != nullptr) {
context_->authStateMachine->Stop();
}
if (context_->timer != nullptr) {
context_->timer->DeleteAll();
}
LOGI("AuthManagerCred context variables destroy successful.");
}
LOGI("AuthManagerCred destructor");
}
int32_t AuthManagerCred::AuthDevice3rd(const PeerTargetId3rd &targetId,
const std::map<std::string, std::string> &authParam, int32_t sessionId, uint64_t logicalSessionId)
{
return ERR_DM_UNSUPPORTED_METHOD;
}
int32_t AuthManagerCred::AuthCredential(const PeerTargetId3rd &targetId,
const std::map<std::string, std::string> &authParam, int32_t sessionId, uint64_t logicalSessionId)
{
LOGI("AuthManagerCred::AuthCredential start");
CHECK_NULL_RETURN(context_, ERR_DM_POINT_NULL);
std::string authParamStr = ConvertMapToJsonString(authParam);
if (!authParam.empty() && authParamStr.empty()) {
LOGE("AuthCredential failed: invalid authParam.");
return ERR_DM_INPUT_PARA_INVALID;
}
GetAuthParam(targetId, authParam);
CHECK_NULL_RETURN(context_->authStateMachine, ERR_DM_POINT_NULL);
context_->authStateMachine->TransitionTo(std::make_shared<AuthCredSrcStartState>());
context_->sessionId = sessionId;
context_->logicalSessionId = logicalSessionId;
context_->requestId = static_cast<int64_t>(logicalSessionId);
context_->authStateMachine->TransitionTo(std::make_shared<AuthSrcNegotiateStartState>());
return DM_OK;
}
void AuthManagerCred::GetAuthParam(const PeerTargetId3rd &targetId, const std::map<std::string, std::string> &authParam)
{
char localDeviceId[DEVICE_UUID_LENGTH] = {0};
GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
CHECK_NULL_VOID(context_);
context_->accesser.deviceId = std::string(localDeviceId);
context_->accessee.deviceId = targetId.deviceId;
context_->accesser.userId = MultipleUserConnector3rd::GetFirstForegroundUserId();
context_->accesser.accountId = MultipleUserConnector3rd::GetOhosAccountIdByUserId(context_->accesser.userId);
if (authParam.find(TAG_BIND_CALLER_UID) != authParam.end()) {
context_->accesser.uid = static_cast<int32_t>(std::atoi(authParam.at(TAG_BIND_CALLER_UID).c_str()));
}
if (authParam.find(TAG_BIND_CALLER_TOKENID) != authParam.end()) {
context_->accesser.tokenId = static_cast<uint32_t>(std::atoi(authParam.at(TAG_BIND_CALLER_TOKENID).c_str()));
}
if (authParam.find(TAG_BIND_CALLER_PROCESSNAME) != authParam.end()) {
context_->accesser.processName = authParam.at(TAG_BIND_CALLER_PROCESSNAME);
context_->accessee.processName = authParam.at(TAG_BIND_CALLER_PROCESSNAME);
}
if (authParam.find(TAG_BUSINESS_NAME) != authParam.end()) {
context_->accesser.businessName = authParam.at(TAG_BUSINESS_NAME);
context_->accessee.businessName = authParam.at(TAG_BUSINESS_NAME);
}
if (authParam.find(TAG_PEER_PROCESS_NAME) != authParam.end()) {
context_->accessee.processName = authParam.at(TAG_PEER_PROCESS_NAME);
}
if (authParam.find(TAG_PEER_BUSINESS_NAME) != authParam.end()) {
context_->accessee.businessName = authParam.at(TAG_PEER_BUSINESS_NAME);
}
if (authParam.find(TAG_OPENID) != authParam.end()) {
std::string openId = authParam.at(TAG_OPENID);
context_->accesser.openIdHash = Crypto3rd::Sha256(openId).substr(0, DM_OPENID_HASH_LEN);
}
if (authParam.find(TAG_OWNER_ID) != authParam.end()) {
context_->accesser.ownerId = authParam.at(TAG_OWNER_ID);
}
if (authParam.find(TAG_CRED_TYPE) != authParam.end()) {
context_->accesser.credType = static_cast<uint8_t>(std::atoi(authParam.at(TAG_CRED_TYPE).c_str()));
}
context_->processInfo.tokenId = context_->accesser.tokenId;
context_->processInfo.uid = context_->accesser.uid;
context_->processInfo.userId = context_->accesser.userId;
context_->processInfo.processName = context_->accesser.processName;
context_->processInfo.businessName = context_->accesser.businessName;
}
std::string AuthManagerCred::GetPeerProcessName(const JsonItemObject &item, const std::string &defaultProcessName)
{
if (item.Contains(TAG_PEER_PROCESS_NAME) && IsString(item, TAG_PEER_PROCESS_NAME)) {
return item[TAG_PEER_PROCESS_NAME].Get<std::string>();
}
return defaultProcessName;
}
AuthSinkManagerCred::AuthSinkManagerCred(std::shared_ptr<SoftbusConnector3rd> softbusConnector,
std::shared_ptr<IDeviceManagerServiceListener3rd> listener,
std::shared_ptr<HiChainAuthConnector3rd> hiChainAuthConnector)
: AuthManagerCred(softbusConnector, listener, hiChainAuthConnector)
{
if (context_ != nullptr) {
context_->direction = DM_AUTH_CRED_SINK;
context_->authStateMachine = std::make_shared<DmAuthStateMachineCred>(context_);
}
}
void AuthSinkManagerCred::OnSessionOpened(int32_t sessionId, int32_t sessionSide, int32_t result)
{
LOGI("sessionId = %{public}d and sessionSide = %{public}d result = %{public}d", sessionId, sessionSide, result);
}
void AuthSinkManagerCred::OnSessionClosed(int32_t sessionId)
{
LOGI("OnSessionClosed sessionId = %{public}d", sessionId);
CHECK_NULL_VOID(context_);
CHECK_NULL_VOID(context_->authStateMachine);
context_->reason = ERR_DM_SESSION_CLOSED;
context_->authStateMachine->TransitionTo(std::make_shared<AuthCredSinkFinishState>());
}
void AuthSinkManagerCred::OnDataReceived(int32_t sessionId, const std::string &message)
{
CHECK_NULL_VOID(context_);
CHECK_NULL_VOID(context_->authMessageProcessor);
context_->sessionId = sessionId;
int32_t ret = context_->authMessageProcessor->ParseMessage(context_, message);
if (ret != DM_OK) {
LOGE("OnDataReceived failed, parse input message error.");
context_->reason = ERR_DM_PARSE_MESSAGE_FAILED;
CHECK_NULL_VOID(context_->authStateMachine);
context_->authStateMachine->TransitionTo(std::make_shared<AuthCredSinkFinishState>());
}
return;
}
bool AuthSinkManagerCred::GetIsCryptoSupport()
{
return false;
}
AuthSrcManagerCred::AuthSrcManagerCred(std::shared_ptr<SoftbusConnector3rd> softbusConnector,
std::shared_ptr<IDeviceManagerServiceListener3rd> listener,
std::shared_ptr<HiChainAuthConnector3rd> hiChainAuthConnector)
: AuthManagerCred(softbusConnector, listener, hiChainAuthConnector)
{
if (context_ != nullptr) {
context_->direction = DM_AUTH_CRED_SOURCE;
context_->authStateMachine = std::make_shared<DmAuthStateMachineCred>(context_);
}
}
void AuthSrcManagerCred::OnSessionOpened(int32_t sessionId, int32_t sessionSide, int32_t result)
{
LOGI("sessionId = %{public}d and sessionSide = %{public}d result = %{public}d", sessionId, sessionSide, result);
}
void AuthSrcManagerCred::OnSessionClosed(int32_t sessionId)
{
LOGI("AuthSrcManagerCred::OnSessionClosed sessionId = %{public}d", sessionId);
CHECK_NULL_VOID(context_);
context_->reason = ERR_DM_SESSION_CLOSED;
CHECK_NULL_VOID(context_->authStateMachine);
context_->authStateMachine->TransitionTo(std::make_shared<AuthCredSrcFinishState>());
}
void AuthSrcManagerCred::OnSessionDisable()
{
CHECK_NULL_VOID(context_);
context_->sessionId = -1;
}
void AuthSrcManagerCred::OnDataReceived(int32_t sessionId, const std::string &message)
{
CHECK_NULL_VOID(context_);
context_->sessionId = sessionId;
CHECK_NULL_VOID(context_->authMessageProcessor);
int32_t ret = context_->authMessageProcessor->ParseMessage(context_, message);
if (ret != DM_OK) {
LOGE("OnDataReceived failed, parse input message error.");
context_->reason = ERR_DM_PARSE_MESSAGE_FAILED;
CHECK_NULL_VOID(context_->authStateMachine);
context_->authStateMachine->TransitionTo(std::make_shared<AuthCredSrcFinishState>());
}
return;
}
bool AuthSrcManagerCred::GetIsCryptoSupport()
{
return false;
}
void AuthSrcManagerCred::AuthDeviceError(int64_t requestId, int32_t errorCode)
{
LOGI("AuthSrcManagerCred::AuthDeviceError start.");
CHECK_NULL_VOID(context_);
if (requestId != context_->requestId) {
LOGE("requestId: %{public}" PRId64", context_->requestId: %{public}" PRId64".", requestId, context_->requestId);
return;
}
CHECK_NULL_VOID(context_->authStateMachine);
LOGI("AuthSrcManagerCred::AuthDeviceError unexpected err.");
context_->reason = (errorCode == ERR_DM_HICHAIN_PROOFMISMATCH ? ERR_DM_BIND_PIN_CODE_ERROR : errorCode);
context_->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL);
}
void AuthSinkManagerCred::AuthDeviceError(int64_t requestId, int32_t errorCode)
{
LOGI("AuthSinkManagerCred::AuthDeviceError start.");
CHECK_NULL_VOID(context_);
if (requestId != context_->requestId) {
LOGE("requestId: %{public}" PRId64", context_->requestId: %{public}" PRId64".", requestId, context_->requestId);
return;
}
CHECK_NULL_VOID(context_->authStateMachine);
auto curState = context_->authStateMachine->GetCurState();
LOGI("AuthSinkManagerCred::AuthDeviceError unexpected err.");
context_->reason = errorCode;
context_->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL);
}
bool AuthSrcManagerCred::AuthDeviceTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen)
{
LOGI("AuthSrcManagerCred::AuthDeviceTransmit start.");
CHECK_NULL_RETURN(context_, false);
if (requestId != context_->requestId) {
LOGE("AuthSrcManagerCred::onTransmit requestId %{public}" PRId64"is error.", requestId);
return false;
}
if (data == nullptr) {
LOGE("data is null.");
return false;
}
context_->transmitData = std::string(reinterpret_cast<const char *>(data), dataLen);
CHECK_NULL_RETURN(context_->authStateMachine, false);
context_->authStateMachine->NotifyEventFinish(ON_TRANSMIT);
LOGI("AuthSrcManagerCred::AuthDeviceTransmit leave.");
return true;
}
bool AuthSinkManagerCred::AuthDeviceTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen)
{
LOGI("AuthSinkManagerCred::AuthDeviceTransmit start.");
CHECK_NULL_RETURN(context_, false);
if (requestId != context_->requestId) {
LOGE("AuthSinkManagerCred::onTransmit requestId %{public}" PRId64"is error.", requestId);
return false;
}
context_->transmitData = std::string(reinterpret_cast<const char *>(data), dataLen);
CHECK_NULL_RETURN(context_->authStateMachine, false);
context_->authStateMachine->NotifyEventFinish(ON_TRANSMIT);
LOGI("AuthSinkManagerCred::AuthDeviceTransmit leave.");
return true;
}
void AuthSrcManagerCred::AuthDeviceFinish(int64_t requestId)
{
LOGI("AuthSrcManagerCred::AuthDeviceFinish start.");
CHECK_NULL_VOID(context_);
CHECK_NULL_VOID(context_->authStateMachine);
context_->authStateMachine->NotifyEventFinish(ON_FINISH);
LOGI("AuthSrcManagerCred::AuthDeviceFinish leave.");
}
void AuthSinkManagerCred::AuthDeviceFinish(int64_t requestId)
{
LOGI("AuthSinkManagerCred::AuthDeviceFinish start.");
CHECK_NULL_VOID(context_);
CHECK_NULL_VOID(context_->authStateMachine);
context_->authStateMachine->NotifyEventFinish(ON_FINISH);
LOGI("AuthSinkManagerCred::AuthDeviceFinish leave.");
}
void AuthSrcManagerCred::AuthDeviceSessionKey(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen)
{
LOGI("start. keyLen: %{public}u", sessionKeyLen);
if (context_ == nullptr || context_->authStateMachine == nullptr) {
LOGE("failed, auth context not initial.");
return;
}
if (requestId != context_->requestId) {
LOGE("requestId %{public}" PRId64 "is error.", requestId);
return;
}
if (sessionKey == nullptr) {
LOGE("sessionKey is null.");
return;
}
context_->accesser.sessionKey = std::vector<unsigned char>(sessionKey, sessionKey + sessionKeyLen);
context_->authStateMachine->NotifyEventFinish(ON_SESSION_KEY_RETURNED);
}
void AuthSinkManagerCred::AuthDeviceSessionKey(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen)
{
LOGI("start. keyLen: %{public}u", sessionKeyLen);
if (context_ == nullptr || context_->authStateMachine == nullptr) {
LOGE("failed, auth context not initial.");
return;
}
if (requestId != context_->requestId) {
LOGE("requestId %{public}" PRId64 "is error.", requestId);
return;
}
if (sessionKey == nullptr) {
LOGE("sessionKey is null.");
return;
}
context_->accessee.sessionKey = std::vector<unsigned char>(sessionKey, sessionKey + sessionKeyLen);
context_->authStateMachine->NotifyEventFinish(ON_SESSION_KEY_RETURNED);
}
char *AuthSrcManagerCred::AuthDeviceRequest(int64_t requestId, int operationCode, const char *reqParams)
{
LOGI("AuthSrcManagerCred::AuthDeviceRequest start");
return nullptr;
}
char *AuthSinkManagerCred::AuthDeviceRequest(int64_t requestId, int operationCode, const char *reqParams)
{
LOGI("AuthSinkManagerCred::AuthDeviceRequest start");
(void)requestId;
(void)reqParams;
CHECK_NULL_RETURN(context_, nullptr);
JsonObject jsonObj;
jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_ACCEPTED;
jsonObj[FIELD_CRED_ID] = context_->accessee.transmitCredentialId;
jsonObj[FIELD_SERVICE_PKG_NAME] = std::string(DM_PKG_NAME);
if (!context_->accesser.openIdHash.empty()) {
jsonObj[TAG_IS_OPEN_CRED_AUTH] = true;
}
std::string jsonStr = jsonObj.Dump();
char *buffer = strdup(jsonStr.c_str());
return buffer;
}
void AuthManagerCred::RegisterCleanNotifyCallback(CleanNotifyCallback cleanNotifyCallback)
{
CHECK_NULL_VOID(context_);
context_->cleanNotifyCallback = cleanNotifyCallback;
return;
}
}
}