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_FEATURE_SESSION_TICKET) && defined(HITLS_TLS_HOST_SERVER)
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_bytes.h"
23 #include "bsl_sal.h"
24 #include "hitls_error.h"
25 #include "rec.h"
26 #include "hs_ctx.h"
27 #include "hs_kx.h"
28 #include "hs_common.h"
29 #include "session_mgr.h"
30 #include "pack.h"
31 #include "send_process.h"
32
33 #ifdef HITLS_TLS_PROTO_TLS13
34 #define HITLS_ONE_WEEK_SECONDS (604800)
35 #endif
36 #ifdef HITLS_TLS_PROTO_TLS_BASIC
SendNewSessionTicketProcess(TLS_Ctx * ctx)37 int32_t SendNewSessionTicketProcess(TLS_Ctx *ctx)
38 {
39 int32_t ret;
40 HS_Ctx *hsCtx = ctx->hsCtx;
41 TLS_SessionMgr *sessMgr = ctx->config.tlsConfig.sessMgr;
42
43 /* determine whether to assemble a message */
44 if (hsCtx->msgLen == 0) {
45 hsCtx->ticketLifetimeHint = (uint32_t)SESSMGR_GetTimeout(sessMgr);
46 BSL_SAL_FREE(hsCtx->ticket);
47 hsCtx->ticketSize = 0;
48 ret = SESSMGR_EncryptSessionTicket(ctx, sessMgr, ctx->session, &hsCtx->ticket, &hsCtx->ticketSize);
49 if (ret != HITLS_SUCCESS) {
50 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16046, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
51 "SESSMGR_EncryptSessionTicket return fail when send new session ticket msg.", 0, 0, 0, 0);
52 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
53 return ret;
54 }
55 /* assemble message */
56 ret = HS_PackMsg(ctx, NEW_SESSION_TICKET, hsCtx->msgBuf, REC_MAX_PLAIN_LENGTH, &hsCtx->msgLen);
57 if (ret != HITLS_SUCCESS) {
58 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15978, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
59 "server pack new session ticket msg fail.", 0, 0, 0, 0);
60 return ret;
61 }
62 }
63
64 /* writing Handshake message */
65 ret = HS_SendMsg(ctx);
66 if (ret != HITLS_SUCCESS) {
67 return ret;
68 }
69
70 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15979, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
71 "send new session ticket msg success.", 0, 0, 0, 0);
72 /* update the state machine */
73 return HS_ChangeState(ctx, TRY_SEND_CHANGE_CIPHER_SPEC);
74 }
75 #endif /* HITLS_TLS_PROTO_TLS_BASIC */
76 #ifdef HITLS_TLS_PROTO_TLS13
Tls13TicketGenerateConfigSession(TLS_Ctx * ctx,HITLS_Session ** sessionPtr,uint8_t * resumePsk,uint32_t hashLen)77 static int32_t Tls13TicketGenerateConfigSession(TLS_Ctx *ctx, HITLS_Session **sessionPtr,
78 uint8_t *resumePsk, uint32_t hashLen)
79 {
80 int32_t ret = HITLS_SUCCESS;
81 HITLS_Session *newSession = NULL;
82 HS_Ctx *hsCtx = ctx->hsCtx;
83 newSession = SESS_Copy(ctx->session);
84 if (newSession == NULL) {
85 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16050, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
86 "copy session info failed.", 0, 0, 0, 0);
87 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
88 return HITLS_MEMALLOC_FAIL;
89 }
90
91 SESS_SetStartTime(newSession, (uint64_t)BSL_SAL_CurrentSysTimeGet());
92 HITLS_SESS_SetTimeout(newSession, (uint64_t)hsCtx->ticketLifetimeHint);
93 HITLS_SESS_SetMasterKey(newSession, resumePsk, hashLen);
94 ret = SAL_CRYPT_Rand(LIBCTX_FROM_CTX(ctx), (uint8_t *)&hsCtx->ticketAgeAdd, sizeof(hsCtx->ticketAgeAdd));
95 if (ret != HITLS_SUCCESS) {
96 HITLS_SESS_Free(newSession);
97 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16047, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
98 "generate ticket_age_add value fail.", 0, 0, 0, 0);
99 return ret;
100 }
101 SESS_SetTicketAgeAdd(newSession, hsCtx->ticketAgeAdd);
102 *sessionPtr = newSession;
103 return HITLS_SUCCESS;
104 }
105
Tls13TicketGenerate(TLS_Ctx * ctx)106 int32_t Tls13TicketGenerate(TLS_Ctx *ctx)
107 {
108 int32_t ret;
109 HITLS_Session *newSession = NULL;
110 HS_Ctx *hsCtx = ctx->hsCtx;
111 TLS_SessionMgr *sessMgr = ctx->config.tlsConfig.sessMgr;
112
113 uint64_t timeout = SESSMGR_GetTimeout(sessMgr);
114 /* TLS1.3 timeout period cannot exceed 604800 seconds, that is, seven days. */
115 if (timeout > HITLS_ONE_WEEK_SECONDS) {
116 hsCtx->ticketLifetimeHint = HITLS_ONE_WEEK_SECONDS;
117 } else {
118 hsCtx->ticketLifetimeHint = (uint32_t)timeout;
119 }
120
121 BSL_SAL_FREE(hsCtx->ticket);
122 hsCtx->ticketSize = 0;
123 uint8_t resumePsk[MAX_DIGEST_SIZE] = {0};
124 uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg);
125 if (hashLen == 0) {
126 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17154, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "DigestSize err", 0, 0, 0, 0);
127 return HITLS_CRYPT_ERR_DIGEST;
128 }
129
130 uint8_t ticketNonce[sizeof(hsCtx->nextTicketNonce)] = {0};
131 BSL_Uint64ToByte(hsCtx->nextTicketNonce, ticketNonce);
132 ret = HS_TLS13DeriveResumePsk(ctx, ticketNonce, sizeof(ticketNonce), resumePsk, hashLen);
133 if (ret != HITLS_SUCCESS) {
134 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17155, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
135 "DeriveResumePsk fail", 0, 0, 0, 0);
136 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
137 (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE);
138 return ret;
139 }
140 ret = Tls13TicketGenerateConfigSession(ctx, &newSession, resumePsk, hashLen);
141 if (ret != HITLS_SUCCESS) {
142 (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE);
143 return ret;
144 }
145
146 ret = SESSMGR_EncryptSessionTicket(ctx, sessMgr, newSession, &hsCtx->ticket, &hsCtx->ticketSize);
147 if (ret != HITLS_SUCCESS) {
148 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16051, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
149 "Encrypt Session Ticket failed.", 0, 0, 0, 0);
150 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
151 HITLS_SESS_Free(newSession);
152 (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE);
153 return ret;
154 }
155
156 HITLS_SESS_Free(ctx->session);
157 ctx->session = newSession;
158 (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE);
159 return HITLS_SUCCESS;
160 }
161
Tls13SendNewSessionTicketProcess(TLS_Ctx * ctx)162 int32_t Tls13SendNewSessionTicketProcess(TLS_Ctx *ctx)
163 {
164 int32_t ret;
165 HS_Ctx *hsCtx = ctx->hsCtx;
166
167 /* determine whether to assemble a message */
168 if (hsCtx->msgLen == 0) {
169 ret = Tls13TicketGenerate(ctx);
170 if (ret != HITLS_SUCCESS) {
171 return ret;
172 }
173
174 /* assemble message */
175 ret = HS_PackMsg(ctx, NEW_SESSION_TICKET, hsCtx->msgBuf, REC_MAX_PLAIN_LENGTH, &hsCtx->msgLen);
176 if (ret != HITLS_SUCCESS) {
177 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16052, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
178 "server pack new session ticket msg fail.", 0, 0, 0, 0);
179 return ret;
180 }
181 }
182
183 /* After the handshake message is written and sent successfully, hsCtx->msgLen is set to 0. */
184 ret = HS_SendMsg(ctx);
185 if (ret != HITLS_SUCCESS) {
186 return ret;
187 }
188
189 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16053, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
190 "send new session ticket msg success.", 0, 0, 0, 0);
191
192 hsCtx->sentTickets++;
193 hsCtx->nextTicketNonce++;
194 /* When the value of ticketNums is greater than 0, a ticket is sent after the session is resumed. */
195 if (hsCtx->sentTickets >= ctx->config.tlsConfig.ticketNums || ctx->negotiatedInfo.isResume) {
196 return HS_ChangeState(ctx, TLS_CONNECTED);
197 }
198 return HS_ChangeState(ctx, TRY_SEND_NEW_SESSION_TICKET);
199 }
200 #endif /* HITLS_TLS_PROTO_TLS13 */
201 #endif /* HITLS_TLS_FEATURE_SESSION_TICKET && HITLS_TLS_HOST_SERVER */