• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_client_unbind_exchange_task.h"
17 #include "hc_log.h"
18 #include "hc_types.h"
19 #include "iso_task_common.h"
20 
21 enum {
22     TASK_TYPE_BEGIN = 1,
23     TASK_TYPE_FINAL,
24 };
25 
GetTaskType(void)26 static CurTaskType GetTaskType(void)
27 {
28     return TASK_TYPE_UNBIND_LITE_EXCHANGE;
29 }
30 
DestroyClientUnbindExchangeTask(struct SymBaseCurTaskT * task)31 static void DestroyClientUnbindExchangeTask(struct SymBaseCurTaskT *task)
32 {
33     HcFree(task);
34 }
35 
Process(struct SymBaseCurTaskT * task,IsoParams * params,const CJson * in,CJson * out,int32_t * status)36 static int Process(struct SymBaseCurTaskT *task, IsoParams *params, const CJson *in, CJson *out, int32_t *status)
37 {
38     IsoClientUnbindExchangeTask *realTask = (IsoClientUnbindExchangeTask *)task;
39     if (realTask->taskBase.taskStatus < TASK_TYPE_BEGIN) {
40         LOGE("Invalid taskStatus: %d", realTask->taskBase.taskStatus);
41         return HC_ERR_BAD_MESSAGE;
42     }
43 
44     if (realTask->taskBase.taskStatus > TASK_TYPE_BEGIN) {
45         LOGI("The message is repeated, ignore it, status: %d", realTask->taskBase.taskStatus);
46         *status = IGNORE_MSG;
47         return HC_SUCCESS;
48     }
49     int res;
50     uint8_t *keyAlias = NULL;
51     int32_t message = 0;
52     res = GetIntFromJson(in, FIELD_MESSAGE, &message);
53     if (res != 0 || message != ISO_SERVER_UNBIND_EXCHANGE_RET) {
54         return HC_ERR_BAD_MESSAGE;
55     }
56     res = CheckEncResult(params, in, UNBIND_ADD_RESPONSE);
57     if (res != 0) {
58         LOGE("CheckEncResult failed, res:%d", res);
59         return res;
60     }
61     keyAlias = (uint8_t *)HcMalloc(ISO_KEY_ALIAS_LEN, 0);
62     if (keyAlias == NULL) {
63         res = HC_ERR_ALLOC_MEMORY;
64         goto ERR;
65     }
66     res = GenerateKeyAliasInIso(params, keyAlias, ISO_KEY_ALIAS_LEN, true);
67     if (res != 0) {
68         LOGE("GenerateKeyAliasInIso failed, res:%d", res);
69         goto ERR;
70     }
71     LOGI("AuthCode alias: %x%x%x%x****.", keyAlias[0], keyAlias[1], keyAlias[2], keyAlias[3]);
72     Uint8Buff outKeyAlias = { (uint8_t *)keyAlias, ISO_KEY_ALIAS_LEN };
73     res = params->baseParams.loader->deleteKey(&outKeyAlias);
74     if (res != 0) {
75         LOGE("delete auth code failed, res:%d", res);
76         goto ERR;
77     }
78     res = SendResultToFinalSelf(params, out, false);
79     if (res == 0) {
80         realTask->taskBase.taskStatus = TASK_TYPE_FINAL;
81         *status = FINISH;
82     }
83 ERR:
84     HcFree(keyAlias);
85     return res;
86 }
87 
PackDataForStartUnbind(const IsoParams * params,const Uint8Buff * encDataBuf,const Uint8Buff * nonceBuf,CJson * out)88 static int PackDataForStartUnbind(const IsoParams *params, const Uint8Buff *encDataBuf, const Uint8Buff *nonceBuf,
89     CJson *out)
90 {
91     int res = 0;
92     CJson *payload = NULL;
93     CJson *sendToPeer = NULL;
94 
95     payload = CreateJson();
96     if (payload == NULL) {
97         res = HC_ERR_ALLOC_MEMORY;
98         goto ERR;
99     }
100     sendToPeer = CreateJson();
101     if (sendToPeer == NULL) {
102         res = HC_ERR_ALLOC_MEMORY;
103         goto ERR;
104     }
105     GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_MESSAGE, ISO_CLIENT_UNBIND_EXCHANGE_CMD), res);
106     GOTO_ERR_AND_SET_RET(AddIntToJson(payload, FIELD_OPERATION_CODE, params->opCode), res);
107     GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_ENC_DATA, encDataBuf->val, encDataBuf->length), res);
108     GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_NONCE, nonceBuf->val, nonceBuf->length), res);
109     GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, payload), res);
110     GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
111 ERR:
112     FreeJson(payload);
113     FreeJson(sendToPeer);
114     return res;
115 }
116 
GenerateEncRemoveInfo(const IsoParams * params,const Uint8Buff * nonceBuf,CJson * out)117 static int GenerateEncRemoveInfo(const IsoParams *params, const Uint8Buff *nonceBuf, CJson *out)
118 {
119     int res;
120     char *rmvInfoStr = NULL;
121     uint8_t *encData = NULL;
122     CJson *rmvInfoJson = CreateJson();
123     if (rmvInfoJson == NULL) {
124         LOGE("Create json failed");
125         return HC_ERR_ALLOC_MEMORY;
126     }
127     GOTO_ERR_AND_SET_RET(AddByteToJson(rmvInfoJson, FIELD_RMV_ID, params->baseParams.authIdSelf.val,
128         params->baseParams.authIdSelf.length), res);
129     GOTO_ERR_AND_SET_RET(AddIntToJson(rmvInfoJson, FIELD_RMV_TYPE, params->selfUserType), res);
130     rmvInfoStr = PackJsonToString(rmvInfoJson);
131     if (rmvInfoStr == NULL) {
132         LOGE("rmvInfoStr PackJsonToString failed");
133         res = HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
134         goto ERR;
135     }
136 
137     Uint8Buff removeInfoBuf = { (uint8_t *)rmvInfoStr, strlen(rmvInfoStr) };
138 
139     int encDataLen = strlen(rmvInfoStr) + TAG_LEN;
140     encData = (uint8_t *)HcMalloc(encDataLen, 0);
141     if (encData == NULL) {
142         res = HC_ERR_ALLOC_MEMORY;
143         goto ERR;
144     }
145     Uint8Buff encDataBuf = { encData, encDataLen };
146     GcmParam gcmParam;
147     gcmParam.aad = (uint8_t *)UNBIND_ADD_REQUEST;
148     gcmParam.aadLen = (uint32_t)strlen(UNBIND_ADD_REQUEST);
149     gcmParam.nonce = nonceBuf->val;
150     gcmParam.nonceLen = nonceBuf->length;
151     res = params->baseParams.loader->aesGcmEncrypt(&params->baseParams.sessionKey, &removeInfoBuf, &gcmParam, false,
152         &encDataBuf);
153     if (res != 0) {
154         LOGE("encrypt removeInfo failed, res:%d", res);
155         goto ERR;
156     }
157     res = PackDataForStartUnbind(params, &encDataBuf, nonceBuf, out);
158     if (res != HC_SUCCESS) {
159         LOGE("PackDataForStartUnbind failed, res:%d", res);
160     }
161 ERR:
162     FreeJson(rmvInfoJson);
163     FreeJsonString(rmvInfoStr);
164     HcFree(encData);
165     return res;
166 }
167 
168 
ClientUnbindExchangeStart(const IsoParams * params,IsoClientUnbindExchangeTask * task,CJson * out,int32_t * status)169 static int ClientUnbindExchangeStart(const IsoParams *params, IsoClientUnbindExchangeTask *task, CJson *out,
170     int32_t *status)
171 {
172     int res;
173     uint8_t *nonce = NULL;
174 
175     nonce = (uint8_t *)HcMalloc(NONCE_SIZE, 0);
176     if (nonce == NULL) {
177         res = HC_ERR_ALLOC_MEMORY;
178         goto ERR;
179     }
180     Uint8Buff nonceBuf = { nonce, NONCE_SIZE };
181     res = params->baseParams.loader->generateRandom(&nonceBuf);
182     if (res != 0) {
183         LOGE("generate nonce failed, res:%d", res);
184         goto ERR;
185     }
186 
187     res = GenerateEncRemoveInfo(params, &nonceBuf, out);
188     if (res != 0) {
189         LOGE("GenerateEncRemoveInfo failed, res:%d", res);
190         goto ERR;
191     }
192     task->taskBase.taskStatus = TASK_TYPE_BEGIN;
193     *status = CONTINUE;
194 ERR:
195     HcFree(nonce);
196     return res;
197 }
198 
CreateClientUnbindExchangeTask(IsoParams * params,const CJson * in,CJson * out,int32_t * status)199 SymBaseCurTask *CreateClientUnbindExchangeTask(IsoParams *params, const CJson *in, CJson *out, int32_t *status)
200 {
201     (void)in;
202     IsoClientUnbindExchangeTask *task = (IsoClientUnbindExchangeTask *)HcMalloc(sizeof(IsoClientUnbindExchangeTask), 0);
203     if (task == NULL) {
204         return NULL;
205     }
206     task->taskBase.destroyTask = DestroyClientUnbindExchangeTask;
207     task->taskBase.process = Process;
208     task->taskBase.getCurTaskType = GetTaskType;
209     int res = ClientUnbindExchangeStart(params, task, out, status);
210     if (res != 0) {
211         DestroyClientUnbindExchangeTask((struct SymBaseCurTaskT *)task);
212         return NULL;
213     }
214     return (SymBaseCurTask *)task;
215 }
216