• 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 #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