* 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"
#if defined(HITLS_TLS_HOST_CLIENT) && defined(HITLS_TLS_PROTO_TLS13)
#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 "hitls_error.h"
#include "tls.h"
#include "rec.h"
#include "hs.h"
#include "hs_extensions.h"
#include "hs_common.h"
#include "parse_extensions.h"
#include "parse_common.h"
#include "custom_extensions.h"
* @brief Release the memory in the message structure.
*
* @param msg [IN] message structure
*/
void CleanEncryptedExtensions(EncryptedExtensions *msg)
{
if (msg == NULL) {
return;
}
BSL_SAL_FREE(msg->supportedGroups);
#ifdef HITLS_TLS_FEATURE_ALPN
BSL_SAL_FREE(msg->alpnSelected);
#endif
return;
}
static int32_t ParseEncryptedSupportGroups(ParsePacket *pkt, EncryptedExtensions *msg)
{
if (msg->haveSupportedGroups == true) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_DUPLICATE_EXTENDED_MSG, BINLOG_ID15709,
BINGLOG_STR("ClientSupportGroups repeated"), ALERT_ILLEGAL_PARAMETER);
}
uint16_t groupLen = 0;
const char *logStr = BINGLOG_STR("parse supported groups len fail.");
int32_t ret = ParseBytesToUint16(pkt, &groupLen);
if (ret != HITLS_SUCCESS) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15710, logStr, ALERT_DECODE_ERROR);
}
groupLen /= sizeof(uint16_t);
the handshake message error is returned */
if (((groupLen * sizeof(uint16_t)) != (pkt->bufLen - sizeof(uint16_t))) || (groupLen == 0)) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15711, logStr, ALERT_DECODE_ERROR);
}
BSL_SAL_FREE(msg->supportedGroups);
msg->supportedGroups = (uint16_t *)BSL_SAL_Malloc(groupLen * sizeof(uint16_t));
if (msg->supportedGroups == NULL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15712,
BINGLOG_STR("supportedGroups malloc fail"), ALERT_UNKNOWN);
}
for (uint32_t i = 0; i < groupLen; i++) {
msg->supportedGroups[i] = BSL_ByteToUint16(&pkt->buf[*pkt->bufOffset]);
*pkt->bufOffset += sizeof(uint16_t);
}
msg->supportedGroupsSize = groupLen;
msg->haveSupportedGroups = true;
return HITLS_SUCCESS;
}
static int32_t ParseEncryptedExBody(TLS_Ctx *ctx, uint16_t extMsgType, const uint8_t *buf, uint32_t extMsgLen,
EncryptedExtensions *msg)
{
uint32_t bufOffset = 0u;
ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = extMsgLen, .bufOffset = &bufOffset};
switch (extMsgType) {
case HS_EX_TYPE_SUPPORTED_GROUPS:
return ParseEncryptedSupportGroups(&pkt, msg);
case HS_EX_TYPE_EARLY_DATA:
return ParseEmptyExtension(ctx, HS_EX_TYPE_EARLY_DATA, extMsgLen, &msg->haveEarlyData);
case HS_EX_TYPE_SERVER_NAME:
return ParseEmptyExtension(ctx, HS_EX_TYPE_SERVER_NAME, extMsgLen, &msg->haveServerName);
case HS_EX_TYPE_SIGNATURE_ALGORITHMS:
case HS_EX_TYPE_KEY_SHARE:
case HS_EX_TYPE_PRE_SHARED_KEY:
case HS_EX_TYPE_STATUS_REQUEST:
case HS_EX_TYPE_STATUS_REQUEST_V2:
case HS_EX_TYPE_PSK_KEY_EXCHANGE_MODES:
case HS_EX_TYPE_COOKIE:
case HS_EX_TYPE_SUPPORTED_VERSIONS:
case HS_EX_TYPE_CERTIFICATE_AUTHORITIES:
case HS_EX_TYPE_POST_HS_AUTH:
case HS_EX_TYPE_SIGNATURE_ALGORITHMS_CERT:
return ParseErrorProcess(ctx, HITLS_PARSE_UNSUPPORTED_EXTENSION, BINLOG_ID16239,
BINGLOG_STR("Illegal extension received"), ALERT_ILLEGAL_PARAMETER);
#ifdef HITLS_TLS_FEATURE_RECORD_SIZE_LIMIT
case HS_EX_TYPE_RECORD_SIZE_LIMIT:
return ParseRecordSizeLimit(ctx, buf, extMsgLen, &msg->haveRecordSizeLimit, &msg->recordSizeLimit);
#endif
#ifdef HITLS_TLS_FEATURE_ALPN
case HS_EX_TYPE_APP_LAYER_PROTOCOLS:
return ParseServerSelectedAlpnProtocol(
&pkt, &msg->haveSelectedAlpn, &msg->alpnSelected, &msg->alpnSelectedSize);
#endif
default:
break;
}
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
if (IsParseNeedCustomExtensions(CUSTOM_EXT_FROM_CTX(ctx), extMsgType, HITLS_EX_TYPE_ENCRYPTED_EXTENSIONS)) {
return ParseCustomExtensions(pkt.ctx, pkt.buf + *pkt.bufOffset, extMsgType, extMsgLen,
HITLS_EX_TYPE_ENCRYPTED_EXTENSIONS, NULL, 0);
}
#endif
return ParseErrorProcess(ctx, HITLS_PARSE_UNSUPPORTED_EXTENSION, BINLOG_ID16982,
"unknow extension received", ALERT_UNSUPPORTED_EXTENSION);
}
int32_t ParseEncryptedEx(TLS_Ctx *ctx, EncryptedExtensions *msg, const uint8_t *buf, uint32_t bufLen)
{
uint32_t bufOffset = 0u;
#ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
uint32_t customExtSeenMask = 0;
#endif
ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = bufLen, .bufOffset = &bufOffset};
while (bufOffset < bufLen) {
uint32_t extMsgLen = 0u;
uint16_t extMsgType = HS_EX_TYPE_END;
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_ENCRYPTED_EXTENSIONS,
&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_ENCRYPTED_EXTENSIONS)
#endif
) {
msg->extensionTypeMask |= 1ULL << extensionId;
if (!GetExtensionFlagValue(ctx, extensionId)) {
BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17329, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"client did not send but get extension type %u.", extensionId, 0, 0, 0);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION);
return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE;
}
}
ret = ParseEncryptedExBody(ctx, extMsgType, &buf[bufOffset], extMsgLen, msg);
if (ret != HITLS_SUCCESS) {
return ret;
}
bufOffset += extMsgLen;
}
if (bufOffset != bufLen) {
return ParseErrorProcess(ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16239,
BINGLOG_STR("encrypted extensions len incorrect"), ALERT_DECODE_ERROR);
}
return HITLS_SUCCESS;
}
int32_t ParseEncryptedExtensions(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg)
{
if ((buf == NULL) || (hsMsg == NULL)) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16983, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "input null", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
return HITLS_NULL_INPUT;
}
EncryptedExtensions *msg = &hsMsg->body.encryptedExtensions;
uint32_t bufOffset = 0u;
ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = bufLen, .bufOffset = &bufOffset};
uint16_t exMsgLen = 0;
const char *logStr = BINGLOG_STR("parse encrypted Extensions len fail.");
int32_t ret = ParseBytesToUint16(&pkt, &exMsgLen);
if (ret != HITLS_SUCCESS) {
return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16128, logStr, ALERT_DECODE_ERROR);
}
if (pkt.bufLen - *pkt.bufOffset != exMsgLen) {
return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15715, logStr, ALERT_DECODE_ERROR);
}
return ParseEncryptedEx(pkt.ctx, msg, &pkt.buf[*pkt.bufOffset], exMsgLen);
}
#endif