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 "securec.h"
16 #include "bsl_err_internal.h"
17 #include "tls_binlog_id.h"
18 #include "bsl_sal.h"
19 #include "bsl_errno.h"
20 #include "bsl_list.h"
21 #include "hitls_error.h"
22 #include "hitls_type.h"
23 #include "hitls_config.h"
24 #include "hitls_cert_type.h"
25 #include "hitls.h"
26 #include "tls.h"
27 #include "tls_config.h"
28 #include "cert.h"
29 #ifdef HITLS_TLS_FEATURE_SESSION
30 #include "session.h"
31 #include "session_mgr.h"
32 #endif
33 #include "bsl_uio.h"
34 #include "config.h"
35 #include "config_check.h"
36 #include "conn_common.h"
37 #include "conn_init.h"
38 #include "crypt.h"
39 #include "cipher_suite.h"
40
41 #ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
PeerInfoInit(HITLS_Ctx * ctx)42 static int32_t PeerInfoInit(HITLS_Ctx *ctx)
43 {
44 /* The peerInfo.caList is used to adapt to the OpenSSL behavior. When creating the SSL_CTX object, OpenSSL
45 * initializes the member so that the member is not null */
46 ctx->peerInfo.caList = BSL_LIST_New(sizeof(HITLS_TrustedCANode *));
47 if (ctx->peerInfo.caList == NULL) {
48 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16468, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "LIST_New fail", 0, 0, 0, 0);
49 return HITLS_MEMALLOC_FAIL;
50 }
51
52 return HITLS_SUCCESS;
53 }
54 #endif
55 /**
56 * @ingroup hitls
57 * @brief Create a TLS object and deep Copy the HITLS_Config to the HITLS_Ctx.
58 * @attention After the creation is successful, the HITLS_Config can be released.
59 * @param config [IN] config Context
60 * @return HITLS_Ctx Pointer. If the operation fails, null is returned.
61 */
HITLS_New(HITLS_Config * config)62 HITLS_Ctx *HITLS_New(HITLS_Config *config)
63 {
64 if (config == NULL) {
65 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16469, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "config null", 0, 0, 0, 0);
66 return NULL;
67 }
68
69 HITLS_Ctx *newCtx = (HITLS_Ctx *)BSL_SAL_Calloc(1u, sizeof(HITLS_Ctx));
70 if (newCtx == NULL) {
71 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16470, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Calloc fail", 0, 0, 0, 0);
72 return NULL;
73 }
74
75 int32_t ret = CheckConfig(config);
76 if (ret != HITLS_SUCCESS) {
77 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16471, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
78 "CheckConfig fail, ret %d", ret, 0, 0, 0);
79 BSL_SAL_FREE(newCtx);
80 return NULL;
81 }
82
83 ret = DumpConfig(newCtx, config);
84 if (ret != HITLS_SUCCESS) {
85 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16472, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
86 "DumpConfig fail, ret %d", ret, 0, 0, 0);
87 BSL_SAL_FREE(newCtx);
88 return NULL;
89 }
90 (void)HITLS_CFG_UpRef(config);
91 newCtx->globalConfig = config;
92 #ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
93 ret = PeerInfoInit(newCtx);
94 if (ret != HITLS_SUCCESS) {
95 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16473, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
96 "PeerInfoInit fail, ret %d", ret, 0, 0, 0);
97 HITLS_Free(newCtx);
98 return NULL;
99 }
100 #endif
101 ChangeConnState(newCtx, CM_STATE_IDLE);
102 return newCtx;
103 }
104
CaListNodeDestroy(void * data)105 static void CaListNodeDestroy(void *data)
106 {
107 HITLS_TrustedCANode *tmpData = (HITLS_TrustedCANode *)data;
108 BSL_SAL_FREE(tmpData->data);
109 BSL_SAL_FREE(tmpData);
110 return;
111 }
112
CleanPeerInfo(PeerInfo * peerInfo)113 static void CleanPeerInfo(PeerInfo *peerInfo)
114 {
115 BSL_SAL_FREE(peerInfo->groups);
116 BSL_SAL_FREE(peerInfo->cipherSuites);
117 BSL_LIST_FREE(peerInfo->caList, CaListNodeDestroy);
118 }
119
120 #if defined(HITLS_TLS_EXTENSION_COOKIE) || defined(HITLS_TLS_FEATURE_ALPN)
CleanNegotiatedInfo(TLS_NegotiatedInfo * negotiatedInfo)121 static void CleanNegotiatedInfo(TLS_NegotiatedInfo *negotiatedInfo)
122 {
123 #ifdef HITLS_TLS_EXTENSION_COOKIE
124 BSL_SAL_FREE(negotiatedInfo->cookie);
125 #endif
126 #ifdef HITLS_TLS_FEATURE_ALPN
127 BSL_SAL_FREE(negotiatedInfo->alpnSelected);
128 #endif
129 return;
130 }
131 #endif
132
133 /**
134 * @ingroup hitls
135 * @brief Release the TLS connection.
136 * @param ctx [IN] TLS connection handle.
137 * @return void
138 */
HITLS_Free(HITLS_Ctx * ctx)139 void HITLS_Free(HITLS_Ctx *ctx)
140 {
141 if (ctx == NULL) {
142 return;
143 }
144 #ifdef HITLS_TLS_CONFIG_STATE
145 ctx->rwstate = HITLS_NOTHING;
146 #endif
147 CONN_Deinit(ctx);
148 BSL_UIO_Free(ctx->uio);
149 #ifdef HITLS_TLS_FEATURE_FLIGHT
150 BSL_UIO_Free(ctx->rUio);
151 ctx->rUio = NULL;
152 #endif
153 ctx->uio = NULL;
154 #ifdef HITLS_TLS_FEATURE_SESSION
155 /* Release certificate resources before releasing the config file. Otherwise, memory leakage occurs */
156 HITLS_SESS_Free(ctx->session);
157 #endif
158 CFG_CleanConfig(&ctx->config.tlsConfig);
159 HITLS_CFG_FreeConfig(ctx->globalConfig);
160 CleanPeerInfo(&(ctx->peerInfo));
161 #if defined(HITLS_TLS_EXTENSION_COOKIE) || defined(HITLS_TLS_FEATURE_ALPN)
162 CleanNegotiatedInfo(&ctx->negotiatedInfo);
163 #endif
164 #ifdef HITLS_TLS_FEATURE_PHA
165 SAL_CRYPT_DigestFree(ctx->phaHash);
166 ctx->phaHash = NULL;
167 SAL_CRYPT_DigestFree(ctx->phaCurHash);
168 ctx->phaCurHash = NULL;
169 ctx->phaState = PHA_NONE;
170 BSL_SAL_FREE(ctx->certificateReqCtx);
171 ctx->certificateReqCtxSize = 0;
172 #endif
173 BSL_SAL_FREE(ctx);
174 return;
175 }
176
177 #ifdef HITLS_TLS_FEATURE_FLIGHT
HITLS_SetReadUio(HITLS_Ctx * ctx,BSL_UIO * uio)178 int32_t HITLS_SetReadUio(HITLS_Ctx *ctx, BSL_UIO *uio)
179 {
180 if ((ctx == NULL) || (uio == NULL)) {
181 return HITLS_NULL_INPUT;
182 }
183
184 int32_t ret = BSL_UIO_UpRef(uio);
185 if (ret != BSL_SUCCESS) {
186 return HITLS_UIO_FAIL;
187 }
188
189 if (ctx->rUio != NULL) {
190 /* A message is displayed, warning the user that the UIO is set repeatedly */
191 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15662, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN,
192 "Warning: Repeated uio setting.", 0, 0, 0, 0);
193 /* Release the original UIO */
194 BSL_UIO_Free(ctx->rUio);
195 }
196
197 ctx->rUio = uio;
198
199 return HITLS_SUCCESS;
200 }
201 #endif
202
ConfigPmtu(HITLS_Ctx * ctx,BSL_UIO * uio)203 static void ConfigPmtu(HITLS_Ctx *ctx, BSL_UIO *uio)
204 {
205 (void)ctx;
206 (void)uio;
207 #ifdef HITLS_TLS_PROTO_DTLS12
208 /* The PMTU needs to be set for DTLS. If the PMTU is not set, use the default value */
209 if ((ctx->config.pmtu == 0) && IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
210 ctx->config.pmtu = DTLS_SCTP_PMTU;
211 }
212 #endif
213 }
214
215 /**
216 * @ingroup hitls
217 * @brief Set the UIO for the HiTLS context.
218 * @attention This function must be called before HITLS_Connect and HITLS_Accept and released after HITLS_Free. If this
219 * function has been called, you must call BSL_UIO_Free to release the UIO.
220 * @param ctx [OUT] TLS connection handle.
221 * @param uio [IN] UIO object
222 * @return HITLS_SUCCESS succeeded
223 * Other Error Codes, see hitls_error.h
224 */
HITLS_SetUio(HITLS_Ctx * ctx,BSL_UIO * uio)225 int32_t HITLS_SetUio(HITLS_Ctx *ctx, BSL_UIO *uio)
226 {
227 if ((ctx == NULL) || (uio == NULL)) {
228 return HITLS_NULL_INPUT;
229 }
230
231 /* The UIO count increases by 1, and the reference counting is performed for the write UIO */
232 int32_t ret = BSL_UIO_UpRef(uio);
233 if (ret != BSL_SUCCESS) {
234 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16474, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN,
235 "UIO_UpRef fail, ret %d", ret, 0, 0, 0);
236 return HITLS_UIO_FAIL;
237 }
238 #ifdef HITLS_TLS_FEATURE_FLIGHT
239 /* The UIO count increases by 1, and the reference counting is performed for reading the UIO */
240 ret = BSL_UIO_UpRef(uio);
241 if (ret != BSL_SUCCESS) {
242 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16475, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN,
243 "UIO_UpRef fail, ret %d", ret, 0, 0, 0);
244 BSL_UIO_Free(uio); // free Drop the one on the top.
245 return HITLS_UIO_FAIL;
246 }
247 #endif
248 /* The original write uio is not empty */
249 if (ctx->uio != NULL) {
250 /* A message is displayed, warning the user that the UIO is set repeatedly. */
251 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15960, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN,
252 "Warning: Repeated uio setting.", 0, 0, 0, 0);
253 /* Release the original write UIO */
254 if (ctx->bUio != NULL) {
255 ctx->uio = BSL_UIO_PopCurrent(ctx->uio);
256 }
257 BSL_UIO_FreeChain(ctx->uio);
258 }
259 ctx->uio = uio;
260 #ifdef HITLS_TLS_FEATURE_FLIGHT
261 if (ctx->bUio != NULL) {
262 ret = BSL_UIO_Append(ctx->bUio, ctx->uio);
263 if (ret != BSL_SUCCESS) {
264 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16476, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN,
265 "UIO_Append fail, ret %d", ret, 0, 0, 0);
266 BSL_UIO_Free(uio); // free Drop the one on the top.
267 return HITLS_UIO_FAIL;
268 }
269 ctx->uio = ctx->bUio;
270 }
271 /* The original read UIO is not empty */
272 if (ctx->rUio != NULL) {
273 /* A message is displayed, warning the user that the UIO is set repeatedly */
274 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15253, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN,
275 "Warning: Repeated uio setting.", 0, 0, 0, 0);
276 /* Release the original read UIO */
277 BSL_UIO_Free(ctx->rUio);
278 }
279 ctx->rUio = uio;
280 #endif
281 ConfigPmtu(ctx, uio);
282 return HITLS_SUCCESS;
283 }
284
HITLS_GetUio(const HITLS_Ctx * ctx)285 BSL_UIO *HITLS_GetUio(const HITLS_Ctx *ctx)
286 {
287 if (ctx == NULL) {
288 return NULL;
289 }
290 #ifdef HITLS_TLS_FEATURE_FLIGHT
291 /* If |bUio| is active, the true caller-configured uio is its |next_uio|. */
292 if (ctx->config.tlsConfig.isFlightTransmitEnable == true && ctx->bUio != NULL) {
293 return BSL_UIO_Next(ctx->bUio);
294 }
295 #endif
296 return ctx->uio;
297 }
298
HITLS_GetReadUio(const HITLS_Ctx * ctx)299 BSL_UIO *HITLS_GetReadUio(const HITLS_Ctx *ctx)
300 {
301 if (ctx == NULL) {
302 return NULL;
303 }
304 return ctx->rUio;
305 }
306
307 /**
308 * @ingroup hitls
309 * @brief Obtain user data from the HiTLS context. Generally, this interface is invoked during the callback registered
310 * with the HiTLS.
311 * @attention must be invoked before HITLS_Connect and HITLS_Accept. The life cycle of the user identifier must be
312 * longer than the life cycle of the TLS object.
313 * @param ctx [OUT] TLS connection handle.
314 * @param userData [IN] User identifier.
315 * @retval HITLS_SUCCESS succeeded.
316 * @retval HITLS_NULL_INPUT The input parameter TLS object is a null pointer.
317 */
HITLS_GetUserData(const HITLS_Ctx * ctx)318 void *HITLS_GetUserData(const HITLS_Ctx *ctx)
319 {
320 if (ctx == NULL) {
321 return NULL;
322 }
323
324 return ctx->config.userData;
325 }
326
327 /**
328 * @ingroup hitls
329 * @brief User data is stored in the HiTLS context and can be obtained from the callback registered with the HiTLS.
330 * @attention must be invoked before HITLS_Connect and HITLS_Accept. The life cycle of the user identifier must be
331 * longer than the life cycle of the TLS object. If the user data needs to be cleared, the
332 * HITLS_SetUserData(ctx, NULL) interface can be invoked directly. The Clean interface is not provided separately.
333 * @param ctx [OUT] TLS connection handle.
334 * @param userData [IN] User identifier.
335 * @retval HITLS_SUCCESS succeeded.
336 * @retval HITLS_NULL_INPUT The input parameter TLS object is a null pointer.
337 */
HITLS_SetUserData(HITLS_Ctx * ctx,void * userData)338 int32_t HITLS_SetUserData(HITLS_Ctx *ctx, void *userData)
339 {
340 if (ctx == NULL) {
341 return HITLS_NULL_INPUT;
342 }
343
344 ctx->config.userData = userData;
345 return HITLS_SUCCESS;
346 }
347
HITLS_SetErrorCode(HITLS_Ctx * ctx,int32_t errorCode)348 int32_t HITLS_SetErrorCode(HITLS_Ctx *ctx, int32_t errorCode)
349 {
350 if (ctx == NULL) {
351 return HITLS_NULL_INPUT;
352 }
353
354 ctx->errorCode = errorCode;
355 return HITLS_SUCCESS;
356 }
357
HITLS_GetErrorCode(const HITLS_Ctx * ctx)358 int32_t HITLS_GetErrorCode(const HITLS_Ctx *ctx)
359 {
360 if (ctx == NULL) {
361 return HITLS_NULL_INPUT;
362 }
363
364 return ctx->errorCode;
365 }
366
367 #ifdef HITLS_TLS_FEATURE_ALPN
HITLS_GetSelectedAlpnProto(HITLS_Ctx * ctx,uint8_t ** proto,uint32_t * protoLen)368 int32_t HITLS_GetSelectedAlpnProto(HITLS_Ctx *ctx, uint8_t **proto, uint32_t *protoLen)
369 {
370 if (ctx == NULL || proto == NULL || protoLen == NULL) {
371 return HITLS_NULL_INPUT;
372 }
373
374 if (ctx->negotiatedInfo.alpnSelected == NULL) {
375 return HITLS_NULL_INPUT;
376 }
377
378 *proto = ctx->negotiatedInfo.alpnSelected;
379 *protoLen = ctx->negotiatedInfo.alpnSelectedSize;
380
381 return HITLS_SUCCESS;
382 }
383 #endif
384
HITLS_IsServer(const HITLS_Ctx * ctx,uint8_t * isServer)385 int32_t HITLS_IsServer(const HITLS_Ctx *ctx, uint8_t *isServer)
386 {
387 if (ctx == NULL || isServer == NULL) {
388 return HITLS_NULL_INPUT;
389 }
390
391 *isServer = 0;
392 if (ctx->isClient == false) {
393 *isServer = 1;
394 }
395
396 return HITLS_SUCCESS;
397 }
398
399 #ifdef HITLS_TLS_FEATURE_SESSION
400 /* Configure the handle for the session information about the HITLS link */
HITLS_SetSession(HITLS_Ctx * ctx,HITLS_Session * session)401 int32_t HITLS_SetSession(HITLS_Ctx *ctx, HITLS_Session *session)
402 {
403 if (ctx == NULL) {
404 return HITLS_NULL_INPUT;
405 }
406
407 /* The client and server are specified only in hitls connect/accept. Therefore, the client cannot be specified here
408 */
409 HITLS_SESS_Free(ctx->session);
410
411 /* Ignore whether the HITLS_SESS_Dup return is NULL or non-NULL */
412 ctx->session = HITLS_SESS_Dup(session);
413 return HITLS_SUCCESS;
414 }
415
416 /* Obtain the session information handle and directly obtain the pointer */
HITLS_GetSession(const HITLS_Ctx * ctx)417 HITLS_Session *HITLS_GetSession(const HITLS_Ctx *ctx)
418 {
419 if (ctx == NULL) {
420 return NULL;
421 }
422 return ctx->session;
423 }
424
425 /* Obtain the handle of the copied session information */
HITLS_GetDupSession(HITLS_Ctx * ctx)426 HITLS_Session *HITLS_GetDupSession(HITLS_Ctx *ctx)
427 {
428 if (ctx == NULL) {
429 return NULL;
430 }
431 return HITLS_SESS_Dup(ctx->session);
432 }
433 #endif
434
435 #ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
HITLS_GetPeerSignatureType(const HITLS_Ctx * ctx,HITLS_SignAlgo * sigType)436 int32_t HITLS_GetPeerSignatureType(const HITLS_Ctx *ctx, HITLS_SignAlgo *sigType)
437 {
438 HITLS_SignAlgo signAlg = HITLS_SIGN_BUTT;
439 HITLS_HashAlgo hashAlg = HITLS_HASH_BUTT;
440
441 if (ctx == NULL || sigType == NULL) {
442 return HITLS_NULL_INPUT;
443 }
444
445 if (CFG_GetSignParamBySchemes(ctx, ctx->peerInfo.peerSignHashAlg,
446 &signAlg, &hashAlg) == false) {
447 return HITLS_CONFIG_NO_SUITABLE_CIPHER_SUITE;
448 }
449
450 *sigType = signAlg;
451
452 return HITLS_SUCCESS;
453 }
454 #endif
455
456 #ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
HITLS_GetLocalSignScheme(const HITLS_Ctx * ctx,HITLS_SignHashAlgo * localSignScheme)457 int32_t HITLS_GetLocalSignScheme(const HITLS_Ctx *ctx, HITLS_SignHashAlgo *localSignScheme)
458 {
459 if (ctx == NULL || localSignScheme == NULL) {
460 return HITLS_NULL_INPUT;
461 }
462
463 *localSignScheme = ctx->negotiatedInfo.signScheme;
464 return HITLS_SUCCESS;
465 }
466 #endif
467
468 #ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
HITLS_GetPeerSignScheme(const HITLS_Ctx * ctx,HITLS_SignHashAlgo * peerSignScheme)469 int32_t HITLS_GetPeerSignScheme(const HITLS_Ctx *ctx, HITLS_SignHashAlgo *peerSignScheme)
470 {
471 if (ctx == NULL || peerSignScheme == NULL) {
472 return HITLS_NULL_INPUT;
473 }
474
475 *peerSignScheme = ctx->peerInfo.peerSignHashAlg;
476 return HITLS_SUCCESS;
477 }
478 #endif
479
HITLS_SetEcGroups(HITLS_Ctx * ctx,uint16_t * lst,uint32_t groupSize)480 int32_t HITLS_SetEcGroups(HITLS_Ctx *ctx, uint16_t *lst, uint32_t groupSize)
481 {
482 if (ctx == NULL) {
483 return HITLS_NULL_INPUT;
484 }
485
486 return HITLS_CFG_SetGroups(&(ctx->config.tlsConfig), lst, groupSize);
487 }
488
HITLS_SetSigalgsList(HITLS_Ctx * ctx,const uint16_t * signAlgs,uint16_t signAlgsSize)489 int32_t HITLS_SetSigalgsList(HITLS_Ctx *ctx, const uint16_t *signAlgs, uint16_t signAlgsSize)
490 {
491 if (ctx == NULL) {
492 return HITLS_NULL_INPUT;
493 }
494
495 return HITLS_CFG_SetSignature(&(ctx->config.tlsConfig), signAlgs, signAlgsSize);
496 }
497
498 #ifdef HITLS_TLS_FEATURE_RENEGOTIATION
HITLS_GetRenegotiationSupport(const HITLS_Ctx * ctx,uint8_t * isSupportRenegotiation)499 int32_t HITLS_GetRenegotiationSupport(const HITLS_Ctx *ctx, uint8_t *isSupportRenegotiation)
500 {
501 if (ctx == NULL) {
502 return HITLS_NULL_INPUT;
503 }
504
505 return HITLS_CFG_GetRenegotiationSupport(&(ctx->config.tlsConfig), isSupportRenegotiation);
506 }
507 #endif
508
HITLS_SetEcPointFormats(HITLS_Ctx * ctx,const uint8_t * pointFormats,uint32_t pointFormatsSize)509 int32_t HITLS_SetEcPointFormats(HITLS_Ctx *ctx, const uint8_t *pointFormats, uint32_t pointFormatsSize)
510 {
511 if (ctx == NULL) {
512 return HITLS_NULL_INPUT;
513 }
514 return HITLS_CFG_SetEcPointFormats(&(ctx->config.tlsConfig), pointFormats, pointFormatsSize);
515 }
516
HITLS_ClearChainCerts(HITLS_Ctx * ctx)517 int32_t HITLS_ClearChainCerts(HITLS_Ctx *ctx)
518 {
519 if (ctx == NULL || ctx->config.tlsConfig.certMgrCtx == NULL) {
520 return HITLS_NULL_INPUT;
521 }
522
523 return HITLS_CFG_ClearChainCerts(&(ctx->config.tlsConfig));
524 }
525
526 #ifdef HITLS_TLS_FEATURE_CERT_MODE
HITLS_SetClientVerifySupport(HITLS_Ctx * ctx,bool support)527 int32_t HITLS_SetClientVerifySupport(HITLS_Ctx *ctx, bool support)
528 {
529 if (ctx == NULL) {
530 return HITLS_NULL_INPUT;
531 }
532 return HITLS_CFG_SetClientVerifySupport(&(ctx->config.tlsConfig), support);
533 }
534
HITLS_SetNoClientCertSupport(HITLS_Ctx * ctx,bool support)535 int32_t HITLS_SetNoClientCertSupport(HITLS_Ctx *ctx, bool support)
536 {
537 if (ctx == NULL) {
538 return HITLS_NULL_INPUT;
539 }
540
541 return HITLS_CFG_SetNoClientCertSupport(&(ctx->config.tlsConfig), support);
542 }
543 #endif
544 #ifdef HITLS_TLS_FEATURE_PHA
HITLS_SetPostHandshakeAuthSupport(HITLS_Ctx * ctx,bool support)545 int32_t HITLS_SetPostHandshakeAuthSupport(HITLS_Ctx *ctx, bool support)
546 {
547 if (ctx == NULL) {
548 return HITLS_NULL_INPUT;
549 }
550
551 return HITLS_CFG_SetPostHandshakeAuthSupport(&(ctx->config.tlsConfig), support);
552 }
553 #endif
554 #ifdef HITLS_TLS_FEATURE_CERT_MODE
HITLS_SetVerifyNoneSupport(HITLS_Ctx * ctx,bool support)555 int32_t HITLS_SetVerifyNoneSupport(HITLS_Ctx *ctx, bool support)
556 {
557 if (ctx == NULL) {
558 return HITLS_NULL_INPUT;
559 }
560
561 return HITLS_CFG_SetVerifyNoneSupport(&(ctx->config.tlsConfig), support);
562 }
563 #endif
564 #if defined(HITLS_TLS_FEATURE_CERT_MODE) && defined(HITLS_TLS_FEATURE_RENEGOTIATION)
HITLS_SetClientOnceVerifySupport(HITLS_Ctx * ctx,bool support)565 int32_t HITLS_SetClientOnceVerifySupport(HITLS_Ctx *ctx, bool support)
566 {
567 if (ctx == NULL) {
568 return HITLS_NULL_INPUT;
569 }
570
571 return HITLS_CFG_SetClientOnceVerifySupport(&(ctx->config.tlsConfig), support);
572 }
573 #endif
574 #ifdef HITLS_TLS_CONFIG_MANUAL_DH
HITLS_SetDhAutoSupport(HITLS_Ctx * ctx,bool support)575 int32_t HITLS_SetDhAutoSupport(HITLS_Ctx *ctx, bool support)
576 {
577 if (ctx == NULL) {
578 return HITLS_NULL_INPUT;
579 }
580
581 return HITLS_CFG_SetDhAutoSupport(&(ctx->config.tlsConfig), support);
582 }
583
HITLS_SetTmpDh(HITLS_Ctx * ctx,HITLS_CRYPT_Key * dhPkey)584 int32_t HITLS_SetTmpDh(HITLS_Ctx *ctx, HITLS_CRYPT_Key *dhPkey)
585 {
586 if (ctx == NULL) {
587 return HITLS_NULL_INPUT;
588 }
589
590 return HITLS_CFG_SetTmpDh(&(ctx->config.tlsConfig), dhPkey);
591 }
592 #endif
593 #if defined(HITLS_TLS_CONNECTION_INFO_NEGOTIATION) && defined(HITLS_TLS_FEATURE_SESSION)
HITLS_GetPeerCertChain(const HITLS_Ctx * ctx)594 HITLS_CERT_Chain *HITLS_GetPeerCertChain(const HITLS_Ctx *ctx)
595 {
596 CERT_Pair *certPair = NULL;
597 if (ctx == NULL) {
598 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16477, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "ctx null", 0, 0, 0, 0);
599 return NULL;
600 }
601
602 int32_t ret = SESS_GetPeerCert(ctx->session, &certPair);
603 if (ret != HITLS_SUCCESS || certPair == NULL) {
604 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16478, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
605 "ret %d, GetPeerCert fail", ret, 0, 0, 0);
606 return NULL;
607 }
608
609 HITLS_CERT_Chain *certChain = SAL_CERT_PairGetChain(certPair);
610 return certChain;
611 }
612 #endif
613 #ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
HITLS_GetClientCAList(const HITLS_Ctx * ctx)614 HITLS_TrustedCAList *HITLS_GetClientCAList(const HITLS_Ctx *ctx)
615 {
616 if (ctx == NULL) {
617 return NULL;
618 }
619
620 if (ctx->isClient) {
621 return ctx->peerInfo.caList;
622 }
623 return ctx->globalConfig->caList;
624 }
625 #endif
626 #ifdef HITLS_TLS_FEATURE_RENEGOTIATION
HITLS_GetSecureRenegotiationSupport(const HITLS_Ctx * ctx,uint8_t * isSecureRenegotiation)627 int32_t HITLS_GetSecureRenegotiationSupport(const HITLS_Ctx *ctx, uint8_t *isSecureRenegotiation)
628 {
629 if (ctx == NULL || isSecureRenegotiation == NULL) {
630 return HITLS_NULL_INPUT;
631 }
632
633 *isSecureRenegotiation = (uint8_t)ctx->negotiatedInfo.isSecureRenegotiation;
634 return HITLS_SUCCESS;
635 }
636 #endif
637 #ifdef HITLS_TLS_MAINTAIN_KEYLOG
Uint8ToHex(const uint8_t * srcBuf,size_t srcLen,size_t * offset,size_t destMaxSize,uint8_t * destBuf)638 static int32_t Uint8ToHex(const uint8_t *srcBuf, size_t srcLen, size_t *offset,
639 size_t destMaxSize, uint8_t *destBuf)
640 {
641 if (destMaxSize < 1) {
642 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16479, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
643 "destMaxSize err", 0, 0, 0, 0);
644 return HITLS_NULL_INPUT;
645 }
646 size_t length = (destMaxSize - 1) / 2;
647 if (destBuf == NULL || offset == NULL || srcLen == 0 || srcBuf == NULL || length < srcLen) {
648 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16480, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "input null", 0, 0, 0, 0);
649 return HITLS_NULL_INPUT;
650 }
651 /* Initialize Offset */
652 size_t offsetTemp = 0u;
653 /* Converting an Array to a Hexadecimal Character String */
654 for (size_t i = 0u; i < srcLen; i++) {
655 if (sprintf_s((char *)&destBuf[offsetTemp], (destMaxSize - offsetTemp), "%02x", srcBuf[i]) == -1) {
656 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16481, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
657 "sprintf_s fail", 0, 0, 0, 0);
658 return HITLS_INVALID_INPUT;
659 }
660 offsetTemp += sizeof(uint16_t);
661 if (offsetTemp >= destMaxSize) {
662 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16482, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
663 "There's not enough memory", 0, 0, 0, 0);
664 return HITLS_INVALID_INPUT;
665 }
666 }
667 /* Update Offset */
668 *offset = offsetTemp;
669
670 return HITLS_SUCCESS;
671 }
672
HITLS_LogSecret(HITLS_Ctx * ctx,const char * label,const uint8_t * secret,size_t secretLen)673 int32_t HITLS_LogSecret(HITLS_Ctx *ctx, const char *label, const uint8_t *secret, size_t secretLen)
674 {
675 if (ctx == NULL || label == NULL || secret == NULL || secretLen == 0) {
676 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16483, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "input null", 0, 0, 0, 0);
677 return HITLS_NULL_INPUT;
678 }
679 if (ctx->globalConfig->keyLogCb == NULL) {
680 return HITLS_SUCCESS;
681 }
682 size_t offset = 0;
683 uint8_t *random = ctx->negotiatedInfo.clientRandom;
684 uint32_t randomLen = RANDOM_SIZE;
685 size_t labelLen = strlen(label);
686 const uint8_t blankSpace = 0x20;
687 // The lengths of random and secret need to be converted into hexadecimal so they are doubled.
688 size_t outLen = labelLen + randomLen + randomLen + secretLen + secretLen + 3;
689 uint8_t *outBuffer = (uint8_t *)BSL_SAL_Calloc((uint32_t)outLen, sizeof(uint8_t));
690 if (outBuffer == NULL) {
691 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16484, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Calloc fail", 0, 0, 0, 0);
692 return HITLS_MEMALLOC_FAIL;
693 }
694
695 // Combine label, random, and secret into a character string separated by spaces and end with '\0'.
696 (void)memcpy_s(outBuffer, outLen, label, labelLen);
697 offset += labelLen;
698 outBuffer[offset++] = blankSpace;
699 size_t index = 0;
700
701 // Convert random to a hexadecimal character string.
702 int32_t ret = Uint8ToHex(random, randomLen, &index, outLen - offset, &outBuffer[offset]);
703 if (ret != HITLS_SUCCESS) {
704 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16485, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
705 "random Uint8ToHex fail", 0, 0, 0, 0);
706 BSL_SAL_FREE(outBuffer);
707 return ret;
708 }
709 offset += index;
710 outBuffer[offset++] = blankSpace;
711
712 // Convert the master key buffer to a hexadecimal character string.
713 ret = Uint8ToHex(secret, secretLen, &index, outLen - offset, &outBuffer[offset]);
714 if (ret != HITLS_SUCCESS) {
715 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16486, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
716 "secret Uint8ToHex fail", 0, 0, 0, 0);
717 BSL_SAL_FREE(outBuffer);
718 return ret;
719 }
720
721 ctx->globalConfig->keyLogCb(ctx, (const char *)outBuffer);
722
723 BSL_SAL_CleanseData(outBuffer, outLen);
724 BSL_SAL_FREE(outBuffer);
725
726 return HITLS_SUCCESS;
727 }
728 #endif /* HITLS_TLS_MAINTAIN_KEYLOG */