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 "standard_server_unbind_exchange_task.h"
17 #include "hc_log.h"
18 #include "hc_types.h"
19 #include "protocol_common.h"
20 #include "standard_exchange_message_util.h"
21
22 enum {
23 TASK_STATUS_SERVER_UNBIND_EXCHANGE_BEGIN = 0,
24 TASK_STATUS_SERVER_UNBIND_EXCHANGE_START,
25 TASK_STATUS_SERVER_UNBIND_EXCHANGE_RESPONSE,
26 };
27
GetTaskType(void)28 static CurTaskType GetTaskType(void)
29 {
30 return TASK_TYPE_UNBIND_STANDARD_EXCHANGE;
31 }
32
ExchangeStart(AsyBaseCurTask * task,PakeParams * params,CJson * out,int * status)33 static int ExchangeStart(AsyBaseCurTask *task, PakeParams *params, CJson *out, int *status)
34 {
35 int res = HC_SUCCESS;
36 if (task->taskStatus != TASK_STATUS_SERVER_UNBIND_EXCHANGE_BEGIN) {
37 LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
38 *status = IGNORE_MSG;
39 return HC_SUCCESS;
40 }
41
42 if (params->baseParams.challengeSelf.val == NULL) {
43 res = GenerateSelfChallenge(params);
44 if (res != HC_SUCCESS) {
45 LOGE("GenerateSelfChallenge failed");
46 return res;
47 }
48 CJson *payload = GetObjFromJson(out, FIELD_PAYLOAD);
49 if (payload == NULL) {
50 LOGE("Get payload failed.");
51 return HC_ERR_JSON_GET;
52 }
53 if (AddByteToJson(payload, FIELD_CHALLENGE,
54 params->baseParams.challengeSelf.val, params->baseParams.challengeSelf.length) != HC_SUCCESS) {
55 LOGE("Failed to add self challenge to payload.");
56 return HC_ERR_JSON_ADD;
57 }
58 }
59
60 task->taskStatus = TASK_STATUS_SERVER_UNBIND_EXCHANGE_START;
61 *status = CONTINUE;
62 return res;
63 }
64
ExchangeResponse(AsyBaseCurTask * task,PakeParams * params,const CJson * in,CJson * out,int * status)65 static int ExchangeResponse(AsyBaseCurTask *task, PakeParams *params, const CJson *in, CJson *out, int *status)
66 {
67 int res = HC_SUCCESS;
68 CJson *data = NULL;
69 CJson *sendToPeer = NULL;
70
71 if (task->taskStatus < TASK_STATUS_SERVER_UNBIND_EXCHANGE_START) {
72 return HC_ERR_BAD_MESSAGE;
73 }
74 if (task->taskStatus > TASK_STATUS_SERVER_UNBIND_EXCHANGE_START) {
75 LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
76 *status = IGNORE_MSG;
77 return HC_SUCCESS;
78 }
79
80 StandardUnbindExchangeServerTask *realTask = (StandardUnbindExchangeServerTask *)task;
81
82 if (params->baseParams.challengePeer.val == NULL) {
83 GOTO_ERR_AND_SET_RET(GetPeerChallenge(params, in), res);
84 }
85 GOTO_ERR_AND_SET_RET(ParseNonceAndCipherFromJson(&(realTask->params.nonce), &(realTask->params.exRmvCipher),
86 in, FIELD_RMV_AUTH_INFO), res);
87
88 // execute
89 res = ServerResponseStandardUnbindExchange(params, &(realTask->params));
90 if (res != HC_SUCCESS) {
91 LOGE("ServerResponseStandardUnbindExchange failed");
92 return res;
93 }
94
95 sendToPeer = CreateJson();
96 if (sendToPeer == NULL) {
97 res = HC_ERR_ALLOC_MEMORY;
98 goto ERR;
99 }
100 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_MESSAGE, PAKE_UNBIND_EXCHANGE_RESPONSE), res);
101 data = CreateJson();
102 if (data == NULL) {
103 res = HC_ERR_ALLOC_MEMORY;
104 goto ERR;
105 }
106 GOTO_ERR_AND_SET_RET(PackageNonceAndCipherToJson(&(realTask->params.nonce), &(realTask->params.resultCipher),
107 data, FIELD_RMV_RETURN), res);
108 GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, data), res);
109 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
110
111 task->taskStatus = TASK_STATUS_SERVER_UNBIND_EXCHANGE_RESPONSE;
112 *status = FINISH;
113 ERR:
114 FreeJson(data);
115 FreeJson(sendToPeer);
116 return res;
117 }
118
Process(struct AsyBaseCurTaskT * task,PakeParams * params,const CJson * in,CJson * out,int * status)119 static int Process(struct AsyBaseCurTaskT *task, PakeParams *params, const CJson *in, CJson *out, int *status)
120 {
121 int res;
122 if ((task == NULL) || (in == NULL) || (out == NULL) || (status == NULL)) {
123 return HC_ERR_INVALID_PARAMS;
124 }
125
126 if (task->taskStatus == TASK_STATUS_SERVER_UNBIND_EXCHANGE_BEGIN) {
127 res = ExchangeStart(task, params, out, status);
128 if (res != HC_SUCCESS) {
129 goto ERR;
130 }
131 return res;
132 }
133
134 int message = 0;
135 res = GetIntFromJson(in, "message", &message);
136 if (res != HC_SUCCESS) {
137 goto ERR;
138 }
139
140 switch (message) {
141 case PAKE_UNBIND_EXCHANGE_REQUEST:
142 res = ExchangeResponse(task, params, in, out, status);
143 break;
144 default:
145 res = HC_ERR_INVALID_PARAMS;
146 break;
147 }
148
149 if (res != HC_SUCCESS) {
150 goto ERR;
151 }
152 return res;
153 ERR:
154 FreeAndCleanKey(&(params->baseParams.sessionKey));
155 return res;
156 }
157
DestroyStandardUnbindExchangeServerTask(struct AsyBaseCurTaskT * task)158 static void DestroyStandardUnbindExchangeServerTask(struct AsyBaseCurTaskT *task)
159 {
160 StandardUnbindExchangeServerTask *innerTask = (StandardUnbindExchangeServerTask *)task;
161 if (innerTask == NULL) {
162 return;
163 }
164
165 DestroyStandardUnbindExchangeParams(&(innerTask->params));
166 HcFree(innerTask);
167 }
168
CreateStandardUnbindExchangeServerTask(void)169 AsyBaseCurTask *CreateStandardUnbindExchangeServerTask(void)
170 {
171 StandardUnbindExchangeServerTask *task =
172 (StandardUnbindExchangeServerTask *)HcMalloc(sizeof(StandardUnbindExchangeServerTask), 0);
173 if (task == NULL) {
174 return NULL;
175 }
176 task->taskBase.destroyTask = DestroyStandardUnbindExchangeServerTask;
177 task->taskBase.process = Process;
178 task->taskBase.taskStatus = TASK_STATUS_SERVER_UNBIND_EXCHANGE_BEGIN;
179 task->taskBase.getCurTaskType = GetTaskType;
180
181 int res = InitStandardUnbindExchangeParams(&(task->params));
182 if (res != HC_SUCCESS) {
183 DestroyStandardUnbindExchangeServerTask((struct AsyBaseCurTaskT *)task);
184 return NULL;
185 }
186
187 return (AsyBaseCurTask *)task;
188 }
189
190