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(const PakeParams * params,CJson * out)41 static int PackageMsgForResponse(const PakeParams *params, CJson *out)
42 {
43 int res = ConstructOutJson(params, out);
44 if (res != HC_SUCCESS) {
45 LOGE("ConstructOutJson failed, res: %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: %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: %d.", res);
63 return res;
64 }
65 if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
66 res = AddByteToJson(payload, FIELD_PEER_AUTH_ID, params->baseParams.idSelf.val,
67 params->baseParams.idSelf.length);
68 if (res != HC_SUCCESS) {
69 LOGE("Add idSelf failed, res: %d.", res);
70 return res;
71 }
72 }
73 return res;
74 }
75
PakeResponse(AsyBaseCurTask * task,PakeParams * params,const CJson * in,CJson * out,int * status)76 static int PakeResponse(AsyBaseCurTask *task, PakeParams *params, const CJson *in, CJson *out, int *status)
77 {
78 int res;
79 if (task->taskStatus > TASK_STATUS_SERVER_PAKE_BEGIN) {
80 LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
81 *status = IGNORE_MSG;
82 return HC_SUCCESS;
83 }
84
85 res = ParsePakeRequestMessage(params, in);
86 if (res != HC_SUCCESS) {
87 LOGE("ParsePakeRequestMessage failed, res: %d.", res);
88 return res;
89 }
90 // parse differentiated data
91 if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
92 res = GetAndCheckAuthIdPeer(in, &(params->baseParams.idSelf), &(params->baseParams.idPeer));
93 if (res != HC_SUCCESS) {
94 LOGE("GetAndCheckAuthIdPeer failed, res: %d.", res);
95 return res;
96 }
97 }
98
99 if (params->isPskSupported && (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND)) {
100 res = FillPskWithDerivedKeyHex(params);
101 if (res != HC_SUCCESS) {
102 LOGE("FillPskWithDerivedKeyHex failed, res: %d.", res);
103 return res;
104 }
105 }
106
107 // execute
108 res = ServerResponsePakeV1Protocol(¶ms->baseParams);
109 if (res != HC_SUCCESS) {
110 LOGE("ServerResponsePakeV1Protocol failed, res:%d", res);
111 return res;
112 }
113
114 // package message
115 res = PackageMsgForResponse(params, out);
116 if (res != HC_SUCCESS) {
117 LOGE("PackageMsgForResponse failed, res: %d.", res);
118 return res;
119 }
120
121 task->taskStatus = TASK_STATUS_SERVER_PAKE_RESPONSE;
122 *status = CONTINUE;
123 return res;
124 }
125
PakeServerConfirm(AsyBaseCurTask * task,PakeParams * params,const CJson * in,CJson * out,int * status)126 static int PakeServerConfirm(AsyBaseCurTask *task, PakeParams *params, const CJson *in, CJson *out, int *status)
127 {
128 int res;
129 if (task->taskStatus < TASK_STATUS_SERVER_PAKE_RESPONSE) {
130 LOGE("Invalid taskStatus: %d", task->taskStatus);
131 return HC_ERR_BAD_MESSAGE;
132 }
133 if (task->taskStatus > TASK_STATUS_SERVER_PAKE_RESPONSE) {
134 LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
135 *status = IGNORE_MSG;
136 return HC_SUCCESS;
137 }
138
139 // parse message
140 res = ParsePakeClientConfirmMessage(params, in);
141 if (res != HC_SUCCESS) {
142 LOGE("ParsePakeClientConfirmMessage failed, res: %d", res);
143 return res;
144 }
145 // differentiated data
146 if (GetByteFromJson(in, FIELD_CHALLENGE, params->baseParams.challengePeer.val,
147 params->baseParams.challengePeer.length) != HC_SUCCESS) {
148 LOGE("Get challengePeer failed.");
149 return HC_ERR_JSON_GET;
150 }
151
152 // execute
153 res = ServerConfirmPakeV1Protocol(¶ms->baseParams);
154 if (res != HC_SUCCESS) {
155 LOGE("ServerConfirmPakeV1Protocol failed, res:%d", res);
156 return res;
157 }
158
159 // package message
160 res = ConstructOutJson(params, out);
161 if (res != HC_SUCCESS) {
162 LOGE("ConstructOutJson failed, res: %d.", res);
163 return res;
164 }
165 CJson *payload = GetObjFromJson(out, FIELD_PAYLOAD);
166 if (payload == NULL) {
167 LOGE("Get payload from json failed.");
168 return HC_ERR_JSON_GET;
169 }
170 res = PackagePakeServerConfirmData(params, payload);
171 if (res != HC_SUCCESS) {
172 LOGE("PackagePakeServerConfirmData failed, res: %d.", res);
173 return res;
174 }
175
176 task->taskStatus = TASK_STATUS_SERVER_PAKE_CONFIRM;
177 *status = FINISH;
178 return res;
179 }
180
Process(struct AsyBaseCurTaskT * task,PakeParams * params,const CJson * in,CJson * out,int * status)181 static int Process(struct AsyBaseCurTaskT *task, PakeParams *params, const CJson *in, CJson *out, int *status)
182 {
183 int res;
184 uint32_t step = ProtocolMessageIn(in);
185 if (step == INVALID_MESSAGE) {
186 res = HC_ERR_BAD_MESSAGE;
187 goto OUT;
188 }
189
190 switch (step) {
191 case STEP_ONE:
192 res = PakeResponse(task, params, in, out, status);
193 break;
194 case STEP_TWO:
195 res = PakeServerConfirm(task, params, in, out, status);
196 break;
197 default:
198 res = HC_ERR_BAD_MESSAGE;
199 break;
200 }
201 OUT:
202 if (res != HC_SUCCESS) {
203 LOGE("Process step:%d failed, res: %x.", step, res);
204 return res;
205 }
206 res = ServerProtocolMessageOut(out, params->opCode, step);
207 if (res != HC_SUCCESS) {
208 LOGE("ServerProtocolMessageOut failed, res: %x.", res);
209 }
210 return res;
211 }
212
CreatePakeV1ProtocolServerTask(void)213 AsyBaseCurTask *CreatePakeV1ProtocolServerTask(void)
214 {
215 PakeV1ProtocolServerTask *task = (PakeV1ProtocolServerTask *)HcMalloc(sizeof(PakeV1ProtocolServerTask), 0);
216 if (task == NULL) {
217 LOGE("Malloc for PakeV1ProtocolServerTask failed.");
218 return NULL;
219 }
220 task->taskBase.destroyTask = DestroyPakeV1ProtocolServerTask;
221 task->taskBase.process = Process;
222 task->taskBase.taskStatus = TASK_STATUS_SERVER_PAKE_BEGIN;
223 task->taskBase.getCurTaskType = GetTaskType;
224 return (AsyBaseCurTask *)task;
225 }
226
227