• 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 "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