• 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 <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include "securec.h"
20 #include "bsl_sal.h"
21 #include "hitls.h"
22 #include "hitls_config.h"
23 #include "hitls_error.h"
24 #include "hitls_type.h"
25 #include "frame_tls.h"
26 #include "frame_msg.h"
27 #include "frame_link.h"
28 #include "frame_io.h"
29 #include "simulate_io.h"
30 
31 #define DEFAUTL_COOKIE_LEN 32
32 
33 /* Used to establish a link and stop in the state. */
34 typedef struct {
35     HITLS_Config *config;
36     FRAME_LinkObj *client;
37     FRAME_LinkObj *server;
38     HITLS_HandshakeState state;
39     bool isClient;
40     BSL_UIO_TransportType transportType;
41 } LinkPara;
42 
CleanLinkPara(LinkPara * linkPara)43 static void CleanLinkPara(LinkPara *linkPara)
44 {
45     HITLS_CFG_FreeConfig(linkPara->config);
46     FRAME_FreeLink(linkPara->client);
47     FRAME_FreeLink(linkPara->server);
48 }
49 
PauseState(LinkPara * linkPara,uint16_t version)50 static int32_t PauseState(LinkPara *linkPara, uint16_t version)
51 {
52     (void)version;
53 
54     BSL_UIO_TransportType transportType = linkPara->transportType;
55 #ifdef HITLS_TLS_PROTO_TLCP11
56     /* Constructing a Link */
57     if ( version == HITLS_VERSION_TLCP_DTLCP11 ) {
58         linkPara->client = FRAME_CreateTLCPLink(linkPara->config, transportType, true);
59         linkPara->server = FRAME_CreateTLCPLink(linkPara->config, transportType, false);
60     } else
61 #endif /* HITLS_TLS_PROTO_TLCP11 */
62     {
63         linkPara->client = FRAME_CreateLink(linkPara->config, transportType);
64         linkPara->server = FRAME_CreateLink(linkPara->config, transportType);
65     }
66 
67     if (linkPara->client == NULL || linkPara->server == NULL) {
68         return HITLS_INTERNAL_EXCEPTION;
69     }
70 
71     /* Establish a link and stop in a certain state. */
72     if (FRAME_CreateConnection(linkPara->client, linkPara->server,
73                                linkPara->isClient, linkPara->state) != HITLS_SUCCESS) {
74         return HITLS_INTERNAL_EXCEPTION;
75     }
76 
77     /* Check whether the status is consistent. */
78     HITLS_Ctx *ctx = linkPara->isClient ? linkPara->client->ssl : linkPara->server->ssl;
79     if ((ctx->hsCtx == NULL) || (ctx->hsCtx->state != linkPara->state)) {
80         return HITLS_INTERNAL_EXCEPTION;
81     }
82 
83     return HITLS_SUCCESS;
84 }
85 
SetLinkState(HS_MsgType hsType,LinkPara * linkPara)86 static int32_t SetLinkState(HS_MsgType hsType, LinkPara *linkPara)
87 {
88     linkPara->isClient = true;
89     switch (hsType) {
90         case CLIENT_HELLO:
91             linkPara->isClient = false;
92             linkPara->state = TRY_RECV_CLIENT_HELLO;
93             return HITLS_SUCCESS;
94         case SERVER_HELLO:
95             linkPara->state = TRY_RECV_SERVER_HELLO;
96             return HITLS_SUCCESS;
97         case CERTIFICATE:
98             linkPara->state = TRY_RECV_CERTIFICATE;
99             return HITLS_SUCCESS;
100         case SERVER_KEY_EXCHANGE:
101             linkPara->state = TRY_RECV_SERVER_KEY_EXCHANGE;
102             return HITLS_SUCCESS;
103         case CERTIFICATE_REQUEST:
104             linkPara->state = TRY_RECV_CERTIFICATE_REQUEST;
105             return HITLS_SUCCESS;
106         case SERVER_HELLO_DONE:
107             linkPara->state = TRY_RECV_SERVER_HELLO_DONE;
108             return HITLS_SUCCESS;
109         case CERTIFICATE_VERIFY:
110             linkPara->isClient = false;
111             linkPara->state = TRY_RECV_CERTIFICATE_VERIFY;
112             return HITLS_SUCCESS;
113         case CLIENT_KEY_EXCHANGE:
114             linkPara->isClient = false;
115             linkPara->state = TRY_RECV_CLIENT_KEY_EXCHANGE;
116             return HITLS_SUCCESS;
117         case FINISHED:
118             // The existing framework does not support parsing of encrypted finished messages.
119             // Therefore, finished messages cannot be obtained.
120             break;
121         default:
122             break;
123     }
124     return HITLS_INTERNAL_EXCEPTION;
125 }
126 
SetLinkConfig(uint16_t version,HITLS_KeyExchAlgo keyExAlgo,LinkPara * linkPara)127 static int32_t SetLinkConfig(uint16_t version, HITLS_KeyExchAlgo keyExAlgo, LinkPara *linkPara)
128 {
129     if (linkPara == NULL) {
130         return HITLS_INTERNAL_EXCEPTION;
131     }
132     linkPara->config = NULL;
133     if (IS_DTLS_VERSION(version)) {
134         linkPara->config = HITLS_CFG_NewDTLS12Config();
135     } else if (version == HITLS_VERSION_TLS12) {
136         linkPara->config = HITLS_CFG_NewTLS12Config();
137     } else if (version == HITLS_VERSION_TLS13) {
138         linkPara->config = HITLS_CFG_NewTLS13Config();
139     } else if (version == HITLS_VERSION_TLCP_DTLCP11) {
140         if (IS_TRANSTYPE_DATAGRAM(linkPara->transportType)) {
141             linkPara->config = HITLS_CFG_NewDTLCPConfig();
142         } else {
143             linkPara->config = HITLS_CFG_NewTLCPConfig();
144         }
145 
146         return HITLS_SUCCESS;
147     }
148 #ifdef HITLS_TLS_CONFIG_KEY_USAGE
149     HITLS_CFG_SetCheckKeyUsage(linkPara->config, false);
150 #endif /* HITLS_TLS_CONFIG_KEY_USAGE */
151 
152 #ifdef HITLS_TLS_FEATURE_CERT_MODE
153     int32_t ret = HITLS_CFG_SetClientVerifySupport(linkPara->config, true);
154     if (ret != HITLS_SUCCESS) {
155         return ret;
156     }
157 #endif /* HITLS_TLS_FEATURE_CERT_MODE */
158     if (keyExAlgo == HITLS_KEY_EXCH_DHE) {
159         uint16_t cipherSuites[] = {HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256};
160         HITLS_CFG_SetCipherSuites(linkPara->config, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t));
161         uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256};
162         HITLS_CFG_SetSignature(linkPara->config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t));
163     } else {
164         uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1};
165         HITLS_CFG_SetGroups(linkPara->config, groups, sizeof(groups) / sizeof(uint16_t));
166         uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256};
167         HITLS_CFG_SetSignature(linkPara->config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t));
168     }
169 
170     return HITLS_SUCCESS;
171 }
172 
GetdefaultHsMsg(FRAME_Type * frameType,FRAME_Msg * parsedMsg)173 static int32_t GetdefaultHsMsg(FRAME_Type *frameType, FRAME_Msg *parsedMsg)
174 {
175     int32_t ret;
176     LinkPara linkPara = {0};
177 
178     /* Configure config. */
179     linkPara.transportType = frameType->transportType;
180     ret = SetLinkConfig(frameType->versionType, frameType->keyExType, &linkPara);
181     if (ret != HITLS_SUCCESS) {
182         CleanLinkPara(&linkPara);
183         return ret;
184     }
185 
186     /* Setting the parked state */
187     ret = SetLinkState(frameType->handshakeType, &linkPara);
188     if (ret != HITLS_SUCCESS) {
189         CleanLinkPara(&linkPara);
190         return ret;
191     }
192 
193     /* Stop in this state */
194     ret = PauseState(&linkPara, frameType->versionType);
195     if (ret != HITLS_SUCCESS) {
196         CleanLinkPara(&linkPara);
197         return ret;
198     }
199 
200     /* Obtain the message buffer. */
201     FRAME_LinkObj *link = linkPara.isClient ? linkPara.client : linkPara.server;
202     FrameUioUserData *ioUserData = BSL_UIO_GetUserData(link->io);
203     uint8_t *buffer = ioUserData->recMsg.msg;
204     uint32_t len = ioUserData->recMsg.len;
205     if (len == 0) {
206         CleanLinkPara(&linkPara);
207         return HITLS_INTERNAL_EXCEPTION;
208     }
209 
210     /* Parse to msg structure */
211     uint32_t parseLen = 0;
212     ret = FRAME_ParseMsg(frameType, buffer, len, parsedMsg, &parseLen);
213     if ((ret != HITLS_SUCCESS) || (len != parseLen)) {
214         CleanLinkPara(&linkPara);
215         return HITLS_INTERNAL_EXCEPTION;
216     }
217 
218     CleanLinkPara(&linkPara);
219     return HITLS_SUCCESS;
220 }
221 
SetDefaultRecordHeader(FRAME_Type * frameType,FRAME_Msg * msg,REC_Type recType)222 static void SetDefaultRecordHeader(FRAME_Type *frameType, FRAME_Msg *msg, REC_Type recType)
223 {
224     msg->recType.state = INITIAL_FIELD;
225     msg->recType.data = recType;
226     msg->recVersion.state = INITIAL_FIELD;
227     if (IS_DTLS_VERSION(frameType->versionType)) {
228         msg->recVersion.data = HITLS_VERSION_DTLS12;
229     } else if (frameType->versionType == HITLS_VERSION_TLCP_DTLCP11) {
230         msg->recVersion.data = HITLS_VERSION_TLCP_DTLCP11;
231     } else {
232         msg->recVersion.data = HITLS_VERSION_TLS12;
233     }
234     msg->epoch.state = INITIAL_FIELD;
235     /* In the default message, the value is set to 0 by default. You need to assign a value to the value. */
236     msg->epoch.data = 0;
237     msg->sequence.state = INITIAL_FIELD;
238     /* In the default message, the value is set to 0 by default. You need to assign a value to the value. */
239     msg->sequence.data = 0;
240     msg->length.state = INITIAL_FIELD;
241     /* The value of length is automatically calculated during assembly.
242      * Therefore, the value of length is initialized to 0. */
243     msg->length.data = 0;
244 }
245 
GetdefaultCcsMsg(FRAME_Type * frameType,FRAME_Msg * msg)246 static int32_t GetdefaultCcsMsg(FRAME_Type *frameType, FRAME_Msg *msg)
247 {
248     SetDefaultRecordHeader(frameType, msg, REC_TYPE_CHANGE_CIPHER_SPEC); /* Setting the Default Record Header */
249     msg->body.ccsMsg.ccsType.state = INITIAL_FIELD;
250     msg->body.ccsMsg.ccsType.data = 1u; /* In the protocol, the CCS type has only this value. */
251     return HITLS_SUCCESS;
252 }
253 
GetdefaultAlertMsg(FRAME_Type * frameType,FRAME_Msg * msg)254 static int32_t GetdefaultAlertMsg(FRAME_Type *frameType, FRAME_Msg *msg)
255 {
256     SetDefaultRecordHeader(frameType, msg, REC_TYPE_ALERT); /* Setting the Default Record Header */
257     msg->body.alertMsg.alertLevel.state = INITIAL_FIELD;
258     /*Default value. You can change the default value as required. */
259     msg->body.alertMsg.alertLevel.data = ALERT_LEVEL_FATAL;
260     msg->body.alertMsg.alertDescription.state = INITIAL_FIELD;
261      /*Default value. You can change the default value as required. */
262     msg->body.alertMsg.alertDescription.data = ALERT_HANDSHAKE_FAILURE;
263     return HITLS_SUCCESS;
264 }
265 
FRAME_GetDefaultMsg(FRAME_Type * frameType,FRAME_Msg * msg)266 int32_t FRAME_GetDefaultMsg(FRAME_Type *frameType, FRAME_Msg *msg)
267 {
268     if ((frameType == NULL) || (msg == NULL)) {
269         return HITLS_INTERNAL_EXCEPTION;
270     }
271 
272     switch (frameType->recordType) {
273         case REC_TYPE_HANDSHAKE:
274             return GetdefaultHsMsg(frameType, msg);
275         case REC_TYPE_CHANGE_CIPHER_SPEC:
276             return GetdefaultCcsMsg(frameType, msg);
277         case REC_TYPE_ALERT:
278             return GetdefaultAlertMsg(frameType, msg);
279         default:
280             break;
281     }
282     return HITLS_INTERNAL_EXCEPTION;
283 }
284 
FRAME_ModifyMsgInteger(const uint64_t data,FRAME_Integer * frameInteger)285 int32_t FRAME_ModifyMsgInteger(const uint64_t data, FRAME_Integer *frameInteger)
286 {
287     if (frameInteger == NULL) {
288         return HITLS_INTERNAL_EXCEPTION;
289     }
290 
291     frameInteger->state = ASSIGNED_FIELD;
292     frameInteger->data = data;
293     return HITLS_SUCCESS;
294 }
295 
FRAME_ModifyMsgArray8(const uint8_t * data,uint32_t dataLen,FRAME_Array8 * frameArray,FRAME_Integer * frameArrayLen)296 int32_t FRAME_ModifyMsgArray8(const uint8_t *data, uint32_t dataLen,
297                               FRAME_Array8 *frameArray, FRAME_Integer *frameArrayLen)
298 {
299     if ((data == NULL) || (frameArray == NULL) || (dataLen == 0)) {
300         return HITLS_INTERNAL_EXCEPTION;
301     }
302     BSL_SAL_FREE(frameArray->data); /* Clear the old memory. */
303 
304     frameArray->data = BSL_SAL_Dump(data, dataLen);
305     if (frameArray->data == NULL) {
306         return HITLS_MEMALLOC_FAIL;
307     }
308     frameArray->state = ASSIGNED_FIELD;
309     frameArray->size = dataLen;
310 
311     if (frameArrayLen != NULL) {
312         frameArrayLen->state = ASSIGNED_FIELD;
313         frameArrayLen->data = dataLen;
314     }
315 
316     return HITLS_SUCCESS;
317 }
318 
FRAME_AppendMsgArray8(const uint8_t * data,uint32_t dataLen,FRAME_Array8 * frameArray,FRAME_Integer * frameArrayLen)319 int32_t FRAME_AppendMsgArray8(const uint8_t *data, uint32_t dataLen,
320                               FRAME_Array8 *frameArray, FRAME_Integer *frameArrayLen)
321 {
322     if ((data == NULL) || (frameArray == NULL) || (dataLen == 0)) {
323         return HITLS_INTERNAL_EXCEPTION;
324     }
325 
326     /* extended memory */
327     uint32_t newDataLen = dataLen + frameArray->size;
328     uint8_t *newData = (uint8_t *)BSL_SAL_Calloc(1u, newDataLen);
329     if (newData == NULL) {
330         return HITLS_MEMALLOC_FAIL;
331     }
332     if (memcpy_s(newData, newDataLen, frameArray->data, frameArray->size) != EOK) {
333         BSL_SAL_FREE(newData);
334         return HITLS_MEMCPY_FAIL;
335     }
336     if (memcpy_s(&newData[frameArray->size], newDataLen - frameArray->size, data, dataLen) != EOK) {
337         BSL_SAL_FREE(newData);
338         return HITLS_MEMCPY_FAIL;
339     }
340 
341     BSL_SAL_FREE(frameArray->data); /* Clear the old memory. */
342     frameArray->state = ASSIGNED_FIELD;
343     frameArray->data = newData;
344     frameArray->size = newDataLen;
345 
346     if (frameArrayLen != NULL) {
347         frameArrayLen->state = ASSIGNED_FIELD;
348         frameArrayLen->data = newDataLen;
349     }
350 
351     return HITLS_SUCCESS;
352 }
353 
FRAME_ModifyMsgArray16(const uint16_t * data,uint32_t dataLen,FRAME_Array16 * frameArray,FRAME_Integer * frameArrayLen)354 int32_t FRAME_ModifyMsgArray16(const uint16_t *data, uint32_t dataLen,
355                                FRAME_Array16 *frameArray, FRAME_Integer *frameArrayLen)
356 {
357     if ((data == NULL) || (frameArray == NULL) || (dataLen == 0)) {
358         return HITLS_INTERNAL_EXCEPTION;
359     }
360     BSL_SAL_FREE(frameArray->data); /* Clear the old memory. */
361 
362     frameArray->data = (uint16_t *)BSL_SAL_Dump(data, dataLen * sizeof(uint16_t));
363     if (frameArray->data == NULL) {
364         return HITLS_MEMALLOC_FAIL;
365     }
366     frameArray->state = ASSIGNED_FIELD;
367     frameArray->size = dataLen;
368 
369     if (frameArrayLen != NULL) {
370         frameArrayLen->state = ASSIGNED_FIELD;
371         frameArrayLen->data = dataLen * sizeof(uint16_t);
372     }
373 
374     return HITLS_SUCCESS;
375 }
376 
FRAME_AppendMsgArray16(const uint16_t * data,uint32_t dataLen,FRAME_Array16 * frameArray,FRAME_Integer * frameArrayLen)377 int32_t FRAME_AppendMsgArray16(const uint16_t *data, uint32_t dataLen,
378                                FRAME_Array16 *frameArray, FRAME_Integer *frameArrayLen)
379 {
380     if ((data == NULL) || (frameArray == NULL) || (dataLen == 0)) {
381         return HITLS_INTERNAL_EXCEPTION;
382     }
383 
384     /* extended memory */
385     uint32_t newDataLen = (frameArray->size + dataLen) * sizeof(uint16_t); /* Data length */
386     uint16_t *newData = (uint16_t *)BSL_SAL_Calloc(1u, newDataLen);
387     if (newData == NULL) {
388         return HITLS_MEMALLOC_FAIL;
389     }
390     for (uint32_t i = 0; i < frameArray->size; i++) {
391         newData[i] = frameArray->data[i];
392     }
393     for (uint32_t i = 0; i < dataLen; i++) {
394         newData[frameArray->size + i] = data[i];
395     }
396 
397     BSL_SAL_FREE(frameArray->data); /* Clear the old memory. */
398     frameArray->state = ASSIGNED_FIELD;
399     frameArray->data = newData;
400     frameArray->size = newDataLen / sizeof(uint16_t); /* Number of data records */
401 
402     if (frameArrayLen != NULL) {
403         frameArrayLen->state = ASSIGNED_FIELD;
404         frameArrayLen->data = newDataLen;
405     }
406 
407     return HITLS_SUCCESS;
408 }
409