• 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 "tlv.h"
18 #include "bsl_log_internal.h"
19 #include "bsl_log.h"
20 #include "bsl_err_internal.h"
21 #include "tls_binlog_id.h"
22 #include "bsl_bytes.h"
23 #include "bsl_list.h"
24 #include "bsl_sal.h"
25 #include "hitls_error.h"
26 #include "session_type.h"
27 #include "cert_mgr_ctx.h"
28 #include "session_enc.h"
29 #include "cert_method.h"
30 
31 typedef int32_t (*PfuncEncSessionObjFunc)(const HITLS_Session *sess, SessionObjType type, uint8_t *data,
32     uint32_t length, uint32_t *encLen);
33 
34 typedef struct {
35     SessionObjType type;
36     PfuncEncSessionObjFunc func;
37 } SessObjEncFunc;
38 
EncSessObjVersion(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)39 static int32_t EncSessObjVersion(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
40     uint32_t *encLen)
41 {
42     int ret;
43     uint16_t version = sess->version;
44     BSL_Tlv tlv = {0};
45     tlv.type = type;
46     tlv.length = sizeof(version);
47     tlv.value = (uint8_t *)&version;
48 
49     if (data == NULL) {
50         /* If the input parameter is NULL, return the length after encoding. */
51         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
52         return HITLS_SUCCESS;
53     }
54 
55     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
56     if (ret != BSL_SUCCESS) {
57         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_VERSION_FAIL);
58         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15992, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
59             "encode session version fail. ret %d", ret, 0, 0, 0);
60         return HITLS_SESS_ERR_ENC_VERSION_FAIL;
61     }
62 
63     return HITLS_SUCCESS;
64 }
65 
EncSessObjCipherSuite(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)66 static int32_t EncSessObjCipherSuite(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
67     uint32_t *encLen)
68 {
69     int ret;
70     uint16_t cipherSuite = sess->cipherSuite;
71     BSL_Tlv tlv = {0};
72     tlv.type = type;
73     tlv.length = sizeof(cipherSuite);
74     tlv.value = (uint8_t *)&cipherSuite;
75 
76     if (data == NULL) {
77         /* If the input parameter is NULL, return the length after encoding. */
78         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
79         return HITLS_SUCCESS;
80     }
81 
82     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
83     if (ret != BSL_SUCCESS) {
84         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_CIPHER_SUITE_FAIL);
85         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15982, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
86             "encode session cipher suite fail. ret %d", ret, 0, 0, 0);
87         return HITLS_SESS_ERR_ENC_CIPHER_SUITE_FAIL;
88     }
89 
90     return HITLS_SUCCESS;
91 }
92 
EncSessObjMasterSecret(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)93 static int32_t EncSessObjMasterSecret(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
94     uint32_t *encLen)
95 {
96     int ret;
97     BSL_Tlv tlv = {0};
98     tlv.type = type;
99     tlv.length = sess->masterKeySize;
100     tlv.value = (uint8_t *)(uintptr_t)(sess->masterKey);
101 
102     if (data == NULL) {
103         /* If the input parameter is NULL, return the length after encoding. */
104         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
105         return HITLS_SUCCESS;
106     }
107 
108     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
109     if (ret != BSL_SUCCESS) {
110         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_MASTER_SECRET_FAIL);
111         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15983, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
112             "encode session master secret fail. ret %d", ret, 0, 0, 0);
113         return HITLS_SESS_ERR_ENC_MASTER_SECRET_FAIL;
114     }
115 
116     return HITLS_SUCCESS;
117 }
118 
EncSessObjStartTime(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)119 static int32_t EncSessObjStartTime(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
120     uint32_t *encLen)
121 {
122     int ret;
123     uint64_t startTime = sess->startTime;
124     BSL_Tlv tlv = {0};
125     tlv.type = type;
126     tlv.length = sizeof(startTime);
127     tlv.value = (uint8_t *)&startTime;
128 
129     if (data == NULL) {
130         /* If the input parameter is NULL, return the length after encoding. */
131         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
132         return HITLS_SUCCESS;
133     }
134 
135     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
136     if (ret != BSL_SUCCESS) {
137         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_START_TIME_FAIL);
138         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15985, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
139             "encode session start time fail. ret %d", ret, 0, 0, 0);
140         return HITLS_SESS_ERR_ENC_START_TIME_FAIL;
141     }
142 
143     return HITLS_SUCCESS;
144 }
145 
EncSessObjTimeout(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)146 static int32_t EncSessObjTimeout(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
147     uint32_t *encLen)
148 {
149     int ret;
150     uint64_t timeout = sess->timeout;
151     BSL_Tlv tlv = {0};
152     tlv.type = type;
153     tlv.length = sizeof(timeout);
154     tlv.value = (uint8_t *)&timeout;
155 
156     if (data == NULL) {
157         /* If the input parameter is NULL, return the length after encoding. */
158         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
159         return HITLS_SUCCESS;
160     }
161 
162     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
163     if (ret != BSL_SUCCESS) {
164         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_TIME_OUT_FAIL);
165         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15986, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
166             "encode session timeout fail. ret %d", ret, 0, 0, 0);
167         return HITLS_SESS_ERR_ENC_TIME_OUT_FAIL;
168     }
169 
170     return HITLS_SUCCESS;
171 }
172 
173 #ifdef HITLS_TLS_FEATURE_SNI
EncSessObjHostName(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)174 static int32_t EncSessObjHostName(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
175     uint32_t *encLen)
176 {
177     if (sess->hostNameSize == 0) {
178         return HITLS_SUCCESS;
179     }
180 
181     int ret;
182     BSL_Tlv tlv = {0};
183     tlv.type = type;
184     tlv.length = sess->hostNameSize;
185     tlv.value = (uint8_t *)sess->hostName;
186 
187     if (data == NULL) {
188         /* If the input parameter is NULL, return the length after encoding. */
189         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
190         return HITLS_SUCCESS;
191     }
192 
193     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
194     if (ret != BSL_SUCCESS) {
195         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_HOST_NAME_FAIL);
196         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15987, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
197             "encode session host name fail. ret %d", ret, 0, 0, 0);
198         return HITLS_SESS_ERR_ENC_HOST_NAME_FAIL;
199     }
200 
201     return HITLS_SUCCESS;
202 }
203 #endif /* HITLS_TLS_FEATURE_SNI */
204 
EncSessObjSessionIdCtx(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)205 static int32_t EncSessObjSessionIdCtx(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
206     uint32_t *encLen)
207 {
208     if (sess->sessionIdCtxSize == 0) {
209         return HITLS_SUCCESS;
210     }
211 
212     int ret;
213     BSL_Tlv tlv = {0};
214     tlv.type = type;
215     tlv.length = sess->sessionIdCtxSize;
216     tlv.value = (uint8_t *)(uintptr_t)(sess->sessionIdCtx);
217 
218     if (data == NULL) {
219         /* If the input parameter is NULL, return the length after encoding. */
220         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
221         return HITLS_SUCCESS;
222     }
223 
224     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
225     if (ret != BSL_SUCCESS) {
226         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_SESSION_ID_CTX_FAIL);
227         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15988, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
228             "encode session session id ctx fail. ret %d", ret, 0, 0, 0);
229         return HITLS_SESS_ERR_ENC_SESSION_ID_CTX_FAIL;
230     }
231 
232     return HITLS_SUCCESS;
233 }
234 
EncSessObjSessionId(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)235 static int32_t EncSessObjSessionId(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
236     uint32_t *encLen)
237 {
238     if (sess->sessionIdSize == 0) {
239         return HITLS_SUCCESS;
240     }
241 
242     int ret;
243     BSL_Tlv tlv = {0};
244     tlv.type = type;
245     tlv.length = sess->sessionIdSize;
246     tlv.value = (uint8_t *)(uintptr_t)(sess->sessionId);
247 
248     if (data == NULL) {
249         /* If the input parameter is NULL, return the length after encoding. */
250         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
251         return HITLS_SUCCESS;
252     }
253 
254     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
255     if (ret != BSL_SUCCESS) {
256         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_SESSION_ID_FAIL);
257         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15989, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
258             "encode session session id fail. ret %d", ret, 0, 0, 0);
259         return HITLS_SESS_ERR_ENC_SESSION_ID_FAIL;
260     }
261 
262     return HITLS_SUCCESS;
263 }
264 
EncSessObjExtendMasterSecret(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)265 static int32_t EncSessObjExtendMasterSecret(const HITLS_Session *sess, SessionObjType type, uint8_t *data,
266     uint32_t length, uint32_t *encLen)
267 {
268     int ret;
269     uint8_t haveExtMasterSecret = (uint8_t)sess->haveExtMasterSecret;
270     BSL_Tlv tlv = {0};
271     tlv.type = type;
272     tlv.length = sizeof(haveExtMasterSecret);
273     tlv.value = (uint8_t *)&haveExtMasterSecret;
274 
275     if (data == NULL) {
276         /* If the input parameter is NULL, return the length after encoding. */
277         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
278         return HITLS_SUCCESS;
279     }
280 
281     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
282     if (ret != BSL_SUCCESS) {
283         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_EXT_MASTER_SECRET_FAIL);
284         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15990, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
285             "encode session extend master secret fail. ret %d", ret, 0, 0, 0);
286         return HITLS_SESS_ERR_ENC_EXT_MASTER_SECRET_FAIL;
287     }
288 
289     return HITLS_SUCCESS;
290 }
291 
EncSessObjVerifyResult(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)292 static int32_t EncSessObjVerifyResult(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
293     uint32_t *encLen)
294 {
295     int ret;
296     int32_t verifyResult = sess->verifyResult;
297     BSL_Tlv tlv = {0};
298     tlv.type = type;
299     tlv.length = sizeof(verifyResult);
300     tlv.value = (uint8_t *)&verifyResult;
301 
302     if (data == NULL) {
303         /* If the input parameter is NULL, return the length after encoding. */
304         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
305         return HITLS_SUCCESS;
306     }
307 
308     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
309     if (ret != BSL_SUCCESS) {
310         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_VERIFY_RESULT_FAIL);
311         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15991, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
312             "encode session verify result fail. ret %d", ret, 0, 0, 0);
313         return HITLS_SESS_ERR_ENC_VERIFY_RESULT_FAIL;
314     }
315 
316     return HITLS_SUCCESS;
317 }
318 
PackCertToBuf(const HITLS_Session * sess,uint8_t * buf,uint32_t bufLen)319 static int32_t PackCertToBuf(const HITLS_Session *sess, uint8_t *buf, uint32_t bufLen)
320 {
321     CERT_Pair *peerCert = sess->peerCert;
322     HITLS_CERT_X509 *cert = peerCert->cert;
323     uint32_t encodeLen = 0;
324 #ifndef HITLS_TLS_FEATURE_PROVIDER
325     CERT_MgrCtx *mgrCtx = sess->certMgrCtx;
326     if (mgrCtx->method.certEncode == NULL) {
327         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16254, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
328             "mgrCtx->method.certEncode is null.", 0, 0, 0, 0);
329         return HITLS_NULL_INPUT;
330     }
331     /* Write the certificate data. */
332     int32_t ret = mgrCtx->method.certEncode(NULL, cert, &buf[CERT_LEN_TAG_SIZE],
333         bufLen - CERT_LEN_TAG_SIZE, &encodeLen);
334 #else
335     int32_t ret = SAL_CERT_X509Encode(NULL, cert, &buf[CERT_LEN_TAG_SIZE],
336         bufLen - CERT_LEN_TAG_SIZE, &encodeLen);
337 #endif
338     if (ret != HITLS_SUCCESS) {
339         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16255, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
340             "certEncode error.", 0, 0, 0, 0);
341         return HITLS_CERT_ERR_ENCODE_CERT;
342     }
343     if (bufLen - CERT_LEN_TAG_SIZE != encodeLen) {
344         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16256, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
345             "encodeLen error.", 0, 0, 0, 0);
346         return HITLS_CERT_ERR_ENCODE_CERT;
347     }
348     BSL_Uint24ToByte(encodeLen, buf);
349 
350     return HITLS_SUCCESS;
351 }
352 
GetPeertCertSize(const HITLS_Session * sess)353 static uint32_t GetPeertCertSize(const HITLS_Session *sess)
354 {
355     uint32_t certLen = 0;
356     CERT_Pair *peerCert = sess->peerCert;
357 #ifndef HITLS_TLS_FEATURE_PROVIDER
358     CERT_MgrCtx *mgrCtx = sess->certMgrCtx;
359     if (mgrCtx == NULL || mgrCtx->method.certCtrl == NULL || peerCert->cert == NULL) {
360         return 0;
361     }
362     int32_t ret = mgrCtx->method.certCtrl(NULL, peerCert->cert, CERT_CTRL_GET_ENCODE_LEN, NULL, (void *)&certLen);
363 #else
364     int32_t ret = SAL_CERT_X509Ctrl(NULL, peerCert->cert, CERT_CTRL_GET_ENCODE_LEN, NULL, (void *)&certLen);
365 #endif
366     if (ret != HITLS_SUCCESS || certLen == 0) {
367         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16257, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
368             "CERT_CTRL_GET_ENCODE_LEN error.", 0, 0, 0, 0);
369         return 0;
370     }
371     return certLen + CERT_LEN_TAG_SIZE;
372 }
373 
EncSessObjPeerCert(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)374 static int32_t EncSessObjPeerCert(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
375     uint32_t *encLen)
376 {
377     CERT_Pair *peerCert = sess->peerCert;
378     if (peerCert == NULL) {
379         return HITLS_SUCCESS;
380     }
381     uint32_t bufLen = GetPeertCertSize(sess);
382     if (bufLen == 0) {
383         return HITLS_SUCCESS;
384     }
385     BSL_Tlv tlv = {0};
386     tlv.type = type;
387     tlv.length = bufLen;
388 
389     if (data == NULL) {
390         /* If the input parameter is NULL, return the length after encoding. */
391         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
392         return HITLS_SUCCESS;
393     }
394     uint8_t *curPos = data;
395     if ((length < TLV_HEADER_LENGTH) || (tlv.length > length - TLV_HEADER_LENGTH)) {
396         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16258, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
397             "TLV build error: length = %u is not enough for tlv length = %u, tlv type = 0x%x.",
398             length, tlv.length, tlv.type, 0);
399         BSL_ERR_PUSH_ERROR(BSL_TLV_ERR_BAD_PARAM);
400         return BSL_TLV_ERR_BAD_PARAM;
401     }
402 
403     /* Write the TLV type */
404     BSL_Uint32ToByte(tlv.type, curPos);
405     curPos += sizeof(uint32_t);
406     /* Write the TLV length */
407     BSL_Uint32ToByte(tlv.length, curPos);
408     curPos += sizeof(uint32_t);
409     int32_t ret = PackCertToBuf(sess, curPos, tlv.length);
410     if (ret != HITLS_SUCCESS) {
411         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16265, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
412             "PackCertToBuf fail. ret %d", ret, 0, 0, 0);
413         return HITLS_SESS_ERR_ENC_PEER_CERT_FAIL;
414     }
415 
416     *encLen = TLV_HEADER_LENGTH + tlv.length;
417 
418     return HITLS_SUCCESS;
419 }
420 
EncSessObjTicketAgeAdd(const HITLS_Session * sess,SessionObjType type,uint8_t * data,uint32_t length,uint32_t * encLen)421 static int32_t EncSessObjTicketAgeAdd(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length,
422     uint32_t *encLen)
423 {
424     int ret;
425     uint32_t ticketAgeAdd = sess->ticketAgeAdd;
426     BSL_Tlv tlv = {0};
427     tlv.type = type;
428     tlv.length = sizeof(ticketAgeAdd);
429     tlv.value = (uint8_t *)&ticketAgeAdd;
430 
431     if (data == NULL) {
432         /* If the input parameter is NULL, the length after encoding is returned. */
433         *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length;
434         return HITLS_SUCCESS;
435     }
436 
437     ret = BSL_TLV_Pack(&tlv, data, length, encLen);
438     if (ret != BSL_SUCCESS) {
439         BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_VERIFY_RESULT_FAIL);
440         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16183, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
441             "encode session TicketAgeAdd fail. ret %d", ret, 0, 0, 0);
442         return HITLS_SESS_ERR_ENC_VERIFY_RESULT_FAIL;
443     }
444 
445     return HITLS_SUCCESS;
446 }
447 
448 /*
449  * Encoding function list.
450  * Ensure that the sequence of decode and encode types is the same.
451  */
452 static const SessObjEncFunc OBJ_LIST[] = {
453     {SESS_OBJ_VERSION, EncSessObjVersion},
454     {SESS_OBJ_CIPHER_SUITE, EncSessObjCipherSuite},
455     {SESS_OBJ_MASTER_SECRET, EncSessObjMasterSecret},
456     {SESS_OBJ_PEER_CERT, EncSessObjPeerCert},
457     {SESS_OBJ_START_TIME, EncSessObjStartTime},
458     {SESS_OBJ_TIMEOUT, EncSessObjTimeout},
459 #ifdef HITLS_TLS_FEATURE_SNI
460     {SESS_OBJ_HOST_NAME, EncSessObjHostName},
461 #endif
462     {SESS_OBJ_SESSION_ID_CTX, EncSessObjSessionIdCtx},
463     {SESS_OBJ_SESSION_ID, EncSessObjSessionId},
464     {SESS_OBJ_SUPPORT_EXTEND_MASTER_SECRET, EncSessObjExtendMasterSecret},
465     {SESS_OBJ_VERIFY_RESULT, EncSessObjVerifyResult},
466     {SESS_OBJ_AGE_ADD, EncSessObjTicketAgeAdd},
467 };
468 
SESS_GetTotalEncodeSize(const HITLS_Session * sess)469 uint32_t SESS_GetTotalEncodeSize(const HITLS_Session *sess)
470 {
471     if (sess == NULL) {
472         return 0;
473     }
474 
475     uint32_t index;
476     uint32_t offset = 0;
477     uint32_t encLen = 0;
478 
479     for (index = 0; index < sizeof(OBJ_LIST) / sizeof(SessObjEncFunc); index++) {
480         encLen = 0;
481         /* This parameter is used only to obtain the encoded length and will not verified the returned value. */
482         (void)OBJ_LIST[index].func(sess, OBJ_LIST[index].type, NULL, 0, &encLen);
483         offset += encLen;
484     }
485 
486     return offset;
487 }
488 
SESS_Encode(const HITLS_Session * sess,uint8_t * data,uint32_t length,uint32_t * usedLen)489 int32_t SESS_Encode(const HITLS_Session *sess, uint8_t *data, uint32_t length, uint32_t *usedLen)
490 {
491     if (sess == NULL || data == NULL || usedLen == 0) {
492         BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION);
493         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16008, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
494             "SESS_Encode input parameter is NULL.", 0, 0, 0, 0);
495         return HITLS_INTERNAL_EXCEPTION;
496     }
497 
498     int32_t ret;
499     uint32_t index;
500     uint8_t *curPos = data;
501     uint32_t offset = 0;
502     uint32_t encLen = 0;
503 
504     for (index = 0; index < sizeof(OBJ_LIST) / sizeof(SessObjEncFunc); index++) {
505         encLen = 0;
506         ret = OBJ_LIST[index].func(sess, OBJ_LIST[index].type, curPos, length - offset, &encLen);
507         if (ret != HITLS_SUCCESS) {
508             return ret;
509         }
510         offset += encLen;
511         curPos += encLen;
512     }
513 
514     *usedLen = offset;
515     return HITLS_SUCCESS;
516 }
517 #endif /* HITLS_TLS_FEATURE_SESSION_TICKET */