* 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 "cipher_suite.h"
#include "bsl_err_internal.h"
#include "tls_binlog_id.h"
#include "bsl_log_internal.h"
#include "bsl_log.h"
#include "bsl_bytes.h"
#include "bsl_list.h"
#include "hitls_error.h"
#include "hitls_sni.h"
#include "hitls_cert_type.h"
#include "hitls_crypt_type.h"
#include "hitls_session.h"
#include "tls.h"
#include "hs_ctx.h"
#include "hs_extensions.h"
#include "hs.h"
#include "hs_msg.h"
#include "hs_common.h"
#include "session.h"
#include "hs_verify.h"
#include "pack_common.h"
#include "custom_extensions.h"
#include "config_type.h"
#include "security.h"
#include "pack_extensions.h"
#define EXTENSION_MSG(exMsgT, needP, packF) \
.exMsgType = (exMsgT), \
.needPack = (needP), \
.packFunc = (packF), \
int32_t PackExtensionHeader(uint16_t exMsgType, uint16_t exMsgLen, PackPacket *pkt)
{
int32_t ret = PackAppendUint16ToBuf(pkt, exMsgType);
if (ret != HITLS_SUCCESS) {
return ret;
}
ret = PackAppendUint16ToBuf(pkt, exMsgLen);
if (ret != HITLS_SUCCESS) {
return ret;
}
ret = PackReserveBytes(pkt, exMsgLen, NULL);
if (ret != HITLS_SUCCESS) {
return ret;
}
return HITLS_SUCCESS;
}
static int32_t PackExtensions(const TLS_Ctx *ctx, PackPacket *pkt, PackExtInfo *extMsgList, uint32_t listSize)
{
int32_t ret = HITLS_SUCCESS;
for (uint32_t index = 0; index < listSize; index++) {
if (extMsgList[index].needPack == false) {
continue;
}
if (extMsgList[index].packFunc == NULL) {
ret = PackEmptyExtension(extMsgList[index].exMsgType, extMsgList[index].needPack, pkt);
} else {
ret = extMsgList[index].packFunc(ctx, pkt);
}
if (ret != HITLS_SUCCESS) {
return ret;
}
}
return HITLS_SUCCESS;
}
static int32_t PackExtensionEnd(PackPacket *pkt, uint32_t extensionLenPosition)
{
uint32_t extensionLength = 0;
int32_t ret = PackGetSubBuffer(pkt, extensionLenPosition, &extensionLength, NULL);
if (ret != HITLS_SUCCESS) {
return ret;
}
if (extensionLength != sizeof(uint16_t)) {
PackCloseUint16Field(pkt, extensionLenPosition);
} else {
*pkt->bufOffset -= sizeof(uint16_t);
}
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_PROTO_TLS13
static bool IsNeedPreSharedKey(const TLS_Ctx *ctx)
{
if (ctx->config.tlsConfig.maxVersion != HITLS_VERSION_TLS13) {
return false;
}
if (ctx->hsCtx->state == TRY_SEND_HELLO_RETRY_REQUEST) {
return false;
}
return true;
}
bool Tls13NeedPack(const TLS_Ctx *ctx, uint32_t version)
{
bool tls13NeedPack = false;
if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
tls13NeedPack = false;
} else {
tls13NeedPack = (version >= HITLS_VERSION_TLS13) ? true : false;
}
return tls13NeedPack;
}
static int32_t PackCookie(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint32_t exMsgDataLen = 0u;
if (ctx->negotiatedInfo.cookie == NULL) {
return HITLS_SUCCESS;
}
exMsgDataLen = sizeof(uint16_t) + (ctx->negotiatedInfo.cookieSize);
uint32_t cookieLen = ctx->negotiatedInfo.cookieSize;
ret = PackExtensionHeader(HS_EX_TYPE_COOKIE, exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint16ToBuf(pkt, cookieLen);
(void)PackAppendDataToBuf(pkt, ctx->negotiatedInfo.cookie, cookieLen);
ctx->hsCtx->extFlag.haveCookie = true;
return HITLS_SUCCESS;
}
#endif
static int32_t PackPointFormats(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint16_t exMsgHeaderLen = 0u;
uint8_t exMsgDataLen = 0u;
const TLS_Config *config = &(ctx->config.tlsConfig);
if (config->pointFormatsSize == 0) {
return HITLS_SUCCESS;
}
if (config->pointFormats == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15415, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"pack point formats extension error, invalid input parameter.", 0, 0, 0, 0);
return HITLS_INTERNAL_EXCEPTION;
}
exMsgHeaderLen = sizeof(uint8_t);
exMsgDataLen = (uint8_t)config->pointFormatsSize;
ret = PackExtensionHeader(HS_EX_TYPE_POINT_FORMATS, exMsgHeaderLen + exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint8ToBuf(pkt, exMsgDataLen);
for (uint32_t index = 0; index < config->pointFormatsSize; index++) {
(void)PackAppendUint8ToBuf(pkt, config->pointFormats[index]);
}
ctx->hsCtx->extFlag.havePointFormats = true;
return HITLS_SUCCESS;
}
int32_t PackEmptyExtension(uint16_t exMsgType, bool needPack, PackPacket *pkt)
{
if (needPack) {
int32_t ret = PackExtensionHeader(exMsgType, 0u, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
}
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_FEATURE_RECORD_SIZE_LIMIT
int32_t PackRecordSizeLimit(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint16_t upperBound = (GET_VERSION_FROM_CTX(ctx) == HITLS_VERSION_TLS13 ? REC_MAX_PLAIN_LENGTH + 1
: REC_MAX_PLAIN_LENGTH);
uint16_t recordSizeLimit = ctx->isClient ?
ctx->config.tlsConfig.recordSizeLimit : ctx->negotiatedInfo.recordSizeLimit;
if (recordSizeLimit == 0) {
return HITLS_SUCCESS;
}
uint16_t exMsgDataLen = sizeof(uint16_t);
ret = PackExtensionHeader(HS_EX_TYPE_RECORD_SIZE_LIMIT, exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
recordSizeLimit = recordSizeLimit <= upperBound ? recordSizeLimit : upperBound;
(void)PackAppendUint16ToBuf(pkt, recordSizeLimit);
ctx->hsCtx->extFlag.haveRecordSizeLimit = true;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_HOST_CLIENT
#ifdef HITLS_TLS_FEATURE_SNI
static int32_t PackServerName(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint16_t exMsgDataLen = 0u;
uint8_t *hostName = NULL;
uint8_t *serverName = NULL;
uint32_t hostNameSize, serverNameSize = 0u;
const TLS_Config *config = &(ctx->config.tlsConfig);
bool isNotTls13 = (config->maxVersion < HITLS_VERSION_TLS13 || config->maxVersion == HITLS_VERSION_DTLS12);
(void)isNotTls13;
(void)hostNameSize;
(void)hostName;
#ifdef HITLS_TLS_FEATURE_SESSION
* field is the hostname in the session */
if (isNotTls13 && ctx->session != NULL) {
SESS_GetHostName(ctx->session, &hostNameSize, &hostName);
serverName = hostName;
} else
#endif
{
serverName = config->serverName;
}
if (serverName == NULL) {
return HITLS_SUCCESS;
}
serverNameSize = (uint32_t)strlen((char *)serverName);
exMsgDataLen = sizeof(uint16_t) + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t) * serverNameSize;
ret = PackExtensionHeader(HS_EX_TYPE_SERVER_NAME, exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint16ToBuf(pkt, exMsgDataLen - sizeof(uint16_t));
(void)PackAppendUint8ToBuf(pkt, HITLS_SNI_HOSTNAME_TYPE);
(void)PackAppendUint16ToBuf(pkt, (uint16_t)serverNameSize);
(void)PackAppendDataToBuf(pkt, serverName, serverNameSize);
ctx->hsCtx->extFlag.haveServerName = true;
return HITLS_SUCCESS;
}
static bool IsNeedClientPackServerName(const TLS_Ctx *ctx)
{
const TLS_Config *config = &(ctx->config.tlsConfig);
if (ctx->session == NULL) {
if (config->serverName == NULL) {
return false;
}
}
if (ctx->session != NULL) {
if (config->maxVersion == HITLS_VERSION_TLS13 && config->serverName == NULL) {
return false;
}
}
return true;
}
#endif
static int32_t PackClientSignatureAlgorithms(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint16_t exMsgHeaderLen = 0u;
uint16_t exMsgDataLen = 0u;
const TLS_Config *config = &(ctx->config.tlsConfig);
if (config->signAlgorithmsSize == 0) {
return HITLS_SUCCESS;
}
if (config->signAlgorithms == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15413, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"pack signature algirithms extension error, invalid input parameter.", 0, 0, 0, 0);
return HITLS_INTERNAL_EXCEPTION;
}
uint32_t signAlgorithmsSize = 0;
uint16_t *signAlgorithms = CheckSupportSignAlgorithms(ctx, config->signAlgorithms,
config->signAlgorithmsSize, &signAlgorithmsSize);
if (signAlgorithms == NULL || signAlgorithmsSize == 0) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17309, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"no available signAlgorithms", 0, 0, 0, 0);
BSL_SAL_FREE(signAlgorithms);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
return HITLS_CERT_ERR_NO_SIGN_SCHEME_MATCH;
}
exMsgHeaderLen = sizeof(uint16_t);
exMsgDataLen = sizeof(uint16_t) * (uint16_t)signAlgorithmsSize;
ret = PackExtensionHeader(HS_EX_TYPE_SIGNATURE_ALGORITHMS, exMsgHeaderLen + exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
BSL_SAL_FREE(signAlgorithms);
return ret;
}
(void)PackAppendUint16ToBuf(pkt, exMsgDataLen);
for (uint32_t index = 0; index < signAlgorithmsSize; index++) {
(void)PackAppendUint16ToBuf(pkt, signAlgorithms[index]);
}
BSL_SAL_FREE(signAlgorithms);
ctx->hsCtx->extFlag.haveSignatureAlgorithms = true;
return HITLS_SUCCESS;
}
static bool IsClientSupportedGroupAvailable(const TLS_Ctx *ctx, uint16_t group)
{
const TLS_Config *config = &ctx->config.tlsConfig;
const TLS_GroupInfo *groupInfo = ConfigGetGroupInfo(config, group);
if (groupInfo == NULL || ((groupInfo->versionBits & config->version) == 0)) {
return false;
}
#ifdef HITLS_TLS_FEATURE_SECURITY
if (SECURITY_SslCheck(ctx, HITLS_SECURITY_SECOP_CURVE_SUPPORTED, 0, (int32_t)group, NULL) != SECURITY_SUCCESS) {
return false;
}
#endif
return true;
}
static int32_t PackClientSupportedGroups(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
const TLS_Config *config = &(ctx->config.tlsConfig);
if (config->groupsSize == 0) {
return HITLS_SUCCESS;
}
if (config->groups == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15414, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"pack supported groups extension error, invalid input parameter.", 0, 0, 0, 0);
return HITLS_INTERNAL_EXCEPTION;
}
ret = PackAppendUint16ToBuf(pkt, HS_EX_TYPE_SUPPORTED_GROUPS);
if (ret != HITLS_SUCCESS) {
return ret;
}
uint32_t extensionLenPosition = 0u;
ret = PackStartLengthField(pkt, sizeof(uint16_t), &extensionLenPosition);
if (ret != HITLS_SUCCESS) {
return ret;
}
uint32_t groupLenPosition = 0u;
ret = PackStartLengthField(pkt, sizeof(uint16_t), &groupLenPosition);
if (ret != HITLS_SUCCESS) {
return ret;
}
bool haveGroup = false;
for (uint32_t i = 0; i < config->groupsSize; ++i) {
if (!IsClientSupportedGroupAvailable(ctx, config->groups[i])) {
continue;
}
haveGroup = true;
ret = PackAppendUint16ToBuf(pkt, config->groups[i]);
if (ret != HITLS_SUCCESS) {
return ret;
}
}
if (!haveGroup) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15076, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"pack supported groups extension error, no available group.", 0, 0, 0, 0);
return HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP;
}
PackCloseUint16Field(pkt, groupLenPosition);
PackCloseUint16Field(pkt, extensionLenPosition);
ctx->hsCtx->extFlag.haveSupportedGroups = true;
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_FEATURE_ALPN
static int32_t PackClientAlpnList(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint16_t exMsgHeaderLen = 0u;
uint8_t exMsgDataLen = 0u;
const TLS_Config *config = &(ctx->config.tlsConfig);
if (config->alpnListSize == 0) {
return HITLS_SUCCESS;
}
if (config->alpnList == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15416, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"pack alpn list extension error, invalid input parameter.", 0, 0, 0, 0);
return HITLS_INTERNAL_EXCEPTION;
}
exMsgHeaderLen = sizeof(uint16_t);
exMsgDataLen = (uint8_t)config->alpnListSize;
ret = PackExtensionHeader(HS_EX_TYPE_APP_LAYER_PROTOCOLS, exMsgHeaderLen + exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint16ToBuf(pkt, exMsgDataLen);
(void)PackAppendDataToBuf(pkt, config->alpnList, config->alpnListSize);
ctx->hsCtx->extFlag.haveAlpn = true;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_SESSION_TICKET
static int32_t PackClientTicket(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint8_t *ticket = NULL;
uint32_t ticketSize = 0;
uint16_t sessVersion = HITLS_VERSION_TLS13;
if (ctx->session != NULL) {
HITLS_SESS_GetProtocolVersion(ctx->session, &sessVersion);
}
if (sessVersion != HITLS_VERSION_TLS13) {
SESS_GetTicket(ctx->session, &ticket, &ticketSize);
}
#ifdef HITLS_TLS_FEATURE_SESSION_CUSTOM_TICKET
if (ctx->config.tlsConfig.maxVersion >= HITLS_VERSION_TLS10) {
if (ticket == NULL || ticketSize == 0) {
ticket = ctx->config.tlsConfig.sessionTicketExt;
ticketSize = ctx->config.tlsConfig.sessionTicketExtSize;
}
}
#endif
ret = PackExtensionHeader(HS_EX_TYPE_SESSION_TICKET, (uint16_t)ticketSize, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendDataToBuf(pkt, ticket, ticketSize);
ctx->hsCtx->extFlag.haveTicket = true;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_RENEGOTIATION
static int32_t PackClientSecRenegoInfo(const TLS_Ctx *ctx, PackPacket *pkt)
{
if (!ctx->negotiatedInfo.isRenegotiation) {
return HITLS_SUCCESS;
}
const uint8_t *clientData = ctx->negotiatedInfo.clientVerifyData;
uint32_t clientDataSize = ctx->negotiatedInfo.clientVerifyDataSize;
uint16_t exMsgHeaderLen = sizeof(uint8_t);
uint16_t exMsgDataLen = (uint16_t)clientDataSize;
int32_t ret = PackExtensionHeader(HS_EX_TYPE_RENEGOTIATION_INFO, exMsgHeaderLen + exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint8ToBuf(pkt, (uint8_t)clientDataSize);
(void)PackAppendDataToBuf(pkt, clientData, clientDataSize);
return HITLS_SUCCESS;
}
#endif
static bool IsNeedPackEcExtension(const TLS_Ctx *ctx)
{
const TLS_Config *config = &(ctx->config.tlsConfig);
#ifdef HITLS_TLS_PROTO_TLS13
if ((config->maxVersion == HITLS_VERSION_TLS13)) {
uint32_t needKeyShareMode = TLS13_KE_MODE_PSK_WITH_DHE | TLS13_CERT_AUTH_WITH_DHE;
if ((ctx->negotiatedInfo.tls13BasicKeyExMode & needKeyShareMode) != 0) {
return true;
}
}
#endif
for (uint32_t index = 0; index < config->cipherSuitesSize; index++) {
CipherSuiteInfo cipherInfo = {0};
* suite is configured */
(void)CFG_GetCipherSuiteInfo(config->cipherSuites[index], &cipherInfo);
if ((cipherInfo.authAlg == HITLS_AUTH_ECDSA) ||
(cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDHE) ||
(cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDH) ||
(cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDHE_PSK)) {
return true;
}
}
return false;
}
#ifdef HITLS_TLS_PROTO_TLS13
static int32_t PackClientSupportedVersions(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint16_t exMsgHeaderLen = 0u;
uint8_t exMsgDataLen = 0u;
const TLS_Config *config = &(ctx->config.tlsConfig);
uint16_t minVersion = config->minVersion;
uint16_t maxVersion = config->maxVersion;
if (config->minVersion < HITLS_VERSION_SSL30 || config->maxVersion > HITLS_VERSION_TLS13) {
BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15418, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"pack supported version extension error, invalid input parameter.", 0, 0, 0, 0);
return HITLS_INTERNAL_EXCEPTION;
}
exMsgHeaderLen = sizeof(uint8_t);
exMsgDataLen = sizeof(uint16_t) * (maxVersion - minVersion + 1);
ret = PackExtensionHeader(HS_EX_TYPE_SUPPORTED_VERSIONS, exMsgHeaderLen + exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint8ToBuf(pkt, exMsgDataLen);
for (uint16_t version = maxVersion; version >= minVersion; version--) {
(void)PackAppendUint16ToBuf(pkt, version);
}
ctx->hsCtx->extFlag.haveSupportedVers = true;
return HITLS_SUCCESS;
}
static int32_t PackClientPskKeyExModes(const TLS_Ctx *ctx, PackPacket *pkt)
{
bool allowOnly = false;
bool allowDhe = false;
const uint32_t configKxMode = ctx->config.tlsConfig.keyExchMode;
uint16_t exMsgHeaderLen = sizeof(uint8_t);
uint16_t exMsgDataLen = 0;
if ((bool)(configKxMode & TLS13_KE_MODE_PSK_WITH_DHE)) {
exMsgDataLen++;
allowDhe = true;
}
if ((bool)(configKxMode & TLS13_KE_MODE_PSK_ONLY)) {
exMsgDataLen++;
allowOnly = true;
}
int32_t ret = PackExtensionHeader(HS_EX_TYPE_PSK_KEY_EXCHANGE_MODES, exMsgHeaderLen + exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint8ToBuf(pkt, (uint8_t)exMsgDataLen);
if (allowDhe) {
(void)PackAppendUint8ToBuf(pkt, PSK_DHE_KE);
}
if (allowOnly) {
(void)PackAppendUint8ToBuf(pkt, PSK_KE);
}
ctx->hsCtx->extFlag.havePskExMode = true;
return HITLS_SUCCESS;
}
static int32_t PackClientKeyShare(const TLS_Ctx *ctx, PackPacket *pkt)
{
uint32_t needKeyShareMode = TLS13_KE_MODE_PSK_WITH_DHE | TLS13_CERT_AUTH_WITH_DHE;
if ((ctx->negotiatedInfo.tls13BasicKeyExMode & needKeyShareMode) == 0) {
return HITLS_SUCCESS;
}
KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx;
if (kxCtx == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16939, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "kxCtx is null", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
return HITLS_NULL_INPUT;
}
uint16_t keyShareLen = 0;
KeyShareParam *keyShare = &(kxCtx->keyExchParam.share);
uint32_t pubKeyLens[MAX_KEYSHARE_COUNT] = {0};
for (uint8_t i = 0; i < keyShare->count; i++) {
pubKeyLens[i] = HS_GetCryptLength(ctx, HITLS_CRYPT_INFO_CMD_GET_PUBLIC_KEY_LEN,
keyShare->groups[i]);
if (pubKeyLens[i] == 0u) {
BSL_ERR_PUSH_ERROR(HITLS_PACK_INVALID_KX_PUBKEY_LENGTH);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15422, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"invalid keyShare length.", 0, 0, 0, 0);
return HITLS_PACK_INVALID_KX_PUBKEY_LENGTH;
}
keyShareLen += sizeof(uint16_t) + sizeof(uint16_t) + pubKeyLens[i];
}
int32_t ret = PackExtensionHeader(HS_EX_TYPE_KEY_SHARE, sizeof(uint16_t) + keyShareLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint16ToBuf(pkt, keyShareLen);
for (uint8_t i = 0; i < keyShare->count; i++) {
(void)PackAppendUint16ToBuf(pkt, (uint16_t)keyShare->groups[i]);
(void)PackAppendUint16ToBuf(pkt, (uint16_t)pubKeyLens[i]);
uint32_t pubKeyUsedLen = 0;
uint8_t *pubKeyBuf = NULL;
(void)PackReserveBytes(pkt, pubKeyLens[i], &pubKeyBuf);
ret = SAL_CRYPT_EncodeEcdhPubKey(kxCtx->keys[i], pubKeyBuf, pubKeyLens[i], &pubKeyUsedLen);
if (ret != HITLS_SUCCESS || pubKeyUsedLen != pubKeyLens[i]) {
BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15423, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"encode client keyShare key fail.", 0, 0, 0, 0);
return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY;
}
(void)PackSkipBytes(pkt, pubKeyUsedLen);
}
ctx->hsCtx->extFlag.haveKeyShare = true;
return HITLS_SUCCESS;
}
static uint32_t GetPreSharedKeyExtLen(const PskInfo13 *pskInfo)
{
uint32_t extLen = HS_EX_HEADER_LEN;
uint32_t binderLen = 0;
if (pskInfo->resumeSession != NULL) {
HITLS_HashAlgo hashAlg = HITLS_HASH_BUTT;
binderLen = HS_GetBinderLen(pskInfo->resumeSession, &hashAlg);
if (binderLen == 0) {
return 0;
}
uint8_t *ticket = NULL;
uint32_t ticketSize = 0;
SESS_GetTicket(pskInfo->resumeSession, &ticket, &ticketSize);
extLen += sizeof(uint16_t) + ticketSize + sizeof(uint32_t) + sizeof(uint8_t) + binderLen;
}
if (pskInfo->userPskSess != NULL) {
HITLS_HashAlgo hashAlg = HITLS_HASH_BUTT;
binderLen = HS_GetBinderLen(pskInfo->userPskSess->pskSession, &hashAlg);
if (binderLen == 0) {
return 0;
}
extLen += sizeof(uint16_t) + pskInfo->userPskSess->identityLen + sizeof(uint32_t) + sizeof(uint8_t) + binderLen;
}
extLen += sizeof(uint16_t) + sizeof(uint16_t);
return extLen;
}
static void PackClientPreSharedKeyIdentity(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen)
{
(void)bufLen;
PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13;
uint32_t offset = 0;
uint32_t offsetStamp = offset;
offset += sizeof(uint16_t);
if (pskInfo->resumeSession != NULL) {
uint8_t *ticket = NULL;
uint32_t ticketSize = 0;
SESS_GetTicket(pskInfo->resumeSession, &ticket, &ticketSize);
BSL_Uint16ToByte((uint16_t)ticketSize, &buf[offset]);
offset += sizeof(uint16_t);
memcpy(&buf[offset], ticket, ticketSize);
offset += ticketSize;
uint32_t ageSec = (uint32_t)((uint64_t)BSL_SAL_CurrentSysTimeGet() - SESS_GetStartTime(pskInfo->resumeSession));
uint32_t agemSec = ageSec * 1000 + (uint32_t)SESS_GetTicketAgeAdd(pskInfo->resumeSession);
BSL_Uint32ToByte(agemSec, &buf[offset]);
offset += sizeof(uint32_t);
}
if (pskInfo->userPskSess != NULL) {
BSL_Uint16ToByte((uint16_t)pskInfo->userPskSess->identityLen, &buf[offset]);
offset += sizeof(uint16_t);
memcpy(&buf[offset], pskInfo->userPskSess->identity, pskInfo->userPskSess->identityLen);
offset += pskInfo->userPskSess->identityLen;
BSL_Uint32ToByte(0, &buf[offset]);
offset += sizeof(uint32_t);
}
BSL_Uint16ToByte((uint16_t)(offset - offsetStamp - sizeof(uint16_t)), &buf[offsetStamp]);
}
static int32_t PackClientPreSharedKey(const TLS_Ctx *ctx, PackPacket *pkt)
{
PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13;
if (pskInfo->resumeSession == NULL && pskInfo->userPskSess == NULL) {
return HITLS_SUCCESS;
}
uint32_t minLen = GetPreSharedKeyExtLen(pskInfo);
if (minLen == 0) {
BSL_ERR_PUSH_ERROR(HITLS_PACK_PRE_SHARED_KEY_ERR);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15939, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Binder size is zero when PackClientPreSharedKey", 0, 0, 0, 0);
return HITLS_PACK_PRE_SHARED_KEY_ERR;
}
int32_t ret = PackExtensionHeader(HS_EX_TYPE_PRE_SHARED_KEY, (uint16_t)(minLen - HS_EX_HEADER_LEN), pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
uint8_t *pskBuf = NULL;
ret = PackReserveBytes(pkt, minLen - HS_EX_HEADER_LEN, &pskBuf);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackSkipBytes(pkt, minLen - HS_EX_HEADER_LEN);
PackClientPreSharedKeyIdentity(ctx, pskBuf, minLen - HS_EX_HEADER_LEN);
ctx->hsCtx->extFlag.havePreShareKey = true;
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_FEATURE_CERTIFICATE_AUTHORITIES
int32_t PackClientCAList(const TLS_Ctx *ctx, PackPacket *pkt)
{
const TLS_Config *config = &(ctx->config.tlsConfig);
int32_t ret = PackAppendUint16ToBuf(pkt, HS_EX_TYPE_CERTIFICATE_AUTHORITIES);
if (ret != HITLS_SUCCESS) {
return ret;
}
uint32_t extensionLenPosition = 0u;
ret = PackStartLengthField(pkt, sizeof(uint16_t), &extensionLenPosition);
if (ret != HITLS_SUCCESS) {
return ret;
}
uint32_t caLenPosition = 0u;
ret = PackStartLengthField(pkt, sizeof(uint16_t), &caLenPosition);
if (ret != HITLS_SUCCESS) {
return ret;
}
ret = PackTrustedCAList(config->caList, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
PackCloseUint16Field(pkt, caLenPosition);
PackCloseUint16Field(pkt, extensionLenPosition);
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_PHA
static bool IsNeedPackPha(const TLS_Ctx *ctx)
{
const TLS_Config *tlsConfig = &ctx->config.tlsConfig;
if (tlsConfig->maxVersion != HITLS_VERSION_TLS13) {
return false;
}
return tlsConfig->isSupportPostHandshakeAuth;
}
#endif
#endif
static int32_t PackClientExtensions(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
const TLS_Config *tlsConfig = &ctx->config.tlsConfig;
(void)tlsConfig;
#ifdef HITLS_TLS_FEATURE_RENEGOTIATION
const TLS_NegotiatedInfo *negoInfo = &ctx->negotiatedInfo;
#endif
#ifdef HITLS_TLS_PROTO_TLS13
bool isTls13 = (tlsConfig->maxVersion == HITLS_VERSION_TLS13);
#endif
bool isEcNeed = IsNeedPackEcExtension(ctx);
bool isSignAlgNeed = (ctx->config.tlsConfig.maxVersion >= HITLS_VERSION_TLS12);
#ifdef HITLS_TLS_FEATURE_SESSION_TICKET
bool isSessionTicketNeed = IsTicketSupport(ctx);
#endif
#ifdef HITLS_TLS_FEATURE_PHA
bool isNeedPha = IsNeedPackPha(ctx);
#endif
PackExtInfo extMsgList[] = {
#ifdef HITLS_TLS_FEATURE_RECORD_SIZE_LIMIT
{ EXTENSION_MSG(HS_EX_TYPE_RECORD_SIZE_LIMIT, (tlsConfig->recordSizeLimit != 0), PackRecordSizeLimit) },
#endif
#ifdef HITLS_TLS_FEATURE_SNI
{ EXTENSION_MSG(HS_EX_TYPE_SERVER_NAME, IsNeedClientPackServerName(ctx), PackServerName) },
#endif
{ EXTENSION_MSG(HS_EX_TYPE_SIGNATURE_ALGORITHMS, isSignAlgNeed, PackClientSignatureAlgorithms) },
{ EXTENSION_MSG(HS_EX_TYPE_SUPPORTED_GROUPS, isEcNeed, PackClientSupportedGroups) },
{ EXTENSION_MSG(HS_EX_TYPE_POINT_FORMATS, isEcNeed, PackPointFormats) },
#ifdef HITLS_TLS_PROTO_TLS13
{ EXTENSION_MSG(HS_EX_TYPE_SUPPORTED_VERSIONS, isTls13, PackClientSupportedVersions) },
#endif
{ EXTENSION_MSG(HS_EX_TYPE_EARLY_DATA, false, NULL) },
#ifdef HITLS_TLS_PROTO_TLS13
{ EXTENSION_MSG(HS_EX_TYPE_COOKIE, isTls13, PackCookie) },
#ifdef HITLS_TLS_FEATURE_PHA
{ EXTENSION_MSG(HS_EX_TYPE_POST_HS_AUTH, isNeedPha, NULL) },
#endif
#endif
#ifdef HITLS_TLS_FEATURE_EXTENDED_MASTER_SECRET
{ EXTENSION_MSG(HS_EX_TYPE_EXTENDED_MASTER_SECRET,
(tlsConfig->emsMode != HITLS_EMS_MODE_FORBID), NULL) },
#endif
#ifdef HITLS_TLS_FEATURE_ALPN
{ EXTENSION_MSG(HS_EX_TYPE_APP_LAYER_PROTOCOLS, (tlsConfig->alpnList != NULL &&
ctx->state == CM_STATE_HANDSHAKING), PackClientAlpnList) },
#endif
#ifdef HITLS_TLS_PROTO_TLS13
{ EXTENSION_MSG(HS_EX_TYPE_PSK_KEY_EXCHANGE_MODES, isTls13, PackClientPskKeyExModes) },
{ EXTENSION_MSG(HS_EX_TYPE_KEY_SHARE, isTls13, PackClientKeyShare) },
#ifdef HITLS_TLS_FEATURE_CERTIFICATE_AUTHORITIES
{ EXTENSION_MSG(HS_EX_TYPE_CERTIFICATE_AUTHORITIES, isTls13 && tlsConfig->caList != NULL, PackClientCAList) },
#endif
#endif
#ifdef HITLS_TLS_FEATURE_RENEGOTIATION
{ EXTENSION_MSG(HS_EX_TYPE_RENEGOTIATION_INFO, negoInfo->isSecureRenegotiation, PackClientSecRenegoInfo) },
#endif
#ifdef HITLS_TLS_FEATURE_SESSION_TICKET
{ EXTENSION_MSG(HS_EX_TYPE_SESSION_TICKET, isSessionTicketNeed, PackClientTicket) },
#endif
#ifdef HITLS_TLS_FEATURE_ETM
{ EXTENSION_MSG(HS_EX_TYPE_ENCRYPT_THEN_MAC, tlsConfig->isEncryptThenMac, NULL) },
#endif
#ifdef HITLS_TLS_PROTO_TLS13
{ EXTENSION_MSG(HS_EX_TYPE_PRE_SHARED_KEY, IsNeedPreSharedKey(ctx), PackClientPreSharedKey) },
#endif
};
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
if (IsPackNeedCustomExtensions(CUSTOM_EXT_FROM_CTX(ctx), HITLS_EX_TYPE_CLIENT_HELLO)) {
ret = PackCustomExtensions(ctx, pkt, HITLS_EX_TYPE_CLIENT_HELLO, NULL, 0);
if (ret != HITLS_SUCCESS) {
return ret;
}
}
#endif
ret = PackExtensions(ctx, pkt, extMsgList, sizeof(extMsgList) / sizeof(extMsgList[0]));
if (ret != HITLS_SUCCESS) {
return ret;
}
#ifdef HITLS_TLS_FEATURE_PHA
ctx->hsCtx->extFlag.havePostHsAuth = isNeedPha;
#endif
#ifdef HITLS_TLS_FEATURE_EXTENDED_MASTER_SECRET
ctx->hsCtx->extFlag.haveExtendedMasterSecret = (tlsConfig->emsMode != HITLS_EMS_MODE_FORBID);
#endif
#ifdef HITLS_TLS_FEATURE_ETM
ctx->hsCtx->extFlag.haveEncryptThenMac = ctx->config.tlsConfig.isEncryptThenMac;
#endif
return HITLS_SUCCESS;
}
int32_t PackClientExtension(const TLS_Ctx *ctx, PackPacket *pkt)
{
uint32_t extensionLenPosition = 0u;
int32_t ret = PackStartLengthField(pkt, sizeof(uint16_t), &extensionLenPosition);
if (ret != HITLS_SUCCESS) {
return ret;
}
ret = PackClientExtensions(ctx, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
return PackExtensionEnd(pkt, extensionLenPosition);
}
#endif
#ifdef HITLS_TLS_HOST_SERVER
static bool IsServerNeedPackEcExtension(const TLS_Ctx *ctx)
{
const TLS_NegotiatedInfo *negotiatedInfo = &(ctx->negotiatedInfo);
CipherSuiteInfo cipherInfo = negotiatedInfo->cipherSuiteInfo;
if (((cipherInfo.authAlg == HITLS_AUTH_ECDSA) || (cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDHE) ||
(cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDH) || (cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDHE_PSK)) &&
ctx->haveClientPointFormats == true) {
return true;
}
return false;
}
#ifdef HITLS_TLS_FEATURE_ALPN
int32_t PackServerSelectAlpnProto(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint16_t exMsgHeaderLen = 0u;
uint8_t exMsgDataLen = 0u;
if (ctx->negotiatedInfo.alpnSelectedSize == 0) {
return HITLS_SUCCESS;
}
exMsgHeaderLen = sizeof(uint16_t);
exMsgDataLen = (uint8_t)ctx->negotiatedInfo.alpnSelectedSize + sizeof(uint8_t);
ret = PackExtensionHeader(HS_EX_TYPE_APP_LAYER_PROTOCOLS, exMsgHeaderLen + exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint16ToBuf(pkt, (uint16_t)exMsgDataLen);
(void)PackAppendUint8ToBuf(pkt, exMsgDataLen - sizeof(uint8_t));
(void)PackAppendDataToBuf(pkt, ctx->negotiatedInfo.alpnSelected, ctx->negotiatedInfo.alpnSelectedSize);
ctx->hsCtx->extFlag.haveAlpn = true;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_PROTO_TLS13
static int32_t PackHrrKeyShare(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint16_t exMsgDataLen = 0u;
KeyShareParam *keyShare = &(ctx->hsCtx->kxCtx->keyExchParam.share);
exMsgDataLen = sizeof(uint16_t);
ret = PackExtensionHeader(HS_EX_TYPE_KEY_SHARE, exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint16ToBuf(pkt, (uint16_t)keyShare->groups[0]);
ctx->hsCtx->extFlag.haveKeyShare = true;
return HITLS_SUCCESS;
}
static int32_t PackServerKeyShare(const TLS_Ctx *ctx, PackPacket *pkt)
{
KeyShareParam *keyShare = &(ctx->hsCtx->kxCtx->keyExchParam.share);
KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx;
* sent */
if (kxCtx->peerPubkey == NULL) {
return HITLS_SUCCESS;
}
const TLS_GroupInfo *groupInfo = ConfigGetGroupInfo(&ctx->config.tlsConfig, ctx->negotiatedInfo.negotiatedGroup);
if (groupInfo == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16246, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"group info not found", 0, 0, 0, 0);
return HITLS_INVALID_INPUT;
}
uint32_t pubKeyLen = groupInfo->isKem ? groupInfo->ciphertextLen : groupInfo->pubkeyLen;
if (pubKeyLen == 0u || (groupInfo->isKem && pubKeyLen != kxCtx->ciphertextLen)) {
BSL_ERR_PUSH_ERROR(HITLS_PACK_INVALID_KX_PUBKEY_LENGTH);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15428, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"invalid keyShare length.", 0, 0, 0, 0);
return HITLS_PACK_INVALID_KX_PUBKEY_LENGTH;
}
uint16_t exMsgDataLen = sizeof(uint16_t) + sizeof(uint16_t) + (uint16_t)pubKeyLen;
int32_t ret = PackReserveBytes(pkt, exMsgDataLen + HS_EX_HEADER_LEN, NULL);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackExtensionHeader(HS_EX_TYPE_KEY_SHARE, exMsgDataLen, pkt);
(void)PackAppendUint16ToBuf(pkt, (uint16_t)keyShare->groups[0]);
(void)PackAppendUint16ToBuf(pkt, (uint16_t)pubKeyLen);
if (groupInfo->isKem) {
ret = PackAppendDataToBuf(pkt, kxCtx->ciphertext, kxCtx->ciphertextLen);
if (ret != HITLS_SUCCESS) {
return ret;
}
} else {
uint8_t *pubKeyBuf = NULL;
uint32_t pubKeyUsedLen = 0;
(void)PackReserveBytes(pkt, pubKeyLen, &pubKeyBuf);
ret = SAL_CRYPT_EncodeEcdhPubKey(kxCtx->key, pubKeyBuf, pubKeyLen, &pubKeyUsedLen);
if (ret != HITLS_SUCCESS || pubKeyLen != pubKeyUsedLen) {
BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15429, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"encode server keyShare key fail.", 0, 0, 0, 0);
return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY;
}
(void)PackSkipBytes(pkt, pubKeyUsedLen);
}
ctx->hsCtx->extFlag.haveKeyShare = true;
return HITLS_SUCCESS;
}
static int32_t PackServerSupportedVersion(const TLS_Ctx *ctx, PackPacket *pkt)
{
int32_t ret = HITLS_SUCCESS;
uint16_t exMsgDataLen = 0u;
const uint16_t supportedVersion = ctx->negotiatedInfo.version;
if (supportedVersion <= 0) {
BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15430, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"pack supported version extension error, invalid input parameter.", 0, 0, 0, 0);
return HITLS_INTERNAL_EXCEPTION;
}
exMsgDataLen = sizeof(uint16_t);
ret = PackExtensionHeader(HS_EX_TYPE_SUPPORTED_VERSIONS, exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint16ToBuf(pkt, supportedVersion);
ctx->hsCtx->extFlag.haveSupportedVers = true;
return HITLS_SUCCESS;
}
static int32_t IsHrrKeyShare(const TLS_Ctx *ctx)
{
bool haveHrr = ctx->hsCtx->haveHrr;
bool haveKeyShare = ctx->hsCtx->extFlag.haveKeyShare;
if (haveHrr && !haveKeyShare) {
return true;
}
return false;
}
static int32_t PackServerPreSharedKey(const TLS_Ctx *ctx, PackPacket *pkt)
{
const PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13;
if (pskInfo->psk == NULL) {
return HITLS_SUCCESS;
}
int32_t ret = PackExtensionHeader(HS_EX_TYPE_PRE_SHARED_KEY, sizeof(uint16_t), pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint16ToBuf(pkt, (uint16_t)pskInfo->selectIndex);
return HITLS_SUCCESS;
}
#endif
#if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
static int32_t PackServerSecRenegoInfo(const TLS_Ctx *ctx, PackPacket *pkt)
{
#ifdef HITLS_TLS_FEATURE_RENEGOTIATION
bool isRenegotiation = ctx->negotiatedInfo.isRenegotiation;
const uint8_t *clientData = ctx->negotiatedInfo.clientVerifyData;
uint32_t clientDataSize = ctx->negotiatedInfo.clientVerifyDataSize;
const uint8_t *serverData = ctx->negotiatedInfo.serverVerifyData;
uint32_t serverDataSize = ctx->negotiatedInfo.serverVerifyDataSize;
uint16_t exMsgHeaderLen = sizeof(uint8_t);
uint16_t exMsgDataLen = (uint16_t)(isRenegotiation ? (clientDataSize + serverDataSize) : 0);
int32_t ret = PackExtensionHeader(HS_EX_TYPE_RENEGOTIATION_INFO, exMsgHeaderLen + exMsgDataLen, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
if (!isRenegotiation) {
(void)PackAppendUint8ToBuf(pkt, 0);
return HITLS_SUCCESS;
}
(void)PackAppendUint8ToBuf(pkt, (uint8_t)(clientDataSize + serverDataSize));
(void)PackAppendDataToBuf(pkt, clientData, clientDataSize);
(void)PackAppendDataToBuf(pkt, serverData, serverDataSize);
#else
(void)ctx;
int32_t ret = PackExtensionHeader(HS_EX_TYPE_RENEGOTIATION_INFO, sizeof(uint8_t), pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
(void)PackAppendUint8ToBuf(pkt, 0);
#endif
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_SNI
static bool IsNeedServerPackServerName(const TLS_Ctx *ctx)
{
const TLS_Config *config = &(ctx->config.tlsConfig);
const TLS_NegotiatedInfo *negoInfo = &ctx->negotiatedInfo;
* by the server contains an empty server name extension */
if (negoInfo->isSniStateOK &&
(config->maxVersion < HITLS_VERSION_TLS13 || config->maxVersion == HITLS_VERSION_DTLS12)) {
return true;
}
return false;
}
#endif
#ifdef HITLS_TLS_FEATURE_ETM
static bool IsNeedServerPackEncryptThenMac(const TLS_Ctx *ctx)
{
const TLS_Config *config = &(ctx->config.tlsConfig);
const TLS_NegotiatedInfo *negoInfo = &ctx->negotiatedInfo;
if (config->isEncryptThenMac && negoInfo->isEncryptThenMac) {
return true;
}
return false;
}
#endif
static int32_t PackServerExtensions(const TLS_Ctx *ctx, PackPacket *pkt)
{
#ifdef HITLS_TLS_PROTO_TLS13
uint32_t version = GET_VERSION_FROM_CTX(ctx);
bool isHrrKeyshare = IsHrrKeyShare(ctx);
bool isTls13 = Tls13NeedPack(ctx, version);
#endif
const TLS_NegotiatedInfo *negoInfo = &ctx->negotiatedInfo;
(void)negoInfo;
PackExtInfo extMsgList[] = {
#ifdef HITLS_TLS_FEATURE_RECORD_SIZE_LIMIT
{ EXTENSION_MSG(HS_EX_TYPE_RECORD_SIZE_LIMIT,
(ctx->negotiatedInfo.version != HITLS_VERSION_TLS13), PackRecordSizeLimit) },
#endif
#ifdef HITLS_TLS_FEATURE_SNI
{ EXTENSION_MSG(HS_EX_TYPE_SERVER_NAME, IsNeedServerPackServerName(ctx), NULL) },
#endif
#ifdef HITLS_TLS_PROTO_TLS13
{ EXTENSION_MSG(HS_EX_TYPE_COOKIE, isTls13, PackCookie) },
#endif
#ifdef HITLS_TLS_FEATURE_SESSION_TICKET
{ EXTENSION_MSG(HS_EX_TYPE_SESSION_TICKET, negoInfo->isTicket, NULL) },
#endif
{ EXTENSION_MSG(HS_EX_TYPE_POINT_FORMATS, IsServerNeedPackEcExtension(ctx), PackPointFormats) },
#ifdef HITLS_TLS_PROTO_TLS13
{ EXTENSION_MSG(HS_EX_TYPE_SUPPORTED_VERSIONS, isTls13, PackServerSupportedVersion) },
#endif
#ifdef HITLS_TLS_FEATURE_EXTENDED_MASTER_SECRET
{ EXTENSION_MSG(HS_EX_TYPE_EXTENDED_MASTER_SECRET, negoInfo->isExtendedMasterSecret, NULL) },
#endif
#ifdef HITLS_TLS_FEATURE_ALPN
{ .exMsgType = HS_EX_TYPE_APP_LAYER_PROTOCOLS,
.needPack = (negoInfo->alpnSelected != NULL
#ifdef HITLS_TLS_PROTO_TLS13
&& !isTls13
#endif
),
.packFunc = PackServerSelectAlpnProto },
#endif
#ifdef HITLS_TLS_PROTO_TLS13
{ EXTENSION_MSG(HS_EX_TYPE_KEY_SHARE, (isTls13 && !isHrrKeyshare), PackServerKeyShare) },
{ EXTENSION_MSG(HS_EX_TYPE_KEY_SHARE, (isTls13 && isHrrKeyshare), PackHrrKeyShare) },
#endif
#if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
{ EXTENSION_MSG(HS_EX_TYPE_RENEGOTIATION_INFO, negoInfo->isSecureRenegotiation, PackServerSecRenegoInfo) },
#endif
#ifdef HITLS_TLS_FEATURE_ETM
{ EXTENSION_MSG(HS_EX_TYPE_ENCRYPT_THEN_MAC, IsNeedServerPackEncryptThenMac(ctx), NULL) },
#endif
#ifdef HITLS_TLS_PROTO_TLS13
{ EXTENSION_MSG(HS_EX_TYPE_PRE_SHARED_KEY, IsNeedPreSharedKey(ctx), PackServerPreSharedKey) },
#endif
};
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
uint32_t context = 0;
#ifdef HITLS_TLS_PROTO_TLS13
if (isTls13) {
if (isHrrKeyshare) {
context = HITLS_EX_TYPE_HELLO_RETRY_REQUEST;
} else {
context = HITLS_EX_TYPE_TLS1_3_SERVER_HELLO;
}
} else
#endif
{
context = HITLS_EX_TYPE_TLS1_2_SERVER_HELLO;
}
if (IsPackNeedCustomExtensions(CUSTOM_EXT_FROM_CTX(ctx), context)) {
int32_t ret = PackCustomExtensions(ctx, pkt, context, NULL, 0);
if (ret != HITLS_SUCCESS) {
return ret;
}
}
#endif
return PackExtensions(ctx, pkt, extMsgList, sizeof(extMsgList) / sizeof(extMsgList[0]));
}
int32_t PackServerExtension(const TLS_Ctx *ctx, PackPacket *pkt)
{
uint32_t extensionLenPosition = 0u;
int32_t ret = PackStartLengthField(pkt, sizeof(uint16_t), &extensionLenPosition);
if (ret != HITLS_SUCCESS) {
return ret;
}
ret = PackServerExtensions(ctx, pkt);
if (ret != HITLS_SUCCESS) {
return ret;
}
return PackExtensionEnd(pkt, extensionLenPosition);
}
#endif