• 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_unbind_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_UNBIND_EXCHANGE_BEGIN = 0,
24     TASK_STATUS_CLIENT_UNBIND_EXCHANGE_REQUEST,
25     TASK_STATUS_CLIENT_UNBIND_EXCHANGE_CONFIRM,
26 };
27 
GetTaskType(void)28 static CurTaskType GetTaskType(void)
29 {
30     return TASK_TYPE_UNBIND_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_UNBIND_EXCHANGE_BEGIN) {
37         LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
38         *status = IGNORE_MSG;
39         return HC_SUCCESS;
40     }
41     StandardUnbindExchangeClientTask *realTask = (StandardUnbindExchangeClientTask *)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     res = ClientRequestStandardUnbindExchange(params, &(realTask->params));
62     if (res != HC_SUCCESS) {
63         LOGE("ClientRequestStandardUnbindExchange failed");
64         goto ERR;
65     }
66 
67     // package message
68     GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_MESSAGE, PAKE_UNBIND_EXCHANGE_REQUEST), res);
69     GOTO_ERR_AND_SET_RET(PackageNonceAndCipherToJson(&(realTask->params.nonce), &(realTask->params.exRmvCipher),
70         data, FIELD_RMV_AUTH_INFO), res);
71     GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, data), res);
72     GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
73 
74     task->taskStatus = TASK_STATUS_CLIENT_UNBIND_EXCHANGE_REQUEST;
75     *status = CONTINUE;
76 ERR:
77     FreeJson(data);
78     FreeJson(sendToPeer);
79     return res;
80 }
81 
ExchangeConfirm(AsyBaseCurTask * task,PakeParams * params,const CJson * in,int * status)82 static int ExchangeConfirm(AsyBaseCurTask *task, PakeParams *params, const CJson *in, int *status)
83 {
84     if (task->taskStatus < TASK_STATUS_CLIENT_UNBIND_EXCHANGE_REQUEST) {
85         LOGE("task status failed");
86         return HC_ERR_BAD_MESSAGE;
87     }
88 
89     if (task->taskStatus > TASK_STATUS_CLIENT_UNBIND_EXCHANGE_REQUEST) {
90         LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
91         *status = IGNORE_MSG;
92         return HC_SUCCESS;
93     }
94 
95     StandardUnbindExchangeClientTask *realTask = (StandardUnbindExchangeClientTask *)task;
96 
97     // parse message
98     int res = ParseNonceAndCipherFromJson(&(realTask->params.nonce), &(realTask->params.resultCipher),
99         in, FIELD_RMV_RETURN);
100     if (res != HC_SUCCESS) {
101         LOGE("ParseNonceAndCipherFromJson failed");
102         return res;
103     }
104 
105     // execute
106     res = ClientConfirmStandardUnbindExchange(params, &(realTask->params));
107     if (res != HC_SUCCESS) {
108         LOGE("ClientRequestStandardUnbindExchange failed");
109         return res;
110     }
111 
112     task->taskStatus = TASK_STATUS_CLIENT_UNBIND_EXCHANGE_CONFIRM;
113     *status = FINISH;
114     return res;
115 }
116 
Process(struct AsyBaseCurTaskT * task,PakeParams * params,const CJson * in,CJson * out,int * status)117 static int Process(struct AsyBaseCurTaskT *task, PakeParams *params, const CJson *in, CJson *out, int *status)
118 {
119     int res;
120     if (task->taskStatus == TASK_STATUS_CLIENT_UNBIND_EXCHANGE_BEGIN) {
121         res = ExchangeRequest(task, params, in, out, status);
122         if (res != HC_SUCCESS) {
123             goto ERR;
124         }
125         return res;
126     }
127 
128     int message = 0;
129     res = GetIntFromJson(in, "message", &message);
130     if (res != HC_SUCCESS) {
131         goto ERR;
132     }
133 
134     switch (message) {
135         case PAKE_UNBIND_EXCHANGE_RESPONSE:
136             res = ExchangeConfirm(task, params, in, status);
137             break;
138         default:
139             res = HC_ERR_INVALID_PARAMS;
140             break;
141     }
142     if (res != HC_SUCCESS) {
143         goto ERR;
144     }
145     return res;
146 ERR:
147     FreeAndCleanKey(&(params->baseParams.sessionKey));
148     return res;
149 }
150 
DestroyStandardUnbindExchangeClientTask(struct AsyBaseCurTaskT * task)151 static void DestroyStandardUnbindExchangeClientTask(struct AsyBaseCurTaskT *task)
152 {
153     StandardUnbindExchangeClientTask *innerTask = (StandardUnbindExchangeClientTask *)task;
154     if (innerTask == NULL) {
155         return;
156     }
157 
158     DestroyStandardUnbindExchangeParams(&(innerTask->params));
159     HcFree(innerTask);
160 }
161 
CreateStandardUnbindExchangeClientTask(void)162 AsyBaseCurTask *CreateStandardUnbindExchangeClientTask(void)
163 {
164     StandardUnbindExchangeClientTask *task =
165         (StandardUnbindExchangeClientTask *)HcMalloc(sizeof(StandardUnbindExchangeClientTask), 0);
166     if (task == NULL) {
167         return NULL;
168     }
169     task->taskBase.destroyTask = DestroyStandardUnbindExchangeClientTask;
170     task->taskBase.process = Process;
171     task->taskBase.taskStatus = TASK_STATUS_CLIENT_UNBIND_EXCHANGE_BEGIN;
172     task->taskBase.getCurTaskType = GetTaskType;
173 
174     int res = InitStandardUnbindExchangeParams(&(task->params));
175     if (res != HC_SUCCESS) {
176         DestroyStandardUnbindExchangeClientTask((struct AsyBaseCurTaskT *)task);
177         return NULL;
178     }
179 
180     return (AsyBaseCurTask *)task;
181 }