• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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