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 #if defined(HITLS_TLS_HOST_CLIENT) && defined(HITLS_TLS_FEATURE_SESSION_TICKET)
17 #include "tls_binlog_id.h"
18 #include "bsl_log_internal.h"
19 #include "bsl_log.h"
20 #include "bsl_err_internal.h"
21 #include "bsl_sal.h"
22 #include "bsl_bytes.h"
23 #include "hitls_error.h"
24 #include "tls.h"
25 #include "hs_msg.h"
26 #include "hs_common.h"
27 #include "hs_extensions.h"
28 #include "parse_msg.h"
29 #include "parse_common.h"
30 #include "parse_extensions.h"
31 #ifdef HITLS_TLS_PROTO_TLS13
ParseTicketNonce(ParsePacket * pkt,NewSessionTicketMsg * msg)32 static int32_t ParseTicketNonce(ParsePacket *pkt, NewSessionTicketMsg *msg)
33 {
34 uint8_t ticketNonceSize = 0;
35 const char *logStr = BINGLOG_STR("ParseOneByteLengthField fail");
36 int32_t ret = ParseOneByteLengthField(pkt, &ticketNonceSize, &msg->ticketNonce);
37 if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
38 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID17010, logStr, ALERT_DECODE_ERROR);
39 } else if (ret == HITLS_MEMALLOC_FAIL) {
40 return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID17011, logStr, ALERT_INTERNAL_ERROR);
41 }
42
43 if (ticketNonceSize == 0) {
44 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID17012, logStr, ALERT_DECODE_ERROR);
45 }
46
47 msg->ticketNonceSize = (uint32_t)ticketNonceSize;
48 return HITLS_SUCCESS;
49 }
50 #endif /* HITLS_TLS_PROTO_TLS13 */
ParseTicket(ParsePacket * pkt,NewSessionTicketMsg * msg)51 static int32_t ParseTicket(ParsePacket *pkt, NewSessionTicketMsg *msg)
52 {
53 bool isTls13 = (pkt->ctx->negotiatedInfo.version == HITLS_VERSION_TLS13);
54 uint16_t ticketSize = 0;
55 /* rfc5077 3.3
56 If the server does not include a ticket after including the SessionTicket extension in the ServerHello,
57 it sends a zero-length ticket in the NewSessionTicket handshake message */
58 int32_t ret = ParseTwoByteLengthField(pkt, &ticketSize, &msg->ticket);
59 if (ret == HITLS_PARSE_INVALID_MSG_LEN) {
60 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16012,
61 BINGLOG_STR("parse ticketSize failed."), ALERT_DECODE_ERROR);
62 } else if (ret == HITLS_MEMALLOC_FAIL) {
63 return ParseErrorProcess(pkt->ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID15968,
64 BINGLOG_STR("malloc ticket failed."), ALERT_UNKNOWN);
65 }
66
67 /* TLS1.3 does not allow the ticket length to be 0 */
68 if ((isTls13 && (ticketSize == 0)) ||
69 (!isTls13 && (pkt->bufLen != *pkt->bufOffset))) {
70 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15967, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
71 "parse sesionticket message failed, bufLen %u, ticket size %u.", pkt->bufLen, ticketSize, 0, 0);
72 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, 0, NULL, ALERT_DECODE_ERROR);
73 }
74
75 msg->ticketSize = (uint32_t)ticketSize;
76 return HITLS_SUCCESS;
77 }
78
ParseNewSessionTicketExtension(TLS_Ctx * ctx,const uint8_t * buf,uint32_t bufLen,NewSessionTicketMsg * msg)79 int32_t ParseNewSessionTicketExtension(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, NewSessionTicketMsg *msg)
80 {
81 uint32_t bufOffset = 0u;
82 int32_t ret = HITLS_SUCCESS;
83
84 while (bufOffset < bufLen) {
85 uint32_t extMsgLen = 0u;
86 uint16_t extMsgType = HS_EX_TYPE_END;
87 ret = ParseExHeader(ctx, &buf[bufOffset], bufLen - bufOffset, &extMsgType, &extMsgLen);
88 if (ret != HITLS_SUCCESS) {
89 return ret;
90 }
91 bufOffset += HS_EX_HEADER_LEN;
92
93 if (bufLen - bufOffset >= extMsgLen) {
94 uint32_t hsExTypeId = HS_GetExtensionTypeId(extMsgType);
95 if (hsExTypeId != HS_EX_TYPE_ID_UNRECOGNIZED
96 #ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
97 || !IsParseNeedCustomExtensions(CUSTOM_EXT_FROM_CTX(ctx),
98 extMsgType, HITLS_EX_TYPE_TLS1_3_NEW_SESSION_TICKET)
99 #endif /* HITLS_TLS_FEATURE_CUSTOM_EXTENSION */
100 ) {
101 msg->extensionTypeMask |= 1ULL << hsExTypeId;
102 }
103
104 #ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
105 if (IsParseNeedCustomExtensions(CUSTOM_EXT_FROM_CTX(ctx),
106 extMsgType, HITLS_EX_TYPE_TLS1_3_NEW_SESSION_TICKET)) {
107 ret = ParseCustomExtensions(ctx, buf + bufOffset, extMsgType, extMsgLen,
108 HITLS_EX_TYPE_TLS1_3_NEW_SESSION_TICKET, NULL, 0);
109 if (ret != HITLS_SUCCESS) {
110 return ret;
111 }
112 }
113 #endif /* HITLS_TLS_FEATURE_CUSTOM_EXTENSION */
114 bufOffset += extMsgLen;
115 } else {
116 return HITLS_PARSE_INVALID_MSG_LEN;
117 }
118 }
119
120 if (bufOffset != bufLen) {
121 return ParseErrorProcess(ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15206,
122 BINGLOG_STR("parse extension failed."), ALERT_DECODE_ERROR);
123 }
124
125 return HITLS_SUCCESS;
126 }
127
ParseNewSessionTicketExtensions(ParsePacket * pkt,NewSessionTicketMsg * msg)128 static int32_t ParseNewSessionTicketExtensions(ParsePacket *pkt, NewSessionTicketMsg *msg)
129 {
130 uint16_t exMsgLen = 0;
131 const char *logStr = BINGLOG_STR("parse extension length failed.");
132 int32_t ret = ParseBytesToUint16(pkt, &exMsgLen);
133 if (ret != HITLS_SUCCESS) {
134 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15788,
135 logStr, ALERT_DECODE_ERROR);
136 }
137
138 if (exMsgLen != (pkt->bufLen - *pkt->bufOffset)) {
139 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15789,
140 logStr, ALERT_DECODE_ERROR);
141 }
142
143 if (exMsgLen == 0u) {
144 return HITLS_SUCCESS;
145 }
146 return ParseNewSessionTicketExtension(pkt->ctx, &pkt->buf[*pkt->bufOffset], exMsgLen, msg);
147 }
148
ParseNewSessionTicket(TLS_Ctx * ctx,const uint8_t * buf,uint32_t bufLen,HS_Msg * hsMsg)149 int32_t ParseNewSessionTicket(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg)
150 {
151 uint32_t bufOffset = 0u;
152 NewSessionTicketMsg *msg = &hsMsg->body.newSessionTicket;
153 ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = bufLen, .bufOffset = &bufOffset};
154
155 const char *logStr = BINGLOG_STR("parse sesionticket len fail.");
156 int32_t ret = ParseBytesToUint32(&pkt, &msg->ticketLifetimeHint);
157 if (ret != HITLS_SUCCESS) {
158 return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15966, logStr, ALERT_DECODE_ERROR);
159 }
160 #ifdef HITLS_TLS_PROTO_TLS13
161 if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) {
162 uint32_t ticketAgeAdd = 0;
163 ret = ParseBytesToUint32(&pkt, &ticketAgeAdd);
164 if (ret != HITLS_SUCCESS) {
165 return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16013, logStr, ALERT_DECODE_ERROR);
166 }
167 msg->ticketAgeAdd = ticketAgeAdd;
168
169 ret = ParseTicketNonce(&pkt, msg);
170 if (ret != HITLS_SUCCESS) {
171 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16014, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
172 "parse ticket nonce failed.", 0, 0, 0, 0);
173 return ret;
174 }
175 }
176 #endif /* HITLS_TLS_PROTO_TLS13 */
177 ret = ParseTicket(&pkt, msg);
178 if (ret != HITLS_SUCCESS) {
179 return ret;
180 }
181
182 #ifdef HITLS_TLS_PROTO_TLS13
183 if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) {
184 ret = ParseNewSessionTicketExtensions(&pkt, msg);
185 if (ret != HITLS_SUCCESS) {
186 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17352, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
187 "parse ticket extensions failed.", 0, 0, 0, 0);
188 return ret;
189 }
190 }
191 #endif /* HITLS_TLS_PROTO_TLS13 */
192 return HITLS_SUCCESS;
193 }
194
CleanNewSessionTicket(NewSessionTicketMsg * msg)195 void CleanNewSessionTicket(NewSessionTicketMsg *msg)
196 {
197 if (msg == NULL) {
198 return;
199 }
200
201 BSL_SAL_FREE(msg->ticketNonce);
202 BSL_SAL_FREE(msg->ticket);
203 msg->ticketSize = 0;
204 msg->ticketNonceSize = 0;
205 return;
206 }
207 #endif /* HITLS_TLS_HOST_CLIENT || HITLS_TLS_PROTO_TLS13 */
208