• 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 #include "securec.h"
18 #include "tls_binlog_id.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_log.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_sal.h"
23 #include "bsl_list.h"
24 #include "bsl_bytes.h"
25 #include "hitls_error.h"
26 #include "hs_ctx.h"
27 #include "hs_msg.h"
28 #include "hs_common.h"
29 #include "parse_msg.h"
30 #include "hs_extensions.h"
31 #include "parse_extensions.h"
32 #include "parse_common.h"
33 
34 #if defined(HITLS_TLS_PROTO_TLS12) || defined(HITLS_TLS_PROTO_DTLS12) || defined(HITLS_TLS_PROTO_TLS13)
35 
36 #define SINGLE_SIG_HASH_ALG_SIZE 2u
37 // Parse the signature algorithm field in the certificate request message.
ParseSignatureAndHashAlgo(ParsePacket * pkt,CertificateRequestMsg * msg)38 static int32_t ParseSignatureAndHashAlgo(ParsePacket *pkt, CertificateRequestMsg *msg)
39 {
40     /* An extension of the same type has already been parsed */
41     if (msg->haveSignatureAndHashAlgo == true) {
42         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_DUPLICATE_EXTENDED_MSG, BINLOG_ID16945,
43             BINGLOG_STR("SignatureAndHashAlgo repeated"), ALERT_ILLEGAL_PARAMETER);
44     }
45 
46     /* Obtain the length of the signature hash algorithm */
47     uint16_t signatureAndHashAlgLen = 0;
48     const char *logStr = BINGLOG_STR("parse signatureAndHashAlgLen fail.");
49     int32_t ret = ParseBytesToUint16(pkt, &signatureAndHashAlgLen);
50     if (ret != HITLS_SUCCESS) {
51         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15458, logStr, ALERT_DECODE_ERROR);
52     }
53     if (((uint32_t)signatureAndHashAlgLen > (pkt->bufLen - *pkt->bufOffset)) ||
54         ((signatureAndHashAlgLen % SINGLE_SIG_HASH_ALG_SIZE) != 0u) || (signatureAndHashAlgLen == 0u)) {
55         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15459, logStr, ALERT_DECODE_ERROR);
56     }
57 
58     /* Parse the length of the signature algorithm */
59     msg->signatureAlgorithmsSize = signatureAndHashAlgLen / SINGLE_SIG_HASH_ALG_SIZE;
60     BSL_SAL_FREE(msg->signatureAlgorithms);
61     msg->signatureAlgorithms = (uint16_t *)BSL_SAL_Malloc(signatureAndHashAlgLen);
62     if (msg->signatureAlgorithms == NULL) {
63         return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15460,
64             BINGLOG_STR("signatureAlgorithms malloc fail"), ALERT_UNKNOWN);
65     }
66     /* Extract the signature algorithm */
67     for (uint16_t index = 0u; index < msg->signatureAlgorithmsSize; index++) {
68         msg->signatureAlgorithms[index] = BSL_ByteToUint16(&pkt->buf[*pkt->bufOffset]);
69         *pkt->bufOffset += sizeof(uint16_t);
70     }
71 
72     msg->haveSignatureAndHashAlgo = true;
73     return HITLS_SUCCESS;
74 }
75 #endif /* HITLS_TLS_PROTO_TLS12 || HITLS_TLS_PROTO_DTLS12 || HITLS_TLS_PROTO_TLS13 */
76 
CaListNodeInnerDestroy(void * data)77 static void CaListNodeInnerDestroy(void *data)
78 {
79     HITLS_TrustedCANode *tmpData = (HITLS_TrustedCANode *)data;
80     BSL_SAL_FREE(tmpData->data);
81     BSL_SAL_FREE(tmpData);
82     return;
83 }
84 
FreeDNList(HITLS_TrustedCAList * caList)85 void FreeDNList(HITLS_TrustedCAList *caList)
86 {
87     BslList *tmpCaList = (BslList *)caList;
88 
89     BSL_LIST_FREE(tmpCaList, CaListNodeInnerDestroy);
90 
91     return;
92 }
93 
ParseDN(const uint8_t * data,uint32_t len)94 HITLS_TrustedCANode *ParseDN(const uint8_t *data, uint32_t len)
95 {
96     HITLS_TrustedCANode *dnNode = (HITLS_TrustedCANode *)BSL_SAL_Calloc(1u, sizeof(HITLS_TrustedCANode));
97     if (dnNode == NULL) {
98         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
99         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15461, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
100             "parse CA RDN error, out of memory.", 0, 0, 0, 0);
101         return NULL;
102     }
103     dnNode->caType = HITLS_TRUSTED_CA_X509_NAME;
104     dnNode->data = BSL_SAL_Dump(data, len);
105     if (dnNode->data == NULL) {
106         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
107         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15462, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
108             "parse CA RDN error, dump %u bytes data fail.", len, 0, 0, 0);
109         BSL_SAL_FREE(dnNode);
110         return NULL;
111     }
112     dnNode->dataSize = len;
113     return dnNode;
114 }
115 
ParseDNList(const uint8_t * data,uint32_t len)116 HITLS_TrustedCAList *ParseDNList(const uint8_t *data, uint32_t len)
117 {
118     int32_t ret;
119     uint32_t dnLen;
120     uint32_t offset = 0u;
121     uint32_t distinguishedNamesLen = len;
122     HITLS_TrustedCANode *tmpNode = NULL;
123 
124     HITLS_TrustedCAList *newCaList = BSL_LIST_New(sizeof(HITLS_TrustedCANode *));
125     if (newCaList == NULL) {
126         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
127         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15547, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
128             "malloc CA List fail.", 0, 0, 0, 0);
129         return NULL;
130     }
131 
132     while (distinguishedNamesLen > sizeof(uint16_t)) {
133         /* Parse the DN length */
134         dnLen = BSL_ByteToUint16(&data[offset]);
135         offset += sizeof(uint16_t);
136         /* Check whether the DN length is valid. */
137         if ((dnLen == 0) || dnLen > (len - offset)) {
138             BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN);
139             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15464, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
140                 "parse CA list error, distinguished name Length = %u, left len = %u.", dnLen, len - offset, 0, 0);
141             goto ERR;
142         }
143         tmpNode = ParseDN(&data[offset], dnLen);
144         if (tmpNode == NULL) {
145             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16947, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
146                 "ParseDN fail", 0, 0, 0, 0);
147             goto ERR;
148         }
149         ret = BSL_LIST_AddElement(newCaList, tmpNode, BSL_LIST_POS_END);
150         if (ret != 0) {
151             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16948, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
152                 "AddElement fail", 0, 0, 0, 0);
153             BSL_SAL_FREE(tmpNode->data);
154             BSL_SAL_FREE(tmpNode);
155             goto ERR;
156         }
157         /* Offset to the next DN data block */
158         offset += dnLen;
159         distinguishedNamesLen = len - offset;
160     }
161 
162     if (distinguishedNamesLen != 0) {
163         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16949, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
164             "distinguishedNamesLen != 0", 0, 0, 0, 0);
165         goto ERR;
166     }
167 
168     return newCaList;
169 ERR:
170     FreeDNList(newCaList);
171     return NULL;
172 }
173 
174 // Parse the identification name field in the certificate request packet.
ParseDistinguishedName(ParsePacket * pkt,CertificateRequestMsg * msg)175 static int32_t ParseDistinguishedName(ParsePacket *pkt, CertificateRequestMsg *msg)
176 {
177     /* An extension of the same type has already been resolved */
178     if (msg->haveDistinguishedName == true) {
179         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_DUPLICATE_EXTENDED_MSG, BINLOG_ID16950,
180             BINGLOG_STR("DistinguishedName repeated"), ALERT_ILLEGAL_PARAMETER);
181     }
182 
183     /* Obtain the DN list length */
184     uint16_t distinguishedNamesLen = 0;
185     const char *logStr = BINGLOG_STR("parse distinguishedNamesLen fail.");
186     int32_t ret = ParseBytesToUint16(pkt, &distinguishedNamesLen);
187     if (ret != HITLS_SUCCESS) {
188         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15465, logStr, ALERT_DECODE_ERROR);
189     }
190 
191     if (distinguishedNamesLen != (pkt->bufLen - *pkt->bufOffset)) {
192         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15466, logStr, ALERT_DECODE_ERROR);
193     }
194 
195     if (distinguishedNamesLen > 0u) {
196         msg->caList = ParseDNList(&pkt->buf[*pkt->bufOffset], distinguishedNamesLen);
197         if (msg->caList == NULL) {
198             return ParseErrorProcess(pkt->ctx, HITLS_PARSE_CA_LIST_ERR, BINLOG_ID16951,
199                 BINGLOG_STR("ParseDNList fail"), ALERT_DECODE_ERROR);
200         }
201         *pkt->bufOffset += distinguishedNamesLen;
202     }
203 
204     msg->haveDistinguishedName = true;
205     return HITLS_SUCCESS;
206 }
207 #if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
208 // Parse the certificate type field in the certificate request message.
ParseClientCertificateType(ParsePacket * pkt,CertificateRequestMsg * msg)209 static int32_t ParseClientCertificateType(ParsePacket *pkt, CertificateRequestMsg *msg)
210 {
211     const char *logStr = BINGLOG_STR("parse certTypesSize fail.");
212     /* Obtain the certificate type length */
213     int32_t ret = ParseBytesToUint8(pkt, &msg->certTypesSize);
214     if (ret != HITLS_SUCCESS) {
215         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15455, logStr, ALERT_DECODE_ERROR);
216     }
217     if (((uint32_t)msg->certTypesSize > (pkt->bufLen - *pkt->bufOffset)) || (msg->certTypesSize == 0u)) {
218         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15456, logStr, ALERT_DECODE_ERROR);
219     }
220 
221     /* Obtain the certificate type */
222     BSL_SAL_FREE(msg->certTypes);
223     msg->certTypes = BSL_SAL_Dump(&pkt->buf[*pkt->bufOffset], msg->certTypesSize);
224     if (msg->certTypes == NULL) {
225         return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15457,
226             BINGLOG_STR("certTypes malloc fail"), ALERT_UNKNOWN);
227     }
228     *pkt->bufOffset += msg->certTypesSize;
229 
230     return HITLS_SUCCESS;
231 }
232 
ParseCertificateRequest(TLS_Ctx * ctx,const uint8_t * buf,uint32_t bufLen,HS_Msg * hsMsg)233 int32_t ParseCertificateRequest(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg)
234 {
235     uint32_t bufOffset = 0;
236     CertificateRequestMsg *msg = &hsMsg->body.certificateReq;
237     ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = bufLen, .bufOffset = &bufOffset};
238 
239     int32_t ret = ParseClientCertificateType(&pkt, msg);
240     if (ret != HITLS_SUCCESS) {
241         return ret;
242     }
243 
244 #if defined(HITLS_TLS_PROTO_TLS12) || defined(HITLS_TLS_PROTO_DTLS12)
245     if (pkt.ctx->negotiatedInfo.version >= HITLS_VERSION_TLS12) {
246         ret = ParseSignatureAndHashAlgo(&pkt, msg);
247         if (ret != HITLS_SUCCESS) {
248             return ret;
249         }
250     }
251 #endif /* HITLS_TLS_PROTO_TLS12 || HITLS_TLS_PROTO_DTLS12 */
252     return ParseDistinguishedName(&pkt, msg);
253 }
254 #endif /* HITLS_TLS_PROTO_TLS_BASIC || HITLS_TLS_PROTO_DTLS12 */
255 
256 #ifdef HITLS_TLS_PROTO_TLS13
257 
258 
ParseCertificateRequestExBody(TLS_Ctx * ctx,uint16_t extMsgType,const uint8_t * buf,uint32_t extMsgLen,CertificateRequestMsg * msg)259 static int32_t ParseCertificateRequestExBody(TLS_Ctx *ctx, uint16_t extMsgType, const uint8_t *buf, uint32_t extMsgLen,
260     CertificateRequestMsg *msg)
261 {
262     uint32_t bufOffset = 0u;
263     ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = extMsgLen, .bufOffset = &bufOffset};
264     switch (extMsgType) {
265         case HS_EX_TYPE_SIGNATURE_ALGORITHMS:
266             return ParseSignatureAndHashAlgo(&pkt, msg);
267         case HS_EX_TYPE_CERTIFICATE_AUTHORITIES:
268             return ParseDistinguishedName(&pkt, msg);
269         default:
270             break;
271     }
272 #ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
273     if (IsParseNeedCustomExtensions(CUSTOM_EXT_FROM_CTX(ctx), extMsgType, HITLS_EX_TYPE_TLS1_3_CERTIFICATE_REQUEST)) {
274         return ParseCustomExtensions(pkt.ctx, pkt.buf + *pkt.bufOffset, extMsgType, extMsgLen,
275             HITLS_EX_TYPE_TLS1_3_CERTIFICATE_REQUEST, NULL, 0);
276     }
277 #endif /* HITLS_TLS_FEATURE_CUSTOM_EXTENSION */
278     return HITLS_SUCCESS;
279 }
280 
ParseTls13CertificateRequestExtensions(ParsePacket * pkt,CertificateRequestMsg * msg)281 int32_t ParseTls13CertificateRequestExtensions(ParsePacket *pkt, CertificateRequestMsg *msg)
282 {
283     if (pkt->bufLen - *pkt->bufOffset == 0u) {
284         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15472,
285             BINGLOG_STR("the extension len of tls1.3 can not be 0"), ALERT_DECODE_ERROR);
286     }
287 
288     /* Parse the extended packet on the server */
289     while (*pkt->bufOffset < pkt->bufLen) {
290         uint16_t extMsgType = HS_EX_TYPE_END;
291         uint32_t extMsgLen = 0u;
292         int32_t ret =
293             ParseExHeader(pkt->ctx, &pkt->buf[*pkt->bufOffset], pkt->bufLen - *pkt->bufOffset, &extMsgType, &extMsgLen);
294         if (ret != HITLS_SUCCESS) {
295             return ret;
296         }
297         *pkt->bufOffset += HS_EX_HEADER_LEN;
298         uint32_t extensionId = HS_GetExtensionTypeId(extMsgType);
299         ret = CheckForDuplicateExtension(msg->extensionTypeMask, extensionId, pkt->ctx);
300         if (ret != HITLS_SUCCESS) {
301             return ret;
302         }
303         msg->extensionTypeMask |= 1ULL << extensionId;
304         ret = ParseCertificateRequestExBody(pkt->ctx, extMsgType, &pkt->buf[*pkt->bufOffset], extMsgLen, msg);
305         if (ret != HITLS_SUCCESS) {
306             return ret;
307         }
308         *pkt->bufOffset += extMsgLen;
309     }
310 
311     /* The extended content is the last field in the CertificateRequest packet. No further data should be displayed. If
312      * the parsed length is inconsistent with the cache length, an error code is returned */
313     if (*pkt->bufOffset != pkt->bufLen) {
314         return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15473,
315             BINGLOG_STR("extension len error"), ALERT_DECODE_ERROR);
316     }
317 
318     return HITLS_SUCCESS;
319 }
320 
Tls13ParseCertificateRequest(TLS_Ctx * ctx,const uint8_t * buf,uint32_t bufLen,HS_Msg * hsMsg)321 int32_t Tls13ParseCertificateRequest(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg)
322 {
323     uint32_t bufOffset = 0;
324     CertificateRequestMsg *msg = &hsMsg->body.certificateReq;
325     ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = bufLen, .bufOffset = &bufOffset};
326 
327     /* Obtain the certificate_request_context_length */
328     uint8_t certReqCtxLen = 0;
329     int32_t ret = ParseBytesToUint8(&pkt, &certReqCtxLen);
330     if (ret != HITLS_SUCCESS) {
331         return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16130,
332             BINGLOG_STR("tls13 certReq length error"), ALERT_DECODE_ERROR);
333     }
334     msg->certificateReqCtxSize = (uint32_t)certReqCtxLen;
335 
336     /* If the message length is incorrect, an error code is returned. */
337     if (*pkt.bufOffset + certReqCtxLen + sizeof(uint16_t) > pkt.bufLen) {
338         return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16962,
339             BINGLOG_STR("certReq length err"), ALERT_DECODE_ERROR);
340     }
341 
342     /* Obtain the certificate_request_context value */
343     if (certReqCtxLen > 0) {
344         msg->certificateReqCtx = BSL_SAL_Calloc(certReqCtxLen, sizeof(uint8_t));
345         if (msg->certificateReqCtx == NULL) {
346             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16963, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Calloc err", 0, 0, 0, 0);
347             return HITLS_MEMALLOC_FAIL;
348         }
349         (void)memcpy_s(msg->certificateReqCtx, certReqCtxLen, &pkt.buf[*pkt.bufOffset], certReqCtxLen);
350         *pkt.bufOffset += certReqCtxLen;
351     }
352 
353     /* Obtain the extended message length */
354     uint16_t exMsgLen = BSL_ByteToUint16(&pkt.buf[*pkt.bufOffset]);
355     *pkt.bufOffset += sizeof(uint16_t);
356 
357     /* If the buffer length does not match the extended length, an error code is returned */
358     if (exMsgLen != (pkt.bufLen - *pkt.bufOffset)) {
359         BSL_SAL_FREE(msg->certificateReqCtx);
360         msg->certificateReqCtxSize = 0;
361         return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15474,
362             BINGLOG_STR("tls13 external message length error"), ALERT_DECODE_ERROR);
363     }
364 
365     ret = ParseTls13CertificateRequestExtensions(&pkt, msg);
366     if (ret != HITLS_SUCCESS) {
367         CleanCertificateRequest(msg);
368     }
369     return ret;
370 }
371 #endif /* HITLS_TLS_PROTO_TLS13 */
CleanCertificateRequest(CertificateRequestMsg * msg)372 void CleanCertificateRequest(CertificateRequestMsg *msg)
373 {
374     if (msg == NULL) {
375         return;
376     }
377 
378     BSL_SAL_FREE(msg->certTypes);
379     BSL_SAL_FREE(msg->signatureAlgorithms);
380 #ifdef HITLS_TLS_PROTO_TLS13
381     BSL_SAL_FREE(msg->certificateReqCtx);
382     BSL_SAL_FREE(msg->signatureAlgorithmsCert);
383 #endif /* HITLS_TLS_PROTO_TLS13 */
384     FreeDNList(msg->caList);
385     msg->caList = NULL;
386     return;
387 }
388 #endif /* HITLS_TLS_HOST_CLIENT */