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_client_bind_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_CLIENT_BIND_EXCHANGE_BEGIN = 0,
24 TASK_STATUS_CLIENT_BIND_EXCHANGE_REQUEST,
25 TASK_STATUS_CLIENT_BIND_EXCHANGE_CONFIRM,
26 };
27
GetTaskType(void)28 static CurTaskType GetTaskType(void)
29 {
30 return TASK_TYPE_BIND_STANDARD_EXCHANGE;
31 }
32
ExchangeRequest(AsyBaseCurTask * task,PakeParams * params,const CJson * in,CJson * out,int * status)33 static int ExchangeRequest(AsyBaseCurTask *task, PakeParams *params, const CJson *in, CJson *out, int *status)
34 {
35 int res;
36 if (task->taskStatus != TASK_STATUS_CLIENT_BIND_EXCHANGE_BEGIN) {
37 LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
38 *status = IGNORE_MSG;
39 return HC_SUCCESS;
40 }
41 StandardBindExchangeClientTask *realTask = (StandardBindExchangeClientTask *)task;
42 CJson *data = CreateJson();
43 if (data == NULL) {
44 return HC_ERR_ALLOC_MEMORY;
45 }
46 CJson *sendToPeer = CreateJson();
47 if (sendToPeer == NULL) {
48 res = HC_ERR_ALLOC_MEMORY;
49 goto ERR;
50 }
51
52 // parse message
53 if (params->baseParams.challengePeer.val == NULL) {
54 GOTO_ERR_AND_SET_RET(GetPeerChallenge(params, in), res);
55 GOTO_ERR_AND_SET_RET(GenerateSelfChallenge(params), res);
56 GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_CHALLENGE, params->baseParams.challengeSelf.val,
57 params->baseParams.challengeSelf.length), res);
58 }
59
60 // execute
61 GOTO_ERR_AND_SET_RET(ClientRequestStandardBindExchange(params, &(realTask->params)), res);
62
63 // package message
64 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_MESSAGE, PAKE_BIND_EXCHANGE_REQUEST), res);
65 GOTO_ERR_AND_SET_RET(PackageNonceAndCipherToJson(&(realTask->params.nonce), &(realTask->params.exInfoCipher),
66 data, FIELD_EX_AUTH_INFO), res);
67 GOTO_ERR_AND_SET_RET(AddIntToJson(data, FIELD_PEER_USER_TYPE, params->userType), res);
68 GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, data), res);
69 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
70
71 task->taskStatus = TASK_STATUS_CLIENT_BIND_EXCHANGE_REQUEST;
72 *status = CONTINUE;
73 ERR:
74 FreeJson(data);
75 FreeJson(sendToPeer);
76 return res;
77 }
78
ExchangeConfirm(AsyBaseCurTask * task,PakeParams * params,const CJson * in,int * status)79 static int ExchangeConfirm(AsyBaseCurTask *task, PakeParams *params, const CJson *in, int *status)
80 {
81 if (task->taskStatus < TASK_STATUS_CLIENT_BIND_EXCHANGE_REQUEST) {
82 LOGE("Invalid taskStatus: %d", task->taskStatus);
83 return HC_ERR_BAD_MESSAGE;
84 }
85 if (task->taskStatus > TASK_STATUS_CLIENT_BIND_EXCHANGE_REQUEST) {
86 LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
87 *status = IGNORE_MSG;
88 return HC_SUCCESS;
89 }
90
91 StandardBindExchangeClientTask *realTask = (StandardBindExchangeClientTask *)task;
92
93 // parse message
94 (void)GetIntFromJson(in, FIELD_PEER_USER_TYPE, &(params->userTypePeer));
95 int res = ParseNonceAndCipherFromJson(&(realTask->params.nonce),
96 &(realTask->params.exInfoCipher), in, FIELD_EX_AUTH_INFO);
97 if (res != HC_SUCCESS) {
98 LOGE("ParseNonceAndCipherFromJson failed");
99 return res;
100 }
101
102 // execute
103 res = ClientConfirmStandardBindExchange(params, &(realTask->params));
104 if (res != HC_SUCCESS) {
105 LOGE("ClientConfirmStandardBindExchange failed");
106 return res;
107 }
108
109 task->taskStatus = TASK_STATUS_CLIENT_BIND_EXCHANGE_CONFIRM;
110 *status = FINISH;
111 return res;
112 }
113
Process(struct AsyBaseCurTaskT * task,PakeParams * params,const CJson * in,CJson * out,int * status)114 static int Process(struct AsyBaseCurTaskT *task, PakeParams *params, const CJson *in, CJson *out, int *status)
115 {
116 int res = HC_SUCCESS;
117 if (task->taskStatus == TASK_STATUS_CLIENT_BIND_EXCHANGE_BEGIN) {
118 res = ExchangeRequest(task, params, in, out, status);
119 if (res != HC_SUCCESS) {
120 goto ERR;
121 }
122 return res;
123 }
124
125 int message = 0;
126 res = GetIntFromJson(in, "message", &message);
127 if (res != HC_SUCCESS) {
128 goto ERR;
129 }
130
131 switch (message) {
132 case PAKE_BIND_EXCHANGE_RESPONSE:
133 res = ExchangeConfirm(task, params, in, status);
134 break;
135 default:
136 res = HC_ERR_INVALID_PARAMS;
137 break;
138 }
139 if (res != HC_SUCCESS) {
140 goto ERR;
141 }
142 return res;
143 ERR:
144 FreeAndCleanKey(&(params->baseParams.sessionKey));
145 return res;
146 }
147
DestroyStandardBindExchangeClientTask(struct AsyBaseCurTaskT * task)148 static void DestroyStandardBindExchangeClientTask(struct AsyBaseCurTaskT *task)
149 {
150 StandardBindExchangeClientTask *innerTask = (StandardBindExchangeClientTask *)task;
151 if (innerTask == NULL) {
152 return;
153 }
154
155 DestroyStandardBindExchangeParams(&(innerTask->params));
156 HcFree(innerTask);
157 }
158
CreateStandardBindExchangeClientTask(void)159 AsyBaseCurTask *CreateStandardBindExchangeClientTask(void)
160 {
161 StandardBindExchangeClientTask *task =
162 (StandardBindExchangeClientTask *)HcMalloc(sizeof(StandardBindExchangeClientTask), 0);
163 if (task == NULL) {
164 return NULL;
165 }
166 task->taskBase.destroyTask = DestroyStandardBindExchangeClientTask;
167 task->taskBase.process = Process;
168 task->taskBase.taskStatus = TASK_STATUS_CLIENT_BIND_EXCHANGE_BEGIN;
169 task->taskBase.getCurTaskType = GetTaskType;
170
171 int res = InitStandardBindExchangeParams(&(task->params));
172 if (res != HC_SUCCESS) {
173 DestroyStandardBindExchangeClientTask((struct AsyBaseCurTaskT *)task);
174 return NULL;
175 }
176
177 return (AsyBaseCurTask *)task;
178 }
179