1 /*
2 * Copyright (c) 2023-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 "hichain_auth_connector.h"
16
17 #include "dm_log.h"
18 #include "dm_anonymous.h"
19 #include "hichain_connector_callback.h"
20 #include "parameter.h"
21
22 namespace OHOS {
23 namespace DistributedHardware {
24
25 std::shared_ptr<IDmDeviceAuthCallback> HiChainAuthConnector::dmDeviceAuthCallback_ = nullptr;
26
HiChainAuthConnector()27 HiChainAuthConnector::HiChainAuthConnector()
28 {
29 int32_t ret = InitDeviceAuthService();
30 if (ret != HC_SUCCESS) {
31 LOGE("hichain InitDeviceAuthService failed, err %{public}d.", ret);
32 }
33 deviceAuthCallback_ = {.onTransmit = HiChainAuthConnector::onTransmit,
34 .onSessionKeyReturned = HiChainAuthConnector::onSessionKeyReturned,
35 .onFinish = HiChainAuthConnector::onFinish,
36 .onError = HiChainAuthConnector::onError,
37 .onRequest = HiChainAuthConnector::onRequest};
38 LOGI("hichain GetGaInstance success.");
39 }
40
~HiChainAuthConnector()41 HiChainAuthConnector::~HiChainAuthConnector()
42 {
43 DestroyDeviceAuthService();
44 }
45
RegisterHiChainAuthCallback(std::shared_ptr<IDmDeviceAuthCallback> callback)46 int32_t HiChainAuthConnector::RegisterHiChainAuthCallback(std::shared_ptr<IDmDeviceAuthCallback> callback)
47 {
48 dmDeviceAuthCallback_ = callback;
49 return DM_OK;
50 }
51
AuthDevice(int32_t pinCode,int32_t osAccountId,std::string udid,int64_t requestId)52 int32_t HiChainAuthConnector::AuthDevice(int32_t pinCode, int32_t osAccountId, std::string udid, int64_t requestId)
53 {
54 LOGI("HiChainAuthConnector::AuthDevice start.");
55 nlohmann::json authParamJson;
56 authParamJson["osAccountId"] = osAccountId;
57 authParamJson["pinCode"] = std::to_string(pinCode);
58 authParamJson["acquireType"] = AcquireType::P2P_BIND;
59 std::string authParam = authParamJson.dump();
60 LOGI("StartAuthDevice authParam %{public}s ,requestId %{public}" PRId64, GetAnonyString(authParam).c_str(),
61 requestId);
62 int32_t ret = StartAuthDevice(requestId, authParam.c_str(), &deviceAuthCallback_);
63 if (ret != HC_SUCCESS) {
64 LOGE("Hichain authDevice failed, ret is %{public}d.", ret);
65 return ERR_DM_FAILED;
66 }
67 return DM_OK;
68 }
69
ProcessAuthData(int64_t requestId,std::string authData,int32_t osAccountId)70 int32_t HiChainAuthConnector::ProcessAuthData(int64_t requestId, std::string authData, int32_t osAccountId)
71 {
72 LOGI("HiChainAuthConnector::ProcessAuthData start.");
73 nlohmann::json jsonAuthParam;
74 jsonAuthParam["osAccountId"] = osAccountId;
75 jsonAuthParam["data"] = authData;
76 int32_t ret = ProcessAuthDevice(requestId, jsonAuthParam.dump().c_str(), &deviceAuthCallback_);
77 if (ret != HC_SUCCESS) {
78 LOGE("Hichain processData failed ret %{public}d.", ret);
79 return ERR_DM_FAILED;
80 }
81 return DM_OK;
82 }
83
onTransmit(int64_t requestId,const uint8_t * data,uint32_t dataLen)84 bool HiChainAuthConnector::onTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen)
85 {
86 LOGI("AuthDevice onTransmit, requestId %{public}" PRId64, requestId);
87 if (dmDeviceAuthCallback_ == nullptr) {
88 LOGE("HiChainAuthConnector::onTransmit dmDeviceAuthCallback_ is nullptr.");
89 return false;
90 }
91 return dmDeviceAuthCallback_->AuthDeviceTransmit(requestId, data, dataLen);
92 }
93
onRequest(int64_t requestId,int operationCode,const char * reqParams)94 char *HiChainAuthConnector::onRequest(int64_t requestId, int operationCode, const char *reqParams)
95 {
96 LOGI("HiChainAuthConnector::onRequest start.");
97 (void)requestId;
98 (void)reqParams;
99 if (dmDeviceAuthCallback_ == nullptr) {
100 LOGE("HiChainAuthConnector::onRequest dmDeviceAuthCallback_ is nullptr.");
101 return nullptr;
102 }
103 nlohmann::json jsonObj;
104 int32_t pinCode = 0;
105 if (dmDeviceAuthCallback_->GetPinCode(pinCode) == ERR_DM_FAILED) {
106 jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_REJECTED;
107 } else {
108 jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_ACCEPTED;
109 }
110 std::string deviceId = "";
111 dmDeviceAuthCallback_->GetRemoteDeviceId(deviceId);
112 jsonObj[FIELD_PIN_CODE] = std::to_string(pinCode);
113 jsonObj[FIELD_PEER_CONN_DEVICE_ID] = deviceId;
114 std::string jsonStr = jsonObj.dump();
115 char *buffer = strdup(jsonStr.c_str());
116 return buffer;
117 }
118
onFinish(int64_t requestId,int operationCode,const char * returnData)119 void HiChainAuthConnector::onFinish(int64_t requestId, int operationCode, const char *returnData)
120 {
121 LOGI("HiChainAuthConnector::onFinish reqId:%{public}" PRId64 ", operation:%{public}d.",
122 requestId, operationCode);
123 (void)returnData;
124 if (dmDeviceAuthCallback_ == nullptr) {
125 LOGE("HiChainAuthConnector::onFinish dmDeviceAuthCallback_ is nullptr.");
126 return;
127 }
128 dmDeviceAuthCallback_->AuthDeviceFinish(requestId);
129 }
130
onError(int64_t requestId,int operationCode,int errorCode,const char * errorReturn)131 void HiChainAuthConnector::onError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn)
132 {
133 LOGI("HichainAuthenCallBack::onError reqId:%{public}" PRId64 ", operation:%{public}d, errorCode:%{public}d.",
134 requestId, operationCode, errorCode);
135 (void)operationCode;
136 (void)errorReturn;
137 if (dmDeviceAuthCallback_ == nullptr) {
138 LOGE("HiChainAuthConnector::onError dmDeviceAuthCallback_ is nullptr.");
139 return;
140 }
141 dmDeviceAuthCallback_->AuthDeviceError(requestId, ERR_DM_FAILED);
142 }
143
onSessionKeyReturned(int64_t requestId,const uint8_t * sessionKey,uint32_t sessionKeyLen)144 void HiChainAuthConnector::onSessionKeyReturned(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen)
145 {
146 LOGI("HiChainAuthConnector::onSessionKeyReturned start.");
147 if (dmDeviceAuthCallback_ == nullptr) {
148 LOGE("HiChainAuthConnector::onSessionKeyReturned dmDeviceAuthCallback_ is nullptr.");
149 return;
150 }
151 dmDeviceAuthCallback_->AuthDeviceSessionKey(requestId, sessionKey, sessionKeyLen);
152 }
153
GenerateCredential(std::string & localUdid,int32_t osAccountId,std::string & publicKey)154 int32_t HiChainAuthConnector::GenerateCredential(std::string &localUdid, int32_t osAccountId, std::string &publicKey)
155 {
156 LOGI("HiChainAuthConnector::GenerateCredential start.");
157 nlohmann::json jsonObj;
158 jsonObj["osAccountId"] = osAccountId;
159 jsonObj["deviceId"] = localUdid;
160 jsonObj["acquireType"] = AcquireType::P2P_BIND;
161 jsonObj["flag"] = 1;
162 std::string requestParam = jsonObj.dump();
163 char *returnData = nullptr;
164 if (ProcessCredential(CRED_OP_CREATE, requestParam.c_str(), &returnData) != HC_SUCCESS) {
165 LOGE("Hichain generate credential failed.");
166 return ERR_DM_FAILED;
167 }
168 std::string returnDataStr = static_cast<std::string>(returnData);
169 nlohmann::json jsonObject = nlohmann::json::parse(returnDataStr, nullptr, false);
170 if (jsonObject.is_discarded()) {
171 LOGE("Decode generate return data jsonStr error.");
172 return ERR_DM_FAILED;
173 }
174 if (!IsInt32(jsonObject, "result") || !IsString(jsonObject, "publicKey") ||
175 jsonObject["result"].get<int32_t>() != HC_SUCCESS) {
176 LOGE("Hichain generate public key jsonObject invalied.");
177 return ERR_DM_FAILED;
178 }
179 if (jsonObject["result"].get<int32_t>() != 0) {
180 LOGE("Hichain generate public key failed");
181 return ERR_DM_FAILED;
182 }
183 publicKey = jsonObject["publicKey"].get<std::string>();
184 return DM_OK;
185 }
186
QueryCredential(std::string & localUdid,int32_t osAccountId)187 bool HiChainAuthConnector::QueryCredential(std::string &localUdid, int32_t osAccountId)
188 {
189 LOGI("HiChainAuthConnector::QueryCredential start.");
190 nlohmann::json jsonObj;
191 jsonObj["osAccountId"] = osAccountId;
192 jsonObj["deviceId"] = localUdid;
193 jsonObj["acquireType"] = AcquireType::P2P_BIND;
194 jsonObj["flag"] = 1;
195 std::string requestParam = jsonObj.dump();
196 char *returnData = nullptr;
197 if (ProcessCredential(CRED_OP_QUERY, requestParam.c_str(), &returnData) != HC_SUCCESS) {
198 LOGE("Hichain query credential failed.");
199 return false;
200 }
201 std::string returnDataStr = static_cast<std::string>(returnData);
202 nlohmann::json jsonObject = nlohmann::json::parse(returnDataStr, nullptr, false);
203 if (jsonObject.is_discarded()) {
204 LOGE("Decode query return data jsonStr error.");
205 return false;
206 }
207 if (!IsInt32(jsonObject, "result") || jsonObject["result"].get<int32_t>() == -1) {
208 LOGE("Hichain generate public key failed.");
209 return false;
210 }
211 if (!IsString(jsonObject, "publicKey") || jsonObject["result"].get<int32_t>() == 1) {
212 LOGI("Credential not exist.");
213 return false;
214 }
215 return true;
216 }
217
GetCredential(std::string & localUdid,int32_t osAccountId,std::string & publicKey)218 int32_t HiChainAuthConnector::GetCredential(std::string &localUdid, int32_t osAccountId, std::string &publicKey)
219 {
220 LOGI("HiChainAuthConnector::GetCredential");
221 nlohmann::json jsonObj;
222 jsonObj["osAccountId"] = osAccountId;
223 jsonObj["deviceId"] = localUdid;
224 jsonObj["acquireType"] = AcquireType::P2P_BIND;
225 jsonObj["flag"] = 1;
226 std::string requestParam = jsonObj.dump();
227 char *returnData = nullptr;
228 if (ProcessCredential(CRED_OP_QUERY, requestParam.c_str(), &returnData) != HC_SUCCESS) {
229 LOGE("Hichain query credential failed.");
230 return ERR_DM_FAILED;
231 }
232 std::string returnDataStr = static_cast<std::string>(returnData);
233 nlohmann::json jsonObject = nlohmann::json::parse(returnDataStr, nullptr, false);
234 if (jsonObject.is_discarded()) {
235 LOGE("Decode query return data jsonStr error.");
236 return ERR_DM_FAILED;
237 }
238 if (!IsInt32(jsonObject, "result") || jsonObject["result"].get<int32_t>() == -1) {
239 LOGE("Hichain generate public key failed.");
240 return ERR_DM_FAILED;
241 }
242 if (!IsString(jsonObject, "publicKey") || jsonObject["result"].get<int32_t>() == 1) {
243 LOGI("Credential not exist.");
244 return ERR_DM_FAILED;
245 }
246 publicKey = jsonObject["publicKey"].get<std::string>();
247 return DM_OK;
248 }
249
ImportCredential(int32_t osAccountId,std::string deviceId,std::string publicKey)250 int32_t HiChainAuthConnector::ImportCredential(int32_t osAccountId, std::string deviceId, std::string publicKey)
251 {
252 LOGI("HiChainAuthConnector::ImportCredential");
253 nlohmann::json jsonObj;
254 jsonObj["osAccountId"] = osAccountId;
255 jsonObj["deviceId"] = deviceId;
256 jsonObj["acquireType"] = AcquireType::P2P_BIND;
257 jsonObj["publicKey"] = publicKey;
258 std::string requestParam = jsonObj.dump();
259 char *returnData = nullptr;
260 if (ProcessCredential(CRED_OP_IMPORT, requestParam.c_str(), &returnData) != HC_SUCCESS) {
261 LOGE("Hichain query credential failed.");
262 return ERR_DM_FAILED;
263 }
264 std::string returnDataStr = static_cast<std::string>(returnData);
265 nlohmann::json jsonObject = nlohmann::json::parse(returnDataStr, nullptr, false);
266 if (jsonObject.is_discarded()) {
267 LOGE("Decode import return data jsonStr error.");
268 return ERR_DM_FAILED;
269 }
270 if (!IsInt32(jsonObject, "result")) {
271 LOGI("Hichain import public key jsonObject invalied.");
272 return ERR_DM_FAILED;
273 }
274 int32_t result = jsonObject["result"].get<int32_t>();
275 if (result != 0) {
276 LOGE("Hichain import public key result is %{public}d.", result);
277 return ERR_DM_FAILED;
278 }
279 return DM_OK;
280 }
281
DeleteCredential(const std::string & deviceId,int32_t userId)282 int32_t HiChainAuthConnector::DeleteCredential(const std::string &deviceId, int32_t userId)
283 {
284 LOGI("DeleteCredential start.");
285 nlohmann::json jsonObj;
286 jsonObj["deviceId"] = deviceId;
287 jsonObj["acquireType"] = AcquireType::P2P_BIND;
288 jsonObj["osAccountId"] = userId;
289 std::string requestParam = jsonObj.dump();
290 char *returnData = nullptr;
291 if (ProcessCredential(CRED_OP_DELETE, requestParam.c_str(), &returnData) != HC_SUCCESS) {
292 LOGE("Hichain query credential failed.");
293 return false;
294 }
295 std::string returnDataStr = static_cast<std::string>(returnData);
296 nlohmann::json jsonObject = nlohmann::json::parse(returnDataStr, nullptr, false);
297 if (jsonObject.is_discarded()) {
298 LOGE("Decode import return data jsonStr error.");
299 return false;
300 }
301 if (!IsInt32(jsonObject, "result")) {
302 LOGI("Hichain delete credential result json key is invalid.");
303 return ERR_DM_FAILED;
304 }
305 return jsonObject["result"].get<int32_t>();
306 }
307 } // namespace DistributedHardware
308 } // namespace OHOS
309