* 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 <string.h>
#include "hitls_build.h"
#ifdef HITLS_TLS_HOST_CLIENT
#if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
#include "tls_binlog_id.h"
#include "bsl_log_internal.h"
#include "bsl_log.h"
#include "bsl_sal.h"
#include "bsl_err_internal.h"
#include "hitls_error.h"
#include "hitls_crypt_type.h"
#include "hitls_cert_type.h"
#include "hitls_config.h"
#include "tls_config.h"
#include "cert_method.h"
#include "cert.h"
#include "cipher_suite.h"
#include "hs_ctx.h"
#include "hs_msg.h"
#include "hs_common.h"
#include "parse_msg.h"
#include "parse_common.h"
int32_t ParseSignAlgorithm(ParsePacket *pkt, uint16_t *signAlg)
{
uint16_t signScheme = 0;
TLS_Ctx *ctx = pkt->ctx;
int32_t ret = ParseBytesToUint16(pkt, &signScheme);
if (ret != HITLS_SUCCESS) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15306,
BINGLOG_STR("parse signAlgorithm failed in serverKeyEx."), ALERT_DECODE_ERROR);
}
ret = CheckPeerSignScheme(ctx, ctx->hsCtx->peerCert, signScheme);
if (ret != HITLS_SUCCESS) {
return ParseErrorProcess(pkt->ctx, ret, 0, NULL, ALERT_ILLEGAL_PARAMETER);
}
uint32_t i = 0;
* the signature algorithm in the extension. */
for (i = 0; i < ctx->config.tlsConfig.signAlgorithmsSize; i++) {
if (ctx->config.tlsConfig.signAlgorithms[i] == signScheme) {
break;
}
}
if (i == ctx->config.tlsConfig.signAlgorithmsSize) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15307, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"check serverKeyEx signature algo fail: 0x%x is not included in client hello.",
signScheme, 0, 0, 0);
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_UNSUPPORT_SIGN_ALG, 0, NULL, ALERT_HANDSHAKE_FAILURE);
}
#ifdef HITLS_TLS_FEATURE_SECURITY
if (SECURITY_SslCheck(ctx, HITLS_SECURITY_SECOP_SIGALG_CHECK, 0, signScheme, NULL) != SECURITY_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17132, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"signScheme 0x%x SslCheck fail", signScheme, 0, 0, 0);
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_UNSUPPORT_SIGN_ALG, 0, NULL, ALERT_HANDSHAKE_FAILURE);
}
#endif
*signAlg = signScheme;
return HITLS_SUCCESS;
}
int32_t ParseSignature(ParsePacket *pkt, uint16_t *signSize, uint8_t **signData)
{
int32_t ret = ParseTwoByteLengthField(pkt, signSize, signData);
if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15308,
BINGLOG_STR("parse serverkeyEx signature failed."), ALERT_DECODE_ERROR);
} else if (ret == HITLS_MEMALLOC_FAIL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15311,
BINGLOG_STR("signData malloc fail."), ALERT_UNKNOWN);
}
if (pkt->bufLen != *pkt->bufOffset) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15308,
BINGLOG_STR("parse serverkeyEx signature failed."), ALERT_DECODE_ERROR);
}
if (*signSize == 0) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15310,
BINGLOG_STR("length of server signSize is 0."), ALERT_ILLEGAL_PARAMETER);
}
return HITLS_SUCCESS;
}
static void GetServerKeyExSignParam(const ServerKeyExchangeMsg *msg,
CERT_SignParam *signParam, HITLS_SignHashAlgo *signScheme)
{
if (msg->keyExType == HITLS_KEY_EXCH_ECDHE) {
*signScheme = msg->keyEx.ecdh.signAlgorithm;
signParam->sign = msg->keyEx.ecdh.signData;
signParam->signLen = msg->keyEx.ecdh.signSize;
} else if (msg->keyExType == HITLS_KEY_EXCH_DHE) {
*signScheme = msg->keyEx.dh.signAlgorithm;
signParam->sign = msg->keyEx.dh.signData;
signParam->signLen = msg->keyEx.dh.signSize;
}
return;
}
int32_t VerifySignature(TLS_Ctx *ctx, const uint8_t *kxData, uint32_t kxDataLen, ServerKeyExchangeMsg *msg)
{
CERT_SignParam signParam = {0};
HITLS_SignHashAlgo signScheme = 0;
GetServerKeyExSignParam(msg, &signParam, &signScheme);
if (!CFG_GetSignParamBySchemes(ctx, signScheme, &signParam.signAlgo, &signParam.hashAlgo)) {
return ParseErrorProcess(ctx, HITLS_PARSE_GET_SIGN_PARA_ERR, BINLOG_ID15312,
BINGLOG_STR("get sign param fail."), ALERT_ILLEGAL_PARAMETER);
}
uint8_t *data = HS_PrepareSignData(ctx, kxData, kxDataLen, &signParam.dataLen);
if (data == NULL) {
return ParseErrorProcess(ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15313,
BINGLOG_STR("data malloc fail."), ALERT_INTERNAL_ERROR);
}
if (ctx->hsCtx->peerCert == NULL) {
BSL_SAL_ClearFree(data, signParam.dataLen);
return ParseErrorProcess(ctx, HITLS_PARSE_VERIFY_SIGN_FAIL, BINLOG_ID17013,
BINGLOG_STR("peerCert null"), ALERT_CERTIFICATE_REQUIRED);
}
HITLS_CERT_X509 *cert = SAL_CERT_PAIR_GET_X509(ctx->hsCtx->peerCert);
HITLS_CERT_Key *pubkey = NULL;
int32_t ret = SAL_CERT_X509Ctrl(&(ctx->config.tlsConfig), cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17014, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"GET_PUB_KEY fail", 0, 0, 0, 0);
BSL_SAL_ClearFree(data, signParam.dataLen);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
return ret;
}
signParam.data = data;
ret = SAL_CERT_VerifySign(ctx, pubkey, &signParam);
SAL_CERT_KeyFree(ctx->config.tlsConfig.certMgrCtx, pubkey);
BSL_SAL_ClearFree(data, signParam.dataLen);
if (ret != HITLS_SUCCESS) {
return ParseErrorProcess(ctx, HITLS_PARSE_VERIFY_SIGN_FAIL, BINLOG_ID15314,
BINGLOG_STR("verify signature fail."), ALERT_DECRYPT_ERROR);
}
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_SUITE_KX_ECDHE
static int32_t ParseEcdhePublicKey(ParsePacket *pkt, ServerEcdh *ecdh)
{
const char *logStr = BINGLOG_STR("parse ecdhe public key fail.");
uint8_t pubKeySize = 0;
int32_t ret = ParseBytesToUint8(pkt, &pubKeySize);
if (ret != HITLS_SUCCESS) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15298,
logStr, ALERT_DECODE_ERROR);
}
#ifdef HITLS_TLS_PROTO_TLCP11
if (pkt->ctx->negotiatedInfo.version == HITLS_VERSION_TLCP_DTLCP11) {
ecdh->ecPara.param.namedcurve = HITLS_EC_GROUP_SM2;
}
#endif
if ((ecdh->ecPara.type == HITLS_EC_CURVE_TYPE_NAMED_CURVE) &&
(pubKeySize != HS_GetCryptLength(pkt->ctx, HITLS_CRYPT_INFO_CMD_GET_PUBLIC_KEY_LEN,
ecdh->ecPara.param.namedcurve))) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15300, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"ecdhe server pubkey length error, curve id = %u, pubkey len = %u.",
ecdh->ecPara.param.namedcurve, pubKeySize, 0, 0);
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_ECDH_PUBKEY_ERR, 0, NULL, ALERT_ILLEGAL_PARAMETER);
}
uint8_t *pubKey = NULL;
ret = ParseBytesToArray(pkt, &pubKey, pubKeySize);
if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15299,
logStr, ALERT_DECODE_ERROR);
} else if (ret == HITLS_MEMALLOC_FAIL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15301,
BINGLOG_STR("pubKey malloc fail."), ALERT_UNKNOWN);
}
ecdh->pubKey = pubKey;
ecdh->pubKeySize = pubKeySize;
return HITLS_SUCCESS;
}
int32_t ParseEcParameters(ParsePacket *pkt, ServerEcdh *ecdh)
{
const char *logStr = BINGLOG_STR("parse ecdhe curve type fail.");
uint8_t curveType = 0;
int32_t ret = ParseBytesToUint8(pkt, &curveType);
if (ret != HITLS_SUCCESS) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15292,
logStr, ALERT_DECODE_ERROR);
}
if (curveType == HITLS_EC_CURVE_TYPE_NAMED_CURVE) {
uint16_t namedCurve = 0;
ret = ParseBytesToUint16(pkt, &namedCurve);
if (ret != HITLS_SUCCESS) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15291,
logStr, ALERT_DECODE_ERROR);
}
ecdh->ecPara.param.namedcurve = namedCurve;
} else {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_UNSUPPORT_KX_CURVE_TYPE, BINLOG_ID15293,
BINGLOG_STR("unsupport curve type in server key exchange."), ALERT_ILLEGAL_PARAMETER);
}
ecdh->ecPara.type = curveType;
return HITLS_SUCCESS;
}
static int32_t ParseEcdhePreSign(ParsePacket *pkt, ServerKeyExchangeMsg *msg)
{
int32_t ret = ParseEcParameters(pkt, &msg->keyEx.ecdh);
if (ret != HITLS_SUCCESS) {
return ret;
}
ret = ParseEcdhePublicKey(pkt, &msg->keyEx.ecdh);
if (ret != HITLS_SUCCESS) {
return ret;
}
return HITLS_SUCCESS;
}
* @brief Parse the server ecdh message.
*
* @param pkt [IN] Context for parsing
* @param msg [OUT] Parsed message structure
*
* @retval HITLS_SUCCESS Parsing succeeded.
* @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect.
* @retval HITLS_PARSE_UNSUPPORT_KX_CURVE_TYPE Unsupported ECC curve type
* @retval HITLS_PARSE_ECDH_PUBKEY_ERR Failed to parse the ECDH public key.
* @retval HITLS_PARSE_ECDH_SIGN_ERR Failed to parse the EDH signature.
* @retval HITLS_PARSE_GET_SIGN_PARA_ERR Failed to obtain the signature algorithm and hash algorithm.
* @retval HITLS_PARSE_VERIFY_SIGN_FAIL Failed to verify the signature.
*/
static int32_t ParseServerEcdhe(ParsePacket *pkt, ServerKeyExchangeMsg *msg)
{
TLS_Ctx *ctx = pkt->ctx;
int32_t ret = ParseEcdhePreSign(pkt, msg);
if (ret != HITLS_SUCCESS) {
return ret;
}
if (ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_ECDHE_PSK ||
ctx->negotiatedInfo.cipherSuiteInfo.authAlg == HITLS_AUTH_NULL) {
if (pkt->bufLen != *pkt->bufOffset) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15317,
BINGLOG_STR("parse serverkeyEx signature failed."), ALERT_DECODE_ERROR);
}
return HITLS_SUCCESS;
}
uint32_t keyExDataLen = *pkt->bufOffset;
uint16_t signAlgorithm = ctx->negotiatedInfo.cipherSuiteInfo.signScheme;
if (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP_DTLCP11) {
ret = ParseSignAlgorithm(pkt, &signAlgorithm);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17015, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"ParseSignAlgorithm fail", 0, 0, 0, 0);
return ret;
}
}
msg->keyEx.ecdh.signAlgorithm = signAlgorithm;
ret = ParseSignature(pkt, &msg->keyEx.ecdh.signSize, &msg->keyEx.ecdh.signData);
if (ret != HITLS_SUCCESS) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_ECDH_SIGN_ERR, BINLOG_ID15318,
BINGLOG_STR("parse ecdhe signature fail."), ALERT_UNKNOWN);
}
ret = VerifySignature(pkt->ctx, pkt->buf, keyExDataLen, msg);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17016, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"VerifySignature fail", 0, 0, 0, 0);
return ret;
}
ctx->peerInfo.peerSignHashAlg = signAlgorithm;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_SUITE_KX_DHE
* @brief Parse the p or g parameter in the DHE kx message.
*
* @param pkt [IN] Context for parsing
* @param paraLen [OUT] Parsed parameter length
* @param para [OUT] Parsed parameter
*
* @return The allocated parameter memory. If the parameter memory is NULL, the parsing fails.
*/
int32_t ParseDhePara(ParsePacket *pkt, uint16_t *paraLen, uint8_t **para)
{
int32_t ret = ParseTwoByteLengthField(pkt, paraLen, para);
if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15294,
BINGLOG_STR("dhe para length error."), ALERT_DECODE_ERROR);
} else if (ret == HITLS_MEMALLOC_FAIL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15297,
BINGLOG_STR("dhePara malloc fail."), ALERT_UNKNOWN);
}
if (*paraLen == 0) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15296,
BINGLOG_STR("length of dhe para is 0."), ALERT_ILLEGAL_PARAMETER);
}
return HITLS_SUCCESS;
}
static int32_t ParseServerDhe(ParsePacket *pkt, ServerKeyExchangeMsg *msg)
{
ServerDh *dh = &msg->keyEx.dh;
#ifdef HITLS_BSL_LOG
const char *logStr = BINGLOG_STR("parse dhe param or PubKey fail. ret %d");
#endif
TLS_Ctx *ctx = pkt->ctx;
int32_t ret = ParseDhePara(pkt, &dh->plen, &dh->p);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15320, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, logStr, ret, 0, 0, 0);
return HITLS_PARSE_DH_P_ERR;
}
ret = ParseDhePara(pkt, &dh->glen, &dh->g);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15321, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, logStr, ret, 0, 0, 0);
return HITLS_PARSE_DH_G_ERR;
}
ret = ParseDhePara(pkt, &dh->pubKeyLen, &dh->pubkey);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15322, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, logStr, ret, 0, 0, 0);
return HITLS_PARSE_DH_PUBKEY_ERR;
}
if (ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_DHE_PSK ||
ctx->negotiatedInfo.cipherSuiteInfo.authAlg == HITLS_AUTH_NULL) {
return pkt->bufLen != *pkt->bufOffset ? ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15323,
BINGLOG_STR("parse serverkeyEx signature failed."), ALERT_DECODE_ERROR) : HITLS_SUCCESS;
}
uint32_t kxDataLen = *pkt->bufOffset;
dh->signAlgorithm = ctx->negotiatedInfo.cipherSuiteInfo.signScheme;
ret = ParseSignAlgorithm(pkt, &dh->signAlgorithm);
if (ret != HITLS_SUCCESS) {
return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17017, "ParseSignAlgorithm fail");
}
ret = ParseSignature(pkt, &dh->signSize, &dh->signData);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17018, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"ParseSignature fail, ret %d", ret, 0, 0, 0);
return HITLS_PARSE_DH_SIGN_ERR;
}
ret = VerifySignature(pkt->ctx, pkt->buf, kxDataLen, msg);
if (ret != HITLS_SUCCESS) {
return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17019, "VerifySignature fail");
}
ctx->peerInfo.peerSignHashAlg = dh->signAlgorithm;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_FEATURE_PSK
* but the length may be empty */
static int32_t ParseServerIdentityHint(ParsePacket *pkt, ServerKeyExchangeMsg *msg)
{
uint16_t identityHintLen = 0;
uint8_t *identityHint = NULL;
uint8_t *tempIdentityHint = NULL;
int32_t ret = ParseTwoByteLengthField(pkt, &identityHintLen, &identityHint);
if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17020, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Parse fail, ret %d", ret, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH);
return HITLS_CONFIG_INVALID_LENGTH;
} else if (ret == HITLS_MEMALLOC_FAIL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17021, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Parse fail, ret %d", ret, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
return HITLS_MEMALLOC_FAIL;
}
if (identityHintLen != 0) {
tempIdentityHint = (uint8_t *)BSL_SAL_Calloc(identityHintLen + 1, sizeof(uint8_t));
if (tempIdentityHint == NULL) {
BSL_SAL_FREE(identityHint);
BSL_LOG_BINLOG_FIXLEN(
BINLOG_ID15085, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Malloc fail", 0, 0, 0, 0);
return HITLS_MEMALLOC_FAIL;
}
memcpy(tempIdentityHint, identityHint, identityHintLen);
BSL_SAL_FREE(identityHint);
BSL_LOG_BINLOG_VARLEN(BINLOG_ID15324, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
"receive server identity hint: %s.", tempIdentityHint);
}
msg->pskIdentityHint = tempIdentityHint;
msg->hintSize = identityHintLen;
return HITLS_SUCCESS;
}
#endif
#ifdef HITLS_TLS_PROTO_TLCP11
static int32_t VerifyServerKxMsgEcc(ParsePacket *pkt, CERT_SignParam *signParam)
{
uint8_t *sign = NULL;
uint16_t signSize = 0;
TLS_Ctx *ctx = pkt->ctx;
* in the ServerKeyExchangeMsg.keyEx.ecdh file */
int32_t ret = ParseSignature(pkt, &signSize, &sign);
if (ret != HITLS_SUCCESS) {
BSL_SAL_FREE(sign);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16223, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"parse ecc signature fail.", 0, 0, 0, 0);
return HITLS_PARSE_ECDH_SIGN_ERR;
}
HITLS_CERT_X509 *signCert = SAL_CERT_PAIR_GET_X509_EX(ctx->hsCtx->peerCert);
HITLS_CERT_Key *pubkey = NULL;
ret = SAL_CERT_X509Ctrl(&(ctx->config.tlsConfig), signCert,
CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey);
if (ret != HITLS_SUCCESS) {
BSL_SAL_FREE(sign);
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
return ret;
}
signParam->sign = sign;
signParam->signLen = signSize;
ret = SAL_CERT_VerifySign(ctx, pubkey, signParam);
SAL_CERT_KeyFree(ctx->config.tlsConfig.certMgrCtx, pubkey);
BSL_SAL_FREE(sign);
return ret;
}
static int32_t ParseServerKxMsgEcc(ParsePacket *pkt)
{
HITLS_SignAlgo signAlgo;
HITLS_HashAlgo hashAlgo;
TLS_Ctx *ctx = pkt->ctx;
* not required. */
if (!CFG_GetSignParamBySchemes(ctx, ctx->negotiatedInfo.cipherSuiteInfo.signScheme, &signAlgo, &hashAlgo)) {
return HITLS_PACK_SIGNATURE_ERR;
}
uint32_t certLen = 0;
uint8_t *cert = SAL_CERT_ClntGmEncodeEncCert(ctx, ctx->hsCtx->peerCert, &certLen);
if (cert == NULL) {
return ParseErrorProcess(pkt->ctx, HITLS_CERT_ERR_ENCODE, BINLOG_ID16206,
BINGLOG_STR("encode encrypt cert failed."), ALERT_INTERNAL_ERROR);
}
uint32_t signDataLen = 0;
uint8_t *signData = HS_PrepareSignDataTlcp(ctx, cert, certLen, &signDataLen);
BSL_SAL_FREE(cert);
if (signData == NULL) {
return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID16207,
BINGLOG_STR("data malloc fail."), ALERT_INTERNAL_ERROR);
}
CERT_SignParam signParam = {signAlgo, hashAlgo, signData, signDataLen, NULL, 0};
int32_t ret = VerifyServerKxMsgEcc(pkt, &signParam);
BSL_SAL_FREE(signData);
if (ret != HITLS_SUCCESS) {
return ParseErrorProcess(pkt->ctx, HITLS_PARSE_VERIFY_SIGN_FAIL, BINLOG_ID16208,
BINGLOG_STR("verify signature fail."), ALERT_DECRYPT_ERROR);
}
return HITLS_SUCCESS;
}
#endif
int32_t ParseServerKeyExchange(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_Msg *hsMsg)
{
int32_t ret = HITLS_SUCCESS;
uint32_t offset = 0u;
HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx;
ServerKeyExchangeMsg *msg = &hsMsg->body.serverKeyExchange;
msg->keyExType = hsCtx->kxCtx->keyExchAlgo;
ParsePacket pkt = {.ctx = ctx, .buf = data, .bufLen = len, .bufOffset = &offset};
(void)pkt;
#ifdef HITLS_TLS_FEATURE_PSK
if (IsPskNegotiation(ctx)) {
if ((ret = ParseServerIdentityHint(&pkt, msg)) != HITLS_SUCCESS) {
return ret;
}
}
#endif
switch (hsCtx->kxCtx->keyExchAlgo) {
#ifdef HITLS_TLS_SUITE_KX_ECDHE
case HITLS_KEY_EXCH_ECDHE:
case HITLS_KEY_EXCH_ECDHE_PSK:
ret = ParseServerEcdhe(&pkt, msg);
break;
#endif
#ifdef HITLS_TLS_SUITE_KX_DHE
case HITLS_KEY_EXCH_DHE:
case HITLS_KEY_EXCH_DHE_PSK:
ret = ParseServerDhe(&pkt, msg);
break;
#endif
case HITLS_KEY_EXCH_PSK:
#ifdef HITLS_TLS_SUITE_KX_RSA
case HITLS_KEY_EXCH_RSA_PSK:
#endif
break;
#ifdef HITLS_TLS_PROTO_TLCP11
case HITLS_KEY_EXCH_ECC:
ret = ParseServerKxMsgEcc(&pkt);
break;
#endif
default:
ret = HITLS_PARSE_UNSUPPORT_KX_ALG;
ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
break;
}
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15325, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"parse serverKeyExMsg fail. keyExchAlgo is %d", hsCtx->kxCtx->keyExchAlgo, 0, 0, 0);
}
return ret;
}
void CleanServerKeyExchange(ServerKeyExchangeMsg *msg)
{
if (msg == NULL) {
return;
}
#ifdef HITLS_TLS_SUITE_KX_ECDHE
if (msg->keyExType == HITLS_KEY_EXCH_ECDHE || msg->keyExType == HITLS_KEY_EXCH_ECDHE_PSK) {
BSL_SAL_FREE(msg->keyEx.ecdh.pubKey);
BSL_SAL_FREE(msg->keyEx.ecdh.signData);
}
#endif
#ifdef HITLS_TLS_SUITE_KX_DHE
if (msg->keyExType == HITLS_KEY_EXCH_DHE || msg->keyExType == HITLS_KEY_EXCH_DHE_PSK) {
BSL_SAL_FREE(msg->keyEx.dh.p);
BSL_SAL_FREE(msg->keyEx.dh.g);
BSL_SAL_FREE(msg->keyEx.dh.pubkey);
BSL_SAL_FREE(msg->keyEx.dh.signData);
}
#endif
BSL_SAL_FREE(msg->pskIdentityHint);
}
#endif
#endif