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 "hitls_build.h"
17 #include "hitls_error.h"
18 #include "bsl_err_internal.h"
19 #include "tls_binlog_id.h"
20 #include "bsl_log_internal.h"
21 #include "hitls_type.h"
22 #include "tls.h"
23 #include "rec.h"
24 #include "alert.h"
25 #include "app.h"
26 #include "conn_common.h"
27 #include "hs.h"
28 #include "hs_msg.h"
29 #include "hs_common.h"
30 #include "hs_ctx.h"
31 #include "crypt.h"
32 #include "hs_state_recv.h"
33 #include "bsl_bytes.h"
34 #include "hs_dtls_timer.h"
35
36 #define HS_MESSAGE_LEN_FIELD 3u
ReadEventInIdleState(HITLS_Ctx * ctx,uint8_t * data,uint32_t bufSize,uint32_t * readLen)37 static int32_t ReadEventInIdleState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen)
38 {
39 (void)ctx;
40 (void)data;
41 (void)bufSize;
42 (void)readLen;
43 return HITLS_CM_LINK_UNESTABLISHED;
44 }
45
RecvUnexpectMsgInTransportingStateProcess(HITLS_Ctx * ctx)46 int32_t RecvUnexpectMsgInTransportingStateProcess(HITLS_Ctx *ctx)
47 {
48 if (ctx->state == CM_STATE_HANDSHAKING) {
49 return CommonEventInHandshakingState(ctx);
50 }
51 #ifdef HITLS_TLS_FEATURE_RENEGOTIATION
52 if (ctx->state == CM_STATE_RENEGOTIATION) {
53 int32_t ret = CommonEventInRenegotiationState(ctx);
54 if (ret == HITLS_SUCCESS) {
55 /* The renegotiation initiated by the peer is processed and returned. */
56 return ret;
57 }
58 if (ret != HITLS_REC_NORMAL_RECV_UNEXPECT_MSG) {
59 /* If an error is returned during renegotiation, the error code must be sent to the user */
60 return ret;
61 }
62 if (ctx->state == CM_STATE_ALERTED) {
63 /* If the alert message has been processed, the link must be disconnected */
64 return ret;
65 }
66 }
67 #endif
68 return HITLS_SUCCESS;
69 }
RecvRenegoReqPreprocess(TLS_Ctx * ctx,uint8_t type)70 static int32_t RecvRenegoReqPreprocess(TLS_Ctx *ctx, uint8_t type)
71 {
72 /* If the version is TLS1.3, ignore the message */
73 if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) {
74 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16514, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
75 "tls13 not support Renegotiation", 0, 0, 0, 0);
76 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
77 return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE;
78 }
79
80 /* If the message is not a renegotiation request, ignore the message */
81 if ((ctx->isClient && (type == CLIENT_HELLO)) ||
82 (!ctx->isClient && (type == HELLO_REQUEST))) {
83 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16515, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
84 "ignore the message", 0, 0, 0, 0);
85 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
86 return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE;
87 }
88 /* if client renegotiate is not allowed, send no renegotiate alert, change state to CM_STATE_HANDSHAKING to
89 finish this process */
90 if (type == CLIENT_HELLO && !ctx->config.tlsConfig.allowClientRenegotiate && !ctx->userRenego) {
91 ChangeConnState(ctx, CM_STATE_HANDSHAKING);
92 (void)HS_ChangeState(ctx, TRY_RECV_CLIENT_HELLO);
93 return HITLS_SUCCESS;
94 }
95 /* Renegotiation request is processed only after security renegotiation is negotiated. Otherwise, no renegotiation
96 * alert is generated and the peer determines whether to disconnect the link */
97 if (!ctx->negotiatedInfo.isSecureRenegotiation || !ctx->config.tlsConfig.isSupportRenegotiation) {
98 if (type == HELLO_REQUEST) {
99 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16516, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
100 "not support Renegotiation", 0, 0, 0, 0);
101 ctx->method.sendAlert(ctx, ALERT_LEVEL_WARNING, ALERT_NO_RENEGOTIATION);
102 return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
103 } else {
104 ChangeConnState(ctx, CM_STATE_HANDSHAKING);
105 (void)HS_ChangeState(ctx, TRY_RECV_CLIENT_HELLO);
106 return HITLS_SUCCESS;
107 }
108 }
109
110 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
111 REC_RetransmitListClean(ctx->recCtx); /* dtls over udp scenario, the retransmission queue needs to be cleared */
112 #endif
113 ChangeConnState(ctx, CM_STATE_RENEGOTIATION);
114 if (type == CLIENT_HELLO) {
115 // When the server start renegotiation, it sends a hello request message first, and the value of
116 // nextSendSeq increases to 1. Then, the hsctx is released and the nextSendSeq is reset to 0.
117 // Therefore, the value of nextSendSeq should return to 1 when sending server hello.
118 #ifdef HITLS_TLS_PROTO_DTLS12
119 if (ctx->userRenego && IS_DTLS_VERSION(ctx->negotiatedInfo.version)) {
120 ctx->hsCtx->nextSendSeq++;
121 }
122 #endif
123 (void)HS_ChangeState(ctx, TRY_RECV_CLIENT_HELLO);
124 } else {
125 (void)HS_ChangeState(ctx, TRY_RECV_HELLO_REQUEST);
126 }
127 return HITLS_SUCCESS;
128 }
129
RecvKeyUpdatePreprocess(TLS_Ctx * ctx)130 static int32_t RecvKeyUpdatePreprocess(TLS_Ctx *ctx)
131 {
132 if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) {
133 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16517, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
134 "negotiatedInfo version is not tls13", 0, 0, 0, 0);
135 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
136 return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
137 }
138 ChangeConnState(ctx, CM_STATE_HANDSHAKING);
139 return HS_ChangeState(ctx, TRY_RECV_KEY_UPDATE);
140 }
141
RecvCertReqPreprocess(TLS_Ctx * ctx)142 static int32_t RecvCertReqPreprocess(TLS_Ctx *ctx)
143 {
144 if (ctx->state != CM_STATE_TRANSPORTING || ctx->phaState != PHA_EXTENSION ||
145 !ctx->isClient || ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) {
146 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16518, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
147 "ctx state err", 0, 0, 0, 0);
148 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
149 return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE;
150 };
151
152 SAL_CRYPT_DigestFree(ctx->hsCtx->verifyCtx->hashCtx);
153 ctx->hsCtx->verifyCtx->hashCtx = SAL_CRYPT_DigestCopy(ctx->phaHash);
154 if (ctx->hsCtx->verifyCtx->hashCtx == NULL) {
155 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16178, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
156 "pha hash copy error: digest copy fail.", 0, 0, 0, 0);
157 return HITLS_CRYPT_ERR_DIGEST;
158 }
159 ctx->phaState = PHA_REQUESTED;
160 ChangeConnState(ctx, CM_STATE_HANDSHAKING);
161 return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE_REQUEST);
162 }
163
RecvCertPreprocess(TLS_Ctx * ctx)164 static int32_t RecvCertPreprocess(TLS_Ctx *ctx)
165 {
166 if (ctx->state != CM_STATE_TRANSPORTING || ctx->phaState != PHA_REQUESTED ||
167 ctx->isClient || ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) {
168 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16519, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
169 "ctx state err", 0, 0, 0, 0);
170 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
171 return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE;
172 }
173
174 ctx->hsCtx->verifyCtx->hashCtx = ctx->phaCurHash;
175 ctx->phaCurHash = NULL;
176
177 ChangeConnState(ctx, CM_STATE_HANDSHAKING);
178 return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE);
179 }
180
RecvNSTPreprocess(TLS_Ctx * ctx)181 static int32_t RecvNSTPreprocess(TLS_Ctx *ctx)
182 {
183 if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13 || ctx->isClient == false) {
184 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16520, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
185 "version err or it is server", 0, 0, 0, 0);
186 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
187 return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
188 }
189 ChangeConnState(ctx, CM_STATE_HANDSHAKING);
190 return HS_ChangeState(ctx, TRY_RECV_NEW_SESSION_TICKET);
191 }
192
193 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
RecvPostFinishPreprocess(TLS_Ctx * ctx)194 static int32_t RecvPostFinishPreprocess(TLS_Ctx *ctx)
195 {
196 if (!IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
197 BSL_LOG_BINLOG_VARLEN(BINLOG_ID16131, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
198 "Unexpected %s handshake state message.", HS_GetMsgTypeStr(ctx->hsCtx->msgBuf[0]));
199 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
200 return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE;
201 }
202 bool isTimeout = false;
203
204 if (!BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
205 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16521, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
206 "GetUioChainTransportType fail", 0, 0, 0, 0);
207 return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
208 }
209
210 if (HS_IsTimeout(ctx, &isTimeout) != HITLS_SUCCESS || isTimeout) {
211 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16522, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
212 "HS_IsTimeout fail or timeout", 0, 0, 0, 0);
213 REC_RetransmitListClean(ctx->recCtx);
214 HS_DeInit(ctx);
215 return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
216 }
217 if ((ctx->isClient && !ctx->negotiatedInfo.isResume) || (!ctx->isClient && ctx->negotiatedInfo.isResume)) {
218 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16523, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
219 "RecvPostFinishPreprocess fail", 0, 0, 0, 0);
220 return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
221 }
222
223 ChangeConnState(ctx, CM_STATE_HANDSHAKING);
224 return HS_ChangeState(ctx, TRY_RECV_FINISH);
225 }
226 #endif
227
PreprocessUnexpectHsMsg(HITLS_Ctx * ctx)228 static int32_t PreprocessUnexpectHsMsg(HITLS_Ctx *ctx)
229 {
230 if (ctx->hsCtx != NULL) {
231 HS_DeInit(ctx);
232 }
233 int32_t ret = HS_Init(ctx);
234 if (ret != HITLS_SUCCESS) {
235 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15977, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
236 "HS_Init fail when receive unexpected handshake message.", 0, 0, 0, 0);
237 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
238 return ret;
239 }
240 // get the handshake message type
241 ret = ReadHsMessage(ctx, 1);
242 if (ret != HITLS_SUCCESS) {
243 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16524, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
244 "ReadHsMessage fail", 0, 0, 0, 0);
245 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
246 return ret;
247 }
248
249 HS_Ctx *hsCtx = ctx->hsCtx;
250 switch (hsCtx->msgBuf[0]) {
251 case HELLO_REQUEST:
252 case CLIENT_HELLO:
253 ret = RecvRenegoReqPreprocess(ctx, hsCtx->msgBuf[0]);
254 break;
255 case KEY_UPDATE:
256 ret = RecvKeyUpdatePreprocess(ctx);
257 break;
258 case CERTIFICATE_REQUEST:
259 ret = RecvCertReqPreprocess(ctx);
260 break;
261 case CERTIFICATE:
262 ret = RecvCertPreprocess(ctx);
263 break;
264 case NEW_SESSION_TICKET:
265 ret = RecvNSTPreprocess(ctx);
266 break;
267 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
268 case FINISHED:
269 ret = RecvPostFinishPreprocess(ctx);
270 break;
271 #endif
272 default:
273 BSL_LOG_BINLOG_VARLEN(BINLOG_ID16529, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
274 "Unexpected %s handshake state message.", HS_GetMsgTypeStr(hsCtx->msgBuf[0]));
275 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
276 ret = HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE;
277 }
278 return ret;
279 }
280
ConsumeHandshakeMessage(HITLS_Ctx * ctx)281 static void ConsumeHandshakeMessage(HITLS_Ctx *ctx)
282 {
283 bool isDtls = IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask);
284 uint32_t headerLen = isDtls ? DTLS_HS_MSG_HEADER_SIZE : HS_MSG_HEADER_SIZE;
285 int32_t ret = ReadHsMessage(ctx, headerLen);
286 if (ret != HITLS_SUCCESS) {
287 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16525, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
288 "ReadHsMessage fail", 0, 0, 0, 0);
289 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
290 return;
291 }
292 uint32_t length = BSL_ByteToUint24(&ctx->hsCtx->msgBuf[headerLen - HS_MESSAGE_LEN_FIELD]);
293 ret = ReadHsMessage(ctx, length + headerLen);
294 if (ret != HITLS_SUCCESS) {
295 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16526, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
296 "ReadHsMessage fail", 0, 0, 0, 0);
297 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
298 return;
299 }
300 }
301
ReadEventInTransportingState(HITLS_Ctx * ctx,uint8_t * data,uint32_t bufSize,uint32_t * readLen)302 static int32_t ReadEventInTransportingState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen)
303 {
304 int32_t ret = 0;
305 int32_t unexpectMsgRet = 0;
306
307 do {
308 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
309 /* In UDP scenarios, the 2MSL timer expires */
310 ret = HS_CheckAndProcess2MslTimeout(ctx);
311 if (ret != HITLS_SUCCESS) {
312 return ret;
313 }
314 #endif
315 ret = APP_Read(ctx, data, bufSize, readLen);
316 if (ret == HITLS_SUCCESS) {
317 if ((!ctx->negotiatedInfo.isRenegotiation) && (ctx->hsCtx != NULL)) {
318 HS_DeInit(ctx);
319 }
320 /* An APP message is received */
321 break;
322 }
323
324 if (ret == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG && REC_GetUnexpectedMsgType(ctx) == REC_TYPE_HANDSHAKE) {
325 unexpectMsgRet = PreprocessUnexpectHsMsg(ctx);
326 if (unexpectMsgRet != HITLS_SUCCESS) {
327 ConsumeHandshakeMessage(ctx);
328 HS_DeInit(ctx);
329 ret = unexpectMsgRet;
330 }
331 }
332
333 if (ALERT_GetFlag(ctx)) {
334 #ifdef HITLS_TLS_FEATURE_RENEGOTIATION
335 /* After the server sends a hello request, the status changes to transporting. In this case, the read
336 command is used to read the message. If the no_renegotiation alert is received, the connection
337 needs to be disconnected. */
338 if (ctx->userRenego) {
339 InnerRenegotiationProcess(ctx);
340 }
341 #endif
342 if (ALERT_HaveExceeded(ctx, MAX_ALERT_COUNT)) {
343 /* If multiple consecutive alerts exist, the link is abnormal and needs to be disconnected */
344 ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
345 }
346
347 unexpectMsgRet = AlertEventProcess(ctx);
348 if (unexpectMsgRet != HITLS_SUCCESS) {
349 /* If the alert fails to be sent, a response is returned to the user for processing */
350 return unexpectMsgRet;
351 }
352
353 /* If fatal alert or close_notify has been processed, the link must be disconnected */
354 if (ctx->state == CM_STATE_ALERTED || ctx->state == CM_STATE_CLOSED) {
355 return ret;
356 }
357 continue;
358 }
359
360 if (ret != HITLS_REC_NORMAL_RECV_UNEXPECT_MSG) {
361 return ret;
362 }
363
364 unexpectMsgRet = RecvUnexpectMsgInTransportingStateProcess(ctx);
365 if (unexpectMsgRet != HITLS_SUCCESS) {
366 return unexpectMsgRet;
367 }
368 } while (ret != HITLS_SUCCESS);
369
370 return ret;
371 }
372
ReadEventInHandshakingState(HITLS_Ctx * ctx,uint8_t * data,uint32_t bufSize,uint32_t * readLen)373 static int32_t ReadEventInHandshakingState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen)
374 {
375 int32_t ret = CommonEventInHandshakingState(ctx);
376 if (ret != HITLS_SUCCESS) {
377 return ret;
378 }
379
380 return ReadEventInTransportingState(ctx, data, bufSize, readLen);
381 }
382
ReadEventInRenegotiationState(HITLS_Ctx * ctx,uint8_t * data,uint32_t bufSize,uint32_t * readLen)383 static int32_t ReadEventInRenegotiationState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen)
384 {
385 #ifdef HITLS_TLS_FEATURE_RENEGOTIATION
386 int32_t ret = CommonEventInRenegotiationState(ctx);
387 if (ret != HITLS_SUCCESS) {
388 if (ret != HITLS_REC_NORMAL_RECV_UNEXPECT_MSG || ctx->state == CM_STATE_ALERTED) {
389 /* If an error is returned during the renegotiation, the error code must be sent to the user */
390 return ret;
391 }
392 /* The scenario is that the HITLS initiates renegotiation, but the peer end does not respond with a handshake
393 * message and continues to send the app message. In this case, you need to read the app message to prevent
394 * message blocking.
395 */
396 ret = APP_Read(ctx, data, bufSize, readLen);
397 return ret;
398 }
399
400 return ReadEventInTransportingState(ctx, data, bufSize, readLen);
401 #else
402 (void)ctx;
403 (void)data;
404 (void)bufSize;
405 (void)readLen;
406 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15407, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN,
407 "invalid conn states %d", CM_STATE_RENEGOTIATION, NULL, NULL, NULL);
408 return HITLS_INTERNAL_EXCEPTION;
409 #endif
410 }
411
ReadEventInAlertedState(HITLS_Ctx * ctx,uint8_t * data,uint32_t bufSize,uint32_t * readLen)412 static int32_t ReadEventInAlertedState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen)
413 {
414 (void)ctx;
415 (void)data;
416 (void)bufSize;
417 (void)readLen;
418 // A message indicating that the link status is abnormal is displayed.
419 return HITLS_CM_LINK_FATAL_ALERTED;
420 }
421
ReadEventInClosedState(HITLS_Ctx * ctx,uint8_t * data,uint32_t bufSize,uint32_t * readLen)422 static int32_t ReadEventInClosedState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen)
423 {
424 // Non-closed state
425 if ((ctx->shutdownState & HITLS_RECEIVED_SHUTDOWN) == 0) {
426 ALERT_CleanInfo(ctx);
427 int32_t ret = APP_Read(ctx, data, bufSize, readLen);
428 if (ret == HITLS_SUCCESS) {
429 return HITLS_SUCCESS;
430 }
431 // There is no alert message to be processed.
432 if (ALERT_GetFlag(ctx) == false) {
433 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16531, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Read fail", 0, 0, 0, 0);
434 return ret;
435 }
436
437 int32_t alertRet = AlertEventProcess(ctx);
438 if (alertRet != HITLS_SUCCESS) {
439 return alertRet;
440 }
441 /* Other warning alerts have been processed. */
442 if ((ctx->shutdownState & HITLS_RECEIVED_SHUTDOWN) == 0) {
443 return ret;
444 }
445 }
446 // Directly return to link closed.
447 return HITLS_CM_LINK_CLOSED;
448 }
ReadProcess(HITLS_Ctx * ctx,uint8_t * data,uint32_t bufSize,uint32_t * readLen)449 static int32_t ReadProcess(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen)
450 {
451 ReadEventProcess readEventProcess[CM_STATE_END] = {
452 ReadEventInIdleState,
453 ReadEventInHandshakingState,
454 ReadEventInTransportingState,
455 ReadEventInRenegotiationState,
456 NULL,
457 ReadEventInAlertedState,
458 ReadEventInClosedState
459 };
460
461 if ((GetConnState(ctx) >= CM_STATE_END) || (GetConnState(ctx) == CM_STATE_ALERTING)) {
462 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16532, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
463 "internal exception occurs", 0, 0, 0, 0);
464 /* If the alert message is sent successfully, the system switches to another state. Otherwise, an internal
465 * exception occurs */
466 return HITLS_INTERNAL_EXCEPTION;
467 }
468
469 ReadEventProcess proc = readEventProcess[GetConnState(ctx)];
470 return proc(ctx, data, bufSize, readLen);
471 }
472
HITLS_Read(HITLS_Ctx * ctx,uint8_t * data,uint32_t bufSize,uint32_t * readLen)473 int32_t HITLS_Read(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen)
474 {
475 int32_t ret;
476 if (ctx == NULL || data == NULL || readLen == NULL) {
477 return HITLS_NULL_INPUT;
478 }
479 ctx->allowAppOut = true;
480 /* Process the unsent alert message first, and then enter the corresponding state processing function based on the
481 * processing result */
482 if (GetConnState(ctx) == CM_STATE_ALERTING) {
483 ret = CommonEventInAlertingState(ctx);
484 if (ret != HITLS_SUCCESS) {
485 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16533, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
486 "Alerting fail", 0, 0, 0, 0);
487 /* If the alert message fails to be sent, the system returns the message to the user for processing */
488 return ret;
489 }
490 }
491
492 return ReadProcess(ctx, data, bufSize, readLen);
493 }
494
HITLS_Peek(HITLS_Ctx * ctx,uint8_t * data,uint32_t bufSize,uint32_t * readLen)495 int32_t HITLS_Peek(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen)
496 {
497 if (ctx == NULL) {
498 return HITLS_NULL_INPUT;
499 }
500 ctx->peekFlag = 1;
501 int32_t ret = HITLS_Read(ctx, data, bufSize, readLen);
502 ctx->peekFlag = 0;
503 return ret;
504 }
505
HITLS_ReadHasPending(const HITLS_Ctx * ctx,uint8_t * isPending)506 int32_t HITLS_ReadHasPending(const HITLS_Ctx *ctx, uint8_t *isPending)
507 {
508 if (ctx == NULL || isPending == NULL) {
509 return HITLS_NULL_INPUT;
510 }
511
512 *isPending = APP_GetReadPendingBytes(ctx) > 0 || REC_ReadHasPending(ctx) ? 1 : 0;
513
514 return HITLS_SUCCESS;
515 }
516
HITLS_GetReadPendingBytes(const HITLS_Ctx * ctx)517 uint32_t HITLS_GetReadPendingBytes(const HITLS_Ctx *ctx)
518 {
519 return APP_GetReadPendingBytes(ctx);
520 }
521