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 #include "securec.h"
17 #include "tls_binlog_id.h"
18 #include "bsl_log_internal.h"
19 #include "bsl_log.h"
20 #include "bsl_sal.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_bytes.h"
23 #include "hitls_error.h"
24 #include "hs_msg.h"
25 #include "hs_common.h"
26 #include "parse_msg.h"
27 #include "parse_common.h"
28 #include "hs_extensions.h"
29 #include "parse_extensions.h"
30
31 /**
32 * @brief Parse the certificate signature
33 *
34 * @param ctx [IN] TLS context
35 * @param buf [IN] message to be parsed
36 * @param bufLen [IN] buffer length
37 * @param readLen [OUT] Parsed length
38 *
39 * @return Return the memory of the applied certificate. If NULL is returned, the parsing fails.
40 */
ParseSingleCert(ParsePacket * pkt,CERT_Item ** certItem)41 int32_t ParseSingleCert(ParsePacket *pkt, CERT_Item **certItem)
42 {
43 uint32_t certLen = 0;
44 /* Obtain the certificate length */
45 int32_t ret = ParseBytesToUint24(pkt, &certLen);
46 if (ret != HITLS_SUCCESS) {
47 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15586,
48 BINGLOG_STR("Parse cert data len error."), ALERT_DECODE_ERROR);
49 }
50
51 if ((certLen == 0) || (certLen > (pkt->bufLen - *pkt->bufOffset))) {
52 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15587, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
53 "Parse cert data error: data len= %u, cert len= %u.", pkt->bufLen, certLen, 0, 0);
54 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, 0, NULL, ALERT_DECODE_ERROR);
55 }
56
57 CERT_Item *item = (CERT_Item*)BSL_SAL_Calloc(1u, sizeof(CERT_Item));
58 if (item == NULL) {
59 return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15588,
60 BINGLOG_STR("CERT_Item malloc fail."), ALERT_UNKNOWN);
61 }
62 item->next = NULL;
63 item->dataSize = certLen; /* Update the length of the certificate message */
64
65 /* Extract the contents of the certificate message */
66 item->data = BSL_SAL_Malloc(item->dataSize);
67 if (item->data == NULL) {
68 BSL_SAL_FREE(item);
69 return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15589,
70 BINGLOG_STR("item->data malloc fail."), ALERT_UNKNOWN);
71 }
72 (void)memcpy_s(item->data, item->dataSize, &pkt->buf[*pkt->bufOffset], item->dataSize);
73 *pkt->bufOffset += certLen;
74 *certItem = item;
75
76 return HITLS_SUCCESS;
77 }
78
ParseCertExtension(ParsePacket * pkt,CertificateMsg * msg,CERT_Item * item,uint32_t certIndex)79 static int32_t ParseCertExtension(ParsePacket *pkt, CertificateMsg *msg, CERT_Item *item, uint32_t certIndex)
80 {
81 (void)item;
82 (void)certIndex;
83 if (pkt->ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) {
84 return HITLS_SUCCESS;
85 }
86
87 uint16_t certExLen = 0;
88 const char *logStr = BINGLOG_STR("length of certificate extension is incorrect.");
89 int32_t ret = ParseBytesToUint16(pkt, &certExLen);
90 if (ret != HITLS_SUCCESS) {
91 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15590, logStr, ALERT_DECODE_ERROR);
92 }
93 if (*pkt->bufOffset + certExLen > pkt->bufLen) {
94 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16235, logStr, ALERT_DECODE_ERROR);
95 }
96
97 uint32_t offset = 0;
98 while (offset < certExLen) {
99 uint16_t extMsgType = HS_EX_TYPE_END;
100 uint32_t extMsgLen = 0u;
101 ret = ParseExHeader(pkt->ctx, &pkt->buf[*pkt->bufOffset],
102 pkt->bufLen - *pkt->bufOffset, &extMsgType, &extMsgLen);
103 if (ret != HITLS_SUCCESS) {
104 return ParseErrorProcess(pkt->ctx, ret, BINLOG_ID15330, logStr, ALERT_DECODE_ERROR);
105 }
106 *pkt->bufOffset += HS_EX_HEADER_LEN;
107 offset += HS_EX_HEADER_LEN;
108 #ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
109 if (IsParseNeedCustomExtensions(CUSTOM_EXT_FROM_CTX(pkt->ctx), extMsgType, HITLS_EX_TYPE_TLS1_3_CERTIFICATE)) {
110 HITLS_CERT_X509 *cert = SAL_CERT_X509Parse(LIBCTX_FROM_CTX(pkt->ctx),
111 ATTRIBUTE_FROM_CTX(pkt->ctx), &pkt->ctx->config.tlsConfig, item->data, item->dataSize,
112 TLS_PARSE_TYPE_BUFF, TLS_PARSE_FORMAT_ASN1);
113 if (cert == NULL) {
114 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15331,
115 "X509Parse fail", ALERT_DECODE_ERROR);
116 }
117 ret = ParseCustomExtensions(pkt->ctx, &pkt->buf[*pkt->bufOffset], extMsgType, extMsgLen,
118 HITLS_EX_TYPE_TLS1_3_CERTIFICATE, cert, certIndex);
119 SAL_CERT_X509Free(cert);
120 if (ret != HITLS_SUCCESS) {
121 return ParseErrorProcess(pkt->ctx, ret, BINLOG_ID15332, "ParseCustomExtensions fail",
122 ALERT_DECODE_ERROR);
123 }
124 } else
125 #endif /* HITLS_TLS_FEATURE_CUSTOM_EXTENSION */
126 {
127 msg->extensionTypeMask |= 1ULL << HS_GetExtensionTypeId(extMsgType);
128 }
129 *pkt->bufOffset += extMsgLen;
130 offset += extMsgLen;
131 }
132
133 if (offset != certExLen) {
134 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15463,
135 BINGLOG_STR("extension len error"), ALERT_DECODE_ERROR);
136 }
137
138 return HITLS_SUCCESS;
139 }
140
ParseCerts(ParsePacket * pkt,HS_Msg * hsMsg)141 int32_t ParseCerts(ParsePacket *pkt, HS_Msg *hsMsg)
142 {
143 int32_t ret;
144 CertificateMsg *msg = &hsMsg->body.certificate;
145 CERT_Item *cur = msg->cert;
146
147 /* Parse the certificate message and save the certificate chain to the structure */
148 while (*pkt->bufOffset < pkt->bufLen) {
149 CERT_Item *item = NULL;
150 ret = ParseSingleCert(pkt, &item);
151 if (ret != HITLS_SUCCESS) {
152 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_CERT_ERR, BINLOG_ID15591,
153 BINGLOG_STR("parse certificate item fail."), ALERT_UNKNOWN);
154 }
155
156 /* Add the parsed certificate to the last node in the linked list */
157 if (msg->cert == NULL) {
158 msg->cert = item;
159 } else if (cur != NULL) {
160 cur->next = item;
161 }
162 cur = item;
163
164 ret = ParseCertExtension(pkt, msg, item, msg->certCount);
165 if (ret != HITLS_SUCCESS) {
166 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15592, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
167 "parse certificate extension fail.", 0, 0, 0, 0);
168 return ret;
169 }
170
171 msg->certCount++;
172 }
173
174 return HITLS_SUCCESS;
175 }
176 #if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
177 /**
178 * @brief Parse the certificate message.
179 *
180 * @param ctx [IN] TLS context
181 * @param buf [IN] message buffer
182 * @param bufLen [IN] Maximum message length
183 * @param hsMsg [OUT] message structure
184 *
185 * @retval HITLS_SUCCESS parsed successfully.
186 * @retval HITLS_PARSE_CERT_ERR Failed to parse the certificate.
187 * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect
188 */
ParseCertificate(TLS_Ctx * ctx,const uint8_t * buf,uint32_t bufLen,HS_Msg * hsMsg)189 int32_t ParseCertificate(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg)
190 {
191 uint32_t offset = 0;
192 uint32_t allCertsLen = 0;
193 ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = bufLen, .bufOffset = &offset};
194 const char *logStr = BINGLOG_STR("length of all certificates is incorrect.");
195 /* Obtain the lengths of all certificates */
196 int32_t ret = ParseBytesToUint24(&pkt, &allCertsLen);
197 if (ret != HITLS_SUCCESS) {
198 return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15593, logStr, ALERT_DECODE_ERROR);
199 }
200
201 if (allCertsLen != (pkt.bufLen - CERT_LEN_TAG_SIZE)) {
202 return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15594, logStr, ALERT_DECODE_ERROR);
203 }
204
205 /*
206 * The client can send a certificate message without a certificate, so if the total length of the certificate is 0,
207 * it directly returns success; If the client receives a certificate message of length 0, it is determined by the
208 * processing layer, which is only responsible for parsing
209 */
210 if (allCertsLen == 0) {
211 return HITLS_SUCCESS;
212 }
213
214 ret = ParseCerts(&pkt, hsMsg);
215 if ((ret != HITLS_SUCCESS) || (*pkt.bufOffset != (allCertsLen + CERT_LEN_TAG_SIZE))) {
216 return ParseErrorProcess(pkt.ctx, HITLS_PARSE_CERT_ERR, BINLOG_ID15595,
217 BINGLOG_STR("Certificate msg parse failed."), ALERT_UNKNOWN);
218 }
219
220 return HITLS_SUCCESS;
221 }
222 #endif /* HITLS_TLS_PROTO_TLS_BASIC || HITLS_TLS_PROTO_DTLS12 */
223 #ifdef HITLS_TLS_PROTO_TLS13
Tls13ParseCertificateReqCtx(ParsePacket * pkt,HS_Msg * hsMsg)224 int32_t Tls13ParseCertificateReqCtx(ParsePacket *pkt, HS_Msg *hsMsg)
225 {
226 CertificateMsg *certMsg = &hsMsg->body.certificate;
227 /* Obtain the certificates_request_context_length */
228 uint8_t len = 0;
229 int32_t ret = ParseBytesToUint8(pkt, &len);
230 if (ret != HITLS_SUCCESS) {
231 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16971,
232 BINGLOG_STR("ParseBytesToUint8 fail"), ALERT_DECODE_ERROR);
233 }
234 uint16_t certReqCtxLen = (uint16_t)len;
235 certMsg->certificateReqCtxSize = (uint32_t)certReqCtxLen;
236 /* At least the length and content of the total certificate length of 3 bytes + certificateReqCtx can be parsed */
237 if (pkt->bufLen < CERT_LEN_TAG_SIZE + certReqCtxLen + sizeof(uint8_t)) {
238 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16129,
239 BINGLOG_STR("the length of tls13 certificate message is incorrect"), ALERT_DECODE_ERROR);
240 }
241 /* Obtain the certificate_request_context value */
242 if (certReqCtxLen > 0) {
243 certMsg->certificateReqCtx = BSL_SAL_Calloc(certReqCtxLen, sizeof(uint8_t));
244 if (certMsg->certificateReqCtx == NULL) {
245 return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15596,
246 BINGLOG_STR("certificateReqCtx malloc fail."), ALERT_UNKNOWN);
247 }
248 (void)memcpy_s(certMsg->certificateReqCtx, certReqCtxLen, &pkt->buf[*pkt->bufOffset], certReqCtxLen);
249 *pkt->bufOffset += certReqCtxLen;
250 }
251 return HITLS_SUCCESS;
252 }
253
254 /**
255 * @brief Parse the certificate message.
256 *
257 * @param ctx [IN] TLS context
258 * @param buf [IN] message buffer
259 * @param bufLen [IN] Maximum message length
260 * @param hsMsg [OUT] message structure
261 *
262 * @retval HITLS_SUCCESS parsed successfully.
263 * @retval HITLS_PARSE_CERT_ERR Failed to parse the certificate.
264 * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect.
265 */
Tls13ParseCertificate(TLS_Ctx * ctx,const uint8_t * buf,uint32_t bufLen,HS_Msg * hsMsg)266 int32_t Tls13ParseCertificate(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg)
267 {
268 CertificateMsg *certMsg = &hsMsg->body.certificate;
269 uint32_t offset = 0;
270 ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = bufLen, .bufOffset = &offset};
271 int32_t ret = Tls13ParseCertificateReqCtx(&pkt, hsMsg);
272 if (ret != HITLS_SUCCESS) {
273 return ret;
274 }
275
276 uint32_t allCertsLen = 0;
277 ret = ParseBytesToUint24(&pkt, &allCertsLen);
278 if (ret != HITLS_SUCCESS || (allCertsLen != (pkt.bufLen - *pkt.bufOffset))) {
279 CleanCertificate(&hsMsg->body.certificate);
280 return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15597,
281 BINGLOG_STR("length of all tls1.3 certificates is incorrect."), ALERT_DECODE_ERROR);
282 }
283
284 /*
285 * The client can send a certificate message without a certificate, so if the total length of the certificate is 0,
286 * it directly returns success; If the client receives a certificate message of length 0, it is determined by the
287 * processing layer, which is only responsible for parsing
288 */
289 if (allCertsLen == 0) {
290 return HITLS_SUCCESS;
291 }
292
293 ret = ParseCerts(&pkt, hsMsg);
294 if ((ret != HITLS_SUCCESS) ||
295 (*pkt.bufOffset != (sizeof(uint8_t) + certMsg->certificateReqCtxSize + CERT_LEN_TAG_SIZE + allCertsLen))) {
296 CleanCertificate(&hsMsg->body.certificate);
297 return ParseErrorProcess(pkt.ctx, HITLS_PARSE_CERT_ERR, BINLOG_ID15598,
298 BINGLOG_STR("Certificate msg parse failed."), ALERT_UNKNOWN);
299 }
300
301 return HITLS_SUCCESS;
302 }
303 #endif /* HITLS_TLS_PROTO_TLS13 */
304 // Clear the memory applied for in the certificate message structure.
CleanCertificate(CertificateMsg * msg)305 void CleanCertificate(CertificateMsg *msg)
306 {
307 if (msg == NULL) {
308 return;
309 }
310 #ifdef HITLS_TLS_PROTO_TLS13
311 BSL_SAL_FREE(msg->certificateReqCtx);
312 #endif
313 CERT_Item *next = msg->cert;
314 while (next != NULL) {
315 CERT_Item *temp = next->next;
316 BSL_SAL_FREE(next->data);
317 BSL_SAL_FREE(next);
318 next = temp;
319 }
320 msg->cert = NULL;
321 return;
322 }
323