1 /*
2 * Copyright (C) 2022 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_v2_auth_server_task.h"
17
18 #include "account_module.h"
19 #include "asy_token_manager.h"
20 #include "clib_error.h"
21 #include "common_defs.h"
22 #include "device_auth_defines.h"
23 #include "hc_log.h"
24 #include "hc_types.h"
25 #include "pake_v2_auth_task_common.h"
26 #include "pake_v2_protocol_common.h"
27 #include "protocol_common.h"
28 #include "account_version_util.h"
29
30 enum {
31 TASK_STATUS_PAKE_FOLLOW_BEGIN = 0,
32 TASK_STATUS_PAKE_FOLLOW_STEP_ONE = 1,
33 TASK_STATUS_PAKE_FOLLOW_STEP_TWO = 2,
34 TASK_STATUS_PAKE_FOLLOW_END = 3,
35 };
36
GetPakeV2AuthServerType(void)37 static AccountTaskType GetPakeV2AuthServerType(void)
38 {
39 return TASK_TYPE_PAKE_V2_AUTH_SERVER;
40 }
41
DestroyAuthServerAuthTask(TaskBase * task)42 static void DestroyAuthServerAuthTask(TaskBase *task)
43 {
44 if (task == NULL) {
45 LOGD("NULL pointer and return");
46 return;
47 }
48 PakeV2AuthServerTask *innerTask = (PakeV2AuthServerTask *)task;
49 DestroyPakeAuthParams(&(innerTask->params));
50 HcFree(innerTask);
51 }
52
DealAsyStepOneData(PakeV2AuthServerTask * task)53 static int32_t DealAsyStepOneData(PakeV2AuthServerTask *task)
54 {
55 int32_t res = VerifyPkSignPeer(&task->params);
56 if (res != HC_SUCCESS) {
57 LOGE("Step one: VerifyPkSignPeer failed for server.");
58 return HC_ERR_ACCOUNT_VERIFY_PK_SIGN;
59 }
60 if (GenerateEcdhSharedKey(&task->params) != HC_SUCCESS) {
61 LOGE("Step one: Generate ecdh shared key failed for server.");
62 return HC_ERR_ACCOUNT_ECDH_FAIL;
63 }
64 res = ServerResponsePakeV2Protocol(&task->params.pakeParams);
65 if (res != HC_SUCCESS) {
66 LOGE("Step one: ServerResponsePakeV2Protocol failed.");
67 return res;
68 }
69 if (ExtractPakeSelfId(&task->params) != HC_SUCCESS) {
70 LOGE("ConstructPayLoad peer failed.");
71 return HC_ERR_AUTH_INTERNAL;
72 }
73 return HC_SUCCESS;
74 }
75
PrepareAsyServerStepOneData(const PakeV2AuthServerTask * innerTask,CJson * out)76 static int32_t PrepareAsyServerStepOneData(const PakeV2AuthServerTask *innerTask, CJson *out)
77 {
78 CJson *sendToPeer = CreateJson();
79 if (sendToPeer == NULL) {
80 LOGE("Create json NULL.");
81 return HC_ERR_JSON_CREATE;
82 }
83 CJson *data = CreateJson();
84 if (data == NULL) {
85 LOGE("Create json NULL.");
86 FreeJson(sendToPeer);
87 return HC_ERR_JSON_CREATE;
88 }
89 int32_t ret = HC_SUCCESS;
90 GOTO_ERR_AND_SET_RET(AddStringToJson(sendToPeer, FIELD_USER_ID,
91 (const char *)innerTask->params.userIdSelf), ret);
92 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_STEP, RET_PAKE_AUTH_FOLLOWER_ONE), ret);
93 GOTO_ERR_AND_SET_RET(AddStringToJson(sendToPeer, FIELD_DEVICE_ID,
94 (const char *)innerTask->params.deviceIdSelf.val), ret);
95 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, innerTask->params.authForm), ret);
96 GOTO_ERR_AND_SET_RET(AddStringToJson(sendToPeer, FIELD_DEV_ID, (const char *)innerTask->params.devIdSelf.val), ret);
97
98 GOTO_ERR_AND_SET_RET(AddIntToJson(data, FIELD_AUTH_KEY_ALG_ENCODE, innerTask->params.authKeyAlgEncode), ret);
99 GOTO_ERR_AND_SET_RET(AddStringToJson(data, FIELD_AUTH_PK_INFO,
100 (const char *)innerTask->params.pkInfoSelf.val), ret);
101 GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_AUTH_PK_INFO_SIGN, innerTask->params.pkInfoSignSelf.val,
102 innerTask->params.pkInfoSignSelf.length), ret);
103 GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_EPK, innerTask->params.pakeParams.epkSelf.val,
104 innerTask->params.pakeParams.epkSelf.length), ret);
105 GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_SALT, innerTask->params.pakeParams.salt.val,
106 innerTask->params.pakeParams.salt.length), ret);
107 GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_DATA, data), ret);
108 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), ret);
109 ERR:
110 FreeJson(sendToPeer);
111 FreeJson(data);
112 return ret;
113 }
114
AsyAuthServerStepOne(TaskBase * task,const CJson * in,CJson * out,int32_t * status)115 static int32_t AsyAuthServerStepOne(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
116 {
117 PakeV2AuthServerTask *innerTask = (PakeV2AuthServerTask *)task;
118 if (innerTask->taskBase.taskStatus != TASK_STATUS_PAKE_FOLLOW_STEP_ONE) {
119 LOGE("Server step one task status error.");
120 return HC_ERR_AUTH_STATUS;
121 }
122 GOTO_IF_ERR(GetIntFromJson(in, FIELD_AUTH_FORM, &innerTask->params.authForm));
123 const char *userIdPeer = GetStringFromJson(in, FIELD_USER_ID);
124 uint32_t userIdPeerLen = HcStrlen(userIdPeer) + 1;
125 if (userIdPeer == NULL || userIdPeerLen > DEV_AUTH_USER_ID_SIZE) {
126 LOGE("Payload not contain peer userId or userId len is invalid.");
127 return HC_ERR_BAD_MESSAGE;
128 }
129 GOTO_IF_ERR(strcpy_s((char *)innerTask->params.userIdPeer, userIdPeerLen, userIdPeer));
130 GOTO_IF_ERR(ExtractPeerDeviceId(&innerTask->params, in));
131 GOTO_IF_ERR(ExtractPeerDevId(&innerTask->params, in));
132
133 GOTO_IF_ERR(GetIntFromJson(in, FIELD_CREDENTIAL_TYPE, &innerTask->params.credentialType));
134 GOTO_IF_ERR(GetIntFromJson(in, FIELD_AUTH_KEY_ALG_ENCODE, &innerTask->params.authKeyAlgEncode));
135 GOTO_IF_ERR(GetPkInfoPeer(&innerTask->params, in));
136 GOTO_IF_ERR(GetByteFromJson(in, FIELD_AUTH_PK_INFO_SIGN, innerTask->params.pkInfoSignPeer.val,
137 innerTask->params.pkInfoSignPeer.length));
138 const char *pkInfoSignPeerStr = GetStringFromJson(in, FIELD_AUTH_PK_INFO_SIGN);
139 if (pkInfoSignPeerStr == NULL) {
140 LOGE("pkInfoSignPeer in server is null.");
141 return HC_ERR_NULL_PTR;
142 }
143 innerTask->params.pkInfoSignPeer.length = HcStrlen(pkInfoSignPeerStr) / BYTE_TO_HEX_OPER_LENGTH;
144 GOTO_IF_ERR(DealAsyStepOneData(innerTask));
145 GOTO_IF_ERR(PrepareAsyServerStepOneData(innerTask, out));
146
147 innerTask->taskBase.taskStatus = TASK_STATUS_PAKE_FOLLOW_STEP_TWO;
148 *status = CONTINUE;
149 return HC_SUCCESS;
150 ERR:
151 LOGE("Server step one failed.");
152 return HC_ERR_AUTH_INTERNAL;
153 }
154
DealAsyStepTwoData(PakeV2AuthServerTask * task)155 static int32_t DealAsyStepTwoData(PakeV2AuthServerTask *task)
156 {
157 if (ServerConfirmPakeV2Protocol(&task->params.pakeParams) != HC_SUCCESS) {
158 LOGE("Server ConfirmPakeV2Protocol failed.");
159 return HC_ERR_SERVER_CONFIRM_PROTOCOL;
160 }
161 return HC_SUCCESS;
162 }
163
SendFinalToOut(PakeV2AuthServerTask * task,CJson * out)164 static int32_t SendFinalToOut(PakeV2AuthServerTask *task, CJson *out)
165 {
166 CJson *sendToSelf = CreateJson();
167 if (sendToSelf == NULL) {
168 LOGE("Create json sendToSelf failed.");
169 return HC_ERR_JSON_CREATE;
170 }
171 CJson *sendToPeer = CreateJson();
172 if (sendToPeer == NULL) {
173 LOGE("Create json sendToPeer failed.");
174 FreeJson(sendToSelf);
175 return HC_ERR_JSON_CREATE;
176 }
177 CJson *sendToPeerData = CreateJson();
178 if (sendToPeerData == NULL) {
179 LOGE("Create json sendToPeerData failed.");
180 FreeJson(sendToPeer);
181 FreeJson(sendToSelf);
182 return HC_ERR_JSON_CREATE;
183 }
184 GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_USER_ID, (const char *)task->params.userIdPeer));
185 GOTO_IF_ERR(AddByteToJson(sendToSelf, FIELD_SESSION_KEY,
186 task->params.pakeParams.sessionKey.val, task->params.pakeParams.sessionKey.length));
187 GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_DEVICE_ID, (const char *)task->params.deviceIdSelf.val));
188 GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_DEV_ID, (const char *)task->params.devIdPeer.val));
189 GOTO_IF_ERR(AddIntToJson(sendToSelf, FIELD_CREDENTIAL_TYPE, ASYMMETRIC_CRED));
190
191 GOTO_IF_ERR(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, task->params.authForm));
192 GOTO_IF_ERR(AddIntToJson(sendToPeer, FIELD_STEP, RET_PAKE_AUTH_FOLLOWER_TWO));
193
194 GOTO_IF_ERR(AddByteToJson(sendToPeerData,
195 FIELD_KCF_DATA, task->params.pakeParams.kcfData.val, task->params.pakeParams.kcfData.length));
196 GOTO_IF_ERR(AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf));
197 GOTO_IF_ERR(AddObjToJson(sendToPeer, FIELD_DATA, sendToPeerData));
198 GOTO_IF_ERR(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer));
199 FreeJson(sendToPeer);
200 FreeJson(sendToSelf);
201 FreeJson(sendToPeerData);
202 FreeAndCleanKey(&task->params.pakeParams.sessionKey);
203 return HC_SUCCESS;
204 ERR:
205 LOGE("Server send final failed");
206 FreeJson(sendToPeer);
207 FreeJson(sendToSelf);
208 FreeJson(sendToPeerData);
209 FreeAndCleanKey(&task->params.pakeParams.sessionKey);
210 return HC_ERR_AUTH_INTERNAL;
211 }
212
AsyAuthServerStepTwo(TaskBase * task,const CJson * in,CJson * out,int32_t * status)213 static int32_t AsyAuthServerStepTwo(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
214 {
215 PakeV2AuthServerTask *innerTask = (PakeV2AuthServerTask *)task;
216 if (innerTask->taskBase.taskStatus != TASK_STATUS_PAKE_FOLLOW_STEP_TWO) {
217 LOGE("Server task status error");
218 return HC_ERR_AUTH_STATUS;
219 }
220 GOTO_IF_ERR(GetByteFromJson(in,
221 FIELD_EPK, innerTask->params.pakeParams.epkPeer.val, innerTask->params.pakeParams.epkPeer.length));
222 GOTO_IF_ERR(GetByteFromJson(in,
223 FIELD_KCF_DATA, innerTask->params.pakeParams.kcfDataPeer.val, innerTask->params.pakeParams.kcfDataPeer.length));
224 GOTO_IF_ERR(ExtractPakePeerId(&innerTask->params, in));
225 GOTO_IF_ERR(DealAsyStepTwoData(innerTask));
226 GOTO_IF_ERR(SendFinalToOut(innerTask, out));
227 innerTask->taskBase.taskStatus = TASK_STATUS_PAKE_FOLLOW_END;
228 *status = FINISH;
229 return HC_SUCCESS;
230 ERR:
231 LOGE("server AsyAuthServerStepTwo failed");
232 return HC_ERR_AUTH_INTERNAL;
233 }
234
ProcessServerTask(TaskBase * task,const CJson * in,CJson * out,int32_t * status)235 static int32_t ProcessServerTask(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
236 {
237 if ((task == NULL) || (in == NULL) || (out == NULL) || (status == NULL)) {
238 LOGE("invalid param");
239 return HC_ERR_INVALID_PARAMS;
240 }
241 int32_t step = 0;
242 if (GetIntFromJson(in, FIELD_STEP, &step) != HC_SUCCESS) {
243 LOGE("server no auth step");
244 return HC_ERR_JSON_GET;
245 }
246 LOGI("ProcessServerTask step: %d", step);
247 int32_t res;
248 switch (step) {
249 case CMD_PAKE_AUTH_MAIN_ONE:
250 res = AsyAuthServerStepOne(task, in, out, status);
251 break;
252 case CMD_PAKE_AUTH_MAIN_TWO:
253 res = AsyAuthServerStepTwo(task, in, out, status);
254 break;
255 case ERR_MSG:
256 return HC_ERR_PEER_ERROR;
257 default:
258 res = HC_ERR_BAD_MESSAGE;
259 break;
260 }
261 if (res != HC_SUCCESS) {
262 LOGE("Server ProcessServerTask failed, step: %d.", step);
263 }
264 return res;
265 }
266
CreatePakeV2AuthServerTask(const CJson * in,CJson * out,const AccountVersionInfo * verInfo)267 TaskBase *CreatePakeV2AuthServerTask(const CJson *in, CJson *out, const AccountVersionInfo *verInfo)
268 {
269 if (in == NULL || out == NULL || verInfo == NULL) {
270 LOGE("Params is null.");
271 return NULL;
272 }
273 PakeV2AuthServerTask *taskParams = (PakeV2AuthServerTask *)HcMalloc(sizeof(PakeV2AuthServerTask), 0);
274 if (taskParams == NULL) {
275 LOGE("Malloc taskParams failed");
276 return NULL;
277 }
278 (void)memset_s(taskParams, sizeof(PakeV2AuthServerTask), 0, sizeof(PakeV2AuthServerTask));
279 taskParams->taskBase.getTaskType = GetPakeV2AuthServerType;
280 taskParams->taskBase.process = ProcessServerTask;
281 taskParams->taskBase.destroyTask = DestroyAuthServerAuthTask;
282
283 if (InitPakeAuthParams(in, &(taskParams->params), verInfo) != HC_SUCCESS) {
284 LOGE("InitPakeAuthParams error.");
285 DestroyAuthServerAuthTask((TaskBase *)taskParams);
286 return NULL;
287 }
288
289 taskParams->taskBase.taskStatus = TASK_STATUS_PAKE_FOLLOW_STEP_ONE;
290 return (TaskBase *)taskParams;
291 }