• 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_FEATURE_SESSION_TICKET
17 #include <stdint.h>
18 #include "securec.h"
19 #include "tls_binlog_id.h"
20 #include "bsl_log_internal.h"
21 #include "bsl_log.h"
22 #include "bsl_err_internal.h"
23 #include "hitls_error.h"
24 #include "tls.h"
25 #include "hs_ctx.h"
26 #include "hs_common.h"
27 #include "hs_verify.h"
28 #include "hs_msg.h"
29 #include "hs_kx.h"
30 #include "session.h"
31 
UpdateTicket(TLS_Ctx * ctx,NewSessionTicketMsg * msg,uint8_t * psk,uint32_t pskSize)32 static int32_t UpdateTicket(TLS_Ctx *ctx, NewSessionTicketMsg *msg, uint8_t *psk, uint32_t pskSize)
33 {
34     HITLS_Session *newSession = SESS_Copy(ctx->session);
35     if (newSession == NULL) {
36         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
37         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16016, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
38             "copy session info failed.", 0, 0, 0, 0);
39         return HITLS_MEMALLOC_FAIL;
40     }
41 
42     SESS_SetStartTime(newSession, (uint64_t)BSL_SAL_CurrentSysTimeGet());
43     HITLS_SESS_SetTimeout(newSession, msg->ticketLifetimeHint);
44 
45     if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) {
46         SESS_SetTicketAgeAdd(newSession, msg->ticketAgeAdd);
47         HITLS_SESS_SetMasterKey(newSession, psk, pskSize);
48     }
49 
50     int32_t ret = SESS_SetTicket(newSession, msg->ticket, msg->ticketSize);
51     if (ret != HITLS_SUCCESS) {
52         HITLS_SESS_Free(newSession);
53         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16017, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
54             "set ticket failed.", 0, 0, 0, 0);
55         return ret;
56     }
57 
58     HITLS_SESS_Free(ctx->session);
59     ctx->session = newSession;
60 
61     /* The server may send multiple tickets. In this case, each ticket received will be notified to the user through
62      * this callback, so that the client can obtain multiple sessions */
63     if (ctx->globalConfig != NULL && ctx->globalConfig->newSessionCb != NULL) {
64         HITLS_SESS_UpRef(newSession);  // It is convenient for users to take away and needs to be released by users
65         if (ctx->globalConfig->newSessionCb(ctx, newSession) == 0) {
66             /* If the user does not reference the session, the number of reference times decreases by 1 */
67             HITLS_SESS_Free(newSession);
68         }
69     }
70 
71     return HITLS_SUCCESS;
72 }
73 #ifdef HITLS_TLS_PROTO_TLS_BASIC
Tls12ClientRecvNewSeesionTicketProcess(TLS_Ctx * ctx,HS_Msg * hsMsg)74 int32_t Tls12ClientRecvNewSeesionTicketProcess(TLS_Ctx *ctx, HS_Msg *hsMsg)
75 {
76     int32_t ret = HITLS_SUCCESS;
77     HS_Ctx *hsCtx = ctx->hsCtx;
78     /* The processing of the msg is complete when the NewSeesionTick operation is performed */
79     NewSessionTicketMsg *newSessionTicket = &hsMsg->body.newSessionTicket;
80 
81     if (newSessionTicket->ticketLifetimeHint != 0 && newSessionTicket->ticketSize != 0) {
82         if (ctx->negotiatedInfo.isResume == true) {
83             ret = UpdateTicket(ctx, newSessionTicket, NULL, 0);
84             if (ret != HITLS_SUCCESS) {
85                 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
86                 return ret;
87             }
88         } else {
89             /* Saved in the context */
90             hsCtx->ticketLifetimeHint = newSessionTicket->ticketLifetimeHint;
91             hsCtx->ticketSize = newSessionTicket->ticketSize;
92             hsCtx->ticket = newSessionTicket->ticket;
93 
94             newSessionTicket->ticket = NULL;
95             newSessionTicket->ticketSize = 0;
96         }
97     }
98 
99     /* The server verify data needs to be calculated in advance */
100     ret = VERIFY_CalcVerifyData(ctx, false, hsCtx->masterKey, MASTER_SECRET_LEN);
101     if (ret != HITLS_SUCCESS) {
102         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15971, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
103             "client Calculate server finished data error.", 0, 0, 0, 0);
104         ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
105         return ret;
106     }
107 
108     ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY);
109     ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_ACTIVE_CIPHER_SPEC);
110 
111     return HS_ChangeState(ctx, TRY_RECV_FINISH);
112 }
113 #endif /* HITLS_TLS_PROTO_TLS_BASIC */
114 #ifdef HITLS_TLS_PROTO_TLS13
Tls13ClientRecvNewSessionTicketProcess(TLS_Ctx * ctx,HS_Msg * hsMsg)115 int32_t Tls13ClientRecvNewSessionTicketProcess(TLS_Ctx *ctx, HS_Msg *hsMsg)
116 {
117     if (!ctx->isClient) {
118         BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE);
119         BSL_LOG_BINLOG_VARLEN(BINLOG_ID16018, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
120             "Unexpected msg: server recv new session ticket", HS_GetMsgTypeStr(hsMsg->type));
121         ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
122         return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE;
123     }
124 
125     int32_t ret = HITLS_SUCCESS;
126     NewSessionTicketMsg *msg = &hsMsg->body.newSessionTicket;
127 
128     /* If the value is 0, the ticket should be discarded immediately. After the TTO is backed up, the ctx->session field
129      * is empty */
130     if (msg->ticketLifetimeHint == 0 || ctx->session == NULL) {
131         return HS_ChangeState(ctx, TLS_CONNECTED);
132     }
133 
134     uint8_t resumePsk[MAX_DIGEST_SIZE] = {0};
135     uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg);
136     if (hashLen == 0) {
137         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17081, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "DigestSize err", 0, 0, 0, 0);
138         return HITLS_CRYPT_ERR_DIGEST;
139     }
140     ret = HS_TLS13DeriveResumePsk(ctx, msg->ticketNonce, msg->ticketNonceSize, resumePsk, hashLen);
141     if (ret != HITLS_SUCCESS) {
142         (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE);
143         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16015, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
144             "Derive resume psk failed.", 0, 0, 0, 0);
145         return ret;
146     }
147 
148     ret = UpdateTicket(ctx, msg, resumePsk, hashLen);
149     (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE);
150     if (ret != HITLS_SUCCESS) {
151         ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
152         return ret;
153     }
154 
155     return HS_ChangeState(ctx, TLS_CONNECTED);
156 }
157 #endif /* HITLS_TLS_PROTO_TLS13 */
158 #endif /* HITLS_TLS_FEATURE_SESSION_TICKET */