• 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 "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(&params->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(&params->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