* This file is part of the openHiTLS project.
*
* openHiTLS is licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <stdint.h>
#include <stdbool.h>
#include "hitls_build.h"
#include <string.h>
#include "bsl_log_internal.h"
#include "bsl_err_internal.h"
#include "bsl_log.h"
#include "bsl_sal.h"
#include "bsl_list.h"
#include "hitls_type.h"
#include "hitls_error.h"
#ifdef HITLS_TLS_FEATURE_PSK
#include "hitls_psk.h"
#endif
#ifdef HITLS_TLS_PROTO_DTLS12
#include "hitls_cookie.h"
#endif
#ifdef HITLS_TLS_FEATURE_ALPN
#include "hitls_alpn.h"
#endif
#include "hitls_cert_type.h"
#ifdef HITLS_TLS_FEATURE_SNI
#include "hitls_sni.h"
#endif
#include "tls.h"
#include "tls_binlog_id.h"
#include "cert.h"
#include "crypt.h"
#ifdef HITLS_TLS_FEATURE_SESSION
#include "session_mgr.h"
#endif
#include "config_check.h"
#include "config_default.h"
#include "rec.h"
#include "config_type.h"
#include "cert_method.h"
#ifdef HITLS_TLS_FEATURE_SECURITY
#include "security.h"
#endif
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
#include "custom_extensions.h"
#endif
void CFG_CleanConfig(HITLS_Config *config)
{
BSL_SAL_FREE(config->cipherSuites);
#ifdef HITLS_TLS_PROTO_TLS13
BSL_SAL_FREE(config->tls13CipherSuites);
#endif
BSL_SAL_FREE(config->pointFormats);
BSL_SAL_FREE(config->groups);
BSL_SAL_FREE(config->tuples);
BSL_SAL_FREE(config->signAlgorithms);
#ifdef HITLS_TLS_FEATURE_PROVIDER_DYNAMIC
#ifndef HITLS_TLS_CAP_NO_STR
for (uint32_t i = 0; i < config->groupInfolen; i++) {
BSL_SAL_FREE(config->groupInfo[i].name);
}
#endif
BSL_SAL_FREE(config->groupInfo);
config->groupInfoSize = 0;
config->groupInfolen = 0;
#ifndef HITLS_TLS_CAP_NO_STR
for (uint32_t i = 0; i < config->sigSchemeInfolen; i++) {
BSL_SAL_FREE(config->sigSchemeInfo[i].name);
}
#endif
BSL_SAL_FREE(config->sigSchemeInfo);
config->sigSchemeInfoSize = 0;
config->sigSchemeInfolen = 0;
#endif
#if defined(HITLS_TLS_PROTO_TLS12) && defined(HITLS_TLS_FEATURE_PSK)
BSL_SAL_FREE(config->pskIdentityHint);
#endif
#ifdef HITLS_TLS_FEATURE_ALPN
BSL_SAL_FREE(config->alpnList);
#endif
#ifdef HITLS_TLS_FEATURE_SNI
BSL_SAL_FREE(config->serverName);
#endif
#ifdef HITLS_TLS_FEATURE_CERTIFICATE_AUTHORITIES
HITLS_CFG_ClearCAList(config);
#endif
#ifdef HITLS_TLS_CONFIG_MANUAL_DH
SAL_CRYPT_FreeDhKey(config->dhTmp);
config->dhTmp = NULL;
#endif
#ifdef HITLS_TLS_FEATURE_SESSION
SESSMGR_Free(config->sessMgr);
config->sessMgr = NULL;
#endif
SAL_CERT_MgrCtxFree(config->certMgrCtx);
config->certMgrCtx = NULL;
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
FreeCustomExtensions(config->customExts);
config->customExts = NULL;
#endif
BSL_SAL_ReferencesFree(&(config->references));
#ifdef HITLS_TLS_FEATURE_SESSION_CUSTOM_TICKET
BSL_SAL_FREE(config->sessionTicketExt);
config->sessionTicketExtSize = 0;
#endif
}
static void ShallowCopy(HITLS_Ctx *ctx, const HITLS_Config *srcConfig)
{
HITLS_Config *destConfig = &ctx->config.tlsConfig;
* Other parameters except CipherSuite, PointFormats, Group, SignAlgorithms, Psk, SessionId, CertMgr, and SessMgr
* are shallowly copied, and some of them reference globalConfig.
*/
destConfig->libCtx = LIBCTX_FROM_CONFIG(srcConfig);
destConfig->attrName = ATTRIBUTE_FROM_CONFIG(srcConfig);
destConfig->minVersion = srcConfig->minVersion;
destConfig->maxVersion = srcConfig->maxVersion;
(void)memcpy(destConfig->keyshareIndex, srcConfig->keyshareIndex, sizeof(srcConfig->keyshareIndex));
#ifdef HITLS_TLS_PROTO_CLOSE_STATE
destConfig->isQuietShutdown = srcConfig->isQuietShutdown;
#endif
#ifdef HITLS_TLS_PROTO_DFX_SERVER_PREFER
destConfig->isSupportServerPreference = srcConfig->isSupportServerPreference;
#endif
destConfig->maxCertList = srcConfig->maxCertList;
destConfig->emsMode = srcConfig->emsMode;
destConfig->emptyRecordsNum = srcConfig->emptyRecordsNum;
destConfig->isKeepPeerCert = srcConfig->isKeepPeerCert;
destConfig->version = srcConfig->version;
destConfig->originVersionMask = srcConfig->originVersionMask;
destConfig->endpoint = srcConfig->endpoint;
#ifdef HITLS_TLS_PROTO_TLS13
destConfig->isMiddleBoxCompat = srcConfig->isMiddleBoxCompat;
#endif
#ifdef HITLS_TLS_FEATURE_MAX_SEND_FRAGMENT
destConfig->maxSendFragment = srcConfig->maxSendFragment;
#endif
#ifdef HITLS_TLS_FEATURE_REC_INBUFFER_SIZE
destConfig->recInbufferSize = srcConfig->recInbufferSize;
#endif
#ifdef HITLS_TLS_FEATURE_RENEGOTIATION
destConfig->isSupportRenegotiation = srcConfig->isSupportRenegotiation;
destConfig->allowClientRenegotiate = srcConfig->allowClientRenegotiate;
#endif
#if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
destConfig->allowLegacyRenegotiate = srcConfig->allowLegacyRenegotiate;
#endif
#ifdef HITLS_TLS_SUITE_KX_RSA
destConfig->needCheckPmsVersion = srcConfig->needCheckPmsVersion;
#endif
#ifdef HITLS_TLS_CONFIG_KEY_USAGE
destConfig->needCheckKeyUsage = srcConfig->needCheckKeyUsage;
#endif
destConfig->userData = srcConfig->userData;
destConfig->userDataFreeCb = srcConfig->userDataFreeCb;
#ifdef HITLS_TLS_FEATURE_MODE
destConfig->modeSupport = srcConfig->modeSupport;
#endif
destConfig->readAhead = srcConfig->readAhead;
destConfig->recordPaddingCb = srcConfig->recordPaddingCb;
destConfig->recordPaddingArg = srcConfig->recordPaddingArg;
#ifdef HITLS_TLS_CONFIG_MANUAL_DH
destConfig->isSupportDhAuto = srcConfig->isSupportDhAuto;
destConfig->dhTmpCb = srcConfig->dhTmpCb;
#endif
#if defined(HITLS_TLS_FEATURE_RENEGOTIATION) && defined(HITLS_TLS_FEATURE_SESSION)
destConfig->isResumptionOnRenego = srcConfig->isResumptionOnRenego;
#endif
#ifdef HITLS_TLS_FEATURE_CERT_MODE_VERIFY_PEER
destConfig->isSupportVerifyNone = srcConfig->isSupportVerifyNone;
#endif
#ifdef HITLS_TLS_FEATURE_CERT_MODE_CLIENT_VERIFY
destConfig->isSupportClientVerify = srcConfig->isSupportClientVerify;
destConfig->isSupportNoClientCert = srcConfig->isSupportNoClientCert;
destConfig->isSupportClientOnceVerify = srcConfig->isSupportClientOnceVerify;
#endif
#ifdef HITLS_TLS_FEATURE_SESSION_TICKET
destConfig->isSupportSessionTicket = srcConfig->isSupportSessionTicket;
#endif
#ifdef HITLS_TLS_FEATURE_PHA
destConfig->isSupportPostHandshakeAuth = srcConfig->isSupportPostHandshakeAuth;
#endif
#ifdef HITLS_TLS_FEATURE_PSK
destConfig->pskClientCb = srcConfig->pskClientCb;
destConfig->pskServerCb = srcConfig->pskServerCb;
#endif
#ifdef HITLS_TLS_PROTO_TLS13
destConfig->keyExchMode = srcConfig->keyExchMode;
#endif
#ifdef HITLS_TLS_FEATURE_INDICATOR
destConfig->infoCb = srcConfig->infoCb;
destConfig->msgCb = srcConfig->msgCb;
destConfig->msgArg = srcConfig->msgArg;
#endif
#if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
destConfig->dtlsTimerCb = srcConfig->dtlsTimerCb;
destConfig->dtlsPostHsTimeoutVal = srcConfig->dtlsPostHsTimeoutVal;
destConfig->isSupportDtlsCookieExchange = srcConfig->isSupportDtlsCookieExchange;
#endif
#ifdef HITLS_TLS_FEATURE_SECURITY
destConfig->securityCb = srcConfig->securityCb;
destConfig->securityExData = srcConfig->securityExData;
destConfig->securityLevel = srcConfig->securityLevel;
#endif
#ifdef HITLS_TLS_SUITE_CIPHER_CBC
destConfig->isEncryptThenMac = srcConfig->isEncryptThenMac;
#endif
#if defined(HITLS_TLS_PROTO_TLS13) && defined(HITLS_TLS_FEATURE_PSK)
destConfig->pskFindSessionCb = srcConfig->pskFindSessionCb;
destConfig->pskUseSessionCb = srcConfig->pskUseSessionCb;
#endif
#ifdef HITLS_TLS_FEATURE_SESSION_TICKET
destConfig->ticketNums = srcConfig->ticketNums;
#endif
#ifdef HITLS_TLS_FEATURE_FLIGHT
destConfig->isFlightTransmitEnable = srcConfig->isFlightTransmitEnable;
#endif
#ifdef HITLS_TLS_FEATURE_RECORD_SIZE_LIMIT
destConfig->recordSizeLimit = srcConfig->recordSizeLimit;
#endif
}
static int32_t DeepCopy(void** destConfig, const void* srcConfig, uint32_t logId, uint32_t len)
{
#ifndef HITLS_BSL_LOG
(void)logId;
#endif
if (*destConfig != NULL) {
BSL_SAL_Free(*destConfig);
}
*destConfig = BSL_SAL_Dump(srcConfig, len);
if (*destConfig == NULL) {
BSL_LOG_BINLOG_FIXLEN(logId, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Dump fail", 0, 0, 0, 0);
return HITLS_MEMALLOC_FAIL;
}
return HITLS_SUCCESS;
}
static int32_t PointFormatsCfgDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (srcConfig->pointFormats != NULL) {
int32_t ret = DeepCopy((void **)&destConfig->pointFormats, srcConfig->pointFormats, BINLOG_ID16584,
srcConfig->pointFormatsSize * sizeof(uint8_t));
if (ret != HITLS_SUCCESS) {
return ret;
}
destConfig->pointFormatsSize = srcConfig->pointFormatsSize;
}
return HITLS_SUCCESS;
}
static int32_t GroupCfgDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (srcConfig->groups != NULL) {
int32_t ret = DeepCopy((void **)&destConfig->groups, srcConfig->groups, BINLOG_ID16585,
srcConfig->groupsSize * sizeof(uint16_t));
if (ret != HITLS_SUCCESS) {
return ret;
}
destConfig->groupsSize = srcConfig->groupsSize;
}
if (srcConfig->tuples != NULL) {
int32_t ret2 = DeepCopy((void **)&destConfig->tuples, srcConfig->tuples, BINLOG_ID16585,
srcConfig->tuplesSize * sizeof(uint32_t));
if (ret2 != HITLS_SUCCESS) {
return ret2;
}
destConfig->tuplesSize = srcConfig->tuplesSize;
}
#ifdef HITLS_TLS_FEATURE_PROVIDER_DYNAMIC
if (srcConfig->groupInfo != NULL) {
#ifndef HITLS_TLS_CAP_NO_STR
for (uint32_t i = 0; i < destConfig->groupInfolen; i++) {
BSL_SAL_FREE(destConfig->groupInfo[i].name);
}
#endif
BSL_SAL_FREE(destConfig->groupInfo);
destConfig->groupInfoSize = 0;
destConfig->groupInfolen = 0;
destConfig->groupInfo= BSL_SAL_Calloc(srcConfig->groupInfolen, sizeof(TLS_GroupInfo));
if (destConfig->groupInfo == NULL) {
return HITLS_MEMALLOC_FAIL;
}
destConfig->groupInfoSize = srcConfig->groupInfolen;
for (uint32_t i = 0; i < srcConfig->groupInfolen; i++) {
destConfig->groupInfo[i] = srcConfig->groupInfo[i];
#ifndef HITLS_TLS_CAP_NO_STR
destConfig->groupInfo[i].name =
BSL_SAL_Dump(srcConfig->groupInfo[i].name, strlen(srcConfig->groupInfo[i].name) + 1);
if (destConfig->groupInfo[i].name == NULL) {
return HITLS_MEMALLOC_FAIL;
}
#endif
destConfig->groupInfolen++;
}
}
#endif
return HITLS_SUCCESS;
}
#if defined(HITLS_TLS_PROTO_TLS12) && defined(HITLS_TLS_FEATURE_PSK)
static int32_t PskCfgDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (srcConfig->pskIdentityHint != NULL) {
if (destConfig->pskIdentityHint != NULL) {
BSL_SAL_Free(destConfig->pskIdentityHint);
}
destConfig->pskIdentityHint = BSL_SAL_Dump(srcConfig->pskIdentityHint, srcConfig->hintSize * sizeof(uint8_t));
if (destConfig->pskIdentityHint == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16586, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Dump fail", 0, 0, 0, 0);
return HITLS_MEMALLOC_FAIL;
}
destConfig->hintSize = srcConfig->hintSize;
}
return HITLS_SUCCESS;
}
#endif
static int32_t SignAlgorithmsCfgDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (srcConfig->signAlgorithms != NULL) {
int32_t ret = DeepCopy((void **)&destConfig->signAlgorithms, srcConfig->signAlgorithms, BINLOG_ID16587,
srcConfig->signAlgorithmsSize * sizeof(uint16_t));
if (ret != HITLS_SUCCESS) {
return ret;
}
destConfig->signAlgorithmsSize = srcConfig->signAlgorithmsSize;
}
#ifdef HITLS_TLS_FEATURE_PROVIDER_DYNAMIC
if (srcConfig->sigSchemeInfo != NULL) {
#ifndef HITLS_TLS_CAP_NO_STR
for (uint32_t i = 0; i < destConfig->sigSchemeInfolen; i++) {
BSL_SAL_FREE(destConfig->sigSchemeInfo[i].name);
}
#endif
BSL_SAL_FREE(destConfig->sigSchemeInfo);
destConfig->sigSchemeInfoSize = 0;
destConfig->sigSchemeInfolen = 0;
destConfig->sigSchemeInfo = BSL_SAL_Calloc(srcConfig->sigSchemeInfolen, sizeof(TLS_SigSchemeInfo));
if (destConfig->sigSchemeInfo == NULL) {
return HITLS_MEMALLOC_FAIL;
}
destConfig->sigSchemeInfoSize = srcConfig->sigSchemeInfolen;
for (uint32_t i = 0; i < srcConfig->sigSchemeInfolen; i++) {
destConfig->sigSchemeInfo[i] = srcConfig->sigSchemeInfo[i];
#ifndef HITLS_TLS_CAP_NO_STR
destConfig->sigSchemeInfo[i].name =
BSL_SAL_Dump(srcConfig->sigSchemeInfo[i].name, strlen(srcConfig->sigSchemeInfo[i].name) + 1);
if (destConfig->sigSchemeInfo[i].name == NULL) {
return HITLS_MEMALLOC_FAIL;
}
#endif
destConfig->sigSchemeInfolen++;
}
}
#endif
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_FEATURE_ALPN
static int32_t AlpnListDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (srcConfig->alpnListSize == 0 || srcConfig->alpnList == NULL) {
return HITLS_SUCCESS;
}
BSL_SAL_FREE(destConfig->alpnList);
destConfig->alpnList = BSL_SAL_Dump(srcConfig->alpnList, (srcConfig->alpnListSize + 1) * sizeof(uint8_t));
if (destConfig->alpnList == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16588, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Dump fail", 0, 0, 0, 0);
return HITLS_MEMALLOC_FAIL;
}
destConfig->alpnListSize = srcConfig->alpnListSize;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_SNI
static int32_t ServerNameDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (srcConfig->serverNameSize != 0 && srcConfig->serverName != NULL) {
int32_t ret = DeepCopy((void **)&destConfig->serverName, srcConfig->serverName, BINLOG_ID16589,
srcConfig->serverNameSize * sizeof(uint8_t));
if (ret != HITLS_SUCCESS) {
return ret;
}
destConfig->serverNameSize = srcConfig->serverNameSize;
}
return HITLS_SUCCESS;
}
#endif
static int32_t CipherSuiteDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (srcConfig->cipherSuites != NULL) {
int32_t ret = DeepCopy((void **)&destConfig->cipherSuites, srcConfig->cipherSuites, BINLOG_ID16590,
srcConfig->cipherSuitesSize * sizeof(uint16_t));
if (ret != HITLS_SUCCESS) {
return ret;
}
destConfig->cipherSuitesSize = srcConfig->cipherSuitesSize;
}
#ifdef HITLS_TLS_PROTO_TLS13
if (srcConfig->tls13CipherSuites != NULL) {
int32_t ret = DeepCopy((void **)&destConfig->tls13CipherSuites, srcConfig->tls13CipherSuites, BINLOG_ID16591,
srcConfig->tls13cipherSuitesSize * sizeof(uint16_t));
if (ret != HITLS_SUCCESS) {
BSL_SAL_FREE(destConfig->cipherSuites);
return ret;
}
destConfig->tls13cipherSuitesSize = srcConfig->tls13cipherSuitesSize;
}
#endif
return HITLS_SUCCESS;
}
static int32_t CertMgrDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (!SAL_CERT_MgrIsEnable()) {
return HITLS_SUCCESS;
}
destConfig->certMgrCtx = SAL_CERT_MgrCtxDup(srcConfig->certMgrCtx);
if (destConfig->certMgrCtx == NULL) {
return HITLS_CERT_ERR_MGR_DUP;
}
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_FEATURE_SESSION_ID
static int32_t SessionIdCtxCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (srcConfig->sessionIdCtxSize != 0 && srcConfig->sessionIdCtxSize > sizeof(destConfig->sessionIdCtx)) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16592, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "memcpy fail", 0, 0, 0, 0);
return HITLS_MEMCPY_FAIL;
}
memcpy(destConfig->sessionIdCtx, srcConfig->sessionIdCtx, srcConfig->sessionIdCtxSize);
destConfig->sessionIdCtxSize = srcConfig->sessionIdCtxSize;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_CONFIG_MANUAL_DH
static int32_t CryptKeyDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (srcConfig->dhTmp != NULL) {
destConfig->dhTmp = SAL_CRYPT_DupDhKey(srcConfig->dhTmp);
if (destConfig->dhTmp == NULL) {
return HITLS_CONFIG_DUP_DH_KEY_FAIL;
}
}
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_CERTIFICATE_AUTHORITIES
void FreeNode(HITLS_TrustedCANode *node)
{
BSL_SAL_FREE(node->data);
BSL_SAL_FREE(node);
}
static HITLS_TrustedCANode *DupNameNode(const HITLS_TrustedCANode *src)
{
HITLS_TrustedCANode *dest = BSL_SAL_Malloc(sizeof(HITLS_TrustedCANode));
if (dest == NULL) {
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
return NULL;
}
dest->caType = src->caType;
dest->dataSize = src->dataSize;
if (dest->dataSize != 0) {
dest->data = BSL_SAL_Dump(src->data, src->dataSize);
if (dest->data == NULL) {
BSL_SAL_Free(dest);
BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
return NULL;
}
}
return dest;
}
static int32_t CaListDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
if (srcConfig->caList != NULL) {
destConfig->caList =
BSL_LIST_Copy(srcConfig->caList, (BSL_LIST_PFUNC_DUP)DupNameNode, (BSL_LIST_PFUNC_FREE)FreeNode);
if (destConfig->caList == NULL) {
return HITLS_MEMCPY_FAIL;
}
}
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
static int32_t CustomExtsDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
destConfig->customExts = DupCustomExtensions(srcConfig->customExts);
if (srcConfig->customExts != NULL && destConfig->customExts == NULL) {
return HITLS_MEMALLOC_FAIL;
}
return HITLS_SUCCESS;
}
#endif
static int32_t BasicConfigDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig)
{
int32_t ret = HITLS_SUCCESS;
const struct {
int32_t (*copyFunc)(HITLS_Config *destConfig, const HITLS_Config *srcConfig);
} copyFeatures[] = {
#ifdef HITLS_TLS_FEATURE_SESSION_ID
{SessionIdCtxCopy},
#endif
{CertMgrDeepCopy},
#ifdef HITLS_TLS_FEATURE_ALPN
{AlpnListDeepCopy},
#endif
#ifdef HITLS_TLS_FEATURE_SNI
{ServerNameDeepCopy},
#endif
#ifdef HITLS_TLS_CONFIG_MANUAL_DH
{CryptKeyDeepCopy},
#endif
#ifdef HITLS_TLS_FEATURE_CERTIFICATE_AUTHORITIES
{CaListDeepCopy},
#endif
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
{CustomExtsDeepCopy},
#endif
};
for (size_t i = 0; i < sizeof(copyFeatures) / sizeof(copyFeatures[0]); i++) {
if (copyFeatures[i].copyFunc != NULL) {
ret = copyFeatures[i].copyFunc(destConfig, srcConfig);
if (ret != HITLS_SUCCESS) {
return ret;
}
}
}
return HITLS_SUCCESS;
}
int32_t DumpConfig(HITLS_Ctx *ctx, const HITLS_Config *srcConfig)
{
int32_t ret;
HITLS_Config *destConfig = &ctx->config.tlsConfig;
ShallowCopy(ctx, srcConfig);
ret = CipherSuiteDeepCopy(destConfig, srcConfig);
if (ret != HITLS_SUCCESS) {
goto EXIT;
}
ret = PointFormatsCfgDeepCopy(destConfig, srcConfig);
if (ret != HITLS_SUCCESS) {
goto EXIT;
}
ret = GroupCfgDeepCopy(destConfig, srcConfig);
if (ret != HITLS_SUCCESS) {
goto EXIT;
}
ret = SignAlgorithmsCfgDeepCopy(destConfig, srcConfig);
if (ret != HITLS_SUCCESS) {
goto EXIT;
}
#if defined(HITLS_TLS_PROTO_TLS12) && defined(HITLS_TLS_FEATURE_PSK)
ret = PskCfgDeepCopy(destConfig, srcConfig);
if (ret != HITLS_SUCCESS) {
goto EXIT;
}
#endif
ret = BasicConfigDeepCopy(destConfig, srcConfig);
if (ret != HITLS_SUCCESS) {
goto EXIT;
}
return HITLS_SUCCESS;
EXIT:
CFG_CleanConfig(destConfig);
return ret;
}
HITLS_Config *CreateConfig(void)
{
HITLS_Config *newConfig = BSL_SAL_Calloc(1u, sizeof(HITLS_Config));
if (newConfig == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16594, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Calloc fail", 0, 0, 0, 0);
return NULL;
}
if (BSL_SAL_ReferencesInit(&(newConfig->references)) != BSL_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16595, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"ReferencesInit fail", 0, 0, 0, 0);
BSL_SAL_Free(newConfig);
return NULL;
}
return newConfig;
}
void HITLS_CFG_FreeConfig(HITLS_Config *config)
{
if (config == NULL) {
return;
}
int ret = 0;
(void)BSL_SAL_AtomicDownReferences(&(config->references), &ret);
if (ret > 0) {
return;
}
CFG_CleanConfig(config);
#ifdef HITLS_TLS_CONFIG_USER_DATA
if (config->userData != NULL && config->userDataFreeCb != NULL) {
(void)config->userDataFreeCb(config->userData);
config->userData = NULL;
}
#endif
BSL_SAL_Free(config);
}
int32_t HITLS_CFG_UpRef(HITLS_Config *config)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
int ret = 0;
(void)BSL_SAL_AtomicUpReferences(&(config->references), &ret);
(void)ret;
return HITLS_SUCCESS;
}
uint32_t MapVersion2VersionBit(bool isDatagram, uint16_t version)
{
(void)isDatagram;
uint32_t ret = 0;
switch (version) {
case HITLS_VERSION_TLS12:
ret = TLS12_VERSION_BIT;
break;
case HITLS_VERSION_TLS13:
ret = TLS13_VERSION_BIT;
break;
case HITLS_VERSION_TLCP_DTLCP11:
if (isDatagram) {
ret = DTLCP11_VERSION_BIT;
} else {
ret = TLCP11_VERSION_BIT;
}
break;
case HITLS_VERSION_DTLS12:
ret = DTLS12_VERSION_BIT;
break;
default:
break;
}
return ret;
}
#ifdef HITLS_TLS_FEATURE_RENEGOTIATION
int32_t CheckRenegotiatedVersion(TLS_Ctx *ctx)
{
if (ctx->negotiatedInfo.isRenegotiation) {
uint16_t oldNegotiationVersion = ctx->negotiatedInfo.version;
uint32_t versionBit =
MapVersion2VersionBit(IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask), oldNegotiationVersion);
if ((versionBit & ctx->config.tlsConfig.version) == 0) {
return HITLS_MSG_HANDLE_UNSUPPORT_VERSION;
}
ctx->config.tlsConfig.version = versionBit;
ctx->config.tlsConfig.minVersion = ctx->negotiatedInfo.version;
ctx->config.tlsConfig.maxVersion = ctx->negotiatedInfo.version;
}
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_CONFIG_VERSION
void ChangeMinMaxVersion(uint32_t versionMask, uint32_t originVersionMask, uint16_t *minVersion, uint16_t *maxVersion)
{
uint32_t versionMaskBit = versionMask;
if ((IS_SUPPORT_TLS(versionMaskBit) || IS_SUPPORT_DTLS(versionMaskBit)) && IS_SUPPORT_TLCP(versionMaskBit)) {
versionMaskBit &= ~TLCP_VERSION_BITS;
}
uint32_t versionBits[] = {TLS12_VERSION_BIT, TLS13_VERSION_BIT, DTLS12_VERSION_BIT, TLCP11_VERSION_BIT,
DTLCP11_VERSION_BIT};
uint16_t versions[] = {HITLS_VERSION_TLS12, HITLS_VERSION_TLS13, HITLS_VERSION_DTLS12, HITLS_VERSION_TLCP_DTLCP11,
HITLS_VERSION_TLCP_DTLCP11};
uint32_t versionBitsSize = sizeof(versionBits) / sizeof(uint32_t);
uint32_t minIdx = 0;
uint32_t maxIdx = 0;
bool found = false;
uint32_t intersection = versionMaskBit & originVersionMask;
for (uint32_t i = 0; i < versionBitsSize; i++) {
if ((intersection & versionBits[i]) == versionBits[i]) {
if (!found) {
minIdx = i;
found = true;
}
maxIdx = i;
} else if (found) {
break;
}
}
if (!found) {
*minVersion = 0;
*maxVersion = 0;
return;
}
*minVersion = versions[minIdx];
*maxVersion = versions[maxIdx];
}
static int ChangeVersionMask(HITLS_Config *config, uint16_t minVersion, uint16_t maxVersion)
{
uint32_t originVersionMask = config->originVersionMask;
uint32_t versionMask = 0;
uint32_t versionBit = 0;
uint16_t begin = IS_DTLS_VERSION(maxVersion) ? maxVersion : minVersion;
uint16_t end = IS_DTLS_VERSION(maxVersion) ? minVersion : maxVersion;
for (uint16_t version = begin; version <= end; version++) {
versionBit = MapVersion2VersionBit(IS_SUPPORT_DATAGRAM(originVersionMask), version);
versionMask |= versionBit;
}
if ((versionMask & originVersionMask) == 0) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16598, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Config version err", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION);
return HITLS_CONFIG_INVALID_VERSION;
}
config->version = (versionMask & originVersionMask);
return HITLS_SUCCESS;
}
static int32_t CheckVersionValid(const HITLS_Config *config, uint16_t minVersion, uint16_t maxVersion)
{
if ((minVersion < HITLS_VERSION_SSL30 && minVersion != 0) ||
(minVersion == HITLS_VERSION_SSL30 && config->minVersion != HITLS_VERSION_SSL30) ||
(maxVersion <= HITLS_VERSION_SSL30 && maxVersion != 0)) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16599, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Config version err", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION);
return HITLS_CONFIG_INVALID_VERSION;
}
return HITLS_SUCCESS;
}
static void ChangeTmpVersion(HITLS_Config *config, uint16_t *tmpMinVersion, uint16_t *tmpMaxVersion)
{
uint16_t minVersion = 0;
uint16_t maxVersion = 0;
ChangeMinMaxVersion(config->originVersionMask, config->originVersionMask, &minVersion, &maxVersion);
if (*tmpMinVersion == 0) {
if (config->originVersionMask == DTLS_VERSION_MASK) {
*tmpMinVersion = HITLS_VERSION_DTLS12;
} else {
*tmpMinVersion = minVersion;
}
}
if (*tmpMaxVersion == 0) {
if (config->originVersionMask == DTLS_VERSION_MASK) {
*tmpMaxVersion = HITLS_VERSION_DTLS12;
} else {
*tmpMaxVersion = maxVersion;
}
}
}
int32_t HITLS_CFG_SetVersion(HITLS_Config *config, uint16_t minVersion, uint16_t maxVersion)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
int32_t ret = 0;
if (config->minVersion == minVersion && config->maxVersion == maxVersion && minVersion != 0 && maxVersion != 0) {
return HITLS_SUCCESS;
}
* initialized only by using the corresponding configuration initialization interface.
*/
ret = CheckVersionValid(config, minVersion, maxVersion);
if (ret != HITLS_SUCCESS) {
return ret;
}
uint16_t tmpMinVersion = minVersion;
uint16_t tmpMaxVersion = maxVersion;
ChangeTmpVersion(config, &tmpMinVersion, &tmpMaxVersion);
ret = CheckVersion(tmpMinVersion, tmpMaxVersion);
if (ret != HITLS_SUCCESS) {
return ret;
}
ret = ChangeVersionMask(config, tmpMinVersion, tmpMaxVersion);
if (ret == HITLS_SUCCESS) {
ChangeMinMaxVersion(config->version, config->originVersionMask, &config->minVersion, &config->maxVersion);
}
return ret;
}
#endif
#ifdef HITLS_TLS_CONFIG_VERSION
int32_t HITLS_CFG_SetVersionForbid(HITLS_Config *config, uint32_t noVersion)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->version &= ~noVersion;
ChangeMinMaxVersion(config->version, config->originVersionMask, &config->minVersion, &config->maxVersion);
return HITLS_SUCCESS;
}
#endif
static void GetCipherSuitesCnt(const uint16_t *cipherSuites, uint32_t cipherSuitesSize,
uint32_t *tls13CipherSize, uint32_t *tlsCipherSize)
{
(void)cipherSuites;
uint32_t tmpCipherSize = *tlsCipherSize;
uint32_t tmpTls13CipherSize = *tls13CipherSize;
for (uint32_t i = 0; i < cipherSuitesSize; i++) {
#ifdef HITLS_TLS_PROTO_TLS13
if ((cipherSuites[i] >= HITLS_AES_128_GCM_SHA256 && cipherSuites[i] <= HITLS_AES_128_CCM_8_SHA256) ||
(cipherSuites[i] == HITLS_SM4_GCM_SM3 || cipherSuites[i] == HITLS_SM4_CCM_SM3)) {
tmpTls13CipherSize++;
continue;
}
#endif
tmpCipherSize++;
}
*tls13CipherSize = tmpTls13CipherSize;
*tlsCipherSize = tmpCipherSize;
}
int32_t HITLS_CFG_SetCipherSuites(HITLS_Config *config, const uint16_t *cipherSuites, uint32_t cipherSuitesSize)
{
if (config == NULL || cipherSuites == NULL || cipherSuitesSize == 0) {
return HITLS_NULL_INPUT;
}
if (cipherSuitesSize > HITLS_CFG_MAX_SIZE) {
return HITLS_CONFIG_INVALID_LENGTH;
}
uint32_t tlsCipherSize = 0;
uint32_t validTlsCipher = 0;
uint32_t tls13CipherSize = 0;
#ifdef HITLS_TLS_PROTO_TLS13
uint32_t validTls13Cipher = 0;
#endif
GetCipherSuitesCnt(cipherSuites, cipherSuitesSize, &tls13CipherSize, &tlsCipherSize);
uint16_t *cipherSuite = BSL_SAL_Calloc(1u, (tlsCipherSize + 1) * sizeof(uint16_t));
if (cipherSuite == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16600, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Calloc fail", 0, 0, 0, 0);
return HITLS_MEMALLOC_FAIL;
}
#ifdef HITLS_TLS_PROTO_TLS13
uint16_t *tls13CipherSuite = BSL_SAL_Calloc(1u, (tls13CipherSize + 1) * sizeof(uint16_t));
if (tls13CipherSuite == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16601, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Calloc fail", 0, 0, 0, 0);
BSL_SAL_FREE(cipherSuite);
return HITLS_MEMALLOC_FAIL;
}
#endif
for (uint32_t i = 0; i < cipherSuitesSize; i++) {
if (CFG_CheckCipherSuiteSupported(cipherSuites[i]) != true) {
continue;
}
if ((cipherSuites[i] >= HITLS_AES_128_GCM_SHA256 && cipherSuites[i] <= HITLS_AES_128_CCM_8_SHA256) ||
(cipherSuites[i] == HITLS_SM4_GCM_SM3 || cipherSuites[i] == HITLS_SM4_CCM_SM3)) {
#ifdef HITLS_TLS_PROTO_TLS13
tls13CipherSuite[validTls13Cipher] = cipherSuites[i];
validTls13Cipher++;
#endif
continue;
}
cipherSuite[validTlsCipher] = cipherSuites[i];
validTlsCipher++;
}
#ifdef HITLS_TLS_PROTO_TLS13
if (validTls13Cipher == 0) {
BSL_SAL_FREE(tls13CipherSuite);
} else {
BSL_SAL_FREE(config->tls13CipherSuites);
config->tls13CipherSuites = tls13CipherSuite;
config->tls13cipherSuitesSize = validTls13Cipher;
}
#endif
if (validTlsCipher == 0) {
BSL_SAL_FREE(cipherSuite);
} else {
BSL_SAL_FREE(config->cipherSuites);
config->cipherSuites = cipherSuite;
config->cipherSuitesSize = validTlsCipher;
}
if (validTlsCipher == 0
#ifdef HITLS_TLS_PROTO_TLS13
&& validTls13Cipher == 0
#endif
) {
return HITLS_CONFIG_NO_SUITABLE_CIPHER_SUITE;
}
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
int32_t HITLS_CFG_GetCipherSuites(HITLS_Config *config, uint16_t *data, uint32_t dataLen, uint32_t *cipherSuitesSize)
{
if (config == NULL || data == NULL || cipherSuitesSize == NULL) {
return HITLS_NULL_INPUT;
}
uint32_t num = 0;
if (dataLen < config->cipherSuitesSize + config->tls13cipherSuitesSize) {
return HITLS_CONFIG_INVALID_LENGTH;
}
if (config->maxVersion == HITLS_VERSION_TLS13) {
for (uint32_t i = 0; i < config->tls13cipherSuitesSize; i++) {
data[num] = config->tls13CipherSuites[i];
num += 1;
}
}
for (uint32_t i = 0; i < config->cipherSuitesSize; i++) {
data[num] = config->cipherSuites[i];
num += 1;
}
*cipherSuitesSize = num;
return HITLS_SUCCESS;
}
#endif
int32_t HITLS_CFG_SetEcPointFormats(HITLS_Config *config, const uint8_t *pointFormats, uint32_t pointFormatsSize)
{
if ((config == NULL) || (pointFormats == NULL) || (pointFormatsSize == 0)) {
return HITLS_NULL_INPUT;
}
if (pointFormatsSize > HITLS_CFG_MAX_SIZE) {
return HITLS_CONFIG_INVALID_LENGTH;
}
uint8_t *newData = BSL_SAL_Dump(pointFormats, pointFormatsSize * sizeof(uint8_t));
if (newData == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16602, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Dump fail", 0, 0, 0, 0);
return HITLS_MEMALLOC_FAIL;
}
BSL_SAL_FREE(config->pointFormats);
config->pointFormats = newData;
config->pointFormatsSize = pointFormatsSize;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_SetGroups(HITLS_Config *config, const uint16_t *groups, uint32_t groupsSize)
{
if ((config == NULL) || (groups == NULL) || (groupsSize == 0u)) {
return HITLS_NULL_INPUT;
}
if (groupsSize > HITLS_CFG_MAX_SIZE) {
BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH);
return HITLS_CONFIG_INVALID_LENGTH;
}
uint16_t *newData = BSL_SAL_Dump(groups, groupsSize * sizeof(uint16_t));
if (newData == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16603, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Dump fail", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
return HITLS_MEMALLOC_FAIL;
}
BSL_SAL_FREE(config->tuples);
config->tuplesSize = 0;
BSL_SAL_FREE(config->groups);
config->groups = newData;
config->groupsSize = groupsSize;
memset(config->keyshareIndex, 0, sizeof(config->keyshareIndex));
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_CONFIG_CIPHER_SUITE
typedef struct {
const char *alias;
const char *name;
} GroupNameMap;
static uint16_t GroupToId(const TLS_Config *tlsConfig, char *name)
{
const char *groupName = name;
const GroupNameMap groupMap[] = {
{"P-256", "secp256r1"}, {"P-384", "secp384r1"}, {"P-521", "secp521r1"}, {"X25519", "x25519"}};
for (uint32_t i = 0; i < sizeof(groupMap) / sizeof(groupMap[0]); i++) {
if (strcmp(name, groupMap[i].alias) == 0) {
groupName = groupMap[i].name;
break;
}
}
uint32_t groupInfoNum = 0;
const TLS_GroupInfo *groupInfo = ConfigGetGroupInfoList(tlsConfig, &groupInfoNum);
if (groupInfo == NULL || groupInfoNum == 0) {
return HITLS_NAMED_GROUP_BUTT;
}
for (uint32_t i = 0; i < groupInfoNum; i++) {
if (strcmp(groupInfo[i].name, groupName) == 0) {
return groupInfo[i].groupId;
}
}
return HITLS_NAMED_GROUP_BUTT;
}
static char *AllocAndCopyGroupName(const char *groupNames, uint32_t groupNamesLen)
{
char *groupNamesTmp = (char *)BSL_SAL_Calloc(groupNamesLen + 1, sizeof(char));
if (groupNamesTmp == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16604, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Calloc fail", 0, 0, 0, 0);
return NULL;
}
(void)memcpy(groupNamesTmp, groupNames, groupNamesLen);
return groupNamesTmp;
}
typedef struct {
uint16_t groupIds[MAX_GROUP_TYPE_NUM];
uint32_t groupsSize;
uint32_t tuples[MAX_GROUP_TYPE_NUM];
uint32_t tuplesSize;
uint32_t keyshareIndex[MAX_KEYSHARE_COUNT];
uint32_t keyshareCount;
} GroupList;
static int32_t ParseGroupNameToId(HITLS_Config *config, char *groupName, GroupList *list)
{
if (list->groupsSize >= MAX_GROUP_TYPE_NUM) {
return RETURN_ERROR_NUMBER_PROCESS(HITLS_INVALID_INPUT, BINLOG_ID16168, "group number exceeds max");
}
bool needKeyshare = false;
bool needIgnore = false;
while (*groupName != '\0') {
if (*groupName == '?') {
if (needIgnore) {
return RETURN_ERROR_NUMBER_PROCESS(HITLS_CONFIG_UNSUPPORT_GROUP, BINLOG_ID16800, "error string format");
}
needIgnore = true;
groupName++;
} else if (*groupName == '*') {
if (needKeyshare) {
return RETURN_ERROR_NUMBER_PROCESS(HITLS_CONFIG_UNSUPPORT_GROUP, BINLOG_ID16801, "error string format");
}
needKeyshare = true;
groupName++;
} else if (*groupName == ' ') {
groupName++;
} else {
break;
}
}
uint16_t groupId = GroupToId(config, groupName);
if (groupId == HITLS_NAMED_GROUP_BUTT && !needIgnore) {
return RETURN_ERROR_NUMBER_PROCESS(HITLS_CONFIG_UNSUPPORT_GROUP, BINLOG_ID16802, "unsupported group id");
}
if (needKeyshare) {
if (list->keyshareCount >= MAX_KEYSHARE_COUNT) {
return RETURN_ERROR_NUMBER_PROCESS(HITLS_CFG_ERR_MAX_LIMIT_KEYSHARE, BINLOG_ID16168,
"keyshareCount too long");
}
list->keyshareIndex[(list->keyshareCount)++] = list->groupsSize;
}
list->groupIds[(list->groupsSize)++] = groupId;
return HITLS_SUCCESS;
}
static int32_t SetTuples(HITLS_Config *config, uint32_t *tuples, uint32_t tuplesSize)
{
if (config == NULL || tuples == NULL) {
return HITLS_NULL_INPUT;
}
uint32_t *tuplesData = BSL_SAL_Dump(tuples, tuplesSize * sizeof(uint32_t));
if (tuplesData == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID16603, "Dump fail");
}
BSL_SAL_FREE(config->tuples);
config->tuples = tuplesData;
config->tuplesSize = tuplesSize;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_SetGroupList(HITLS_Config *config, const char *groupNames, uint32_t groupNamesLen)
{
if (config == NULL || groupNames == NULL) {
return HITLS_NULL_INPUT;
}
GroupList list = {0};
char *groupNamesTmp = AllocAndCopyGroupName(groupNames, groupNamesLen);
if (groupNamesTmp == NULL) {
return HITLS_MEMALLOC_FAIL;
}
char *tupleContext = NULL;
int32_t ret;
char *tupleToken = strtok_r(groupNamesTmp, "/", &tupleContext);
while (tupleToken != NULL) {
uint32_t tupleGroupCount = 0;
char *groupContext = NULL;
char *groupName = strtok_r(tupleToken, ":", &groupContext);
while (groupName != NULL) {
ret = ParseGroupNameToId(config, groupName, &list);
if (ret != HITLS_SUCCESS) {
BSL_SAL_FREE(groupNamesTmp);
return ret;
}
tupleGroupCount++;
groupName = strtok_r(NULL, ":", &groupContext);
}
if (list.tuplesSize >= MAX_GROUP_TYPE_NUM) {
BSL_SAL_FREE(groupNamesTmp);
return RETURN_ERROR_NUMBER_PROCESS(HITLS_INVALID_INPUT, BINLOG_ID16167, "tuple number exceeds max");
}
list.tuples[(list.tuplesSize)++] = tupleGroupCount;
tupleToken = strtok_r(NULL, "/", &tupleContext);
}
BSL_SAL_FREE(groupNamesTmp);
ret = HITLS_CFG_SetGroups(config, list.groupIds, list.groupsSize);
if (ret != HITLS_SUCCESS) {
return ret;
}
ret = SetTuples(config, list.tuples, list.tuplesSize);
(void)memcpy(config->keyshareIndex, list.keyshareIndex, sizeof(list.keyshareIndex));
return ret;
}
#endif
#ifdef HITLS_TLS_CONFIG_MANUAL_DH
int32_t HITLS_CFG_SetDhAutoSupport(HITLS_Config *config, bool support)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->isSupportDhAuto = support;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_SetTmpDh(HITLS_Config *config, HITLS_CRYPT_Key *dhPkey)
{
if ((config == NULL) || (dhPkey == NULL)) {
return HITLS_NULL_INPUT;
}
#ifdef HITLS_TLS_FEATURE_SECURITY
int32_t secBits = 0;
int32_t ret = SAL_CERT_KeyCtrl(config, dhPkey, CERT_KEY_CTRL_GET_SECBITS, NULL, (void *)&secBits);
if (ret != HITLS_SUCCESS) {
return HITLS_CERT_KEY_CTRL_ERR_GET_SECBITS;
}
ret = SECURITY_CfgCheck(config, HITLS_SECURITY_SECOP_TMP_DH, secBits, 0, dhPkey);
if (ret != SECURITY_SUCCESS) {
return HITLS_CRYPT_ERR_DH;
}
#endif
SAL_CRYPT_FreeDhKey(config->dhTmp);
config->dhTmp = dhPkey;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_GetDhAutoSupport(HITLS_Config *config, bool *isSupport)
{
if (config == NULL || isSupport == NULL) {
return HITLS_NULL_INPUT;
}
*isSupport = config->isSupportDhAuto;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_SUITE_KX_RSA
int32_t HITLS_CFG_SetNeedCheckPmsVersion(HITLS_Config *config, bool needCheck)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->needCheckPmsVersion = needCheck;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_CONFIG_USER_DATA
void *HITLS_CFG_GetConfigUserData(const HITLS_Config *config)
{
if (config == NULL) {
return NULL;
}
return config->userData;
}
int32_t HITLS_CFG_SetConfigUserData(HITLS_Config *config, void *userData)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->userData = userData;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_SetConfigUserDataFreeCb(HITLS_Config *config, HITLS_ConfigUserDataFreeCb callback)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->userDataFreeCb = callback;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_CONFIG_MANUAL_DH
int32_t HITLS_CFG_SetTmpDhCb(HITLS_Config *config, HITLS_DhTmpCb callback)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->dhTmpCb = callback;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_CONFIG_RECORD_PADDING
int32_t HITLS_CFG_SetRecordPaddingCb(HITLS_Config *config, HITLS_RecordPaddingCb callback)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->recordPaddingCb = callback;
return HITLS_SUCCESS;
}
HITLS_RecordPaddingCb HITLS_CFG_GetRecordPaddingCb(HITLS_Config *config)
{
if (config == NULL) {
return NULL;
}
return config->recordPaddingCb;
}
int32_t HITLS_CFG_SetRecordPaddingCbArg(HITLS_Config *config, void *arg)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->recordPaddingArg = arg;
return HITLS_SUCCESS;
}
void *HITLS_CFG_GetRecordPaddingCbArg(HITLS_Config *config)
{
if (config == NULL) {
return NULL;
}
return config->recordPaddingArg;
}
#endif
#ifdef HITLS_TLS_CONFIG_KEY_USAGE
int32_t HITLS_CFG_SetCheckKeyUsage(HITLS_Config *config, bool isCheck)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->needCheckKeyUsage = isCheck;
return HITLS_SUCCESS;
}
#endif
int32_t HITLS_CFG_SetReadAhead(HITLS_Config *config, int32_t onOff)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->readAhead = onOff;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_GetReadAhead(HITLS_Config *config, int32_t *onOff)
{
if (config == NULL || onOff == NULL) {
return HITLS_NULL_INPUT;
}
*onOff = config->readAhead;
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_CONFIG_CERT_CALLBACK
int32_t HITLS_CFG_SetCertVerifyCb(HITLS_Config *config, HITLS_APPVerifyCb callback, void *arg)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->appVerifyCb = callback;
config->appVerifyCbArg = arg;
return HITLS_SUCCESS;
}
#endif
int32_t HITLS_CFG_SetSignature(HITLS_Config *config, const uint16_t *signAlgs, uint16_t signAlgsSize)
{
if ((config == NULL) || (signAlgs == NULL) || (signAlgsSize == 0)) {
return HITLS_NULL_INPUT;
}
if (signAlgsSize > HITLS_CFG_MAX_SIZE) {
return HITLS_CONFIG_INVALID_LENGTH;
}
uint16_t *newData = BSL_SAL_Dump(signAlgs, signAlgsSize * sizeof(uint16_t));
if (newData == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16605, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Dump fail", 0, 0, 0, 0);
return HITLS_MEMALLOC_FAIL;
}
BSL_SAL_FREE(config->signAlgorithms);
config->signAlgorithms = newData;
config->signAlgorithmsSize = signAlgsSize;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_SetRenegotiationSupport(HITLS_Config *config, bool support)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
#ifdef HITLS_TLS_PROTO_TLCP11
if (support && IS_SUPPORT_TLCP(config->originVersionMask)) {
config->allowLegacyRenegotiate = false;
}
#endif
config->isSupportRenegotiation = support;
return HITLS_SUCCESS;
}
#if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
int32_t HITLS_CFG_SetLegacyRenegotiateSupport(HITLS_Config *config, bool support)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->allowLegacyRenegotiate = support;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_GetLegacyRenegotiateSupport(HITLS_Config *config, bool *isSupport)
{
if (config == NULL || isSupport == NULL) {
return HITLS_NULL_INPUT;
}
*isSupport = config->allowLegacyRenegotiate;
return HITLS_SUCCESS;
}
#endif
int32_t HITLS_CFG_SetExtendedMasterSecretSupport(HITLS_Config *config, bool support)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
return HITLS_CFG_SetExtendedMasterSecretMode(config, support ? HITLS_EMS_MODE_FORCE : HITLS_EMS_MODE_PREFER);
}
#if defined(HITLS_TLS_FEATURE_PSK) && (defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12))
int32_t HITLS_CFG_SetPskIdentityHint(HITLS_Config *config, const uint8_t *hint, uint32_t hintSize)
{
if ((config == NULL) || (hint == NULL) || (hintSize == 0)) {
return HITLS_NULL_INPUT;
}
if (hintSize > HS_PSK_IDENTITY_MAX_LEN) {
return HITLS_CONFIG_INVALID_LENGTH;
}
uint8_t *newData = BSL_SAL_Dump(hint, hintSize * sizeof(uint8_t));
if (newData == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16607, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Dump fail", 0, 0, 0, 0);
return HITLS_MEMALLOC_FAIL;
}
BSL_SAL_FREE(config->pskIdentityHint);
config->pskIdentityHint = newData;
config->hintSize = hintSize;
return HITLS_SUCCESS;
}
#endif
int32_t HITLS_CFG_GetExtendedMasterSecretSupport(HITLS_Config *config, bool *isSupport)
{
if (config == NULL || isSupport == NULL) {
return HITLS_NULL_INPUT;
}
*isSupport = (config->emsMode == HITLS_EMS_MODE_FORCE);
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_SetExtendedMasterSecretMode(HITLS_Config *config, int32_t mode)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
if (mode != HITLS_EMS_MODE_FORBID && mode != HITLS_EMS_MODE_PREFER && mode != HITLS_EMS_MODE_FORCE) {
return HITLS_INVALID_INPUT;
}
config->emsMode = mode;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_GetExtendedMasterSecretMode(HITLS_Config *config, int32_t *mode)
{
if (config == NULL || mode == NULL) {
return HITLS_NULL_INPUT;
}
*mode = config->emsMode;
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_CONFIG_VERSION
int32_t HITLS_CFG_GetMaxVersion(const HITLS_Config *config, uint16_t *maxVersion)
{
if (config == NULL || maxVersion == NULL) {
return HITLS_NULL_INPUT;
}
*maxVersion = config->maxVersion;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_GetMinVersion(const HITLS_Config *config, uint16_t *minVersion)
{
if (config == NULL || minVersion == NULL) {
return HITLS_NULL_INPUT;
}
*minVersion = config->minVersion;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_CONFIG_VERSION
int32_t HITLS_CFG_GetVersionSupport(const HITLS_Config *config, uint32_t *version)
{
if ((config == NULL) || (version == NULL)) {
return HITLS_NULL_INPUT;
}
*version = config->version;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_SetVersionSupport(HITLS_Config *config, uint32_t version)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
if ((version & SSLV3_VERSION_BIT) == SSLV3_VERSION_BIT) {
return HITLS_CONFIG_INVALID_VERSION;
}
uint32_t tmp = version & config->originVersionMask;
config->version |= tmp;
ChangeMinMaxVersion(config->version, config->originVersionMask, &config->minVersion, &config->maxVersion);
return HITLS_SUCCESS;
}
int32_t HITLS_SetVersion(HITLS_Ctx *ctx, uint32_t minVersion, uint32_t maxVersion)
{
if (ctx == NULL) {
return HITLS_NULL_INPUT;
}
return HITLS_CFG_SetVersion(&(ctx->config.tlsConfig), (uint16_t)minVersion, (uint16_t)maxVersion);
}
int32_t HITLS_SetVersionForbid(HITLS_Ctx *ctx, uint32_t noVersion)
{
if (ctx == NULL) {
return HITLS_NULL_INPUT;
}
return HITLS_CFG_SetVersionForbid(&(ctx->config.tlsConfig), noVersion);
}
#endif
#ifdef HITLS_TLS_PROTO_CLOSE_STATE
int32_t HITLS_CFG_SetQuietShutdown(HITLS_Config *config, int32_t mode)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
* disconnection mode is enabled.
*/
if (mode != 0 && mode != 1) {
return HITLS_CONFIG_INVALID_SET;
}
if (mode == 0) {
config->isQuietShutdown = false;
} else {
config->isQuietShutdown = true;
}
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_GetQuietShutdown(const HITLS_Config *config, int32_t *mode)
{
if (config == NULL || mode == NULL) {
return HITLS_NULL_INPUT;
}
*mode = (int32_t)config->isQuietShutdown;
return HITLS_SUCCESS;
}
#endif
int32_t HITLS_CFG_SetEncryptThenMac(HITLS_Config *config, bool encryptThenMacType)
{
#ifdef HITLS_TLS_SUITE_CIPHER_CBC
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->isEncryptThenMac = encryptThenMacType;
return HITLS_SUCCESS;
#else
(void)config;
(void)encryptThenMacType;
return HITLS_CONFIG_UNSUPPORT;
#endif
}
int32_t HITLS_CFG_GetEncryptThenMac(const HITLS_Config *config, bool *encryptThenMacType)
{
#ifdef HITLS_TLS_SUITE_CIPHER_CBC
if (config == NULL || encryptThenMacType == NULL) {
return HITLS_NULL_INPUT;
}
*encryptThenMacType = config->isEncryptThenMac;
return HITLS_SUCCESS;
#else
(void)config;
(void)encryptThenMacType;
return HITLS_CONFIG_UNSUPPORT;
#endif
}
#ifdef HITLS_TLS_PROTO_DFX_SERVER_PREFER
int32_t HITLS_CFG_SetCipherServerPreference(HITLS_Config *config, bool isSupport)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->isSupportServerPreference = isSupport;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_GetCipherServerPreference(const HITLS_Config *config, bool *isSupport)
{
if (config == NULL || isSupport == NULL) {
return HITLS_NULL_INPUT;
}
*isSupport = config->isSupportServerPreference;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_MAINTAIN_KEYLOG
int32_t HITLS_CFG_SetKeyLogCb(HITLS_Config *config, HITLS_KeyLogCb callback)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->keyLogCb = callback;
return HITLS_SUCCESS;
}
HITLS_KeyLogCb HITLS_CFG_GetKeyLogCb(HITLS_Config *config)
{
if (config == NULL) {
return NULL;
}
return config->keyLogCb;
}
#endif
int32_t HITLS_CFG_SetEmptyRecordsNum(HITLS_Config *config, uint32_t emptyNum)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->emptyRecordsNum = emptyNum;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_GetEmptyRecordsNum(const HITLS_Config *config, uint32_t *emptyNum)
{
if (config == NULL || emptyNum == NULL) {
return HITLS_NULL_INPUT;
}
*emptyNum = config->emptyRecordsNum;
return HITLS_SUCCESS;
}
int32_t HITLS_CFG_SetEndPoint(HITLS_Config *config, bool isClient)
{
if (config == NULL) {
return HITLS_NULL_INPUT;
}
config->endpoint = isClient ? HITLS_ENDPOINT_CLIENT : HITLS_ENDPOINT_SERVER;
return HITLS_SUCCESS;
}