* 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_PROTO_TLS13
#ifdef HITLS_TLS_HOST_CLIENT
#include <stdint.h>
#include "tls_binlog_id.h"
#include "bsl_log_internal.h"
#include "bsl_log.h"
#include "bsl_err_internal.h"
#include "hitls_error.h"
#include "tls.h"
#include "record.h"
#include "hs_ctx.h"
#include "hs_common.h"
#include "hs_extensions.h"
#include "hs_msg.h"
#include "hs_verify.h"
#include "alpn.h"
typedef int32_t (*CheckEncryptedExtFunc)(TLS_Ctx *ctx, const EncryptedExtensions *eEMsg);
#ifdef HITLS_TLS_FEATURE_SNI
static int32_t Tls13ClientCheckServerName(TLS_Ctx *ctx, const EncryptedExtensions *eEMsg)
{
if ((ctx->hsCtx->extFlag.haveServerName == false) && (eEMsg->haveServerName == true)) {
BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16200, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"client did not send server_name but get extended server_name .", 0, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION);
return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE;
}
if ((ctx->hsCtx->extFlag.haveServerName == true) && (eEMsg->haveServerName == true)) {
if (ctx->session == NULL && ctx->config.tlsConfig.serverName != NULL &&
ctx->config.tlsConfig.serverNameSize > 0) {
ctx->negotiatedInfo.isSniStateOK = true;
ctx->negotiatedInfo.serverNameSize = ctx->config.tlsConfig.serverNameSize;
BSL_SAL_FREE(ctx->negotiatedInfo.serverName);
ctx->negotiatedInfo.serverName =
(uint8_t *)BSL_SAL_Dump(ctx->config.tlsConfig.serverName,
ctx->negotiatedInfo.serverNameSize * sizeof(uint8_t));
if (ctx->negotiatedInfo.serverName == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17075, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Dump fail", 0, 0, 0, 0);
return HITLS_MEMCPY_FAIL;
}
}
}
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_RECORD_SIZE_LIMIT
static int32_t Tls13ClientCheckRecordSizeLimit(TLS_Ctx *ctx, const EncryptedExtensions *eEMsg)
{
if (!ctx->hsCtx->extFlag.haveRecordSizeLimit && eEMsg->haveRecordSizeLimit) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16252, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"client did not send but get record size limit.", 0, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION);
BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE);
return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE;
}
if (ctx->hsCtx->extFlag.haveRecordSizeLimit && !eEMsg->haveRecordSizeLimit) {
return HITLS_SUCCESS;
}
if (eEMsg->haveRecordSizeLimit) {
uint16_t upperBound =
(ctx->negotiatedInfo.version == HITLS_VERSION_TLS13 ? REC_MAX_PLAIN_LENGTH + 1 : REC_MAX_PLAIN_LENGTH);
if (eEMsg->recordSizeLimit < 64u ||
(eEMsg->recordSizeLimit > upperBound)) {
BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_INVALID_RECORD_SIZE_LIMIT);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16250, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"The value of record size limit is invalid.", 0, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER);
return HITLS_MSG_HANDLE_INVALID_RECORD_SIZE_LIMIT;
}
ctx->negotiatedInfo.recordSizeLimit = (ctx->config.tlsConfig.recordSizeLimit <= upperBound) ?
ctx->config.tlsConfig.recordSizeLimit : upperBound;
ctx->negotiatedInfo.peerRecordSizeLimit = eEMsg->recordSizeLimit;
}
return REC_RecOutBufReSet(ctx);
}
#endif
#ifdef HITLS_TLS_FEATURE_ALPN
static int32_t Tls13ClientCheckNegotiatedAlpn(TLS_Ctx *ctx, const EncryptedExtensions *eEMsg)
{
return ClientCheckNegotiatedAlpn(
ctx, eEMsg->haveSelectedAlpn, eEMsg->alpnSelected, eEMsg->alpnSelectedSize);
}
#endif
static int32_t ClientCheckEncryptedExtensionsFlag(TLS_Ctx *ctx, const EncryptedExtensions *eEMsg)
{
static const CheckEncryptedExtFunc EXT_INFO_LIST[] = {
#ifdef HITLS_TLS_FEATURE_SNI
Tls13ClientCheckServerName,
#endif
#ifdef HITLS_TLS_FEATURE_RECORD_SIZE_LIMIT
Tls13ClientCheckRecordSizeLimit,
#endif
#ifdef HITLS_TLS_FEATURE_ALPN
Tls13ClientCheckNegotiatedAlpn,
#endif
NULL,
};
int32_t ret = HS_CheckReceivedExtension(ctx, ENCRYPTED_EXTENSIONS, eEMsg->extensionTypeMask,
HS_EX_TYPE_TLS1_3_ALLOWED_OF_ENCRYPTED_EXTENSIONS);
if (ret != HITLS_SUCCESS) {
return ret;
}
for (uint32_t i = 0; i < sizeof(EXT_INFO_LIST) / sizeof(EXT_INFO_LIST[0]); i++) {
if (EXT_INFO_LIST[i] == NULL) {
continue;
}
ret = EXT_INFO_LIST[i](ctx, eEMsg);
if (ret != HITLS_SUCCESS) {
return ret;
}
}
return HITLS_SUCCESS;
}
int32_t Tls13ClientRecvEncryptedExtensionsProcess(TLS_Ctx *ctx, const HS_Msg *msg)
{
int32_t ret;
const EncryptedExtensions *eEMsg = &msg->body.encryptedExtensions;
ret = ClientCheckEncryptedExtensionsFlag(ctx, eEMsg);
if (ret != HITLS_SUCCESS) {
return ret;
}
* for verifying the 'finished' message from the server. */
PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13;
if ((pskInfo->psk != NULL)) {
ret = VERIFY_Tls13CalcVerifyData(ctx, false);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15856, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"client calculate server finished data error.", 0, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
return ret;
}
return HS_ChangeState(ctx, TRY_RECV_FINISH);
}
return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE_REQUEST);
}
#endif
#endif