• 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 "securec.h"
18 #include "tls_binlog_id.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_log.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_list.h"
23 #include "tls.h"
24 #include "hitls.h"
25 #include "hitls_error.h"
26 #include "hitls_type.h"
27 #ifdef HITLS_TLS_FEATURE_PSK
28 #include "hitls_psk.h"
29 #endif
30 #ifdef HITLS_TLS_FEATURE_ALPN
31 #include "hitls_alpn.h"
32 #endif
33 #include "hs.h"
34 #include "alert.h"
35 #include "app.h"
36 #ifdef HITLS_TLS_FEATURE_SESSION
37 #include "session.h"
38 #endif
39 #ifdef HITLS_TLS_FEATURE_INDICATOR
40 #include "indicator.h"
41 #endif
42 #include "rec.h"
43 #ifdef HITLS_TLS_FEATURE_SECURITY
44 #include "security.h"
45 #endif
46 #include "hs_ctx.h"
47 #include "conn_common.h"
48 
49 
GetStateString(uint32_t state)50 static const char *GetStateString(uint32_t state)
51 {
52     /* * Unknown status */
53     if (state >= CM_STATE_END) {
54         return "Unknown";
55     }
56 
57     static const char *stateMachineStr[CM_STATE_END] = {
58         [CM_STATE_IDLE] = "Idle",
59         [CM_STATE_RENEGOTIATION] = "SecRenego",
60         [CM_STATE_HANDSHAKING] = "Handshaking",
61         [CM_STATE_TRANSPORTING] = "Transporting",
62         [CM_STATE_ALERTING] = "Alerting",
63         [CM_STATE_ALERTED] = "Alerted",
64         [CM_STATE_CLOSED] = "Closed",
65     };
66     /* Current status */
67     return stateMachineStr[state];
68 }
69 
ChangeConnState(HITLS_Ctx * ctx,CM_State state)70 void ChangeConnState(HITLS_Ctx *ctx, CM_State state)
71 {
72     if (GetConnState(ctx) == state) {
73         return;
74     }
75 
76     ctx->preState = ctx->state;
77     ctx->state = state;
78     BSL_LOG_BINLOG_VARLEN(BINLOG_ID15839, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, "state [%s]",
79         GetStateString(ctx->preState));
80     BSL_LOG_BINLOG_VARLEN(BINLOG_ID15840, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, "change to [%s]",
81         GetStateString(state));
82     return;
83 }
84 
CommonEventInAlertingState(HITLS_Ctx * ctx)85 int32_t CommonEventInAlertingState(HITLS_Ctx *ctx)
86 {
87     /* The alerting state indicates that an alert message is being sent over the current link. In this case, the alert
88      * message should firstly be sent and then the link status will be updated */
89     ALERT_Info alertInfo = { 0 };
90     ALERT_GetInfo(ctx, &alertInfo);
91 
92     if (alertInfo.level > ALERT_LEVEL_FATAL) {
93         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16458, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "level error", 0, 0, 0, 0);
94         BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
95         return HITLS_INTERNAL_EXCEPTION;
96     }
97 
98     int32_t ret = ALERT_Flush(ctx);
99     if (ret != HITLS_SUCCESS) {
100         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16459, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
101             "ALERT_Flush fail", 0, 0, 0, 0);
102         /* If the alert fails to be sent, return error code to user */
103         return ret;
104     }
105 #ifdef HITLS_TLS_FEATURE_INDICATOR
106     uint8_t data[2] = {alertInfo.level, alertInfo.description};
107     INDICATOR_MessageIndicate(1, HS_GetVersion(ctx), REC_TYPE_ALERT, data, sizeof(data) / sizeof(uint8_t), ctx,
108         ctx->config.tlsConfig.msgArg);
109 
110     INDICATOR_StatusIndicate(ctx, INDICATE_EVENT_WRITE_ALERT,
111         (int32_t)(((uint32_t)(alertInfo.level) << INDICATOR_ALERT_LEVEL_OFFSET) | (uint32_t)(alertInfo.description)));
112 #endif
113     /* If a fatal alert is sent, the link must be disconnected */
114     if (alertInfo.level == ALERT_LEVEL_FATAL) {
115 #ifdef HITLS_TLS_FEATURE_SESSION
116         SESS_Disable(ctx->session);
117 #endif
118         ChangeConnState(ctx, CM_STATE_ALERTED);
119         return HITLS_SUCCESS;
120     }
121 
122     /* If the close_notify message is sent, the link must be disconnected */
123     if (alertInfo.description == ALERT_CLOSE_NOTIFY) {
124         if (ctx->userShutDown) {
125             ChangeConnState(ctx, CM_STATE_CLOSED);
126         } else {
127             ChangeConnState(ctx, CM_STATE_ALERTED);
128         }
129         ctx->shutdownState |= HITLS_SENT_SHUTDOWN;
130         /* If the previous state was not in the transporting state, the connection should be closed directly, and
131          * reading and writing are not allowed. */
132         if (ctx->preState != CM_STATE_TRANSPORTING) {
133             ctx->shutdownState |= HITLS_RECEIVED_SHUTDOWN;
134         }
135         return HITLS_SUCCESS;
136     }
137 
138     /* Other warning alerts will not terminate the connection and the status will be restored to the previous status */
139     ctx->state = ctx->preState;
140     ALERT_CleanInfo(ctx);
141     return HITLS_SUCCESS;
142 }
143 
AlertRecvProcess(HITLS_Ctx * ctx,const ALERT_Info * alertInfo)144 static int32_t AlertRecvProcess(HITLS_Ctx *ctx, const ALERT_Info *alertInfo)
145 {
146 #ifdef HITLS_TLS_FEATURE_INDICATOR
147     uint8_t data[2] = {alertInfo->level, alertInfo->description};
148     INDICATOR_MessageIndicate(0, HS_GetVersion(ctx), REC_TYPE_ALERT, data, sizeof(data) / sizeof(uint8_t), ctx,
149         ctx->config.tlsConfig.msgArg);
150 
151     INDICATOR_StatusIndicate(ctx, INDICATE_EVENT_READ_ALERT,
152         (int32_t)(((uint32_t)(alertInfo->level) << INDICATOR_ALERT_LEVEL_OFFSET) | (uint32_t)(alertInfo->description)));
153 #endif
154     /* If a fatal alert is received, the link must be disconnected */
155     if (alertInfo->level == ALERT_LEVEL_FATAL) {
156 #ifdef HITLS_TLS_FEATURE_SESSION
157         SESS_Disable(ctx->session);
158 #endif
159         ChangeConnState(ctx, CM_STATE_ALERTED);
160         ctx->shutdownState |= HITLS_RECEIVED_SHUTDOWN;
161         return HITLS_SUCCESS;
162     }
163 
164     /* If a warning alert is received, the connection must be terminated if the alert is close_notify. Otherwise, the
165      * alert will not be processed  */
166     ALERT_CleanInfo(ctx);
167     if (alertInfo->description != ALERT_CLOSE_NOTIFY) {
168         /* Other warning alerts will not be processed */
169         return HITLS_SUCCESS;
170     }
171 
172     ctx->shutdownState |= HITLS_RECEIVED_SHUTDOWN;
173 
174     /* In quiet disconnection mode, close_notify does not need to be sent */
175     if (ctx->config.tlsConfig.isQuietShutdown) {
176         ctx->shutdownState |= HITLS_SENT_SHUTDOWN;
177         ChangeConnState(ctx, CM_STATE_ALERTED);
178         return HITLS_SUCCESS;
179     }
180 
181     if ((ctx->shutdownState & HITLS_SENT_SHUTDOWN) == 0) {
182         if (GetConnState(ctx) != CM_STATE_TRANSPORTING) {
183             /* If the close_notify message is received, the close_notify message must be sent to the peer */
184             ALERT_Send(ctx, ALERT_LEVEL_WARNING, ALERT_CLOSE_NOTIFY);
185             ChangeConnState(ctx, CM_STATE_ALERTING);
186             int32_t ret = ALERT_Flush(ctx);
187             if (ret != HITLS_SUCCESS) {
188                 return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID16460, "ALERT_Flush fail");
189             }
190             ctx->shutdownState |= HITLS_SENT_SHUTDOWN;
191         } else {
192             ChangeConnState(ctx, CM_STATE_CLOSED);
193         }
194     }
195 
196     if (ctx->state != CM_STATE_CLOSED) {
197         ChangeConnState(ctx, CM_STATE_ALERTED);
198     }
199     return HITLS_CM_LINK_CLOSED;
200 }
201 
AlertEventProcess(HITLS_Ctx * ctx)202 int32_t AlertEventProcess(HITLS_Ctx *ctx)
203 {
204     ALERT_Info alertInfo = { 0 };
205     ALERT_GetInfo(ctx, &alertInfo);
206 
207     /* An alert message is received. */
208     if (alertInfo.flag == ALERT_FLAG_RECV) {
209         return AlertRecvProcess(ctx, &alertInfo);
210     }
211 
212     /* An alert message needs to be sent */
213     if (alertInfo.flag == ALERT_FLAG_SEND) {
214         ChangeConnState(ctx, CM_STATE_ALERTING);
215         return CommonEventInAlertingState(ctx);
216     }
217 
218     return HITLS_SUCCESS;
219 }
220 
CommonEventInHandshakingState(HITLS_Ctx * ctx)221 int32_t CommonEventInHandshakingState(HITLS_Ctx *ctx)
222 {
223     int32_t ret;
224     int32_t alertRet;
225 
226     do {
227         ret = HS_DoHandshake(ctx);
228         if (ret == HITLS_SUCCESS) {
229             /* The handshake has completed */
230             break;
231         }
232         if (ret == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG && REC_GetUnexpectedMsgType(ctx) == REC_TYPE_APP) {
233             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16489, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
234                 "The app message is received in the handshake state", 0, 0, 0, 0);
235             ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
236         }
237         if (!ALERT_GetFlag(ctx)) {
238             /* The handshake fails, but no alert is received. Return the error code to the user */
239             return ret;
240         }
241 
242         if (ALERT_HaveExceeded(ctx, MAX_ALERT_COUNT)) {
243             /* If there are multiple consecutive alerts, the link is abnormal and needs to be terminated. */
244             ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
245             alertRet = AlertEventProcess(ctx);
246             return (alertRet == HITLS_SUCCESS) ? ret : alertRet;
247         }
248 
249         alertRet = AlertEventProcess(ctx);
250         if (alertRet != HITLS_SUCCESS) {
251             /* If the alert message fails to be sent, return the error code to the user */
252             return alertRet;
253         }
254 
255         /* If fatal alert or close_notify has been processed, the handshake must be terminated */
256         if (ctx->state == CM_STATE_ALERTED) {
257             return ret;
258         }
259     } while (ret != HITLS_SUCCESS);
260 
261     // If HS_DoHandshake returns success, the connection has been established.
262     ChangeConnState(ctx, CM_STATE_TRANSPORTING);
263 
264     /* In the UDP scenario, peer may retransmit the finished message even if the local endpoint is connected
265      * Therefore, the hsCtx is not released in the UDP scenario */
266     if (!BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
267         HS_DeInit(ctx);
268     }
269 
270     return HITLS_SUCCESS;
271 }
272 
HITLS_GetConfig(const HITLS_Ctx * ctx)273 const HITLS_Config *HITLS_GetConfig(const HITLS_Ctx *ctx)
274 {
275     if (ctx == NULL) {
276         return NULL;
277     }
278     return &(ctx->config.tlsConfig);
279 }
280 
HITLS_GetGlobalConfig(const HITLS_Ctx * ctx)281 HITLS_Config *HITLS_GetGlobalConfig(const HITLS_Ctx *ctx)
282 {
283     if (ctx == NULL) {
284         return NULL;
285     }
286     return ctx->globalConfig;
287 }
288 
289 #ifdef HITLS_TLS_PROTO_TLS13
HITLS_ClearTLS13CipherSuites(HITLS_Ctx * ctx)290 int32_t HITLS_ClearTLS13CipherSuites(HITLS_Ctx *ctx)
291 {
292     if (ctx == NULL) {
293         return HITLS_NULL_INPUT;
294     }
295     return HITLS_CFG_ClearTLS13CipherSuites(&(ctx->config.tlsConfig));
296 }
297 #endif
HITLS_SetCipherSuites(HITLS_Ctx * ctx,const uint16_t * cipherSuites,uint32_t cipherSuitesSize)298 int32_t HITLS_SetCipherSuites(HITLS_Ctx *ctx, const uint16_t *cipherSuites, uint32_t cipherSuitesSize)
299 {
300     if (ctx == NULL) {
301         return HITLS_NULL_INPUT;
302     }
303     return HITLS_CFG_SetCipherSuites(&(ctx->config.tlsConfig), cipherSuites, cipherSuitesSize);
304 }
305 #ifdef HITLS_TLS_FEATURE_ALPN
HITLS_SetAlpnProtos(HITLS_Ctx * ctx,const uint8_t * protos,uint32_t protosLen)306 int32_t HITLS_SetAlpnProtos(HITLS_Ctx *ctx, const uint8_t *protos, uint32_t protosLen)
307 {
308     if (ctx == NULL) {
309         return HITLS_NULL_INPUT;
310     }
311     return HITLS_CFG_SetAlpnProtos(&(ctx->config.tlsConfig), protos, protosLen);
312 }
313 #endif
314 #ifdef HITLS_TLS_FEATURE_PSK
HITLS_SetPskClientCallback(HITLS_Ctx * ctx,HITLS_PskClientCb cb)315 int32_t HITLS_SetPskClientCallback(HITLS_Ctx *ctx, HITLS_PskClientCb cb)
316 {
317     if (ctx == NULL) {
318         return HITLS_NULL_INPUT;
319     }
320     return HITLS_CFG_SetPskClientCallback(&(ctx->config.tlsConfig), cb);
321 }
322 
HITLS_SetPskServerCallback(HITLS_Ctx * ctx,HITLS_PskServerCb cb)323 int32_t HITLS_SetPskServerCallback(HITLS_Ctx *ctx, HITLS_PskServerCb cb)
324 {
325     if (ctx == NULL) {
326         return HITLS_NULL_INPUT;
327     }
328     return HITLS_CFG_SetPskServerCallback(&(ctx->config.tlsConfig), cb);
329 }
330 
331 #if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
HITLS_SetPskIdentityHint(HITLS_Ctx * ctx,const uint8_t * identityHint,uint32_t identityHintLen)332 int32_t HITLS_SetPskIdentityHint(HITLS_Ctx *ctx, const uint8_t *identityHint, uint32_t identityHintLen)
333 {
334     if (ctx == NULL) {
335         return HITLS_NULL_INPUT;
336     }
337     return HITLS_CFG_SetPskIdentityHint(&(ctx->config.tlsConfig), identityHint, identityHintLen);
338 }
339 #endif
340 #endif
341 
342 #ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
HITLS_GetCurrentCipher(const HITLS_Ctx * ctx)343 const HITLS_Cipher *HITLS_GetCurrentCipher(const HITLS_Ctx *ctx)
344 {
345     if (ctx == NULL) {
346         return NULL;
347     }
348 
349     return &(ctx->negotiatedInfo.cipherSuiteInfo);
350 }
351 #endif
352 
HITLS_IsClient(const HITLS_Ctx * ctx,bool * isClient)353 int32_t HITLS_IsClient(const HITLS_Ctx *ctx, bool *isClient)
354 {
355     if (ctx == NULL || isClient == NULL) {
356         return HITLS_NULL_INPUT;
357     }
358     *isClient = ctx->isClient;
359     return HITLS_SUCCESS;
360 }
361 
362 #ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
HITLS_GetHsRandom(const HITLS_Ctx * ctx,uint8_t * out,uint32_t * outlen,bool isClient)363 int32_t HITLS_GetHsRandom(const HITLS_Ctx *ctx, uint8_t *out, uint32_t *outlen, bool isClient)
364 {
365     if (ctx == NULL || outlen == NULL) {
366         return HITLS_NULL_INPUT;
367     }
368 
369     if (*outlen == 0) {
370         *outlen = RANDOM_SIZE;
371         return HITLS_SUCCESS;
372     }
373 
374     uint32_t resLen = *outlen;
375 
376     if (resLen > RANDOM_SIZE) {
377         resLen = RANDOM_SIZE;
378     }
379 
380     if (out == NULL) {
381         *outlen = resLen;
382         return HITLS_SUCCESS;
383     }
384 
385     if (isClient) {
386         (void)memcpy_s(out, resLen, ctx->negotiatedInfo.clientRandom, resLen);
387     } else {
388         (void)memcpy_s(out, resLen, ctx->negotiatedInfo.serverRandom, resLen);
389     }
390 
391     *outlen = resLen;
392     return HITLS_SUCCESS;
393 }
394 
395 /*
396  * If current endpoint is a server and the server preference is supported, the local server group array is preferred.
397  * If current endpoint is a server and the client preference is supported, the peer (client)group array is preferred
398  */
FindPreference(const HITLS_Ctx * ctx,int32_t nmatch,bool * haveFound)399 static uint16_t FindPreference(const HITLS_Ctx *ctx, int32_t nmatch, bool *haveFound)
400 {
401     uint16_t ans = 0;
402     uint32_t preferGroupSize = 0;
403     uint32_t secondPreferGroupSize = 0;
404     uint16_t *preferGroups = NULL;
405     uint16_t *secondPreferGroups = NULL;
406     uint32_t peerGroupSize = ctx->peerInfo.groupsSize;
407     uint32_t localGroupSize = ctx->config.tlsConfig.groupsSize;
408     uint16_t *peerGroups = ctx->peerInfo.groups;
409     uint16_t *localGroups = ctx->config.tlsConfig.groups;
410     bool chooseServerPre = ctx->config.tlsConfig.isSupportServerPreference;
411     uint16_t intersectionCnt = 0;
412 
413     preferGroupSize = (chooseServerPre == true) ? localGroupSize : peerGroupSize;
414     secondPreferGroupSize = (chooseServerPre == true) ? peerGroupSize : localGroupSize;
415     preferGroups = (chooseServerPre == true) ? localGroups : peerGroups;
416     secondPreferGroups = (chooseServerPre == true) ? peerGroups : localGroups;
417 
418     for (uint32_t i = 0; i < preferGroupSize; i++) {
419         for (uint32_t j = 0; j < secondPreferGroupSize; j++) {
420             if (preferGroups[i] == secondPreferGroups[j]) {
421                 intersectionCnt++;
422                 // Currently, the preferred nmatch is already matched
423                 bool isMatch = (intersectionCnt == nmatch);
424                 *haveFound = (isMatch ? true : (*haveFound));
425                 ans = (isMatch ? preferGroups[i] : ans);
426                 // Jump out of the inner village and change
427                 break;
428             }
429         }
430         if (*haveFound) {
431             // Exit a loop
432             break;
433         }
434     }
435     if (nmatch == GET_GROUPS_CNT) {
436         return (uint16_t)intersectionCnt;
437     }
438     return ans;
439 }
440 
441 /*
442  * nmatch Value range: - 1 or a positive integer
443  * This function can be invoked only after negotiation and can be invoked only by the server.
444  * When nmatch is a positive integer, check the intersection of groups on the client and server, and return the nmatch
445  * group in the intersection by groupId. If the value of nmatch is - 1, the number of intersection groups on the client
446  * and server is returned based on groupId.
447  */
HITLS_GetSharedGroup(const HITLS_Ctx * ctx,int32_t nmatch,uint16_t * groupId)448 int32_t HITLS_GetSharedGroup(const HITLS_Ctx *ctx, int32_t nmatch, uint16_t *groupId)
449 {
450     bool haveFound = false;
451     if (ctx == NULL || groupId == NULL) {
452         return HITLS_NULL_INPUT;
453     }
454     *groupId = 0;
455     // Check the value range of nmatch and whether the interface is invoked by the server. The client cannot invoke the
456     // interface because the client cannot sense the peerInfo.
457     if (nmatch < GET_GROUPS_CNT || nmatch == 0 || ctx->isClient) {
458         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16464, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "invalid input", 0, 0, 0, 0);
459         return HITLS_INVALID_INPUT;
460     }
461 
462     *groupId = FindPreference(ctx, nmatch, &haveFound);
463 
464     if (nmatch == GET_GROUPS_CNT) {
465         // The value of *groupId is the number of intersections
466         return HITLS_SUCCESS;
467     } else if (haveFound == false) {
468         // If nmatch is not equal to GET_GROUPS_CNT and haveFound is false
469         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16465, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "input err", 0, 0, 0, 0);
470         return HITLS_INVALID_INPUT;
471     }
472     return HITLS_SUCCESS;
473 }
474 #endif /* HITLS_TLS_CONNECTION_INFO_NEGOTIATION */
475 
476 #ifdef HITLS_TLS_FEATURE_RENEGOTIATION
HITLS_GetPeerFinishVerifyData(const HITLS_Ctx * ctx,void * buf,uint32_t bufLen,uint32_t * dataLen)477 int32_t HITLS_GetPeerFinishVerifyData(const HITLS_Ctx *ctx, void *buf, uint32_t bufLen, uint32_t *dataLen)
478 {
479     uint32_t verifyDataSize, bufSize;
480     const uint8_t *verifyData = NULL;
481 
482     if (ctx == NULL || buf == NULL || bufLen == 0 || dataLen == NULL) {
483         return HITLS_NULL_INPUT;
484     }
485 
486     if (ctx->isClient) {
487         verifyDataSize = ctx->negotiatedInfo.serverVerifyDataSize;
488         verifyData = ctx->negotiatedInfo.serverVerifyData;
489     } else {
490         verifyDataSize = ctx->negotiatedInfo.clientVerifyDataSize;
491         verifyData = ctx->negotiatedInfo.clientVerifyData;
492     }
493 
494     if (bufLen > verifyDataSize) {
495         bufSize = verifyDataSize;
496     } else {
497         bufSize = bufLen;
498     }
499 
500     (void)memcpy_s(buf, bufLen, verifyData, bufSize);
501     *dataLen = verifyDataSize;
502     return HITLS_SUCCESS;
503 }
504 
HITLS_GetFinishVerifyData(const HITLS_Ctx * ctx,void * buf,uint32_t bufLen,uint32_t * dataLen)505 int32_t HITLS_GetFinishVerifyData(const HITLS_Ctx *ctx, void *buf, uint32_t bufLen, uint32_t *dataLen)
506 {
507     uint32_t verifyDataSize, bufSize;
508     const uint8_t *verifyData = NULL;
509 
510     if (ctx == NULL || buf == NULL || bufLen == 0 || dataLen == NULL) {
511         return HITLS_NULL_INPUT;
512     }
513 
514     if (ctx->isClient) {
515         verifyDataSize = ctx->negotiatedInfo.clientVerifyDataSize;
516         verifyData = ctx->negotiatedInfo.clientVerifyData;
517     } else {
518         verifyDataSize = ctx->negotiatedInfo.serverVerifyDataSize;
519         verifyData = ctx->negotiatedInfo.serverVerifyData;
520     }
521 
522     if (bufLen > verifyDataSize) {
523         bufSize = verifyDataSize;
524     } else {
525         bufSize = bufLen;
526     }
527 
528     (void)memcpy_s(buf, bufLen, verifyData, bufSize);
529     *dataLen = verifyDataSize;
530     return HITLS_SUCCESS;
531 }
532 #endif /* HITLS_TLS_FEATURE_RENEGOTIATION */
533 
534 #ifdef HITLS_TLS_PROTO_ALL
HITLS_GetVersionSupport(const HITLS_Ctx * ctx,uint32_t * version)535 int32_t HITLS_GetVersionSupport(const HITLS_Ctx *ctx, uint32_t *version)
536 {
537     if (ctx == NULL) {
538         return HITLS_NULL_INPUT;
539     }
540 
541     return HITLS_CFG_GetVersionSupport(&(ctx->config.tlsConfig), version);
542 }
543 
HITLS_SetVersionSupport(HITLS_Ctx * ctx,uint32_t version)544 int32_t HITLS_SetVersionSupport(HITLS_Ctx *ctx, uint32_t version)
545 {
546     if (ctx == NULL) {
547         return HITLS_NULL_INPUT;
548     }
549 
550     return HITLS_CFG_SetVersionSupport(&(ctx->config.tlsConfig), version);
551 }
552 #endif
553 
554 #ifdef HITLS_TLS_SUITE_KX_RSA
HITLS_SetNeedCheckPmsVersion(HITLS_Ctx * ctx,bool needCheck)555 int32_t HITLS_SetNeedCheckPmsVersion(HITLS_Ctx *ctx, bool needCheck)
556 {
557     if (ctx == NULL) {
558         return HITLS_NULL_INPUT;
559     }
560 
561     return HITLS_CFG_SetNeedCheckPmsVersion(&(ctx->config.tlsConfig), needCheck);
562 }
563 #endif
564 
565 #ifdef HITLS_TLS_FEATURE_RENEGOTIATION
HS_IsAppDataAllowed(TLS_Ctx * ctx)566 static bool HS_IsAppDataAllowed(TLS_Ctx *ctx)
567 {
568     uint32_t hsState = HS_GetState(ctx);
569     if (ctx->isClient) {
570         if (hsState == TRY_RECV_SERVER_HELLO) {
571             return true;
572         }
573     } else {
574         if (hsState == TRY_RECV_CLIENT_HELLO) {
575             return true;
576         }
577     }
578     return false;
579 }
580 
InnerRenegotiationProcess(HITLS_Ctx * ctx)581 void InnerRenegotiationProcess(HITLS_Ctx *ctx)
582 {
583     ALERT_Info alertInfo = { 0 };
584     ALERT_GetInfo(ctx, &alertInfo);
585     if ((alertInfo.level == ALERT_LEVEL_WARNING) && (alertInfo.description == ALERT_NO_RENEGOTIATION)) {
586         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16234, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
587             "Receive no renegotiation alert during renegotiation process", 0, 0, 0, 0);
588         ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE);
589     }
590 }
591 
CommonEventInRenegotiationState(HITLS_Ctx * ctx)592 int32_t CommonEventInRenegotiationState(HITLS_Ctx *ctx)
593 {
594     int32_t ret;
595 
596     do {
597         ret = HS_DoHandshake(ctx);
598         if (ret == HITLS_SUCCESS) {
599             /* The handshake has completed */
600             break;
601         }
602 
603         if (ret == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG && REC_GetUnexpectedMsgType(ctx) == REC_TYPE_APP) {
604             if (ctx->allowAppOut && HS_IsAppDataAllowed(ctx)) {
605                 return ret;
606             }
607             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17106, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
608                 "The app message is received in the handshake state", 0, 0, 0, 0);
609             ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
610         }
611 
612         if (!ALERT_GetFlag(ctx)) {
613             /* The handshake fails, but no alert is displayed. The system returns a message
614              * to the user for processing */
615             return ret;
616         }
617         InnerRenegotiationProcess(ctx);
618         if (ALERT_HaveExceeded(ctx, MAX_ALERT_COUNT)) {
619             /* If multiple consecutive alerts exist, the link is abnormal and needs to be terminated */
620             ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
621         }
622 
623         int32_t alertRet = AlertEventProcess(ctx);
624         if (alertRet != HITLS_SUCCESS) {
625             if (alertRet != HITLS_CM_LINK_CLOSED) {
626                 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16466, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
627                     "AlertEventProcess fail", 0, 0, 0, 0);
628             }
629             /* If the alert fails to be sent, the system sends a message to the user for processing */
630             return alertRet;
631         }
632 
633         /*
634             If fatal alert or close_notify has been processed, the handshake must be terminated.
635         */
636         if (ctx->state == CM_STATE_ALERTED) {
637             return ret;
638         }
639     } while (ret != HITLS_SUCCESS);
640 
641     // If the HS_DoHandshake message is returned successfully, the link has been terminated.
642     ChangeConnState(ctx, CM_STATE_TRANSPORTING);
643 
644     /* In the UDP scenario, the peer end may retransmit the finished message even if the local end is terminated.
645      * Therefore, the hsCtx is not released in the UDP scenario */
646     if (!BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_UDP)) {
647         HS_DeInit(ctx);
648     }
649 
650     // Prevent the renegotiation status from being changed after the Hello Request message is sent.
651     if (ctx->negotiatedInfo.isRenegotiation) {
652         ctx->userRenego = false;
653         ctx->negotiatedInfo.isRenegotiation = false; /* Disabling renegotiation */
654         BSL_LOG_BINLOG_FIXLEN(
655             BINLOG_ID15952, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, "renegotiate completed.", 0, 0, 0, 0);
656     }
657     return HITLS_SUCCESS;
658 }
659 #endif /* HITLS_TLS_FEATURE_RENEGOTIATION */
660 
661 #if defined(HITLS_TLS_FEATURE_PSK) && defined(HITLS_TLS_PROTO_TLS13)
HITLS_SetPskFindSessionCallback(HITLS_Ctx * ctx,HITLS_PskFindSessionCb cb)662 int32_t HITLS_SetPskFindSessionCallback(HITLS_Ctx *ctx, HITLS_PskFindSessionCb cb)
663 {
664     if (ctx == NULL) {
665         return HITLS_NULL_INPUT;
666     }
667 
668     return HITLS_CFG_SetPskFindSessionCallback(&(ctx->config.tlsConfig), cb);
669 }
670 
HITLS_SetPskUseSessionCallback(HITLS_Ctx * ctx,HITLS_PskUseSessionCb cb)671 int32_t HITLS_SetPskUseSessionCallback(HITLS_Ctx *ctx, HITLS_PskUseSessionCb cb)
672 {
673     if (ctx == NULL) {
674         return HITLS_NULL_INPUT;
675     }
676     return HITLS_CFG_SetPskUseSessionCallback(&(ctx->config.tlsConfig), cb);
677 }
678 #endif
679 
680 #ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
HITLS_GetNegotiateGroup(const HITLS_Ctx * ctx,uint16_t * group)681 int32_t HITLS_GetNegotiateGroup(const HITLS_Ctx *ctx, uint16_t *group)
682 {
683     if (ctx == NULL || group == NULL) {
684         return HITLS_NULL_INPUT;
685     }
686 
687     *group = ctx->negotiatedInfo.negotiatedGroup;
688     return HITLS_SUCCESS;
689 }
690 #endif