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