* 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 "hitls_build.h"
#ifdef HITLS_TLS_HOST_SERVER
#include <string.h>
#include "tls_binlog_id.h"
#include "bsl_log_internal.h"
#include "bsl_log.h"
#include "bsl_sal.h"
#include "bsl_err_internal.h"
#include "bsl_bytes.h"
#include "bsl_list.h"
#include "hitls_error.h"
#include "hitls_cert_type.h"
#include "tls.h"
#include "hs_extensions.h"
#include "hs_common.h"
#include "parse_common.h"
#include "hs_ctx.h"
#include "alert.h"
#include "parse_extensions.h"
#include "custom_extensions.h"
static int32_t StorePeerSupportGroup(TLS_Ctx *ctx, ClientHelloMsg *msg)
{
(void)ctx;
(void)msg;
#ifdef HITLS_TLS_CONNECTION_INFO_NEGOTIATION
BSL_SAL_FREE(ctx->peerInfo.groups);
ctx->peerInfo.groups = (uint16_t *)BSL_SAL_Dump(
msg->extension.content.supportedGroups, msg->extension.content.supportedGroupsSize * sizeof(uint16_t));
if (ctx->peerInfo.groups == NULL) {
BSL_SAL_FREE(msg->extension.content.supportedGroups);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15136, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"supportedGroups dump fail when parse extensions msg.", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
return HITLS_MEMALLOC_FAIL;
}
ctx->peerInfo.groupsSize = msg->extension.content.supportedGroupsSize;
#endif
return HITLS_SUCCESS;
}
static int32_t ParseClientSupportGroups(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.haveSupportedGroups == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15132, BINGLOG_STR("ClientSupportGroups"));
}
uint16_t groupBufLen = 0;
int32_t ret = ParseBytesToUint16(pkt, &groupBufLen);
if (ret != HITLS_SUCCESS) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15133, BINGLOG_STR("supported groups"));
}
uint16_t groupCount = groupBufLen / sizeof(uint16_t);
* is returned */
if (((groupBufLen & 1) != 0) || (groupBufLen != (pkt->bufLen - *pkt->bufOffset)) || (groupCount == 0)) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15134, BINGLOG_STR("supported groups"));
}
groupCount = groupCount > MAX_SUPPORTED_GROUPS_COUNT ? MAX_SUPPORTED_GROUPS_COUNT : groupCount;
msg->extension.content.supportedGroups = (uint16_t *)BSL_SAL_Calloc(groupCount, sizeof(uint16_t));
if (msg->extension.content.supportedGroups == NULL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15135,
BINGLOG_STR("supportedGroups malloc fail."), ALERT_UNKNOWN);
}
for (uint32_t i = 0; i < groupCount; i++) {
msg->extension.content.supportedGroups[i] = BSL_ByteToUint16(&pkt->buf[*pkt->bufOffset]);
*pkt->bufOffset += sizeof(uint16_t);
}
*pkt->bufOffset += groupBufLen - groupCount * sizeof(uint16_t);
msg->extension.content.supportedGroupsSize = groupCount;
msg->extension.flag.haveSupportedGroups = true;
return StorePeerSupportGroup(pkt->ctx, msg);
}
static int32_t ParseClientSignatureAlgorithms(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.haveSignatureAlgorithms == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15128, BINGLOG_STR("ClientSignatureAlgorithms"));
}
uint16_t signAlgBufLen = 0;
int32_t ret = ParseBytesToUint16(pkt, &signAlgBufLen);
if (ret != HITLS_SUCCESS) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15129, BINGLOG_STR("signatureAlgorithms"));
}
uint16_t signatureAlgorithmsCount = signAlgBufLen / sizeof(uint16_t);
signatureAlgorithmsCount = signatureAlgorithmsCount > MAX_SIGNATURE_ALGORITHMS_COUNT ?
MAX_SIGNATURE_ALGORITHMS_COUNT : signatureAlgorithmsCount;
* returned. */
if (((signAlgBufLen & 1) != 0) || (signAlgBufLen != (pkt->bufLen - *pkt->bufOffset)) ||
(signatureAlgorithmsCount == 0)) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15130, BINGLOG_STR("signatureAlgorithms"));
}
uint16_t *signatureAlgorithms = (uint16_t *)BSL_SAL_Calloc(signatureAlgorithmsCount, sizeof(uint16_t));
if (signatureAlgorithms == NULL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15131,
BINGLOG_STR("signatureAlgorithms malloc fail."), ALERT_UNKNOWN);
}
for (uint32_t i = 0; i < signatureAlgorithmsCount; i++) {
signatureAlgorithms[i] = BSL_ByteToUint16(&pkt->buf[*pkt->bufOffset]);
*pkt->bufOffset += sizeof(uint16_t);
}
*pkt->bufOffset += signAlgBufLen - signatureAlgorithmsCount * sizeof(uint16_t);
msg->extension.content.signatureAlgorithmsSize = signatureAlgorithmsCount;
msg->extension.content.signatureAlgorithms = signatureAlgorithms;
BSL_SAL_FREE(pkt->ctx->peerInfo.signatureAlgorithms);
pkt->ctx->peerInfo.signatureAlgorithms =
BSL_SAL_Dump(signatureAlgorithms, signatureAlgorithmsCount * sizeof(uint16_t));
if (pkt->ctx->peerInfo.signatureAlgorithms == NULL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID17382,
BINGLOG_STR("signatureAlgorithms malloc fail."), ALERT_UNKNOWN);
}
pkt->ctx->peerInfo.signatureAlgorithmsSize = signatureAlgorithmsCount;
msg->extension.flag.haveSignatureAlgorithms = true;
return HITLS_SUCCESS;
}
static int32_t ParseClientPointFormats(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.havePointFormats == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15137, BINGLOG_STR("ClientPointFormats"));
}
uint8_t pointFormatsSize = 0;
int32_t ret = ParseOneByteLengthField(pkt, &pointFormatsSize, &msg->extension.content.pointFormats);
if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15138, BINGLOG_STR("point formats"));
} else if (ret == HITLS_MEMALLOC_FAIL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15140,
BINGLOG_STR("pointFormats malloc fail."), ALERT_UNKNOWN);
}
if ((pkt->bufLen != *pkt->bufOffset) || (pointFormatsSize == 0u)) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15139, BINGLOG_STR("point formats"));
}
msg->extension.flag.havePointFormats = true;
msg->extension.content.pointFormatsSize = pointFormatsSize;
pkt->ctx->haveClientPointFormats = true;
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_FEATURE_EXTENDED_MASTER_SECRET
static int32_t ParseClientExtMasterSecret(ParsePacket *pkt, ClientHelloMsg *msg)
{
return ParseEmptyExtension(pkt->ctx, HS_EX_TYPE_EXTENDED_MASTER_SECRET, pkt->bufLen,
&msg->extension.flag.haveExtendedMasterSecret);
}
#endif
#ifdef HITLS_TLS_FEATURE_SNI
static void SetRevMsgExtServernameInfo(ClientHelloMsg *msg, uint8_t serverNameType, uint8_t *serverName,
uint16_t serverNameLen)
{
serverName[serverNameLen - 1] = '\0';
msg->extension.content.serverName = serverName;
msg->extension.content.serverNameSize = serverNameLen;
msg->extension.content.serverNameType = serverNameType;
msg->extension.flag.haveServerName = true;
}
static int32_t ParseClientServerNameIndication(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg)
{
const uint32_t baseSize = sizeof(uint8_t) + sizeof(uint16_t);
uint32_t bufOffset = 0;
bool haveParseHostName = false;
while (bufOffset + baseSize < bufLen) {
uint8_t serverNameType = buf[bufOffset];
bufOffset += sizeof(uint8_t);
uint16_t serverNameLen = BSL_ByteToUint16(&buf[bufOffset]);
bufOffset += sizeof(uint16_t);
if (bufLen < bufOffset + serverNameLen) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16986, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"bufLen err", 0, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR);
return HITLS_PARSE_SERVER_NAME_ERR;
}
if (serverNameType != 0) {
bufOffset += serverNameLen;
continue;
}
if (haveParseHostName || serverNameLen == 0 || serverNameLen > 0xff ||
strnlen((const char *)&buf[bufOffset], serverNameLen) != serverNameLen) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16987, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"serverNameLen err", 0, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER);
return HITLS_PARSE_SERVER_NAME_ERR;
}
haveParseHostName = true;
uint8_t *serverName = (uint8_t *)BSL_SAL_Calloc((serverNameLen + 1), sizeof(uint8_t));
if (serverName == NULL) {
return ParseErrorProcess(ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15127,
BINGLOG_STR("server_name malloc fail."), ALERT_INTERNAL_ERROR);
}
memcpy(serverName, &buf[bufOffset], serverNameLen);
SetRevMsgExtServernameInfo(msg, serverNameType, serverName, serverNameLen + 1);
bufOffset += serverNameLen;
}
if (bufOffset != bufLen) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16988, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"bufOffset err", 0, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR);
return HITLS_PARSE_SERVER_NAME_ERR;
}
if (!msg->extension.flag.haveServerName) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16989, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"it is not have server name", 0, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER);
return HITLS_PARSE_SERVER_NAME_ERR;
}
return HITLS_SUCCESS;
}
static int32_t ParseClientServerName(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.haveServerName == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15122, BINGLOG_STR("Client ServerName"));
}
uint16_t serverNameListSize = 0;
int32_t ret = ParseBytesToUint16(pkt, &serverNameListSize);
if (ret != HITLS_SUCCESS) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15123, BINGLOG_STR("ServerName"));
}
if ((serverNameListSize != pkt->bufLen - *pkt->bufOffset) ||
(serverNameListSize < sizeof(uint8_t) + sizeof(uint16_t))) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15124, BINGLOG_STR("ServerName"));
}
return ParseClientServerNameIndication(pkt->ctx, &pkt->buf[*pkt->bufOffset], (uint32_t)serverNameListSize, msg);
}
#endif
#ifdef HITLS_TLS_FEATURE_ALPN
static int32_t ParseClientAlpnProposeList(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.haveAlpn == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15141, BINGLOG_STR("alpn list"));
}
uint16_t alpnLen = 0;
int32_t ret = ParseBytesToUint16(pkt, &alpnLen);
if (ret != HITLS_SUCCESS) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15142, BINGLOG_STR("alpn"));
}
* message error is returned */
if (((alpnLen * sizeof(uint8_t)) != (pkt->bufLen - sizeof(uint16_t))) || (alpnLen < 2)) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15143, BINGLOG_STR("alpn"));
}
uint32_t alpnListOffset = *pkt->bufOffset;
do {
uint8_t alpnStringLen = pkt->buf[alpnListOffset];
alpnListOffset += alpnStringLen + 1;
if (alpnListOffset > pkt->bufLen || alpnStringLen == 0) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15144, BINGLOG_STR("alpn"));
}
} while (pkt->bufLen - alpnListOffset != 0);
BSL_SAL_FREE(msg->extension.content.alpnList);
msg->extension.content.alpnList = (uint8_t *)BSL_SAL_Dump(&pkt->buf[*pkt->bufOffset], alpnLen);
if (msg->extension.content.alpnList == NULL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15145,
BINGLOG_STR("alpn list malloc fail."), ALERT_UNKNOWN);
}
msg->extension.content.alpnListSize = alpnLen;
msg->extension.flag.haveAlpn = true;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_PROTO_TLS13
int32_t ParseIdentities(TLS_Ctx *ctx, PreSharedKey *preSharedKey, const uint8_t *buf, uint32_t bufLen)
{
uint32_t bufOffset = 0u;
PreSharedKey *tmp = preSharedKey;
while (bufOffset + sizeof(uint16_t) < bufLen) {
PreSharedKey *node = (PreSharedKey *)BSL_SAL_Calloc(1, sizeof(PreSharedKey));
if (node == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16990, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Calloc fail", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
return HITLS_MEMALLOC_FAIL;
}
LIST_ADD_AFTER(&tmp->pskNode, &node->pskNode);
tmp = node;
uint16_t identitySize = BSL_ByteToUint16(&buf[bufOffset]);
node->identitySize = identitySize;
bufOffset += sizeof(uint16_t);
if ((bufOffset + identitySize + sizeof(uint32_t)) > bufLen || identitySize == 0) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15146, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"ParseIdentities error. bufLen = %d, identitySize = %d.", bufLen, identitySize, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER);
BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN);
return HITLS_PARSE_INVALID_MSG_LEN;
}
node->identity = (uint8_t *)BSL_SAL_Calloc(1u, (node->identitySize + 1) * sizeof(uint8_t));
if (node->identity == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16991, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Calloc fail", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
return HITLS_MEMALLOC_FAIL;
}
memcpy(node->identity, &buf[bufOffset], identitySize);
bufOffset += node->identitySize;
node->obfuscatedTicketAge = BSL_ByteToUint32(&buf[bufOffset]);
bufOffset += sizeof(uint32_t);
}
if (bufOffset != bufLen) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15147, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"IdentityEntry error. bufLen = %d ", bufLen, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER);
BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN);
return HITLS_PARSE_INVALID_MSG_LEN;
}
return HITLS_SUCCESS;
}
void CleanKeyShare(KeyShare *keyShare)
{
ListHead *node = NULL;
ListHead *tmpNode = NULL;
KeyShare *cur = NULL;
KeyShare *cache = keyShare;
if (cache != NULL) {
LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(cache->head))
{
cur = BSL_LIST_ENTRY(node, KeyShare, head);
BSL_LIST_REMOVE(node);
BSL_SAL_FREE(cur->keyExchange);
BSL_SAL_FREE(cur);
}
BSL_SAL_FREE(keyShare);
}
}
for the same group. Clients MUST NOT offer any KeyShareEntry values
for groups not listed in the client's "supported_groups" extension.
Servers MAY check for violations of these rules and abort the
handshake with an "illegal_parameter" alert if one is violated. */
static bool KeyShareGroupAdd(uint16_t *groupSet, uint32_t groupSetCapacity, uint32_t *groupSetSize, uint16_t group)
{
for (uint32_t i = 0; (i < *groupSetSize) && (i + 1 < groupSetCapacity); i++) {
if (groupSet[i] == group) {
return false;
}
}
groupSet[*groupSetSize] = group;
*groupSetSize = *groupSetSize + 1;
return true;
}
* @brief Parse KeyShareEntry and create a linked list node,
* @attention The caller needs to pay attention to the function. If the function fails to be returned, the caller
* releases the call.
*
* @param keyShare [OUT] Linked list header
* @param buf [IN] message buffer
* @param bufLen [IN] message length
*
* @return HITLS_SUCCESS parsed successfully.
*/
int32_t ParseKeyShare(KeyShare *keyshare, const uint8_t *buf, uint32_t bufLen, ALERT_Description *alert)
{
uint32_t bufOffset = 0u;
KeyShare *node = keyshare;
uint16_t *groupSet = (uint16_t *)BSL_SAL_Calloc(MAX_KEY_SHARE_ENTRY_COUNT, sizeof(uint16_t));
if (groupSet == NULL) {
*alert = ALERT_INTERNAL_ERROR;
return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID16992, "Calloc fail");
}
uint32_t groupSetSize = 0;
uint32_t keyShareCount = 0;
while (bufOffset + sizeof(uint16_t) + sizeof(uint16_t) < bufLen && keyShareCount < MAX_KEY_SHARE_ENTRY_COUNT) {
KeyShare *tmpNode = (KeyShare *)BSL_SAL_Calloc(1u, sizeof(KeyShare));
if (tmpNode == NULL) {
*alert = ALERT_INTERNAL_ERROR;
BSL_SAL_FREE(groupSet);
return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID16993, "Calloc fail");
}
BSL_LIST_INIT(&tmpNode->head);
LIST_ADD_AFTER(&node->head, &tmpNode->head);
node = tmpNode;
node->group = BSL_ByteToUint16(&buf[bufOffset]);
bufOffset += sizeof(uint16_t);
if (!KeyShareGroupAdd(groupSet, MAX_KEY_SHARE_ENTRY_COUNT, &groupSetSize, node->group)) {
*alert = ALERT_ILLEGAL_PARAMETER;
BSL_SAL_FREE(groupSet);
return RETURN_ERROR_NUMBER_PROCESS(HITLS_PARSE_DUPLICATED_KEY_SHARE, BINLOG_ID16994, "key share repeated");
}
node->keyExchangeSize = BSL_ByteToUint16(&buf[bufOffset]);
bufOffset += sizeof(uint16_t);
if (node->keyExchangeSize == 0 || bufOffset + node->keyExchangeSize > bufLen) {
*alert = ALERT_DECODE_ERROR;
BSL_SAL_FREE(groupSet);
return RETURN_ERROR_NUMBER_PROCESS(HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16995, "keyExchangeSize error");
}
BSL_SAL_FREE(node->keyExchange);
node->keyExchange = (uint8_t *)BSL_SAL_Dump(&buf[bufOffset], node->keyExchangeSize);
if (node->keyExchange == NULL) {
*alert = ALERT_INTERNAL_ERROR;
BSL_SAL_FREE(groupSet);
return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID16996, "Dump fail");
}
bufOffset += node->keyExchangeSize;
keyShareCount++;
}
BSL_SAL_FREE(groupSet);
if (bufOffset != bufLen && keyShareCount != MAX_KEY_SHARE_ENTRY_COUNT) {
*alert = ALERT_DECODE_ERROR;
return RETURN_ERROR_NUMBER_PROCESS(HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16997, "bufLen error");
}
return HITLS_SUCCESS;
}
int32_t ParseClientKeyShare(ParsePacket *pkt, ClientHelloMsg *msg)
{
uint32_t bufOffset = 0u;
int32_t ret = HITLS_SUCCESS;
ALERT_Description alert = ALERT_UNKNOWN;
do {
if (msg->extension.flag.haveKeyShare == true) {
return RETURN_ALERT_PROCESS(pkt->ctx, HITLS_PARSE_DUPLICATE_EXTENDED_MSG, BINLOG_ID16998,
"KeyShare repeated", ALERT_ILLEGAL_PARAMETER);
}
if (pkt->bufLen < sizeof(uint16_t)) {
return RETURN_ALERT_PROCESS(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16999,
"bufLen error", ALERT_DECODE_ERROR);
}
uint16_t keyShareLen = BSL_ByteToUint16(&pkt->buf[bufOffset]);
bufOffset += sizeof(uint16_t);
if (keyShareLen + bufOffset != pkt->bufLen) {
return RETURN_ALERT_PROCESS(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID17000,
"bufLen error", ALERT_DECODE_ERROR);
}
if (keyShareLen == 0) {
break;
}
msg->extension.content.keyShare = (KeyShare *)BSL_SAL_Calloc(1u, sizeof(KeyShare));
if (msg->extension.content.keyShare == NULL) {
return RETURN_ALERT_PROCESS(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15150,
"calloc fail", ALERT_INTERNAL_ERROR);
}
BSL_LIST_INIT(&msg->extension.content.keyShare->head);
ret = ParseKeyShare(msg->extension.content.keyShare, &pkt->buf[bufOffset], keyShareLen, &alert);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15151, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"parse client key share fail.", 0, 0, 0, 0);
break;
}
} while (false);
msg->extension.flag.haveKeyShare = true;
if (ret != HITLS_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
pkt->ctx->method.sendAlert(pkt->ctx, ALERT_LEVEL_FATAL, alert);
}
return ret;
}
int32_t ParseClientSupportedVersions(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.haveSupportedVers == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15152, BINGLOG_STR("ClientSupportedVersions"));
}
uint8_t len = 0;
int32_t ret = ParseBytesToUint8(pkt, &len);
if (ret != HITLS_SUCCESS) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15153, BINGLOG_STR("SupportVersion"));
}
if ((len == 0) || ((len % sizeof(uint16_t)) != 0) || (len + *pkt->bufOffset != pkt->bufLen)) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15154, BINGLOG_STR("SupportVersion"));
}
msg->extension.content.supportedVersions = (uint16_t *)BSL_SAL_Calloc(1u, len);
if (msg->extension.content.supportedVersions == NULL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15155,
BINGLOG_STR("SupportVersion malloc fail."), ALERT_INTERNAL_ERROR);
}
for (uint32_t i = 0; i < len / sizeof(uint16_t); i++) {
msg->extension.content.supportedVersions[i] = BSL_ByteToUint16(&pkt->buf[*pkt->bufOffset]);
*pkt->bufOffset += sizeof(uint16_t);
}
msg->extension.content.supportedVersionsCount = len / sizeof(uint16_t);
msg->extension.flag.haveSupportedVers = true;
return HITLS_SUCCESS;
}
static int32_t ParseBinders(TLS_Ctx *ctx, PreSharedKey *preSharedKey, const uint8_t *buf, uint32_t bufLen)
{
uint32_t bufOffset = 0u;
ListHead *node = NULL;
ListHead *tmpNode = NULL;
PreSharedKey *cur = NULL;
PreSharedKey *cache = preSharedKey;
LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(cache->pskNode))
{
cur = BSL_LIST_ENTRY(node, PreSharedKey, pskNode);
if (bufLen < bufOffset + sizeof(uint8_t)) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17001, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"bufLen error", 0, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR);
return HITLS_PARSE_INVALID_MSG_LEN;
}
uint8_t binderLen = buf[bufOffset];
bufOffset += sizeof(uint8_t);
if (binderLen > (bufLen - bufOffset)) {
return ParseErrorExtLengthProcess(ctx, BINLOG_ID15165, BINGLOG_STR("binder in pre share key"));
}
cur->binderSize = binderLen;
cur->binder = (uint8_t *)BSL_SAL_Calloc(cur->binderSize, sizeof(uint8_t));
if (cur->binder == NULL) {
return ParseErrorProcess(ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15166,
BINGLOG_STR("pre_share_key malloc fail."), ALERT_UNKNOWN);
}
memcpy(cur->binder, &buf[bufOffset], binderLen);
bufOffset += binderLen;
}
if (bufLen != bufOffset) {
return ParseErrorExtLengthProcess(ctx, BINLOG_ID15167, BINGLOG_STR("binder in pre share key"));
}
return HITLS_SUCCESS;
}
static int32_t ParseClientPreSharedKey(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.havePreShareKey == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15168, BINGLOG_STR("pre share key"));
}
uint16_t identitiesLen = 0;
int32_t ret = ParseBytesToUint16(pkt, &identitiesLen);
if (ret != HITLS_SUCCESS) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15169, BINGLOG_STR("pre share key"));
}
if (pkt->bufLen <= identitiesLen + *pkt->bufOffset || identitiesLen == 0) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15170, BINGLOG_STR("pre share key"));
}
PreSharedKey *offeredPsks = (PreSharedKey *)BSL_SAL_Calloc(1, sizeof(PreSharedKey));
if (offeredPsks == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17002, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Calloc fail", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
return HITLS_MEMALLOC_FAIL;
}
msg->extension.content.preSharedKey = offeredPsks;
BSL_LIST_INIT(&offeredPsks->pskNode);
ret = ParseIdentities(pkt->ctx, offeredPsks, &pkt->buf[*pkt->bufOffset], identitiesLen);
if (ret != HITLS_SUCCESS) {
return ret;
}
*pkt->bufOffset += identitiesLen;
msg->truncateHelloLen = &pkt->buf[*pkt->bufOffset] - pkt->ctx->hsCtx->msgBuf;
if (pkt->bufLen < sizeof(uint16_t) + *pkt->bufOffset) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17003, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "bufLen error", 0, 0, 0, 0);
pkt->ctx->method.sendAlert(pkt->ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR);
return HITLS_PARSE_INVALID_MSG_LEN;
}
uint16_t bindersLen = BSL_ByteToUint16(&pkt->buf[*pkt->bufOffset]);
*pkt->bufOffset += sizeof(uint16_t);
if (pkt->bufLen != *pkt->bufOffset + bindersLen) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17004, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "bufLen error", 0, 0, 0, 0);
pkt->ctx->method.sendAlert(pkt->ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR);
return HITLS_PARSE_INVALID_MSG_LEN;
}
ret = ParseBinders(pkt->ctx, offeredPsks, &pkt->buf[*pkt->bufOffset], bindersLen);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15171, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"parse binders extensions msg.", 0, 0, 0, 0);
return ret;
}
msg->extension.flag.havePreShareKey = true;
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_FEATURE_CERTIFICATE_AUTHORITIES
static int32_t ParseClientTrustedCaList(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.haveCA == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15172, BINGLOG_STR("certificate_authorities"));
}
uint16_t distinguishedNamesLen = 0;
int32_t ret = ParseBytesToUint16(pkt, &distinguishedNamesLen);
if (ret != HITLS_SUCCESS) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15173, BINGLOG_STR("CaList"));
}
opaque DistinguishedName<1..2^16-1>
struct {
DistinguishedName authorities<3..2^16-1>
} CertificateAuthoritiesExtension
*/
if (distinguishedNamesLen != (pkt->bufLen - *pkt->bufOffset) || (distinguishedNamesLen < 3)) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15174, BINGLOG_STR("CaList"));
}
FreeDNList(msg->extension.content.caList);
msg->extension.content.caList = ParseDNList(&pkt->buf[*pkt->bufOffset], distinguishedNamesLen);
if (msg->extension.content.caList == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17005, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"ParseDNList fail", 0, 0, 0, 0);
pkt->ctx->method.sendAlert(pkt->ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR);
BSL_ERR_PUSH_ERROR(HITLS_PARSE_CA_LIST_ERR);
return HITLS_PARSE_CA_LIST_ERR;
}
HITLS_TrustedCAList *tmp = pkt->ctx->peerInfo.caList;
pkt->ctx->peerInfo.caList = msg->extension.content.caList;
msg->extension.content.caList = tmp;
msg->extension.flag.haveCA = true;
return HITLS_SUCCESS;
}
#endif
static int32_t ParseClientPskKeyExModes(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.havePskExMode == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15175, BINGLOG_STR("pskKeyExchangeMode"));
}
uint8_t len = 0;
int32_t ret = ParseOneByteLengthField(pkt, &len, &msg->extension.content.keModes);
if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15176, BINGLOG_STR("pskKeyExchangeMode"));
} else if (ret == HITLS_MEMALLOC_FAIL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15177,
BINGLOG_STR("pskKeyExchangeMode malloc fail."), ALERT_UNKNOWN);
}
if ((pkt->bufLen != *pkt->bufOffset) || (len == 0u)) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17006, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "bufLen error", 0, 0, 0, 0);
pkt->ctx->method.sendAlert(pkt->ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR);
return HITLS_PARSE_INVALID_MSG_LEN;
}
msg->extension.content.keModesSize = len;
msg->extension.flag.havePskExMode = true;
return HITLS_SUCCESS;
}
static int32_t ParseClientCookie(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.haveCookie == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15178, BINGLOG_STR("cookie"));
}
int32_t ret = ParseExCookie(pkt->buf, pkt->bufLen, &msg->extension.content.cookie,
&msg->extension.content.cookieLen);
if (ret != HITLS_SUCCESS) {
return ret;
}
msg->extension.flag.haveCookie = true;
return HITLS_SUCCESS;
}
static int32_t ParseClientPostHsAuth(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.havePostHsAuth == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15182, BINGLOG_STR("post_handshake_auth"));
}
if (pkt->bufLen != 0) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID15183, BINGLOG_STR("post_handshake_auth"));
}
msg->extension.flag.havePostHsAuth = true;
return HITLS_SUCCESS;
}
#endif
#if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
static int32_t ParseClientSecRenegoInfo(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.haveSecRenego == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15187, BINGLOG_STR("renegotiation info"));
}
uint8_t secRenegoInfoSize = 0;
uint8_t *secRenegoInfo = NULL;
int32_t ret = ParseSecRenegoInfo(pkt->ctx, pkt->buf, pkt->bufLen, &secRenegoInfo, &secRenegoInfoSize);
if (ret != HITLS_SUCCESS) {
return ret;
}
msg->extension.content.secRenegoInfo = secRenegoInfo;
msg->extension.content.secRenegoInfoSize = secRenegoInfoSize;
msg->extension.flag.haveSecRenego = true;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_ETM
static int32_t ParseClientEncryptThenMac(ParsePacket *pkt, ClientHelloMsg *msg)
{
return ParseEmptyExtension(pkt->ctx, HS_EX_TYPE_ENCRYPT_THEN_MAC, pkt->bufLen,
&msg->extension.flag.haveEncryptThenMac);
}
#endif
#ifdef HITLS_TLS_FEATURE_SESSION_TICKET
static int32_t ParseClientTicket(ParsePacket *pkt, ClientHelloMsg *msg)
{
uint8_t *ticket = NULL;
if (msg->extension.flag.haveTicket == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID15975, BINGLOG_STR("tiket"));
}
#ifdef HITLS_TLS_FEATURE_SESSION_CUSTOM_TICKET
if (pkt->ctx->config.tlsConfig.sessionTicketExtCb != NULL) {
int32_t ret = pkt->ctx->config.tlsConfig.sessionTicketExtCb(pkt->ctx, pkt->buf, pkt->bufLen,
pkt->ctx->config.tlsConfig.sessionTicketExtCbArg);
if (ret == 0) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_SESSION_TICKET_FAIL, BINLOG_ID17379,
BINGLOG_STR("parse ticket extension failed."), ALERT_INTERNAL_ERROR);
}
}
#endif
if (pkt->bufLen != 0) {
ticket = (uint8_t *)BSL_SAL_Dump(&pkt->buf[0], pkt->bufLen);
if (ticket == NULL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15976,
BINGLOG_STR("ticket malloc fail."), ALERT_INTERNAL_ERROR);
}
}
msg->extension.content.ticket = ticket;
msg->extension.content.ticketSize = pkt->bufLen;
msg->extension.flag.haveTicket = true;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_RECORD_SIZE_LIMIT
static int32_t ParseClientRecordSizeLimit(ParsePacket *pkt, ClientHelloMsg *msg)
{
if (msg->extension.flag.haveRecordSizeLimit == true) {
return ParseDupExtProcess(pkt->ctx, BINLOG_ID16243, BINGLOG_STR("recordSizeLimit"));
}
if (pkt->bufLen != sizeof(uint16_t)) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID16244, BINGLOG_STR("recordSizeLimit"));
}
int32_t ret = ParseBytesToUint16(pkt, &msg->extension.content.recordSizeLimit);
if (ret != HITLS_SUCCESS) {
return ParseErrorExtLengthProcess(pkt->ctx, BINLOG_ID16244, BINGLOG_STR("recordSizeLimit"));
}
* Endpoints MUST NOT send a "record_size_limit" extension with a value
* smaller than 64. An endpoint MUST treat receipt of a smaller value
* as a fatal error and generate an "illegal_parameter" alert.
*/
msg->extension.flag.haveRecordSizeLimit = true;
return HITLS_SUCCESS;
}
#endif
static int32_t ParseClientExBody(TLS_Ctx *ctx, uint16_t extMsgType, const uint8_t *buf, uint32_t extMsgLen,
ClientHelloMsg *msg)
{
uint32_t bufOffset = 0u;
ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = extMsgLen, .bufOffset = &bufOffset};
static struct {
uint16_t exMsgType;
int32_t (*parseFunc)(ParsePacket *, ClientHelloMsg *);
} extMsgList [] = {
{ .exMsgType = HS_EX_TYPE_POINT_FORMATS, .parseFunc = ParseClientPointFormats },
{ .exMsgType = HS_EX_TYPE_SUPPORTED_GROUPS, .parseFunc = ParseClientSupportGroups },
{ .exMsgType = HS_EX_TYPE_SIGNATURE_ALGORITHMS, .parseFunc = ParseClientSignatureAlgorithms},
#ifdef HITLS_TLS_FEATURE_SNI
{ .exMsgType = HS_EX_TYPE_SERVER_NAME, .parseFunc = ParseClientServerName},
#endif
#ifdef HITLS_TLS_FEATURE_EXTENDED_MASTER_SECRET
{ .exMsgType = HS_EX_TYPE_EXTENDED_MASTER_SECRET, .parseFunc = ParseClientExtMasterSecret},
#endif
#ifdef HITLS_TLS_FEATURE_ALPN
{ .exMsgType = HS_EX_TYPE_APP_LAYER_PROTOCOLS, .parseFunc = ParseClientAlpnProposeList},
#endif
#ifdef HITLS_TLS_PROTO_TLS13
{ .exMsgType = HS_EX_TYPE_SUPPORTED_VERSIONS, .parseFunc = ParseClientSupportedVersions},
{ .exMsgType = HS_EX_TYPE_PRE_SHARED_KEY, .parseFunc = ParseClientPreSharedKey},
{ .exMsgType = HS_EX_TYPE_PSK_KEY_EXCHANGE_MODES, .parseFunc = ParseClientPskKeyExModes},
{ .exMsgType = HS_EX_TYPE_COOKIE, .parseFunc = ParseClientCookie},
#ifdef HITLS_TLS_FEATURE_CERTIFICATE_AUTHORITIES
{ .exMsgType = HS_EX_TYPE_CERTIFICATE_AUTHORITIES, .parseFunc = ParseClientTrustedCaList},
#endif
{ .exMsgType = HS_EX_TYPE_POST_HS_AUTH, .parseFunc = ParseClientPostHsAuth},
{ .exMsgType = HS_EX_TYPE_KEY_SHARE, .parseFunc = ParseClientKeyShare},
#endif
#if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
{ .exMsgType = HS_EX_TYPE_RENEGOTIATION_INFO, .parseFunc = ParseClientSecRenegoInfo},
#endif
#ifdef HITLS_TLS_FEATURE_SESSION_TICKET
{ .exMsgType = HS_EX_TYPE_SESSION_TICKET, .parseFunc = ParseClientTicket},
#endif
#ifdef HITLS_TLS_FEATURE_ETM
{ .exMsgType = HS_EX_TYPE_ENCRYPT_THEN_MAC, .parseFunc = ParseClientEncryptThenMac},
#endif
#ifdef HITLS_TLS_FEATURE_RECORD_SIZE_LIMIT
{ .exMsgType = HS_EX_TYPE_RECORD_SIZE_LIMIT, .parseFunc = ParseClientRecordSizeLimit},
#endif
};
for (uint32_t index = 0; index < sizeof(extMsgList) / sizeof(extMsgList[0]); index++) {
if (extMsgList[index].exMsgType == extMsgType) {
return extMsgList[index].parseFunc(&pkt, msg);
}
}
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
if (IsParseNeedCustomExtensions(CUSTOM_EXT_FROM_CTX(ctx), extMsgType, HITLS_EX_TYPE_CLIENT_HELLO)) {
return ParseCustomExtensions(pkt.ctx, pkt.buf + *pkt.bufOffset, extMsgType, extMsgLen,
HITLS_EX_TYPE_CLIENT_HELLO, NULL, 0);
}
#endif
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15188, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
"unknown extension message type:%d len:%lu in client hello message.", extMsgType, extMsgLen, 0, 0);
return HITLS_SUCCESS;
}
int32_t ParseClientExtension(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg)
{
uint32_t bufOffset = 0u;
uint32_t extensionCount = 0;
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
uint32_t customExtSeenMask = 0;
#endif
ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = bufLen, .bufOffset = &bufOffset};
while (bufOffset < bufLen) {
uint16_t extMsgType = HS_EX_TYPE_END;
uint32_t extMsgLen = 0u;
uint32_t extensionId = 0;
int32_t ret = CheckForDuplicateExtension(&pkt, &extMsgType, &extMsgLen, &extensionId, msg->extensionTypeMask);
if (ret != HITLS_SUCCESS) {
return ret;
}
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
if (extensionId == HS_EX_TYPE_ID_UNRECOGNIZED) {
ret = CheckForDuplicateCustomExtension(ctx, extMsgType, HITLS_EX_TYPE_CLIENT_HELLO,
&customExtSeenMask, NULL);
if (ret != HITLS_SUCCESS) {
return ret;
}
}
#endif
if (extensionId != HS_EX_TYPE_ID_UNRECOGNIZED
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
|| !IsParseNeedCustomExtensions(CUSTOM_EXT_FROM_CTX(ctx), extMsgType, HITLS_EX_TYPE_CLIENT_HELLO)
#endif
) {
msg->extensionTypeMask |= 1ULL << extensionId;
}
ret = ParseClientExBody(ctx, extMsgType, &buf[bufOffset], extMsgLen, msg);
if (ret != HITLS_SUCCESS) {
return ret;
}
bufOffset += extMsgLen;
ClientHello (this facilitates implementation as described below).
Servers MUST check that it is the last extension and otherwise fail
the handshake with an "illegal_parameter" alert. */
if (extMsgType == HS_EX_TYPE_PRE_SHARED_KEY && bufOffset != bufLen) {
return ParseErrorProcess(ctx, HITLS_PARSE_PRE_SHARED_KEY_FAILED, BINLOG_ID16136,
BINGLOG_STR("psk is not the last extension."), ALERT_ILLEGAL_PARAMETER);
}
extensionCount++;
}
* length is inconsistent with the buffer length, an error code is returned */
if (bufOffset != bufLen) {
return ParseErrorExtLengthProcess(ctx, BINLOG_ID15192, BINGLOG_STR("client hello"));
}
#ifdef HITLS_TLS_FEATURE_CLIENT_HELLO_CB
if (ctx->globalConfig != NULL && ctx->globalConfig->clientHelloCb != NULL) {
msg->extensionBuff = BSL_SAL_Dump(buf, bufLen);
if (msg->extensionBuff == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
return ParseErrorProcess(ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID17356,
BINGLOG_STR("extensionBuff dump fail."), ALERT_INTERNAL_ERROR);
}
msg->extensionBuffLen = bufLen;
msg->extensionCount = extensionCount;
}
#else
(void)extensionCount;
#endif
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_PROTO_TLS13
void CleanPreShareKey(PreSharedKey *preSharedKey)
{
ListHead *node = NULL;
ListHead *tmpNode = NULL;
PreSharedKey *cur = NULL;
PreSharedKey *cache = preSharedKey;
if (cache != NULL) {
LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(cache->pskNode))
{
cur = BSL_LIST_ENTRY(node, PreSharedKey, pskNode);
BSL_LIST_REMOVE(node);
BSL_SAL_FREE(cur->identity);
BSL_SAL_FREE(cur->binder);
BSL_SAL_FREE(cur);
}
BSL_SAL_FREE(preSharedKey);
}
}
#endif
void CleanClientHelloExtension(ClientHelloMsg *msg)
{
if (msg == NULL) {
return;
}
BSL_SAL_FREE(msg->extension.content.supportedGroups);
BSL_SAL_FREE(msg->extension.content.pointFormats);
BSL_SAL_FREE(msg->extension.content.signatureAlgorithms);
#ifdef HITLS_TLS_FEATURE_ALPN
BSL_SAL_FREE(msg->extension.content.alpnList);
#endif
#ifdef HITLS_TLS_FEATURE_SNI
BSL_SAL_FREE(msg->extension.content.serverName);
#endif
#if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
BSL_SAL_FREE(msg->extension.content.secRenegoInfo);
#endif
#ifdef HITLS_TLS_FEATURE_SESSION_TICKET
BSL_SAL_FREE(msg->extension.content.ticket);
#endif
#ifdef HITLS_TLS_PROTO_TLS13
BSL_SAL_FREE(msg->extension.content.signatureAlgorithmsCert);
BSL_SAL_FREE(msg->extension.content.supportedVersions);
BSL_SAL_FREE(msg->extension.content.keModes);
BSL_SAL_FREE(msg->extension.content.cookie);
CleanKeyShare(msg->extension.content.keyShare);
msg->extension.content.keyShare = NULL;
CleanPreShareKey(msg->extension.content.preSharedKey);
msg->extension.content.preSharedKey = NULL;
#ifdef HITLS_TLS_FEATURE_CERTIFICATE_AUTHORITIES
FreeDNList(msg->extension.content.caList);
#endif
msg->extension.content.caList = NULL;
#endif
}
#endif