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