• 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 #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 */