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