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