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 */