1 /*
2 * Copyright (C) 2021 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 "iso_server_unbind_exchange_task.h"
17 #include "das_module_defines.h"
18 #include "hc_log.h"
19 #include "hc_types.h"
20 #include "iso_task_common.h"
21 #include "string_util.h"
22
23 enum {
24 TASK_TYPE_BEGIN = 1,
25 TASK_TYPE_FINAL,
26 };
27
GetTaskType(void)28 static CurTaskType GetTaskType(void)
29 {
30 return TASK_TYPE_UNBIND_LITE_EXCHANGE;
31 }
32
DestroyServerUnbindExchangeTask(struct SymBaseCurTaskT * task)33 static void DestroyServerUnbindExchangeTask(struct SymBaseCurTaskT *task)
34 {
35 HcFree(task);
36 }
37
Process(struct SymBaseCurTaskT * task,IsoParams * params,const CJson * in,CJson * out,int32_t * status)38 static int Process(struct SymBaseCurTaskT *task, IsoParams *params, const CJson *in, CJson *out, int32_t *status)
39 {
40 (void)task;
41 (void)params;
42 (void)in;
43 (void)out;
44 (void)status;
45 return HC_ERROR;
46 }
47
CheckRemoveInfo(const Uint8Buff * removeInfoBuf,const IsoParams * params)48 static int CheckRemoveInfo(const Uint8Buff *removeInfoBuf, const IsoParams *params)
49 {
50 CJson *removeInfoJson = CreateJsonFromString((const char *)(removeInfoBuf->val));
51 if (removeInfoJson == NULL) {
52 LOGE("Get remove info json failed");
53 return HC_ERR_JSON_GET;
54 }
55 int32_t userType = 0;
56 uint8_t *peerAuthId = NULL;
57 int res = GetIntFromJson(removeInfoJson, FIELD_RMV_TYPE, &userType);
58 if (res != HC_SUCCESS) {
59 LOGE("Get user type failed");
60 goto ERR;
61 }
62 if (userType != params->peerUserType) {
63 LOGE("User type not match :%d", userType);
64 res = HC_ERR_JSON_GET;
65 goto ERR;
66 }
67 peerAuthId = (uint8_t *)HcMalloc(params->baseParams.authIdPeer.length, 0);
68 if (peerAuthId == NULL) {
69 LOGE("Malloc failed");
70 res = HC_ERR_ALLOC_MEMORY;
71 goto ERR;
72 }
73 res = GetByteFromJson(removeInfoJson, FIELD_RMV_ID, peerAuthId, params->baseParams.authIdPeer.length);
74 if (res != HC_SUCCESS) {
75 LOGE("Get remove id failed, res:%d", res);
76 goto ERR;
77 }
78 if (memcmp(peerAuthId, params->baseParams.authIdPeer.val, params->baseParams.authIdPeer.length) != 0) {
79 LOGE("Compare peerAuthId failed");
80 res = HC_ERROR;
81 }
82 ERR:
83 FreeJson(removeInfoJson);
84 HcFree(peerAuthId);
85 return res;
86 }
87
GetAndCheckEncDataStr(const CJson * in,uint32_t * removeInfoFromJsonLen)88 static char *GetAndCheckEncDataStr(const CJson *in, uint32_t *removeInfoFromJsonLen)
89 {
90 char *removeInfoFromJson = (char *)GetStringFromJson(in, FIELD_ENC_DATA);
91 if (removeInfoFromJson == NULL) {
92 LOGE("No encData in unbind json");
93 return NULL;
94 }
95
96 *removeInfoFromJsonLen = strlen(removeInfoFromJson);
97 if (*removeInfoFromJsonLen <= TAG_LEN || *removeInfoFromJsonLen > MAX_BUFFER_LEN) {
98 LOGE("The length of removeInfoFromJson is invalid.");
99 return NULL;
100 }
101 return removeInfoFromJson;
102 }
103
DecryptRemoveInfo(const IsoParams * params,const CJson * in)104 static int DecryptRemoveInfo(const IsoParams *params, const CJson *in)
105 {
106 int res;
107 uint8_t *nonce = NULL;
108 uint8_t *removeInfo = NULL;
109 Uint8Buff encDataBuf = { NULL, 0 };
110
111 nonce = (uint8_t *)HcMalloc(NONCE_SIZE, 0);
112 if (nonce == NULL) {
113 res = HC_ERR_ALLOC_MEMORY;
114 goto ERR;
115 }
116 GOTO_ERR_AND_SET_RET(GetByteFromJson(in, FIELD_NONCE, nonce, NONCE_SIZE), res);
117 uint32_t removeInfoFromJsonLen = 0;
118 char *removeInfoFromJson = GetAndCheckEncDataStr(in, &removeInfoFromJsonLen);
119 if (removeInfoFromJson == NULL) {
120 res = HC_ERR_JSON_GET;
121 goto ERR;
122 }
123
124 uint32_t removeInfoLen = removeInfoFromJsonLen - TAG_LEN;
125 removeInfo = (uint8_t *)HcMalloc(removeInfoLen, 0);
126 if (removeInfo == NULL) {
127 res = HC_ERR_ALLOC_MEMORY;
128 goto ERR;
129 }
130
131 encDataBuf.length = removeInfoFromJsonLen / BYTE_TO_HEX_OPER_LENGTH;
132 encDataBuf.val = (uint8_t *)HcMalloc(encDataBuf.length, 0);
133 if (encDataBuf.val == NULL) {
134 LOGE("Malloc encDataBuf.val failed.");
135 res = HC_ERR_ALLOC_MEMORY;
136 goto ERR;
137 }
138 res = HexStringToByte(removeInfoFromJson, encDataBuf.val, encDataBuf.length);
139 if (res != HC_SUCCESS) {
140 LOGE("HexStringToByte for encData failed.");
141 goto ERR;
142 }
143 Uint8Buff removeInfoBuf = { removeInfo, removeInfoLen };
144 GcmParam gcmParam = { nonce, NONCE_SIZE, (uint8_t *)UNBIND_ADD_REQUEST, HcStrlen(UNBIND_ADD_REQUEST) };
145 res = params->baseParams.loader->aesGcmDecrypt(¶ms->baseParams.sessionKey, &encDataBuf, &gcmParam, false,
146 &removeInfoBuf);
147 if (res != 0) {
148 LOGE("decrypt removeInfo failed, res:%d", res);
149 goto ERR;
150 }
151 res = CheckRemoveInfo(&removeInfoBuf, params);
152 ERR:
153 HcFree(nonce);
154 HcFree(removeInfo);
155 HcFree(encDataBuf.val);
156 return res;
157 }
158
ServerUnbindExchangeStart(IsoParams * param,IsoServerUnbindExchangeTask * task,const CJson * in,CJson * out,int32_t * status)159 static int ServerUnbindExchangeStart(IsoParams *param, IsoServerUnbindExchangeTask *task,
160 const CJson *in, CJson *out, int32_t *status)
161 {
162 int res = DecryptRemoveInfo(param, in);
163 if (res != 0) {
164 return res;
165 }
166
167 res = GenEncResult(param, ISO_SERVER_UNBIND_EXCHANGE_RET, out, UNBIND_ADD_RESPONSE, false);
168 if (res != 0) {
169 LOGE("unbind exchange gen enc result failed, res:%d", res);
170 goto ERR;
171 }
172
173 task->taskBase.taskStatus = TASK_TYPE_BEGIN;
174 *status = FINISH;
175 ERR:
176 return res;
177 }
178
CreateServerUnbindExchangeTask(IsoParams * params,const CJson * in,CJson * out,int32_t * status)179 SymBaseCurTask *CreateServerUnbindExchangeTask(IsoParams *params, const CJson *in, CJson *out, int32_t *status)
180 {
181 (void)in;
182 IsoServerUnbindExchangeTask *task = (IsoServerUnbindExchangeTask *)HcMalloc(sizeof(IsoServerUnbindExchangeTask), 0);
183 if (task == NULL) {
184 return NULL;
185 }
186 task->taskBase.destroyTask = DestroyServerUnbindExchangeTask;
187 task->taskBase.process = Process;
188 task->taskBase.getCurTaskType = GetTaskType;
189 int res = ServerUnbindExchangeStart(params, task, in, out, status);
190 if (res != 0) {
191 DestroyServerUnbindExchangeTask((struct SymBaseCurTaskT *)task);
192 return NULL;
193 }
194 return (SymBaseCurTask *)task;
195 }
196