• 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 #include "hitls_build.h"
16 #include "securec.h"
17 #include "tls_binlog_id.h"
18 #include "bsl_log_internal.h"
19 #include "bsl_log.h"
20 #include "bsl_err_internal.h"
21 #include "hitls_error.h"
22 #include "hitls.h"
23 #include "rec.h"
24 #include "tls.h"
25 #include "hs.h"
26 #include "hs_ctx.h"
27 #include "hs_common.h"
28 #include "parse.h"
29 #include "hs_state_recv.h"
30 #include "hs_state_send.h"
31 #include "bsl_errno.h"
32 #include "bsl_uio.h"
33 #include "uio_base.h"
34 #ifdef HITLS_TLS_FEATURE_INDICATOR
35 #include "indicator.h"
36 #endif /* HITLS_TLS_FEATURE_INDICATOR */
37 #include "transcript_hash.h"
38 #include "recv_process.h"
39 #include "hs_dtls_timer.h"
40 
HandshakeDone(TLS_Ctx * ctx)41 static int32_t HandshakeDone(TLS_Ctx *ctx)
42 {
43     (void)ctx;
44     int32_t ret = HITLS_SUCCESS;
45 #ifdef HITLS_TLS_FEATURE_FLIGHT
46     /* If isFlightTransmitEnable is enabled, the server CCS and Finish information stored in the bUio must be sent after
47      * the handshake is complete */
48     if (ctx->config.tlsConfig.isFlightTransmitEnable) {
49         ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL);
50         if (ret == BSL_UIO_IO_BUSY) {
51             return HITLS_REC_NORMAL_IO_BUSY;
52         }
53         if (ret != BSL_SUCCESS) {
54             BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_IO_EXCEPTION);
55             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16109, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
56                 "fail to send the CCS and Finish message of server in bUio.", 0, 0, 0, 0);
57             return HITLS_REC_ERR_IO_EXCEPTION;
58         }
59     }
60 #endif /* HITLS_TLS_FEATURE_FLIGHT */
61 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_SCTP)
62 
63     if (!BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_SCTP)) {
64         return HITLS_SUCCESS;
65     }
66 
67     bool isBuffEmpty = false;
68     ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_SCTP_SND_BUFF_IS_EMPTY, sizeof(isBuffEmpty), &isBuffEmpty);
69     if (ret != BSL_SUCCESS) {
70         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17188, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN,
71             "SCTP_SND_BUFF_IS_EMPTY fail, ret %d", ret, 0, 0, 0);
72         return HITLS_UIO_SCTP_IS_SND_BUF_EMPTY_FAIL;
73     }
74 
75     if (isBuffEmpty != true) {
76         return HITLS_REC_NORMAL_IO_BUSY;
77     }
78 
79     // This branch is entered only when the hello request is just sent.
80     if (!ctx->negotiatedInfo.isRenegotiation && ctx->userRenego) {
81         return HITLS_SUCCESS;
82     }
83 
84     ret = HS_ActiveSctpAuthKey(ctx);
85     if (ret != HITLS_SUCCESS) {
86         return ret;
87     }
88 
89     ret = HS_DeletePreviousSctpAuthKey(ctx);
90 #endif /* HITLS_TLS_PROTO_DTLS12 && HITLS_BSL_UIO_SCTP */
91 
92     return ret;
93 }
94 
IsHsSendState(HITLS_HandshakeState state)95 static bool IsHsSendState(HITLS_HandshakeState state)
96 {
97     switch (state) {
98         case TRY_SEND_HELLO_REQUEST:
99         case TRY_SEND_CLIENT_HELLO:
100         case TRY_SEND_HELLO_RETRY_REQUEST:
101         case TRY_SEND_SERVER_HELLO:
102         case TRY_SEND_HELLO_VERIFY_REQUEST:
103         case TRY_SEND_ENCRYPTED_EXTENSIONS:
104         case TRY_SEND_CERTIFICATE:
105         case TRY_SEND_SERVER_KEY_EXCHANGE:
106         case TRY_SEND_CERTIFICATE_REQUEST:
107         case TRY_SEND_SERVER_HELLO_DONE:
108         case TRY_SEND_CLIENT_KEY_EXCHANGE:
109         case TRY_SEND_CERTIFICATE_VERIFY:
110         case TRY_SEND_NEW_SESSION_TICKET:
111         case TRY_SEND_CHANGE_CIPHER_SPEC:
112         case TRY_SEND_END_OF_EARLY_DATA:
113         case TRY_SEND_FINISH:
114         case TRY_SEND_KEY_UPDATE:
115             return true;
116         default:
117             break;
118     }
119 
120     return false;
121 }
122 
IsHsRecvState(HITLS_HandshakeState state)123 static bool IsHsRecvState(HITLS_HandshakeState state)
124 {
125     switch (state) {
126         case TRY_RECV_CLIENT_HELLO:
127         case TRY_RECV_SERVER_HELLO:
128         case TRY_RECV_HELLO_VERIFY_REQUEST:
129         case TRY_RECV_ENCRYPTED_EXTENSIONS:
130         case TRY_RECV_CERTIFICATE:
131         case TRY_RECV_SERVER_KEY_EXCHANGE:
132         case TRY_RECV_CERTIFICATE_REQUEST:
133         case TRY_RECV_SERVER_HELLO_DONE:
134         case TRY_RECV_CLIENT_KEY_EXCHANGE:
135         case TRY_RECV_CERTIFICATE_VERIFY:
136         case TRY_RECV_NEW_SESSION_TICKET:
137         case TRY_RECV_END_OF_EARLY_DATA:
138         case TRY_RECV_FINISH:
139         case TRY_RECV_KEY_UPDATE:
140         case TRY_RECV_HELLO_REQUEST:
141             return true;
142         default:
143             break;
144     }
145 
146     return false;
147 }
148 
HS_DoHandshake(TLS_Ctx * ctx)149 int32_t HS_DoHandshake(TLS_Ctx *ctx)
150 {
151     int32_t ret = HITLS_SUCCESS;
152     HS_Ctx *hsCtx = ctx->hsCtx;
153 #ifdef HITLS_TLS_FEATURE_INDICATOR
154     int32_t eventType = (ctx->isClient) ? INDICATE_EVENT_STATE_CONNECT_EXIT : INDICATE_EVENT_STATE_ACCEPT_EXIT;
155 #endif /* HITLS_TLS_FEATURE_INDICATOR */
156     while (hsCtx->state != TLS_CONNECTED) {
157         if (IsHsSendState(hsCtx->state)) {
158             ret = HS_SendMsgProcess(ctx);
159         } else if (IsHsRecvState(hsCtx->state)) {
160             ret = HS_RecvMsgProcess(ctx);
161         } else {
162             BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_STATE_ILLEGAL);
163             BSL_LOG_BINLOG_VARLEN(BINLOG_ID15884, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
164                 "Handshake state unable to process, current state is %s.", HS_GetStateStr(hsCtx->state));
165             ret = HITLS_MSG_HANDLE_STATE_ILLEGAL;
166         }
167 
168         if (ret != HITLS_SUCCESS) {
169 #ifdef HITLS_TLS_FEATURE_INDICATOR
170             INDICATOR_StatusIndicate(ctx, eventType, ret);
171 #endif /* HITLS_TLS_FEATURE_INDICATOR */
172             return ret;
173         }
174     }
175 #ifdef HITLS_TLS_FEATURE_INDICATOR
176     INDICATOR_StatusIndicate(ctx, INDICATE_EVENT_HANDSHAKE_DONE, INDICATE_VALUE_SUCCESS);
177 #endif /* HITLS_TLS_FEATURE_INDICATOR */
178 
179     ret = HandshakeDone(ctx);
180     if (ret != HITLS_SUCCESS) {
181 #ifdef HITLS_TLS_FEATURE_INDICATOR
182         INDICATOR_StatusIndicate(ctx, eventType, ret);
183 #endif /* HITLS_TLS_FEATURE_INDICATOR */
184         return ret;
185     }
186 #ifdef HITLS_TLS_FEATURE_INDICATOR
187     INDICATOR_StatusIndicate(ctx, eventType, INDICATE_VALUE_SUCCESS);
188 #endif /* HITLS_TLS_FEATURE_INDICATOR */
189     return HITLS_SUCCESS;
190 }
191 
192 #ifdef HITLS_TLS_FEATURE_KEY_UPDATE
HS_CheckKeyUpdateState(TLS_Ctx * ctx,uint32_t updateType)193 int32_t HS_CheckKeyUpdateState(TLS_Ctx *ctx, uint32_t updateType)
194 {
195     if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) {
196         return HITLS_MSG_HANDLE_UNSUPPORT_VERSION;
197     }
198 
199     if (ctx->state != CM_STATE_TRANSPORTING) {
200         return HITLS_MSG_HANDLE_STATE_ILLEGAL;
201     }
202 
203     if (updateType != HITLS_UPDATE_REQUESTED && updateType != HITLS_UPDATE_NOT_REQUESTED) {
204         return HITLS_MSG_HANDLE_ILLEGAL_KEY_UPDATE_TYPE;
205     }
206 
207     return HITLS_SUCCESS;
208 }
209 
210 #endif /* HITLS_TLS_FEATURE_KEY_UPDATE */
211 
212 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
HS_CheckAndProcess2MslTimeout(TLS_Ctx * ctx)213 int32_t HS_CheckAndProcess2MslTimeout(TLS_Ctx *ctx)
214 {
215     /* In non-UDP scenarios, the 2MSL timer timeout does not need to be checked */
216     if ((ctx->hsCtx == NULL) || !BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
217         return HITLS_SUCCESS;
218     }
219 
220     bool isTimeout = false;
221     int32_t ret = HS_IsTimeout(ctx, &isTimeout);
222     if (ret != HITLS_SUCCESS) {
223         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17189, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
224             "HS_IsTimeout fail", 0, 0, 0, 0);
225         return ret;
226     }
227 
228     /* If the retransmission queue times out, the retransmission queue is cleared and the hsCtx memory is released */
229     if (isTimeout) {
230         REC_RetransmitListClean(ctx->recCtx);
231         HS_DeInit(ctx);
232     }
233     return HITLS_SUCCESS;
234 }
235 #endif /* HITLS_TLS_PROTO_DTLS12 && HITLS_BSL_UIO_UDP */
236 
237 #ifdef HITLS_TLS_FEATURE_PHA
HS_CheckPostHandshakeAuth(TLS_Ctx * ctx)238 int32_t HS_CheckPostHandshakeAuth(TLS_Ctx *ctx)
239 {
240     int32_t ret = HS_Init(ctx);
241     if (ret != HITLS_SUCCESS) {
242         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17190, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
243             "CONN_Init fail", 0, 0, 0, 0);
244         return ret;
245     }
246     HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_REQUEST);
247     SAL_CRYPT_DigestFree(ctx->hsCtx->verifyCtx->hashCtx);
248     ctx->hsCtx->verifyCtx->hashCtx = SAL_CRYPT_DigestCopy(ctx->phaHash);
249     if (ctx->hsCtx->verifyCtx->hashCtx == NULL) {
250         BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST);
251         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16179, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
252             "pha hash copy error: digest copy fail.", 0, 0, 0, 0);
253         return HITLS_CRYPT_ERR_DIGEST;
254     }
255     return HITLS_SUCCESS;
256 }
257 #endif /* HITLS_TLS_FEATURE_PHA */