• 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_server_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_SERVER_UNBIND_EXCHANGE_BEGIN = 0,
24     TASK_STATUS_SERVER_UNBIND_EXCHANGE_START,
25     TASK_STATUS_SERVER_UNBIND_EXCHANGE_RESPONSE,
26 };
27 
GetTaskType(void)28 static CurTaskType GetTaskType(void)
29 {
30     return TASK_TYPE_UNBIND_STANDARD_EXCHANGE;
31 }
32 
ExchangeStart(AsyBaseCurTask * task,PakeParams * params,CJson * out,int * status)33 static int ExchangeStart(AsyBaseCurTask *task, PakeParams *params, CJson *out, int *status)
34 {
35     int res = HC_SUCCESS;
36     if (task->taskStatus != TASK_STATUS_SERVER_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 
42     if (params->baseParams.challengeSelf.val == NULL) {
43         res = GenerateSelfChallenge(params);
44         if (res != HC_SUCCESS) {
45             LOGE("GenerateSelfChallenge failed");
46             return res;
47         }
48         CJson *payload = GetObjFromJson(out, FIELD_PAYLOAD);
49         if (payload == NULL) {
50             LOGE("Get payload failed.");
51             return HC_ERR_JSON_GET;
52         }
53         if (AddByteToJson(payload, FIELD_CHALLENGE,
54             params->baseParams.challengeSelf.val, params->baseParams.challengeSelf.length) != HC_SUCCESS) {
55             LOGE("Failed to add self challenge to payload.");
56             return HC_ERR_JSON_ADD;
57         }
58     }
59 
60     task->taskStatus = TASK_STATUS_SERVER_UNBIND_EXCHANGE_START;
61     *status = CONTINUE;
62     return res;
63 }
64 
ExchangeResponse(AsyBaseCurTask * task,PakeParams * params,const CJson * in,CJson * out,int * status)65 static int ExchangeResponse(AsyBaseCurTask *task, PakeParams *params, const CJson *in, CJson *out, int *status)
66 {
67     int res = HC_SUCCESS;
68     CJson *data = NULL;
69     CJson *sendToPeer = NULL;
70 
71     if (task->taskStatus < TASK_STATUS_SERVER_UNBIND_EXCHANGE_START) {
72         return HC_ERR_BAD_MESSAGE;
73     }
74     if (task->taskStatus > TASK_STATUS_SERVER_UNBIND_EXCHANGE_START) {
75         LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
76         *status = IGNORE_MSG;
77         return HC_SUCCESS;
78     }
79 
80     StandardUnbindExchangeServerTask *realTask = (StandardUnbindExchangeServerTask *)task;
81 
82     if (params->baseParams.challengePeer.val == NULL) {
83         GOTO_ERR_AND_SET_RET(GetPeerChallenge(params, in), res);
84     }
85     GOTO_ERR_AND_SET_RET(ParseNonceAndCipherFromJson(&(realTask->params.nonce), &(realTask->params.exRmvCipher),
86         in, FIELD_RMV_AUTH_INFO), res);
87 
88     // execute
89     res = ServerResponseStandardUnbindExchange(params, &(realTask->params));
90     if (res != HC_SUCCESS) {
91         LOGE("ServerResponseStandardUnbindExchange failed");
92         return res;
93     }
94 
95     sendToPeer = CreateJson();
96     if (sendToPeer == NULL) {
97         res = HC_ERR_ALLOC_MEMORY;
98         goto ERR;
99     }
100     GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_MESSAGE, PAKE_UNBIND_EXCHANGE_RESPONSE), res);
101     data = CreateJson();
102     if (data == NULL) {
103         res = HC_ERR_ALLOC_MEMORY;
104         goto ERR;
105     }
106     GOTO_ERR_AND_SET_RET(PackageNonceAndCipherToJson(&(realTask->params.nonce), &(realTask->params.resultCipher),
107         data, FIELD_RMV_RETURN), res);
108     GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, data), res);
109     GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
110 
111     task->taskStatus = TASK_STATUS_SERVER_UNBIND_EXCHANGE_RESPONSE;
112     *status = FINISH;
113 ERR:
114     FreeJson(data);
115     FreeJson(sendToPeer);
116     return res;
117 }
118 
Process(struct AsyBaseCurTaskT * task,PakeParams * params,const CJson * in,CJson * out,int * status)119 static int Process(struct AsyBaseCurTaskT *task, PakeParams *params, const CJson *in, CJson *out, int *status)
120 {
121     int res;
122     if ((task == NULL) || (in == NULL) || (out == NULL) || (status == NULL)) {
123         return HC_ERR_INVALID_PARAMS;
124     }
125 
126     if (task->taskStatus == TASK_STATUS_SERVER_UNBIND_EXCHANGE_BEGIN) {
127         res = ExchangeStart(task, params, out, status);
128         if (res != HC_SUCCESS) {
129             goto ERR;
130         }
131         return res;
132     }
133 
134     int message = 0;
135     res = GetIntFromJson(in, "message", &message);
136     if (res != HC_SUCCESS) {
137         goto ERR;
138     }
139 
140     switch (message) {
141         case PAKE_UNBIND_EXCHANGE_REQUEST:
142             res = ExchangeResponse(task, params, in, out, status);
143             break;
144         default:
145             res = HC_ERR_INVALID_PARAMS;
146             break;
147     }
148 
149     if (res != HC_SUCCESS) {
150         goto ERR;
151     }
152     return res;
153 ERR:
154     FreeAndCleanKey(&(params->baseParams.sessionKey));
155     return res;
156 }
157 
DestroyStandardUnbindExchangeServerTask(struct AsyBaseCurTaskT * task)158 static void DestroyStandardUnbindExchangeServerTask(struct AsyBaseCurTaskT *task)
159 {
160     StandardUnbindExchangeServerTask *innerTask = (StandardUnbindExchangeServerTask *)task;
161     if (innerTask == NULL) {
162         return;
163     }
164 
165     DestroyStandardUnbindExchangeParams(&(innerTask->params));
166     HcFree(innerTask);
167 }
168 
CreateStandardUnbindExchangeServerTask(void)169 AsyBaseCurTask *CreateStandardUnbindExchangeServerTask(void)
170 {
171     StandardUnbindExchangeServerTask *task =
172         (StandardUnbindExchangeServerTask *)HcMalloc(sizeof(StandardUnbindExchangeServerTask), 0);
173     if (task == NULL) {
174         return NULL;
175     }
176     task->taskBase.destroyTask = DestroyStandardUnbindExchangeServerTask;
177     task->taskBase.process = Process;
178     task->taskBase.taskStatus = TASK_STATUS_SERVER_UNBIND_EXCHANGE_BEGIN;
179     task->taskBase.getCurTaskType = GetTaskType;
180 
181     int res = InitStandardUnbindExchangeParams(&(task->params));
182     if (res != HC_SUCCESS) {
183         DestroyStandardUnbindExchangeServerTask((struct AsyBaseCurTaskT *)task);
184         return NULL;
185     }
186 
187     return (AsyBaseCurTask *)task;
188 }
189 
190