• 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 "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: %" LOG_PUB "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: %" LOG_PUB "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: %" LOG_PUB "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             LOGE("ExchangeRequest failed!");
121             goto ERR;
122         }
123         return res;
124     }
125 
126     int message = 0;
127     res = GetIntFromJson(in, "message", &message);
128     if (res != HC_SUCCESS) {
129         LOGE("GetIntFromJson failed!");
130         goto ERR;
131     }
132 
133     switch (message) {
134         case PAKE_BIND_EXCHANGE_RESPONSE:
135             res = ExchangeConfirm(task, params, in, status);
136             break;
137         default:
138             res = HC_ERR_INVALID_PARAMS;
139             break;
140     }
141     if (res != HC_SUCCESS) {
142         goto ERR;
143     }
144     return res;
145 ERR:
146     FreeAndCleanKey(&(params->baseParams.sessionKey));
147     return res;
148 }
149 
DestroyStandardBindExchangeClientTask(struct AsyBaseCurTaskT * task)150 static void DestroyStandardBindExchangeClientTask(struct AsyBaseCurTaskT *task)
151 {
152     StandardBindExchangeClientTask *innerTask = (StandardBindExchangeClientTask *)task;
153     if (innerTask == NULL) {
154         return;
155     }
156 
157     DestroyStandardBindExchangeParams(&(innerTask->params));
158     HcFree(innerTask);
159 }
160 
CreateStandardBindExchangeClientTask(void)161 AsyBaseCurTask *CreateStandardBindExchangeClientTask(void)
162 {
163     StandardBindExchangeClientTask *task =
164         (StandardBindExchangeClientTask *)HcMalloc(sizeof(StandardBindExchangeClientTask), 0);
165     if (task == NULL) {
166         return NULL;
167     }
168     task->taskBase.destroyTask = DestroyStandardBindExchangeClientTask;
169     task->taskBase.process = Process;
170     task->taskBase.taskStatus = TASK_STATUS_CLIENT_BIND_EXCHANGE_BEGIN;
171     task->taskBase.getCurTaskType = GetTaskType;
172 
173     int res = InitStandardBindExchangeParams(&(task->params));
174     if (res != HC_SUCCESS) {
175         DestroyStandardBindExchangeClientTask((struct AsyBaseCurTaskT *)task);
176         return NULL;
177     }
178 
179     return (AsyBaseCurTask *)task;
180 }
181