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