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_SERVER) && defined(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 "bsl_bytes.h"
24 #include "hitls_error.h"
25 #include "pack_common.h"
26 #include "tls.h"
27 #include "hs_ctx.h"
28 #include "custom_extensions.h"
29
30 #if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
PackNewSessionTicket(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)31 int32_t PackNewSessionTicket(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
32 {
33 uint32_t offset = 0u;
34
35 HS_Ctx *hsCtx = ctx->hsCtx;
36
37 if (bufLen < (sizeof(uint32_t) + sizeof(uint16_t) + hsCtx->ticketSize)) {
38 return PackBufLenError(BINLOG_ID16054, BINGLOG_STR("NewSessionTicket"));
39 }
40
41 /* hsCtx->ticket is the encrypted ticket content, which corresponds to the ticket field in the protocol */
42 BSL_Uint32ToByte(hsCtx->ticketLifetimeHint, &buf[offset]);
43 offset += sizeof(uint32_t);
44 BSL_Uint16ToByte((uint16_t)hsCtx->ticketSize, &buf[offset]);
45 offset += sizeof(uint16_t);
46
47 /* rfc5077 3.3. NewSessionTicket Handshake Message
48 If the server determines that it does not want to include a ticket after including the SessionTicket extension
49 in the ServerHello, it sends a zero-length ticket in the NewSessionTicket handshake message. */
50 if (hsCtx->ticketSize != 0) {
51 (void)memcpy_s(&buf[offset], bufLen - offset, hsCtx->ticket, hsCtx->ticketSize);
52 }
53
54 *usedLen = offset + hsCtx->ticketSize;
55
56 return HITLS_SUCCESS;
57 }
58 #endif /* HITLS_TLS_PROTO_TLS_BASIC || HITLS_TLS_PROTO_DTLS12 */
59 #ifdef HITLS_TLS_PROTO_TLS13
Tls13PackNewSessionTicket(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)60 int32_t Tls13PackNewSessionTicket(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
61 {
62 uint32_t ticketAgeAdd = 0u;
63 uint32_t offset = 0u;
64 uint32_t exLen = 0;
65
66 HS_Ctx *hsCtx = ctx->hsCtx;
67
68 /* size of ticketLifetime + size of ticketAgeAdd + size of ticketNonce + size of nextTicketNonce + size of ticket + ticketSize */
69 if (bufLen < (sizeof(uint32_t) + sizeof(uint32_t) +
70 sizeof(uint8_t) + sizeof(hsCtx->nextTicketNonce) +
71 sizeof(uint16_t) + hsCtx->ticketSize)) {
72 return PackBufLenError(BINLOG_ID16055, BINGLOG_STR("NewSessionTicket"));
73 }
74
75 BSL_Uint32ToByte(hsCtx->ticketLifetimeHint, &buf[offset]);
76 offset += sizeof(uint32_t);
77
78 ticketAgeAdd = hsCtx->ticketAgeAdd;
79 BSL_Uint32ToByte(ticketAgeAdd, &buf[offset]);
80 offset += sizeof(uint32_t);
81
82 /* The TicketNonce length field occupies one byte and the length value is 8. */
83 buf[offset] = sizeof(hsCtx->nextTicketNonce);
84 offset += sizeof(uint8_t);
85
86 BSL_Uint64ToByte(hsCtx->nextTicketNonce, &buf[offset]);
87 offset += sizeof(hsCtx->nextTicketNonce);
88
89 BSL_Uint16ToByte((uint16_t)hsCtx->ticketSize, &buf[offset]);
90 offset += sizeof(uint16_t);
91
92 /* In TLS1.3, no empty new session ticket is sent
93 because we ensure that hsCtx->ticketSize is not empty at the invoking point.
94 Therefore, you do not need to check whether hsCtx->ticketSize is empty. */
95 (void)memcpy_s(&buf[offset], bufLen - offset, hsCtx->ticket, hsCtx->ticketSize);
96 offset += hsCtx->ticketSize;
97
98 /* extension is not supported currently, set the total extension length to 0 */
99 /* total extension length */
100 if (bufLen < (offset + sizeof(uint16_t))) {
101 return PackBufLenError(BINLOG_ID16049, BINGLOG_STR("NewSessionTicket"));
102 }
103 #ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
104 if (IsPackNeedCustomExtensions(CUSTOM_EXT_FROM_CTX(ctx), HITLS_EX_TYPE_TLS1_3_NEW_SESSION_TICKET)) {
105 int32_t ret = PackCustomExtensions(ctx, &buf[offset + sizeof(uint16_t)], bufLen - offset - sizeof(uint16_t),
106 &exLen, HITLS_EX_TYPE_TLS1_3_NEW_SESSION_TICKET, NULL, 0);
107 if (ret != HITLS_SUCCESS) {
108 return ret;
109 }
110 }
111 #endif /* HITLS_TLS_FEATURE_CUSTOM_EXTENSION */
112
113 if (bufLen < (offset + sizeof(uint16_t) + exLen)) {
114 return PackBufLenError(BINLOG_ID16049, BINGLOG_STR("NewSessionTicket"));
115 }
116 BSL_Uint16ToByte(exLen, &buf[offset]);
117 offset += exLen + sizeof(uint16_t);
118
119 *usedLen = offset;
120 return HITLS_SUCCESS;
121 }
122 #endif /* HITLS_TLS_PROTO_TLS13 */
123 #endif /* HITLS_TLS_HOST_SERVER && HITLS_TLS_FEATURE_SESSION_TICKET */
124