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 "pake_v1_server_protocol_task.h"
17 #include "das_task_common.h"
18 #include "hc_log.h"
19 #include "hc_types.h"
20 #include "pake_message_util.h"
21 #include "pake_v1_protocol_common.h"
22 #include "pake_v1_protocol_task_common.h"
23 #include "pake_task_common.h"
24
25 enum {
26 TASK_STATUS_SERVER_PAKE_BEGIN = 0,
27 TASK_STATUS_SERVER_PAKE_RESPONSE,
28 TASK_STATUS_SERVER_PAKE_CONFIRM
29 };
30
GetTaskType(void)31 static CurTaskType GetTaskType(void)
32 {
33 return TASK_TYPE_PAKE_V1_PROTOCOL;
34 }
35
DestroyPakeV1ProtocolServerTask(struct AsyBaseCurTaskT * task)36 static void DestroyPakeV1ProtocolServerTask(struct AsyBaseCurTaskT *task)
37 {
38 HcFree(task);
39 }
40
PackageMsgForResponse(PakeParams * params,CJson * out)41 static int PackageMsgForResponse(PakeParams *params, CJson *out)
42 {
43 int res = ConstructOutJson(params, out);
44 if (res != HC_SUCCESS) {
45 LOGE("The operation of ConstructOutJson failed, res: %" LOG_PUB "d.", res);
46 return res;
47 }
48 CJson *payload = GetObjFromJson(out, FIELD_PAYLOAD);
49 if (payload == NULL) {
50 LOGE("Get payload from json failed.");
51 return HC_ERR_JSON_GET;
52 }
53 res = PackagePakeResponseData(params, payload);
54 if (res != HC_SUCCESS) {
55 LOGE("PackagePakeResponseData failed, res: %" LOG_PUB "d.", res);
56 return res;
57 }
58 // package differentiated data
59 res = AddByteToJson(payload, FIELD_CHALLENGE, params->baseParams.challengeSelf.val,
60 params->baseParams.challengeSelf.length);
61 if (res != HC_SUCCESS) {
62 LOGE("Add challengeSelf failed, res: %" LOG_PUB "d.", res);
63 return res;
64 }
65 if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
66 if (params->opCode == AUTHENTICATE && params->isPseudonym) {
67 res = AddPseudonymIdAndChallenge(params, payload);
68 } else {
69 res = AddByteToJson(payload, FIELD_PEER_AUTH_ID, params->baseParams.idSelf.val,
70 params->baseParams.idSelf.length);
71 }
72 if (res != HC_SUCCESS) {
73 LOGE("Add idSelf failed, res: %" LOG_PUB "d.", res);
74 return res;
75 }
76 }
77 return res;
78 }
79
PakeResponse(AsyBaseCurTask * task,PakeParams * params,const CJson * in,CJson * out,int * status)80 static int PakeResponse(AsyBaseCurTask *task, PakeParams *params, const CJson *in, CJson *out, int *status)
81 {
82 int res;
83 if (task->taskStatus > TASK_STATUS_SERVER_PAKE_BEGIN) {
84 LOGI("The message is repeated, ignore it, status: %" LOG_PUB "d", task->taskStatus);
85 *status = IGNORE_MSG;
86 return HC_SUCCESS;
87 }
88
89 res = ParsePakeRequestMessage(params, in);
90 if (res != HC_SUCCESS) {
91 LOGE("ParsePakeRequestMessage failed, res: %" LOG_PUB "d.", res);
92 return res;
93 }
94 // parse differentiated data
95 if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
96 if (params->opCode == AUTHENTICATE && params->isPseudonym) {
97 res = CheckPseudonymId(params, in);
98 } else {
99 res = GetAndCheckAuthIdPeer(in, &(params->baseParams.idSelf), &(params->baseParams.idPeer));
100 }
101 if (res != HC_SUCCESS) {
102 LOGE("The oparetion of GetAndCheckAuthIdPeer failed, res: %" LOG_PUB "d.", res);
103 return res;
104 }
105 }
106
107 if (params->isPskSupported && (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND)) {
108 res = FillPskWithDerivedKeyHex(params);
109 if (res != HC_SUCCESS) {
110 LOGE("FillPskWithDerivedKeyHex failed, res: %" LOG_PUB "d.", res);
111 return res;
112 }
113 }
114
115 // execute
116 res = ServerResponsePakeV1Protocol(¶ms->baseParams);
117 if (res != HC_SUCCESS) {
118 LOGE("ServerResponsePakeV1Protocol failed, res:%" LOG_PUB "d", res);
119 return res;
120 }
121
122 // package message
123 res = PackageMsgForResponse(params, out);
124 if (res != HC_SUCCESS) {
125 LOGE("PackageMsgForResponse failed, res: %" LOG_PUB "d.", res);
126 return res;
127 }
128
129 task->taskStatus = TASK_STATUS_SERVER_PAKE_RESPONSE;
130 *status = CONTINUE;
131 return res;
132 }
133
PakeServerConfirm(AsyBaseCurTask * task,PakeParams * params,const CJson * in,CJson * out,int * status)134 static int PakeServerConfirm(AsyBaseCurTask *task, PakeParams *params, const CJson *in, CJson *out, int *status)
135 {
136 int res;
137 if (task->taskStatus < TASK_STATUS_SERVER_PAKE_RESPONSE) {
138 LOGE("Invalid taskStatus: %" LOG_PUB "d", task->taskStatus);
139 return HC_ERR_BAD_MESSAGE;
140 }
141 if (task->taskStatus > TASK_STATUS_SERVER_PAKE_RESPONSE) {
142 LOGI("The message is repeated, ignore it, status: %" LOG_PUB "d", task->taskStatus);
143 *status = IGNORE_MSG;
144 return HC_SUCCESS;
145 }
146
147 // parse message
148 res = ParsePakeClientConfirmMessage(params, in);
149 if (res != HC_SUCCESS) {
150 LOGE("ParsePakeClientConfirmMessage failed, res: %" LOG_PUB "d", res);
151 return res;
152 }
153 // differentiated data
154 if (GetByteFromJson(in, FIELD_CHALLENGE, params->baseParams.challengePeer.val,
155 params->baseParams.challengePeer.length) != HC_SUCCESS) {
156 LOGE("Get challengePeer failed.");
157 return HC_ERR_JSON_GET;
158 }
159 PRINT_DEBUG_MSG(params->baseParams.challengePeer.val, params->baseParams.challengePeer.length, "challengePeer");
160
161 // execute
162 res = ServerConfirmPakeV1Protocol(¶ms->baseParams);
163 if (res != HC_SUCCESS) {
164 LOGE("ServerConfirmPakeV1Protocol failed, res:%" LOG_PUB "d", res);
165 return res;
166 }
167
168 // package message
169 res = ConstructOutJson(params, out);
170 if (res != HC_SUCCESS) {
171 LOGE("ConstructOutJson failed, res: %" LOG_PUB "d.", res);
172 return res;
173 }
174 CJson *payload = GetObjFromJson(out, FIELD_PAYLOAD);
175 if (payload == NULL) {
176 LOGE("Get payload from json failed.");
177 return HC_ERR_JSON_GET;
178 }
179 res = PackagePakeServerConfirmData(params, payload);
180 if (res != HC_SUCCESS) {
181 LOGE("PackagePakeServerConfirmData failed, res: %" LOG_PUB "d.", res);
182 return res;
183 }
184
185 task->taskStatus = TASK_STATUS_SERVER_PAKE_CONFIRM;
186 *status = FINISH;
187 return res;
188 }
189
Process(struct AsyBaseCurTaskT * task,PakeParams * params,const CJson * in,CJson * out,int * status)190 static int Process(struct AsyBaseCurTaskT *task, PakeParams *params, const CJson *in, CJson *out, int *status)
191 {
192 int res;
193 uint32_t step = ProtocolMessageIn(in);
194 if (step == INVALID_MESSAGE) {
195 res = HC_ERR_BAD_MESSAGE;
196 goto OUT;
197 }
198
199 switch (step) {
200 case STEP_ONE:
201 res = PakeResponse(task, params, in, out, status);
202 break;
203 case STEP_TWO:
204 res = PakeServerConfirm(task, params, in, out, status);
205 break;
206 default:
207 res = HC_ERR_BAD_MESSAGE;
208 break;
209 }
210 OUT:
211 if (res != HC_SUCCESS) {
212 LOGE("Process Step: %" LOG_PUB "d failed, res: %" LOG_PUB "x.", step, res);
213 return res;
214 }
215 res = ServerProtocolMessageOut(out, params->opCode, step);
216 if (res != HC_SUCCESS) {
217 LOGE("ServerProtocolMessageOut failed, res: %" LOG_PUB "x.", res);
218 }
219 return res;
220 }
221
CreatePakeV1ProtocolServerTask(void)222 AsyBaseCurTask *CreatePakeV1ProtocolServerTask(void)
223 {
224 PakeV1ProtocolServerTask *task = (PakeV1ProtocolServerTask *)HcMalloc(sizeof(PakeV1ProtocolServerTask), 0);
225 if (task == NULL) {
226 LOGE("Malloc for PakeV1ProtocolServerTask failed.");
227 return NULL;
228 }
229 task->taskBase.destroyTask = DestroyPakeV1ProtocolServerTask;
230 task->taskBase.process = Process;
231 task->taskBase.taskStatus = TASK_STATUS_SERVER_PAKE_BEGIN;
232 task->taskBase.getCurTaskType = GetTaskType;
233 return (AsyBaseCurTask *)task;
234 }
235
236