1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <stdbool.h>
20 #include <semaphore.h>
21 #include "hlt_type.h"
22 #include "securec.h"
23 #include "logger.h"
24 #include "rpc_func.h"
25 #include "channel_res.h"
26 #include "handle_cmd.h"
27
28 #define SUCCESS 0
29 #define ERROR (-1)
30 #define ASSERT_RETURN(condition, log) \
31 do { \
32 if (!(condition)) { \
33 LOG_ERROR(log); \
34 return ERROR; \
35 } \
36 } while (0)
37
ExpectResult(CmdData * expectCmdData)38 int ExpectResult(CmdData *expectCmdData)
39 {
40 int ret, id;
41 char *endPtr = NULL;
42 CmdData cmdData;
43 ControlChannelRes *channelRes;
44 channelRes = GetControlChannelRes();
45 OsLock(channelRes->rcvBufferLock);
46
47 id = (int)strtol(expectCmdData->id, &endPtr, 0) % MAX_RCV_BUFFER_NUM;
48 // Check whether the corresponding buffer contains content.
49 if (strlen(channelRes->rcvBuffer[id]) == 0) {
50 OsUnLock(channelRes->rcvBufferLock);
51 return ERROR;
52 }
53
54 // Parsing the CMD
55 ret = ParseCmdFromStr(channelRes->rcvBuffer[id], &cmdData);
56 if (ret != SUCCESS) {
57 LOG_ERROR("ParseCmdFromStr ERROR");
58 OsUnLock(channelRes->rcvBufferLock);
59 return ERROR;
60 }
61
62 if ((strncmp(expectCmdData->id, cmdData.id, strlen(cmdData.id)) == 0) &&
63 (strncmp(expectCmdData->funcId, cmdData.funcId, strlen(cmdData.funcId)) == 0)) {
64 ret = memcpy_s(expectCmdData->paras, sizeof(expectCmdData->paras), cmdData.paras, sizeof(cmdData.paras));
65 if (ret != EOK) {
66 LOG_ERROR("memcpy_s ERROR");
67 OsUnLock(channelRes->rcvBufferLock);
68 return ERROR;
69 }
70 (void)memset_s(channelRes->rcvBuffer[id], CONTROL_CHANNEL_MAX_MSG_LEN, 0, CONTROL_CHANNEL_MAX_MSG_LEN);
71 OsUnLock(channelRes->rcvBufferLock);
72 return SUCCESS;
73 }
74 OsUnLock(channelRes->rcvBufferLock);
75 LOG_ERROR("strncmp ERROR [expectCmdData->id=%s, cmdData.id = %s, expectCmdData->funcId = %s, cmdData.funcId = %s]",
76 expectCmdData->id, cmdData.id, expectCmdData->funcId, cmdData.funcId);
77 return ERROR;
78 }
79
WaitResultFromPeer(CmdData * expectCmdData)80 int WaitResultFromPeer(CmdData *expectCmdData)
81 {
82 int ret;
83 int tryNum = 0;
84 do {
85 ret = ExpectResult(expectCmdData);
86 usleep(1000); // Waiting for 1000 subtleties
87 tryNum++;
88 } while ((ret != SUCCESS) && (tryNum < 150000));
89 ASSERT_RETURN(ret == SUCCESS, "ExpectResult Error");
90 return SUCCESS;
91 }
92
ParseCmdFromStr(char * str,CmdData * cmdData)93 int ParseCmdFromStr(char *str, CmdData *cmdData)
94 {
95 int ret, count, strBufLen;
96 char *token = NULL;
97 char *rest = NULL;
98 char *strBuf = NULL;
99 (void)memset_s(cmdData, sizeof(CmdData), 0, sizeof(CmdData));
100
101 strBufLen = strlen(str) + 1;
102 strBuf = (char*)malloc(strBufLen);
103 ASSERT_RETURN(strBuf != NULL, "Malloc Error");
104 (void)memset_s(strBuf, strBufLen, 0, strBufLen);
105 ret = memcpy_s(strBuf, strBufLen, str, strlen(str));
106 if (ret != EOK) {
107 LOG_ERROR("memcpy_s Error");
108 goto ERR;
109 }
110
111 /*
112 The command message structure is as follows:
113 ID | FUNC | PARAS1 | PARAS2 |......
114 Fields are separated by vertical bars (|).
115 */
116 // Get ID
117 token = strtok_s(strBuf, "|", &rest);
118 ret = strcpy_s(cmdData->id, sizeof(cmdData->id), token); // Get Id
119 if (ret != EOK) {
120 LOG_ERROR("strcpy_s Error");
121 goto ERR;
122 }
123
124 // Get FUNC.
125 token = strtok_s(NULL, "|", &rest);
126 ret = strcpy_s(cmdData->funcId, sizeof(cmdData->funcId), token); // Get FunId
127 if (ret != EOK) {
128 LOG_ERROR("strcpy_s Error");
129 goto ERR;
130 }
131
132 // Obtaining Parameters
133 token = strtok_s(NULL, "|", &rest);
134 count = 0;
135 for (; token != NULL; token = strtok_s(NULL, "|", &rest)) {
136 // Maximum length of argument is CONTROL_CHANNEL_MAX_MSG_LEN
137 ret = strcpy_s(cmdData->paras[count], sizeof(cmdData->paras[0]), token);
138 int offset = 0;
139 while (rest[offset] == '|') {
140 count++;
141 offset++;
142 }
143 count++;
144 if (ret != EOK) {
145 break;
146 }
147 }
148 if (ret != EOK) {
149 LOG_ERROR("strcpy_s error");
150 goto ERR;
151 }
152 cmdData->parasNum = count;
153 free(strBuf);
154 return SUCCESS;
155
156 ERR:
157 free(strBuf);
158 return ERROR;
159 }
160
ParseCmdFromBuf(ControlChannelBuf * dataBuf,CmdData * cmdData)161 int ParseCmdFromBuf(ControlChannelBuf *dataBuf, CmdData *cmdData)
162 {
163 return ParseCmdFromStr(dataBuf->data, cmdData);
164 }
165
ExecuteCmd(CmdData * cmdData)166 int ExecuteCmd(CmdData *cmdData)
167 {
168 int ret;
169 RpcFunList *rcpFuncList = GetRpcFuncList();
170 int funcNum = GetRpcFuncNum();
171 ret = ERROR;
172 for (int i = 0; i < funcNum; i++) {
173 if (strncmp(rcpFuncList[i].funcId, cmdData->funcId, strlen(cmdData->funcId)) == 0) {
174 ret = rcpFuncList[i].hfunc(cmdData);
175 return ret;
176 }
177 }
178 LOG_ERROR("Not Find FuncId");
179 (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result));
180 ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ERROR);
181 ASSERT_RETURN(ret > 0, "sprintf_s Error");
182 return ret;
183 }
184
ParseCtxConfigFromString(char (* string)[CONTROL_CHANNEL_MAX_MSG_LEN],HLT_Ctx_Config * ctxConfig)185 int ParseCtxConfigFromString(char (*string)[CONTROL_CHANNEL_MAX_MSG_LEN], HLT_Ctx_Config *ctxConfig)
186 {
187 int ret;
188 /*
189 The message structure is as follows:
190 minVersion | maxVersion |cipherSuites |CA |......
191 Fields are separated by vertical bars (|).
192 */
193 int index = 1;
194 // minimum version number
195 // The first parameter indicates the minimum version number.
196 ctxConfig->minVersion = (int)strtol(string[index++], NULL, 10);
197 LOG_DEBUG("Remote Process Set Ctx minVersion is %u", ctxConfig->minVersion);
198
199 // Maximum version number
200 // The second parameter indicates the maximum version number.
201 ctxConfig->maxVersion = (int)strtol(string[index++], NULL, 10);
202 LOG_DEBUG("Remote Process Set Ctx maxVersion is %u", ctxConfig->maxVersion);
203
204 // Obtaining the Algorithm Suite
205 // The third parameter indicates the algorithm suite.
206 ret = strcpy_s(ctxConfig->cipherSuites, sizeof(ctxConfig->cipherSuites), string[index++]);
207 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
208 LOG_DEBUG("Remote Process Set Ctx cipherSuites is %s", ctxConfig->cipherSuites);
209
210 // The fourth parameter indicates the algorithm suite.
211 ret = strcpy_s(ctxConfig->tls13CipherSuites, sizeof(ctxConfig->tls13CipherSuites), string[index++]);
212 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
213 LOG_DEBUG("Remote Process Set Ctx tls13cipherSuites is %s", ctxConfig->tls13CipherSuites);
214
215 // ECC Point Format Configuration for Asymmetric Algorithms
216 // The fifth parameter indicates the dot format.
217 ret = strcpy_s(ctxConfig->pointFormats, sizeof(ctxConfig->pointFormats), string[index++]);
218 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
219 LOG_DEBUG("Remote Process Set Ctx pointFormats is %s", ctxConfig->pointFormats);
220
221 // Obtaining a Group
222 // The sixth parameter indicates a group.
223 ret = strcpy_s(ctxConfig->groups, sizeof(ctxConfig->groups), string[index++]);
224 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
225 LOG_DEBUG("Remote Process Set Ctx groups is %s", ctxConfig->groups);
226
227 // Obtaining a Signature
228 // The seventh parameter indicates the signature.
229 ret = strcpy_s(ctxConfig->signAlgorithms, sizeof(ctxConfig->signAlgorithms), string[index++]);
230 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
231 LOG_DEBUG("Remote Process Set Ctx signAlgorithms is %s", ctxConfig->signAlgorithms);
232
233 // Whether to support renegotiation
234 // The eighth parameter indicates whether renegotiation is supported.
235 ctxConfig->isSupportRenegotiation = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
236 LOG_DEBUG("Remote Process Set Ctx isSupportRenegotiation is %d", ctxConfig->isSupportRenegotiation);
237
238 // Indicates whether to verify the client.
239 // The tenth parameter indicates whether to verify the client.
240 ctxConfig->isSupportClientVerify = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
241 LOG_DEBUG("Remote Process Set Ctx isSupportClientVerify is %d", ctxConfig->isSupportClientVerify);
242
243 // Indicates whether the client can send an empty certificate chain.
244 // The eleventh parameter indicates whether the client can send an empty certificate chain.
245 ctxConfig->isSupportNoClientCert = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
246 LOG_DEBUG("Remote Process Set Ctx isSupportNoClientCert is %d", ctxConfig->isSupportNoClientCert);
247
248 // Indicates whether extended master keys are supported.
249 // The twelfth parameter indicates whether the extended master key is supported.
250 ctxConfig->isSupportExtendMasterSecret = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
251 LOG_DEBUG("Remote Process Set Ctx isSupportExtendMasterSecret is %d", ctxConfig->isSupportExtendMasterSecret);
252
253 // device certificate
254 // The thirteenth parameter indicates the location of the device certificate.
255 ret = strcpy_s(ctxConfig->eeCert, sizeof(ctxConfig->eeCert), string[index++]);
256 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
257 LOG_DEBUG("Remote Process Set Ctx EE is %s", ctxConfig->eeCert);
258
259 // private key
260 // The fourteenth parameter indicates the location of the private key.
261 ret = strcpy_s(ctxConfig->privKey, sizeof(ctxConfig->privKey), string[index++]);
262 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
263 LOG_DEBUG("Remote Process Set Ctx privKey is %s", ctxConfig->privKey);
264
265 // private key password
266 // The fifteenth parameter indicates the password of the private key.
267 ret = strcpy_s(ctxConfig->password, sizeof(ctxConfig->password), string[index++]);
268 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
269 LOG_DEBUG("Remote Process Set Ctx password is %s", ctxConfig->password);
270
271 // CA certificate
272 // The 16th parameter indicates the CA certificate.
273 ret = strcpy_s(ctxConfig->caCert, sizeof(ctxConfig->caCert), string[index++]);
274 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
275 LOG_DEBUG("Remote Process Set Ctx caCert is %s", ctxConfig->caCert);
276
277 // Chain certificate
278 // The 17th parameter indicates the certificate chain.
279 ret = strcpy_s(ctxConfig->chainCert, sizeof(ctxConfig->chainCert), string[index++]);
280 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
281 LOG_DEBUG("Remote Process Set Ctx chainCert is %s", ctxConfig->chainCert);
282
283 // signature certificate
284 LOG_DEBUG("Remote Process Set Ctx signCert is %s", string[index]);
285 // The eighteenth parameter indicates the position of the signature certificate.
286 ret = strcpy_s(ctxConfig->signCert, sizeof(ctxConfig->signCert), string[index++]);
287 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
288
289 // private key for signature
290 LOG_DEBUG("Remote Process Set Ctx signPrivKey is %s", string[index]);
291 // The 19th parameter indicates the location of the signature private key.
292 ret = strcpy_s(ctxConfig->signPrivKey, sizeof(ctxConfig->signPrivKey), string[index++]);
293 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
294
295 // psk
296 ret = strcpy_s(ctxConfig->psk, sizeof(ctxConfig->psk), string[index++]); // 21st parameter psk
297 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
298 LOG_DEBUG("Remote Process Set Ctx psk is %s", ctxConfig->psk);
299
300 // Indicates whether to support session tickets.
301 // Indicates whether to enable the sessionTicket function. The value is a decimal number.
302 ctxConfig->isSupportSessionTicket = (int)strtol(string[index++], NULL, 10);
303 LOG_DEBUG("Remote Process Set Ctx isSupportSessionTicket is %d", ctxConfig->isSupportSessionTicket);
304
305 // Setting the Session Storage Mode
306 // The 23rd parameter is used to set the session storage mode. The value is a decimal number.
307 ctxConfig->setSessionCache = (int)strtol(string[index++], NULL, 10);
308 LOG_DEBUG("Remote Process Set Ctx SessionCache is %d", ctxConfig->setSessionCache);
309
310 // Setting the ticket key cb
311 // 24th parameter ticket key cb
312 ret = strcpy_s(ctxConfig->ticketKeyCb, sizeof(ctxConfig->ticketKeyCb), string[index++]);
313 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
314 LOG_DEBUG("Remote Process Set Ctx ticketKeyCb is %s", ctxConfig->ticketKeyCb);
315
316 // Indicates whether isFlightTransmitEnable is supported. The 25th parameter indicates whether to send handshake
317 // messages by flight. The value is converted into a decimal number.
318 ctxConfig->isFlightTransmitEnable = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
319 LOG_DEBUG("Remote Process Set Ctx isFlightTransmitEnable is %d", ctxConfig->isFlightTransmitEnable);
320
321 // Setting the server name
322 ret = strcpy_s(ctxConfig->serverName, sizeof(ctxConfig->serverName), string[index++]); // Parameter 26
323 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
324 LOG_DEBUG("Remote Process Set Ctx ServerName is %s", ctxConfig->serverName);
325
326 // Setting the server name cb
327 // 27th parameter server name cb
328 ret = strcpy_s(ctxConfig->sniDealCb, sizeof(ctxConfig->sniDealCb), string[index++]);
329 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
330 LOG_DEBUG("Remote Process Set Ctx ServerNameCb is %s", ctxConfig->sniDealCb);
331
332 // Setting the server name arg
333 // 28th parameter server name arg cb
334 ret = strcpy_s(ctxConfig->sniArg, sizeof(ctxConfig->sniArg), string[index++]);
335 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
336 LOG_DEBUG("Remote Process Set Ctx ServerNameArg is %s", ctxConfig->sniArg);
337
338 // Setting the ALPN
339 ret = strcpy_s(ctxConfig->alpnList, sizeof(ctxConfig->alpnList), string[index++]); // 29th parameter
340 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
341 LOG_DEBUG("Remote Process Set Ctx alpnList is %s", ctxConfig->alpnList);
342
343 // Setting the ALPN cb
344 ret = strcpy_s(ctxConfig->alpnSelectCb, sizeof(ctxConfig->alpnSelectCb), string[index++]); // 30th parameter
345 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
346 LOG_DEBUG("Remote Process Set Ctx alpnSelectCb is %s", ctxConfig->alpnSelectCb);
347
348 // Setting the ALPN data
349 ret = strcpy_s(ctxConfig->alpnUserData, sizeof(ctxConfig->alpnUserData), string[index++]); // 31th parameter
350 ASSERT_RETURN(ret == EOK, "strcpy_s Error");
351 LOG_DEBUG("Remote Process Set Ctx alpnUserData is %s", ctxConfig->alpnUserData);
352
353 // Sets the security level. The parameter indicates that the security strength of the key meets the security level
354 // requirements and is converted into a decimal number.
355 ctxConfig->securitylevel = (int)strtol(string[index++], NULL, 10);
356 LOG_DEBUG("Remote Process Set Ctx SecurityLevel is %d", ctxConfig->securitylevel);
357
358 // Indicates whether the DH key length follows the certificate. The parameter indicates whether the DH key length
359 // follows the certificate, which is converted into a decimal number.
360 ctxConfig->isSupportDhAuto = (int)strtol(string[index++], NULL, 10);
361 LOG_DEBUG("Remote Process Set Ctx issupportDhauto is %d", ctxConfig->isSupportDhAuto);
362
363 // Sets the TLS1.3 key exchange mode. The parameter indicates the TLS1.3 key exchange mode,
364 // which is converted into a decimal number.
365 ctxConfig->keyExchMode = (int)strtol(string[index++], NULL, 10);
366 LOG_DEBUG("Remote Process Set Ctx keyExchMode is %u", ctxConfig->keyExchMode);
367
368 // The parameter indicates the SupportType callback type, which converts characters into decimal numbers.
369 ctxConfig->SupportType = (int)strtol(string[index++], NULL, 10);
370 LOG_DEBUG("Remote Process Set Ctx SupportType is %d", ctxConfig->SupportType);
371
372 ctxConfig->isSupportPostHandshakeAuth = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
373
374 ctxConfig->readAhead = (int)strtol(string[index++], NULL, 10);
375 LOG_DEBUG("Remote Process Set Ctx readAhead is %u", ctxConfig->readAhead);
376 // Sets whether to verify the keyusage in the certificate. The keyusage is converted into a decimal number.
377 ctxConfig->needCheckKeyUsage = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
378 LOG_DEBUG("Remote Process Set Ctx needCheckKeyUsage is %d", ctxConfig->needCheckKeyUsage);
379
380 // Set whether to continue the handshake when the verification of peer certificate fails
381 ctxConfig->isSupportVerifyNone = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
382 LOG_DEBUG("Remote Process Set Ctx isSupportVerifyNone is %d", ctxConfig->isSupportVerifyNone);
383
384 // Whether allow a renegotiation initiated by the client
385 ctxConfig->allowClientRenegotiate = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
386 LOG_DEBUG("Remote Process Set Ctx allowClientRenegotiate is %d", ctxConfig->allowClientRenegotiate);
387
388 // Set the empty record number.
389 ctxConfig->emptyRecordsNum = (int)strtol(string[index++], NULL, 10);
390 LOG_DEBUG("Remote Process Set Ctx emptyRecordsNum is %u", ctxConfig->emptyRecordsNum);
391
392 // Whether allow legacy renegotiation
393 ctxConfig->allowLegacyRenegotiate = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
394 LOG_DEBUG("Remote Process Set Ctx allowLegacyRenegotiate is %d", ctxConfig->allowLegacyRenegotiate);
395
396 // Indicates whether encrypt then mac are supported.
397 ctxConfig->isEncryptThenMac = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false;
398 LOG_DEBUG("Remote Process Set Ctx isEncryptThenMac is %d", ctxConfig->isEncryptThenMac);
399
400 // set the features supported by modesupport, The value is a decimal number.
401 ctxConfig->modeSupport = (int)strtol(string[index++], NULL, 10);
402 LOG_DEBUG("Remote Process Set Ctx modeSupport is %d", ctxConfig->modeSupport);
403
404 // Setting the info cb
405 ctxConfig->infoCb = NULL; // The pointer cannot be transferred. Set this parameter to null.
406
407 return SUCCESS;
408 }
409