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 */