• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 #include "hitls_build.h"
16 #ifdef HITLS_TLS_HOST_CLIENT
17 #if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
18 #include "securec.h"
19 #include "tls_binlog_id.h"
20 #include "bsl_log_internal.h"
21 #include "bsl_log.h"
22 #include "bsl_sal.h"
23 #include "bsl_err_internal.h"
24 #include "bsl_bytes.h"
25 #include "hitls_error.h"
26 #include "hitls_crypt_type.h"
27 #include "hitls_cert_type.h"
28 #include "hitls_config.h"
29 #include "tls_config.h"
30 #include "cert_method.h"
31 #include "cert.h"
32 #include "cipher_suite.h"
33 #include "hs_ctx.h"
34 #include "hs_msg.h"
35 #include "hs_common.h"
36 #include "parse_msg.h"
37 #include "parse_common.h"
38 
39 // Parse signature algorithm in the context message.
ParseSignAlgorithm(ParsePacket * pkt,uint16_t * signAlg)40 int32_t ParseSignAlgorithm(ParsePacket *pkt, uint16_t *signAlg)
41 {
42     uint16_t signScheme = 0;
43     TLS_Ctx *ctx = pkt->ctx;
44     int32_t ret = ParseBytesToUint16(pkt, &signScheme);
45     if (ret != HITLS_SUCCESS) {
46         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15306,
47             BINGLOG_STR("parse signAlgorithm failed in serverKeyEx."), ALERT_DECODE_ERROR);
48     }
49 
50     ret = CheckPeerSignScheme(ctx, ctx->hsCtx->peerCert, signScheme);
51     if (ret != HITLS_SUCCESS) {
52         return ParseErrorProcess(pkt->ctx, ret, 0, NULL, ALERT_ILLEGAL_PARAMETER);
53     }
54 
55     uint32_t i = 0;
56     /* If the client_hello message contains the signature_algorithms extension, the server_key_exchange message must use
57      * the signature algorithm in the extension. */
58     for (i = 0; i < ctx->config.tlsConfig.signAlgorithmsSize; i++) {
59         if (ctx->config.tlsConfig.signAlgorithms[i] == signScheme) {
60             break;
61         }
62     }
63     if (i == ctx->config.tlsConfig.signAlgorithmsSize) {
64         /* Handshake failed because it is not an extended signature algorithm. */
65         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15307, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
66             "check serverKeyEx signature algo fail: 0x%x is not included in client hello.",
67             signScheme, 0, 0, 0);
68         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_UNSUPPORT_SIGN_ALG, 0, NULL, ALERT_HANDSHAKE_FAILURE);
69     }
70 
71 #ifdef HITLS_TLS_FEATURE_SECURITY
72     if (SECURITY_SslCheck(ctx, HITLS_SECURITY_SECOP_SIGALG_CHECK, 0, signScheme, NULL) != SECURITY_SUCCESS) {
73         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17132, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
74             "signScheme 0x%x SslCheck fail", signScheme, 0, 0, 0);
75         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_UNSUPPORT_SIGN_ALG, 0, NULL, ALERT_HANDSHAKE_FAILURE);
76     }
77 #endif
78 
79     *signAlg = signScheme;
80 
81     return HITLS_SUCCESS;
82 }
83 
84 // Parse the signature in the ECDHE kx message.
ParseSignature(ParsePacket * pkt,uint16_t * signSize,uint8_t ** signData)85 int32_t ParseSignature(ParsePacket *pkt, uint16_t *signSize, uint8_t **signData)
86 {
87     int32_t ret = ParseTwoByteLengthField(pkt, signSize, signData);
88     if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
89         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15308,
90             BINGLOG_STR("parse serverkeyEx signature failed."), ALERT_DECODE_ERROR);
91     } else if (ret == HITLS_MEMALLOC_FAIL) {
92         return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15311,
93             BINGLOG_STR("signData malloc fail."), ALERT_UNKNOWN);
94     }
95 
96     if (pkt->bufLen != *pkt->bufOffset) {
97         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15308,
98             BINGLOG_STR("parse serverkeyEx signature failed."), ALERT_DECODE_ERROR);
99     }
100 
101     if (*signSize == 0) {
102         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15310,
103             BINGLOG_STR("length of server signSize is 0."), ALERT_ILLEGAL_PARAMETER);
104     }
105 
106     return HITLS_SUCCESS;
107 }
108 
GetServerKeyExSignParam(const ServerKeyExchangeMsg * msg,CERT_SignParam * signParam,HITLS_SignHashAlgo * signScheme)109 static void GetServerKeyExSignParam(const ServerKeyExchangeMsg *msg,
110     CERT_SignParam *signParam, HITLS_SignHashAlgo *signScheme)
111 {
112     if (msg->keyExType == HITLS_KEY_EXCH_ECDHE) {
113         *signScheme = msg->keyEx.ecdh.signAlgorithm;
114         signParam->sign = msg->keyEx.ecdh.signData;
115         signParam->signLen = msg->keyEx.ecdh.signSize;
116     } else if (msg->keyExType == HITLS_KEY_EXCH_DHE) {
117         *signScheme = msg->keyEx.dh.signAlgorithm;
118         signParam->sign = msg->keyEx.dh.signData;
119         signParam->signLen = msg->keyEx.dh.signSize;
120     }
121 
122     return;
123 }
124 
VerifySignature(TLS_Ctx * ctx,const uint8_t * kxData,uint32_t kxDataLen,ServerKeyExchangeMsg * msg)125 int32_t VerifySignature(TLS_Ctx *ctx, const uint8_t *kxData, uint32_t kxDataLen, ServerKeyExchangeMsg *msg)
126 {
127     CERT_SignParam signParam = {0};
128     HITLS_SignHashAlgo signScheme = 0;
129 
130     GetServerKeyExSignParam(msg, &signParam, &signScheme);
131 
132     /* Obtain the signature algorithm and hash algorithm */
133     if (!CFG_GetSignParamBySchemes(ctx, signScheme, &signParam.signAlgo, &signParam.hashAlgo)) {
134         return ParseErrorProcess(ctx, HITLS_PARSE_GET_SIGN_PARA_ERR, BINLOG_ID15312,
135             BINGLOG_STR("get sign param fail."), ALERT_ILLEGAL_PARAMETER);
136     }
137     /* Obtain all signature data (random number + server kx content). */
138     uint8_t *data = HS_PrepareSignData(ctx, kxData, kxDataLen, &signParam.dataLen);
139     if (data == NULL) {
140         return ParseErrorProcess(ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15313,
141             BINGLOG_STR("data malloc fail."), ALERT_INTERNAL_ERROR);
142     }
143 
144     if (ctx->hsCtx->peerCert == NULL) {
145         BSL_SAL_FREE(data);
146         return ParseErrorProcess(ctx, HITLS_PARSE_VERIFY_SIGN_FAIL, BINLOG_ID17013,
147             BINGLOG_STR("peerCert null"), ALERT_CERTIFICATE_REQUIRED);
148     }
149 
150     HITLS_CERT_X509 *cert = SAL_CERT_PairGetX509(ctx->hsCtx->peerCert);
151     HITLS_CERT_Key *pubkey = NULL;
152     int32_t ret = SAL_CERT_X509Ctrl(&(ctx->config.tlsConfig), cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey);
153     if (ret != HITLS_SUCCESS) {
154         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17014, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
155             "GET_PUB_KEY fail", 0, 0, 0, 0);
156         BSL_SAL_FREE(data);
157         ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
158         return ret;
159     }
160 
161     signParam.data = data;
162     ret = SAL_CERT_VerifySign(ctx, pubkey, &signParam);
163     SAL_CERT_KeyFree(ctx->config.tlsConfig.certMgrCtx, pubkey);
164     BSL_SAL_FREE(data);
165     if (ret != HITLS_SUCCESS) {
166         return ParseErrorProcess(ctx, HITLS_PARSE_VERIFY_SIGN_FAIL, BINLOG_ID15314,
167             BINGLOG_STR("verify signature fail."), ALERT_DECRYPT_ERROR);
168     }
169     return HITLS_SUCCESS;
170 }
171 #ifdef HITLS_TLS_SUITE_KX_ECDHE
172 
ParseEcdhePublicKey(ParsePacket * pkt,ServerEcdh * ecdh)173 static int32_t ParseEcdhePublicKey(ParsePacket *pkt, ServerEcdh *ecdh)
174 {
175     const char *logStr = BINGLOG_STR("parse ecdhe public key fail.");
176     uint8_t pubKeySize = 0;
177     int32_t ret = ParseBytesToUint8(pkt, &pubKeySize);
178     if (ret != HITLS_SUCCESS) {
179         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15298,
180             logStr, ALERT_DECODE_ERROR);
181     }
182 
183 #ifdef HITLS_TLS_PROTO_TLCP11
184     if (pkt->ctx->negotiatedInfo.version == HITLS_VERSION_TLCP_DTLCP11) {
185         ecdh->ecPara.param.namedcurve = HITLS_EC_GROUP_SM2;
186     }
187 #endif /* HITLS_TLS_PROTO_TLCP11 */
188     if ((ecdh->ecPara.type == HITLS_EC_CURVE_TYPE_NAMED_CURVE) &&
189         (pubKeySize != SAL_CRYPT_GetCryptLength(pkt->ctx, HITLS_CRYPT_INFO_CMD_GET_PUBLIC_KEY_LEN,
190             ecdh->ecPara.param.namedcurve))) {
191         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15300, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
192             "ecdhe server pubkey length error, curve id = %u, pubkey len = %u.",
193             ecdh->ecPara.param.namedcurve, pubKeySize, 0, 0);
194         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_ECDH_PUBKEY_ERR, 0, NULL, ALERT_ILLEGAL_PARAMETER);
195     }
196 
197     uint8_t *pubKey = NULL;
198     ret = ParseBytesToArray(pkt, &pubKey, pubKeySize);
199     if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
200         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15299,
201             logStr, ALERT_DECODE_ERROR);
202     } else if (ret == HITLS_MEMALLOC_FAIL) {
203         return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15301,
204             BINGLOG_STR("pubKey malloc fail."), ALERT_UNKNOWN);
205     }
206 
207     ecdh->pubKey = pubKey;
208     ecdh->pubKeySize = pubKeySize;
209     return HITLS_SUCCESS;
210 }
211 
ParseEcParameters(ParsePacket * pkt,ServerEcdh * ecdh)212 int32_t ParseEcParameters(ParsePacket *pkt, ServerEcdh *ecdh)
213 {
214     const char *logStr = BINGLOG_STR("parse ecdhe curve type fail.");
215     uint8_t curveType = 0;
216     int32_t ret = ParseBytesToUint8(pkt, &curveType);
217     if (ret != HITLS_SUCCESS) {
218         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15292,
219             logStr, ALERT_DECODE_ERROR);
220     }
221 
222     /* In the TLCP, this content can choose not to be sent. */
223     if (curveType == HITLS_EC_CURVE_TYPE_NAMED_CURVE) {
224         uint16_t namedCurve = 0;
225         ret = ParseBytesToUint16(pkt, &namedCurve);
226         if (ret != HITLS_SUCCESS) {
227             return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15291,
228                 logStr, ALERT_DECODE_ERROR);
229         }
230         ecdh->ecPara.param.namedcurve = namedCurve;
231     } else {
232         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_UNSUPPORT_KX_CURVE_TYPE, BINLOG_ID15293,
233             BINGLOG_STR("unsupport curve type in server key exchange."), ALERT_ILLEGAL_PARAMETER);
234     }
235 
236     ecdh->ecPara.type = curveType;
237     return HITLS_SUCCESS;
238 }
239 
240 /**
241  * @brief Parse the server ecdh message.
242  *
243  * @param pkt [IN] Context for parsing
244  * @param msg [OUT] Parsed message structure
245  *
246  * @retval HITLS_SUCCESS Parsing succeeded.
247  * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect.
248  * @retval HITLS_PARSE_UNSUPPORT_KX_CURVE_TYPE Unsupported ECC curve type
249  * @retval HITLS_PARSE_ECDH_PUBKEY_ERR Failed to parse the ECDH public key.
250  * @retval HITLS_PARSE_ECDH_SIGN_ERR Failed to parse the EDH signature.
251  * @retval HITLS_PARSE_GET_SIGN_PARA_ERR Failed to obtain the signature algorithm and hash algorithm.
252  * @retval HITLS_PARSE_VERIFY_SIGN_FAIL Failed to verify the signature.
253  */
ParseServerEcdhe(ParsePacket * pkt,ServerKeyExchangeMsg * msg)254 static int32_t ParseServerEcdhe(ParsePacket *pkt, ServerKeyExchangeMsg *msg)
255 {
256     TLS_Ctx *ctx = pkt->ctx;
257     /* Parse the EC parameter in the ECDH message on the server */
258     int32_t ret = ParseEcParameters(pkt, &msg->keyEx.ecdh);
259     if (ret != HITLS_SUCCESS) {
260         return ret;
261     }
262 
263     /* Parse DH public key from peer */
264     ret = ParseEcdhePublicKey(pkt, &msg->keyEx.ecdh);
265     if (ret != HITLS_SUCCESS) {
266         return ret;
267     }
268 
269     /*  ECDHE_PSK and ANON_ECDHE key exchange are not signed */
270     if (ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_ECDHE_PSK ||
271         ctx->negotiatedInfo.cipherSuiteInfo.authAlg == HITLS_AUTH_NULL) {
272         if (pkt->bufLen != *pkt->bufOffset) {
273             return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15317,
274                 BINGLOG_STR("parse serverkeyEx signature failed."), ALERT_DECODE_ERROR);
275         }
276         return HITLS_SUCCESS;
277     }
278 
279     uint32_t keyExDataLen = *pkt->bufOffset;
280     uint16_t signAlgorithm = ctx->negotiatedInfo.cipherSuiteInfo.signScheme;
281 
282     if (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP_DTLCP11) {
283         ret = ParseSignAlgorithm(pkt, &signAlgorithm);
284         if (ret != HITLS_SUCCESS) {
285             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17015, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
286                 "ParseSignAlgorithm fail", 0, 0, 0, 0);
287             return ret;
288         }
289     }
290 
291     msg->keyEx.ecdh.signAlgorithm = signAlgorithm;
292 
293     ret = ParseSignature(pkt, &msg->keyEx.ecdh.signSize, &msg->keyEx.ecdh.signData);
294     if (ret != HITLS_SUCCESS) {
295         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_ECDH_SIGN_ERR, BINLOG_ID15318,
296             BINGLOG_STR("parse ecdhe signature fail."), ALERT_UNKNOWN);
297     }
298 
299     ret = VerifySignature(pkt->ctx, pkt->buf, keyExDataLen, msg);
300     if (ret != HITLS_SUCCESS) {
301         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17016, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
302             "VerifySignature fail", 0, 0, 0, 0);
303         return ret;
304     }
305 
306     ctx->peerInfo.peerSignHashAlg = signAlgorithm;
307     return HITLS_SUCCESS;
308 }
309 #endif /* HITLS_TLS_SUITE_KX_ECDHE */
310 #ifdef HITLS_TLS_SUITE_KX_DHE
311 
312 /**
313  * @brief Parse the p or g parameter in the DHE kx message.
314  *
315  * @param pkt [IN] Context for parsing
316  * @param paraLen [OUT] Parsed parameter length
317  * @param para [OUT] Parsed parameter
318  *
319  * @return The allocated parameter memory. If the parameter memory is NULL, the parsing fails.
320  */
ParseDhePara(ParsePacket * pkt,uint16_t * paraLen,uint8_t ** para)321 int32_t ParseDhePara(ParsePacket *pkt, uint16_t *paraLen, uint8_t **para)
322 {
323     int32_t ret = ParseTwoByteLengthField(pkt, paraLen, para);
324     if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
325         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15294,
326             BINGLOG_STR("dhe para length error."), ALERT_DECODE_ERROR);
327     } else if (ret == HITLS_MEMALLOC_FAIL) {
328         return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15297,
329             BINGLOG_STR("dhePara malloc fail."), ALERT_UNKNOWN);
330     }
331 
332     if (*paraLen == 0) {
333         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15296,
334             BINGLOG_STR("length of dhe para is 0."), ALERT_ILLEGAL_PARAMETER);
335     }
336 
337     return HITLS_SUCCESS;
338 }
339 
ParseServerDhe(ParsePacket * pkt,ServerKeyExchangeMsg * msg)340 static int32_t ParseServerDhe(ParsePacket *pkt, ServerKeyExchangeMsg *msg)
341 {
342     ServerDh *dh = &msg->keyEx.dh;
343     const char *logStr = BINGLOG_STR("parse dhe param or PubKey fail. ret %d");
344     TLS_Ctx *ctx = pkt->ctx;
345     int32_t ret = ParseDhePara(pkt, &dh->plen, &dh->p);
346     if (ret != HITLS_SUCCESS) {
347         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15320, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, logStr, ret, 0, 0, 0);
348         return HITLS_PARSE_DH_P_ERR;
349     }
350 
351     ret = ParseDhePara(pkt, &dh->glen, &dh->g);
352     if (ret != HITLS_SUCCESS) {
353         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15321, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, logStr, ret, 0, 0, 0);
354         return HITLS_PARSE_DH_G_ERR;
355     }
356 
357     /* Parse DH public key from peer */
358     ret = ParseDhePara(pkt, &dh->pubKeyLen, &dh->pubkey);
359     if (ret != HITLS_SUCCESS) {
360         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15322, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, logStr, ret, 0, 0, 0);
361         return HITLS_PARSE_DH_PUBKEY_ERR;
362     }
363 
364     /* DHE_PSK | ANON_DHE key exchange is not signed */
365     if (ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_DHE_PSK ||
366         ctx->negotiatedInfo.cipherSuiteInfo.authAlg == HITLS_AUTH_NULL) {
367         if (pkt->bufLen != *pkt->bufOffset) {
368             return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15323,
369                 BINGLOG_STR("parse serverkeyEx signature failed."), ALERT_DECODE_ERROR);
370         }
371         return HITLS_SUCCESS;
372     }
373 
374     uint32_t kxDataLen = *pkt->bufOffset;
375 
376     dh->signAlgorithm = ctx->negotiatedInfo.cipherSuiteInfo.signScheme;
377     ret = ParseSignAlgorithm(pkt, &dh->signAlgorithm);
378     if (ret != HITLS_SUCCESS) {
379         return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17017, "ParseSignAlgorithm fail");
380     }
381 
382     ret = ParseSignature(pkt, &dh->signSize, &dh->signData);
383     if (ret != HITLS_SUCCESS) {
384         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17018, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
385             "ParseSignature fail, ret %d", ret, 0, 0, 0);
386         return HITLS_PARSE_DH_SIGN_ERR;
387     }
388 
389     ret = VerifySignature(pkt->ctx, pkt->buf, kxDataLen, msg);
390     if (ret != HITLS_SUCCESS) {
391         return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID17019, "VerifySignature fail");
392     }
393 
394     ctx->peerInfo.peerSignHashAlg = dh->signAlgorithm;
395     return HITLS_SUCCESS;
396 }
397 #endif /* HITLS_TLS_SUITE_KX_DHE */
398 #ifdef HITLS_TLS_FEATURE_PSK
399 /* In the case of psk negotiation, if ServerKeyExchange is received, the length of the identity hint must be parseed,
400  * but the length may be empty */
ParseServerIdentityHint(ParsePacket * pkt,ServerKeyExchangeMsg * msg)401 static int32_t ParseServerIdentityHint(ParsePacket *pkt, ServerKeyExchangeMsg *msg)
402 {
403     uint16_t identityHintLen = 0;
404     uint8_t *identityHint = NULL;
405 
406     int32_t ret = ParseTwoByteLengthField(pkt, &identityHintLen, &identityHint);
407     if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
408         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17020, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
409             "Parse fail, ret %d", ret, 0, 0, 0);
410         BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH);
411         return HITLS_CONFIG_INVALID_LENGTH;
412     } else if (ret == HITLS_MEMALLOC_FAIL) {
413         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17021, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
414             "Parse fail, ret %d", ret, 0, 0, 0);
415         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
416         return HITLS_MEMALLOC_FAIL;
417     }
418 
419     if (identityHintLen != 0) {
420         BSL_LOG_BINLOG_VARLEN(BINLOG_ID15324, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
421             "receive server identity hint: %s.", identityHint);
422     }
423 
424     msg->pskIdentityHint = identityHint;
425     msg->hintSize = identityHintLen;
426 
427     return HITLS_SUCCESS;
428 }
429 #endif /* HITLS_TLS_FEATURE_PSK */
430 #ifdef HITLS_TLS_PROTO_TLCP11
VerifyServerKxMsgEcc(ParsePacket * pkt,CERT_SignParam * signParam)431 static int32_t VerifyServerKxMsgEcc(ParsePacket *pkt, CERT_SignParam *signParam)
432 {
433     uint8_t *sign = NULL;
434     uint16_t signSize = 0;
435     TLS_Ctx *ctx = pkt->ctx;
436     /* Parse the signature data. The signature data is released after it is used up. The information is not maintained
437      * in the ServerKeyExchangeMsg.keyEx.ecdh file */
438     int32_t ret = ParseSignature(pkt, &signSize, &sign);
439     if (ret != HITLS_SUCCESS) {
440         BSL_SAL_FREE(sign);
441         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16223, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
442             "parse ecc signature fail.", 0, 0, 0, 0);
443         return HITLS_PARSE_ECDH_SIGN_ERR;
444     }
445     HITLS_CERT_X509 *signCert = SAL_CERT_PairGetX509(ctx->hsCtx->peerCert);
446     HITLS_CERT_Key *pubkey = NULL;
447     ret = SAL_CERT_X509Ctrl(&(ctx->config.tlsConfig), signCert,
448         CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey);
449     if (ret != HITLS_SUCCESS) {
450         BSL_SAL_FREE(sign);
451         ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
452         return ret;
453     }
454 
455     signParam->sign = sign;
456     signParam->signLen = signSize;
457     ret = SAL_CERT_VerifySign(ctx, pubkey, signParam);
458     SAL_CERT_KeyFree(ctx->config.tlsConfig.certMgrCtx, pubkey);
459     BSL_SAL_FREE(sign);
460     return ret;
461 }
462 
463 /* Signature verification is complete and does not need to be exported to the ServerKeyExchangeMsg structure */
ParseServerKxMsgEcc(ParsePacket * pkt)464 static int32_t ParseServerKxMsgEcc(ParsePacket *pkt)
465 {
466     HITLS_SignAlgo signAlgo;
467     HITLS_HashAlgo hashAlgo;
468     TLS_Ctx *ctx = pkt->ctx;
469     /* The algorithm suite has been determined. The error probability of this function is low. Therefore, the alert is
470      * not required. */
471     if (!CFG_GetSignParamBySchemes(ctx, ctx->negotiatedInfo.cipherSuiteInfo.signScheme, &signAlgo, &hashAlgo)) {
472         return HITLS_PACK_SIGNATURE_ERR;
473     }
474 
475     uint32_t certLen = 0;
476     uint8_t *cert = SAL_CERT_ClntGmEncodeEncCert(ctx, ctx->hsCtx->peerCert, &certLen);
477     if (cert == NULL) {
478         return ParseErrorProcess(pkt->ctx, HITLS_CERT_ERR_ENCODE, BINLOG_ID16206,
479             BINGLOG_STR("encode encrypt cert failed."), ALERT_INTERNAL_ERROR);
480     }
481     uint32_t signDataLen = 0;
482     uint8_t *signData = HS_PrepareSignDataTlcp(ctx, cert, certLen, &signDataLen);
483     BSL_SAL_FREE(cert);
484     if (signData == NULL) {
485         return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID16207,
486             BINGLOG_STR("data malloc fail."), ALERT_INTERNAL_ERROR);
487     }
488 
489     CERT_SignParam signParam = {signAlgo, hashAlgo, signData, signDataLen, NULL, 0};
490     int32_t ret = VerifyServerKxMsgEcc(pkt, &signParam);
491     BSL_SAL_FREE(signData);
492     if (ret != HITLS_SUCCESS) {
493         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_VERIFY_SIGN_FAIL, BINLOG_ID16208,
494             BINGLOG_STR("verify signature fail."), ALERT_DECRYPT_ERROR);
495     }
496     return HITLS_SUCCESS;
497 }
498 #endif
499 
ParseServerKeyExchange(TLS_Ctx * ctx,const uint8_t * data,uint32_t len,HS_Msg * hsMsg)500 int32_t ParseServerKeyExchange(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_Msg *hsMsg)
501 {
502     int32_t ret;
503     uint32_t offset = 0u;
504     HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx;
505     ServerKeyExchangeMsg *msg = &hsMsg->body.serverKeyExchange;
506     msg->keyExType = hsCtx->kxCtx->keyExchAlgo;
507     ParsePacket pkt = {.ctx = ctx, .buf = data, .bufLen = len, .bufOffset = &offset};
508     (void)pkt;
509 #ifdef HITLS_TLS_FEATURE_PSK
510     if (IsPskNegotiation(ctx)) {
511         if ((ret = ParseServerIdentityHint(&pkt, msg)) != HITLS_SUCCESS) {
512             // log here
513             return ret;
514         }
515     }
516 #endif /* HITLS_TLS_FEATURE_PSK */
517     switch (hsCtx->kxCtx->keyExchAlgo) {
518 #ifdef HITLS_TLS_SUITE_KX_ECDHE
519         case HITLS_KEY_EXCH_ECDHE: /** contains the TLCP */
520         case HITLS_KEY_EXCH_ECDHE_PSK:
521             ret = ParseServerEcdhe(&pkt, msg);
522             break;
523 #endif /* HITLS_TLS_SUITE_KX_ECDHE */
524 #ifdef HITLS_TLS_SUITE_KX_DHE
525         case HITLS_KEY_EXCH_DHE:
526         case HITLS_KEY_EXCH_DHE_PSK:
527             ret = ParseServerDhe(&pkt, msg);
528             break;
529 #endif /* HITLS_TLS_SUITE_KX_DHE */
530 #ifdef HITLS_TLS_SUITE_KX_RSA
531         /* PSK & RSA_PSK nego may pack identity hint inside ServerKeyExchange msg */
532         case HITLS_KEY_EXCH_PSK:
533         case HITLS_KEY_EXCH_RSA_PSK:
534             ret = HITLS_SUCCESS;
535             break;
536 #endif /* HITLS_TLS_SUITE_KX_RSA */
537 #ifdef HITLS_TLS_PROTO_TLCP11
538         case HITLS_KEY_EXCH_ECC:
539             ret = ParseServerKxMsgEcc(&pkt);
540             break;
541 #endif
542         default:
543             ret = HITLS_PARSE_UNSUPPORT_KX_ALG;
544             ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
545             break;
546     }
547     if (ret != HITLS_SUCCESS) {
548         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15325, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
549             "parse serverKeyExMsg fail. keyExchAlgo is %d", hsCtx->kxCtx->keyExchAlgo, 0, 0, 0);
550     }
551 
552     return ret;
553 }
554 
CleanServerKeyExchange(ServerKeyExchangeMsg * msg)555 void CleanServerKeyExchange(ServerKeyExchangeMsg *msg)
556 {
557     if (msg == NULL) {
558         return;
559     }
560 #ifdef HITLS_TLS_SUITE_KX_ECDHE
561     if (msg->keyExType == HITLS_KEY_EXCH_ECDHE || msg->keyExType == HITLS_KEY_EXCH_ECDHE_PSK) {
562         BSL_SAL_FREE(msg->keyEx.ecdh.pubKey);
563         BSL_SAL_FREE(msg->keyEx.ecdh.signData);
564     }
565 #endif
566 #ifdef HITLS_TLS_SUITE_KX_DHE
567     if (msg->keyExType == HITLS_KEY_EXCH_DHE || msg->keyExType == HITLS_KEY_EXCH_DHE_PSK) {
568         BSL_SAL_FREE(msg->keyEx.dh.p);
569         BSL_SAL_FREE(msg->keyEx.dh.g);
570         BSL_SAL_FREE(msg->keyEx.dh.pubkey);
571         BSL_SAL_FREE(msg->keyEx.dh.signData);
572     }
573 #endif
574     BSL_SAL_FREE(msg->pskIdentityHint);
575 
576     return;
577 }
578 #endif /* HITLS_TLS_PROTO_TLS_BASIC || HITLS_TLS_PROTO_DTLS12 */
579 #endif /* HITLS_TLS_HOST_CLIENT */