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