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 <string.h>
17 #include "securec.h"
18 #include "bsl_sal.h"
19 #include "hitls_error.h"
20 #include "hs_ctx.h"
21 #include "hs_common.h"
22 #include "change_cipher_spec.h"
23 #include "stub_replace.h"
24 #include "frame_tls.h"
25 #include "frame_io.h"
26 #include "frame_link.h"
27
28 #define ENTER_USER_SPECIFY_STATE (HITLS_UIO_FAIL_START + 0xFFFF)
29
30 #define READ_BUF_SIZE 18432
31 HITLS_HandshakeState g_nextState;
32 bool g_isClient;
33
FRAME_TrasferMsgBetweenLink(FRAME_LinkObj * linkA,FRAME_LinkObj * linkB)34 int32_t FRAME_TrasferMsgBetweenLink(FRAME_LinkObj *linkA, FRAME_LinkObj *linkB)
35 {
36 int32_t ret = HITLS_SUCCESS;
37 uint32_t readLen = 0;
38 char *buffer = BSL_SAL_Calloc(1u, MAX_RECORD_LENTH);
39 if (buffer == NULL) {
40 return HITLS_MEMALLOC_FAIL;
41 }
42
43 // linkA->io->userData to buffer
44 ret = FRAME_TransportSendMsg(linkA->io, buffer, MAX_RECORD_LENTH, &readLen);
45 if (ret != HITLS_SUCCESS) {
46 BSL_SAL_FREE(buffer);
47 return ret;
48 }
49 if (readLen == 0) {
50 BSL_SAL_FREE(buffer);
51 return HITLS_SUCCESS;
52 }
53
54 // buffer to linkB->io->userData
55 ret = FRAME_TransportRecMsg(linkB->io, buffer, readLen);
56 if (ret != HITLS_SUCCESS) {
57 BSL_SAL_FREE(buffer);
58 return ret;
59 }
60
61 BSL_SAL_FREE(buffer);
62 return HITLS_SUCCESS;
63 }
64
STUB_ChangeState(TLS_Ctx * ctx,uint32_t nextState)65 static int32_t STUB_ChangeState(TLS_Ctx *ctx, uint32_t nextState)
66 {
67 int32_t ret = HITLS_SUCCESS;
68 if (g_nextState == nextState) {
69 if (g_isClient == ctx->isClient) {
70 ret = HITLS_REC_NORMAL_RECV_BUF_EMPTY;
71 }
72 }
73
74 HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx;
75 hsCtx->state = nextState;
76 return ret;
77 }
78
StateCompare(FRAME_LinkObj * link,bool isClient,HITLS_HandshakeState state)79 static bool StateCompare(FRAME_LinkObj *link, bool isClient, HITLS_HandshakeState state)
80 {
81 if ((isClient == link->ssl->isClient) && (link->ssl->hsCtx != NULL) && (link->ssl->hsCtx->state == state)) {
82 if (state != TRY_RECV_FINISH && state != TRY_RECV_CERTIFICATE) {
83 return true;
84 }
85 /* In tls1.3, if the single-end verification is used, the server may receive the CCS message in the TRY_RECV_FINISH phase */
86 if (state == TRY_RECV_FINISH){
87 if (link->needStopBeforeRecvCCS || CCS_IsRecv(link->ssl) == true ||
88 (link->ssl->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13 && isClient == true) ||
89 (link->ssl->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13 &&
90 link->ssl->config.tlsConfig.isSupportClientVerify == true)) {
91 return true;
92 }
93 }
94 // In tls1.3, the server may receive the CCS message in the TRY_RECV_CERTIFICATIONATE phase
95 if (state == TRY_RECV_CERTIFICATE){
96 if (link->needStopBeforeRecvCCS || CCS_IsRecv(link->ssl) == true ||
97 #ifdef HITLS_TLS_PROTO_TLS13
98 link->ssl->hsCtx->haveHrr == true ||
99 #endif /* HITLS_TLS_PROTO_TLS13 */
100 link->ssl->config.tlsConfig.maxVersion != HITLS_VERSION_TLS13 || isClient == true) {
101 return true;
102 }
103 }
104 }
105 return false;
106 }
107
FRAME_CreateConnection(FRAME_LinkObj * client,FRAME_LinkObj * server,bool isClient,HITLS_HandshakeState state)108 int32_t FRAME_CreateConnection(FRAME_LinkObj *client, FRAME_LinkObj *server, bool isClient, HITLS_HandshakeState state)
109 {
110 int32_t clientRet;
111 int32_t serverRet;
112 int32_t ret;
113 uint32_t count = 0;
114
115 if (client == NULL || server == NULL) {
116 return HITLS_NULL_INPUT;
117 }
118
119 g_isClient = isClient;
120 g_nextState = state;
121
122 FuncStubInfo tmpRpInfo = {0};
123 STUB_Init();
124 STUB_Replace(&tmpRpInfo, HS_ChangeState, STUB_ChangeState);
125
126 do {
127 // Check whether the client needs to be stopped. If yes, return success
128 if (StateCompare(client, isClient, state)) {
129 ret = HITLS_SUCCESS;
130 break;
131 }
132
133 // Invoke the client to establish a connection
134 clientRet = HITLS_Connect(client->ssl);
135 if (clientRet != HITLS_SUCCESS) {
136 ret = clientRet;
137 if ((clientRet != HITLS_REC_NORMAL_IO_BUSY) && (clientRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) {
138 break;
139 }
140 }
141
142 // Transfer the message to the server
143 ret = FRAME_TrasferMsgBetweenLink(client, server);
144 if (ret != HITLS_SUCCESS) {
145 break;
146 }
147
148 // Check whether the server needs to be stopped. If yes, return success
149 if (StateCompare(server, isClient, state)) {
150 ret = HITLS_SUCCESS;
151 break;
152 }
153
154 // Invoke the server to establish a connection
155 serverRet = HITLS_Accept(server->ssl);
156 if (serverRet != HITLS_SUCCESS) {
157 ret = serverRet;
158 if ((serverRet != HITLS_REC_NORMAL_IO_BUSY) && (serverRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) {
159 break;
160 }
161 }
162
163 // Transfer the message to the client
164 ret = FRAME_TrasferMsgBetweenLink(server, client);
165 if (ret != HITLS_SUCCESS) {
166 break;
167 }
168
169 /* To receive TLS1.3 new session ticket messages */
170 if (clientRet == HITLS_SUCCESS) {
171 uint8_t readBuf[READ_BUF_SIZE] = {0};
172 uint32_t readLen = 0;
173 ret = HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readLen);
174 // No application data. return HITLS_REC_NORMAL_RECV_BUF_EMPTY
175 if (ret != HITLS_REC_NORMAL_RECV_BUF_EMPTY) {
176 return ret;
177 }
178 }
179
180 // If the connection is set up on both sides, return success
181 if (clientRet == HITLS_SUCCESS && serverRet == HITLS_SUCCESS) {
182 ret = HITLS_SUCCESS;
183 break;
184 }
185
186 count++;
187 ret = HITLS_INTERNAL_EXCEPTION;
188 // Prevent infinite loop. No more than 30 messages are exchanged between the client and server during the handshake
189 } while (count < 30);
190
191 //Check whether the hsCtx status meets the expectation. If hsCtx is destructed, HITLS_INTERNAL_EXCEPTION is returned
192 if (state != HS_STATE_BUTT) {
193 FRAME_LinkObj *point = (isClient) ? (client) : (server);
194 if (point->ssl->hsCtx == NULL) {
195 ret = HITLS_INTERNAL_EXCEPTION;
196 } else if (point->ssl->hsCtx->state != state) {
197 ret = HITLS_INTERNAL_EXCEPTION;
198 }
199 }
200
201 STUB_Reset(&tmpRpInfo);
202 return ret;
203 }
204
FRAME_CreateRenegotiation(FRAME_LinkObj * linkA,FRAME_LinkObj * linkB)205 int32_t FRAME_CreateRenegotiation(FRAME_LinkObj *linkA, FRAME_LinkObj *linkB)
206 {
207 int32_t clientRet;
208 int32_t serverRet;
209 int32_t ret;
210 uint32_t count = 0;
211 // renegotiation signal
212 uint8_t writeBuf[1] = {1};
213 uint8_t readBuf[32] = {0}; // buffer for receive temporary messages, 32 bytes long
214 uint32_t readBufLen = 0;
215
216 if (linkA->ssl->state != CM_STATE_RENEGOTIATION) {
217 return HITLS_SUCCESS;
218 }
219
220 do {
221 uint32_t len = 0;
222 clientRet = HITLS_Write(linkA->ssl, writeBuf, sizeof(writeBuf), &len);
223 if (clientRet != HITLS_SUCCESS) {
224 ret = clientRet;
225 if ((clientRet != HITLS_REC_NORMAL_IO_BUSY) && (clientRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) {
226 break;
227 }
228 }
229
230 ret = FRAME_TrasferMsgBetweenLink(linkA, linkB);
231 if (ret != HITLS_SUCCESS) {
232 break;
233 }
234
235 readBufLen = 0;
236 (void)memset_s(readBuf, sizeof(readBuf), 0, sizeof(readBuf));
237 serverRet = HITLS_Read(linkB->ssl, readBuf, sizeof(readBuf), &readBufLen);
238 if (serverRet != HITLS_SUCCESS) {
239 ret = serverRet;
240 if ((serverRet != HITLS_REC_NORMAL_IO_BUSY) && (serverRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) {
241 break;
242 }
243 }
244
245 ret = FRAME_TrasferMsgBetweenLink(linkB, linkA);
246 if (ret != HITLS_SUCCESS) {
247 break;
248 }
249
250 // If the connection is set up on both sides, return success
251 if (clientRet == HITLS_SUCCESS && serverRet == HITLS_SUCCESS &&
252 linkA->ssl->state == CM_STATE_TRANSPORTING && linkB->ssl->state == CM_STATE_TRANSPORTING) {
253 if ((readBufLen != sizeof(writeBuf)) ||
254 (memcmp(writeBuf, readBuf, readBufLen) != 0)) {
255 ret = HITLS_INTERNAL_EXCEPTION;
256 } else {
257 ret = HITLS_SUCCESS;
258 }
259 break;
260 }
261
262 count++;
263 ret = HITLS_INTERNAL_EXCEPTION;
264 // Prevent infinite loop. No more than 30 messages are exchanged between the client and server during the handshake
265 } while (count < 30);
266
267 return ret;
268 }
269
FRAME_CreateRenegotiationServer(FRAME_LinkObj * server,FRAME_LinkObj * client)270 int32_t FRAME_CreateRenegotiationServer(FRAME_LinkObj *server, FRAME_LinkObj *client)
271 {
272 int32_t clientRet;
273 int32_t serverRet;
274 int32_t ret;
275 uint32_t count = 0;
276 // renegotiation signal
277 uint8_t readBuf[32] = {0}; // buffer for receive temporary messages, 32 bytes long
278 uint32_t readBufLen = 0;
279
280 if (server->ssl->state != CM_STATE_RENEGOTIATION) {
281 return HITLS_SUCCESS;
282 }
283 do {
284 readBufLen = 0;
285 (void)memset_s(readBuf, sizeof(readBuf), 0, sizeof(readBuf));
286 serverRet = HITLS_Read(server->ssl, readBuf, sizeof(readBuf), &readBufLen);
287 if (serverRet != HITLS_SUCCESS) {
288 ret = serverRet;
289 if ((serverRet != HITLS_REC_NORMAL_IO_BUSY) && (serverRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) {
290 break;
291 }
292 }
293
294 ret = FRAME_TrasferMsgBetweenLink(server, client);
295 if (ret != HITLS_SUCCESS) {
296 break;
297 }
298
299 readBufLen = 0;
300 (void)memset_s(readBuf, sizeof(readBuf), 0, sizeof(readBuf));
301 clientRet = HITLS_Read(client->ssl, readBuf, sizeof(readBuf), &readBufLen);
302 if (clientRet != HITLS_SUCCESS) {
303 ret = clientRet;
304 if ((clientRet != HITLS_REC_NORMAL_IO_BUSY) && (clientRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) {
305 break;
306 }
307 }
308
309 ret = FRAME_TrasferMsgBetweenLink(client, server);
310 if (ret != HITLS_SUCCESS) {
311 break;
312 }
313
314 // If the connection is set up on both sides, return success
315 if (clientRet == HITLS_REC_NORMAL_RECV_BUF_EMPTY && serverRet == HITLS_REC_NORMAL_RECV_BUF_EMPTY &&
316 server->ssl->state == CM_STATE_TRANSPORTING && client->ssl->state == CM_STATE_TRANSPORTING) {
317 ret = HITLS_SUCCESS;
318 break;
319 }
320
321 count++;
322 ret = HITLS_INTERNAL_EXCEPTION;
323 // Prevent infinite loop. No more than 30 messages are exchanged between the client and server during the handshake
324 } while (count < 30);
325
326 return ret;
327 }
328
FRAME_CreateRenegotiationState(FRAME_LinkObj * client,FRAME_LinkObj * server,bool isClient,HITLS_HandshakeState state)329 int32_t FRAME_CreateRenegotiationState(FRAME_LinkObj *client, FRAME_LinkObj *server, bool isClient, HITLS_HandshakeState state)
330 {
331 int32_t clientRet;
332 int32_t serverRet;
333 int32_t ret;
334 uint32_t count = 0;
335 // renegotiation signal
336 uint8_t writeBuf[1] = {1};
337 uint8_t readBuf[32] = {0}; // buffer for receive temporary messages, 32 bytes long
338 uint32_t readBufLen = 0;
339
340 if (client->ssl->state != CM_STATE_RENEGOTIATION) {
341 return HITLS_SUCCESS;
342 }
343
344 g_isClient = isClient;
345 g_nextState = state;
346
347 FuncStubInfo tmpRpInfo = {0};
348 STUB_Init();
349 STUB_Replace(&tmpRpInfo, HS_ChangeState, STUB_ChangeState);
350
351 do {
352 // Check whether the client needs to be stopped. If yes, return success
353 if (StateCompare(client, isClient, state)) {
354 ret = HITLS_SUCCESS;
355 break;
356 }
357 uint32_t len = 0;
358 clientRet = HITLS_Write(client->ssl, writeBuf, sizeof(writeBuf), &len);
359 if (clientRet != HITLS_SUCCESS) {
360 ret = clientRet;
361 if ((clientRet != HITLS_REC_NORMAL_IO_BUSY) && (clientRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) {
362 break;
363 }
364 }
365
366 ret = FRAME_TrasferMsgBetweenLink(client, server);
367 if (ret != HITLS_SUCCESS) {
368 break;
369 }
370
371 // Check whether the server needs to be stopped. If yes, return success
372 if (StateCompare(server, isClient, state)) {
373 ret = HITLS_SUCCESS;
374 break;
375 }
376
377 readBufLen = 0;
378 (void)memset_s(readBuf, sizeof(readBuf), 0, sizeof(readBuf));
379 serverRet = HITLS_Read(server->ssl, readBuf, sizeof(readBuf), &readBufLen);
380 if (serverRet != HITLS_SUCCESS) {
381 ret = serverRet;
382 if ((serverRet != HITLS_REC_NORMAL_IO_BUSY) && (serverRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) {
383 break;
384 }
385 }
386
387 ret = FRAME_TrasferMsgBetweenLink(server, client);
388 if (ret != HITLS_SUCCESS) {
389 break;
390 }
391
392 // If the connection is set up on both sides, return success
393 if (clientRet == HITLS_SUCCESS && serverRet == HITLS_SUCCESS &&
394 client->ssl->state == CM_STATE_TRANSPORTING && server->ssl->state == CM_STATE_TRANSPORTING) {
395 if ((readBufLen != sizeof(writeBuf)) ||
396 (memcmp(writeBuf, readBuf, readBufLen) != 0)) {
397 ret = HITLS_INTERNAL_EXCEPTION;
398 } else {
399 ret = HITLS_SUCCESS;
400 }
401 break;
402 }
403
404 count++;
405 ret = HITLS_INTERNAL_EXCEPTION;
406 // Prevent infinite loop. No more than 30 messages are exchanged between the client and server during the handshake
407 } while (count < 30);
408
409 //Check whether the hsCtx status meets the expectation. If hsCtx is destructed, HITLS_INTERNAL_EXCEPTION is returned
410 if (state != HS_STATE_BUTT) {
411 FRAME_LinkObj *point = (isClient) ? (client) : (server);
412 if (point->ssl->hsCtx == NULL) {
413 ret = HITLS_INTERNAL_EXCEPTION;
414 } else if (point->ssl->hsCtx->state != state) {
415 ret = HITLS_INTERNAL_EXCEPTION;
416 }
417 }
418 STUB_Reset(&tmpRpInfo);
419 return ret;
420 }