• 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_HOST_SERVER
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 "hitls_security.h"
26 #include "tls.h"
27 #ifdef HITLS_TLS_FEATURE_SECURITY
28 #include "security.h"
29 #endif
30 #include "hs_ctx.h"
31 #include "pack_common.h"
32 #include "pack_extensions.h"
33 
34 // Pack the mandatory content of the ServerHello message
PackServerHelloMandatoryField(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)35 static int32_t PackServerHelloMandatoryField(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
36 {
37     /* The bufLen must be able to pack at least the version number (2 bytes) + random number (32 bytes) + session ID
38      * (1 byte length field) + algorithm suite (2 bytes) + compression method (1 byte) */
39     if (bufLen < (sizeof(uint16_t) + HS_RANDOM_SIZE + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t))) {
40         return PackBufLenError(BINLOG_ID16079, BINGLOG_STR("server hello"));
41     }
42 
43     int32_t ret = HITLS_SUCCESS;
44     (void)ret;
45     uint32_t offset = 0u;
46     uint16_t negotiatedVersion = ctx->negotiatedInfo.version;
47 
48     uint16_t version =
49 #ifdef HITLS_TLS_PROTO_TLS13
50     (negotiatedVersion == HITLS_VERSION_TLS13) ? HITLS_VERSION_TLS12 :
51 #endif
52         negotiatedVersion;
53 #ifdef HITLS_TLS_FEATURE_SECURITY
54     ret = SECURITY_CfgCheck(&ctx->config.tlsConfig, HITLS_SECURITY_SECOP_VERSION, 0, version, NULL);
55     if (ret != SECURITY_SUCCESS) {
56         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16940, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
57             "CfgCheck fail, ret %d", ret, 0, 0, 0);
58         BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSECURE_VERSION);
59         ctx->method.sendAlert((TLS_Ctx *)(uintptr_t)ctx, ALERT_LEVEL_FATAL, ALERT_INSUFFICIENT_SECURITY);
60         return HITLS_PACK_UNSECURE_VERSION;
61     }
62 #endif
63     BSL_Uint16ToByte(version, &buf[offset]);    // version number
64     offset += sizeof(uint16_t);
65     (void)memcpy_s(&buf[offset], bufLen - offset, ctx->hsCtx->serverRandom, HS_RANDOM_SIZE);    // server random number
66     offset += HS_RANDOM_SIZE;
67 #if defined(HITLS_TLS_FEATURE_SESSION_ID) || defined(HITLS_TLS_PROTO_TLS13)
68     HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx;
69     uint32_t len = 0u;
70     ret = PackSessionId(hsCtx->sessionId, hsCtx->sessionIdSize, &buf[offset], bufLen - offset, &len);
71     if (ret != HITLS_SUCCESS) {
72         (void)memset_s(hsCtx->sessionId, hsCtx->sessionIdSize, 0, hsCtx->sessionIdSize);
73         return ret;
74     }
75     offset += len;
76 #else // Session recovery is not supported.
77     buf[offset] = 0;
78     offset += sizeof(uint8_t);
79 #endif
80     BSL_Uint16ToByte(ctx->negotiatedInfo.cipherSuiteInfo.cipherSuite, &buf[offset]);    // cipher suite
81     offset += sizeof(uint16_t);
82 
83     buf[offset] = 0;    // Compression method, currently supports uncompression
84     offset += sizeof(uint8_t);
85 
86     *usedLen = offset;
87     return HITLS_SUCCESS;
88 }
89 
90 // Pack the ServertHello message.
PackServerHello(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)91 int32_t PackServerHello(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
92 {
93     int32_t ret = HITLS_SUCCESS;
94     uint32_t offset = 0u;
95     uint32_t msgLen = 0u;
96     uint32_t exMsgLen = 0u;
97 
98     ret = PackServerHelloMandatoryField(ctx, buf, bufLen, &msgLen);
99     if (ret != HITLS_SUCCESS) {
100         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15863, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
101             "pack server hello mandatory content fail.", 0, 0, 0, 0);
102         return ret;
103     }
104     offset += msgLen;
105 
106     exMsgLen = 0u;
107     ret = PackServerExtension(ctx, &buf[offset], bufLen - offset, &exMsgLen);
108     if (ret != HITLS_SUCCESS) {
109         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15864, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
110             "pack server hello extension content fail.", 0, 0, 0, 0);
111         return ret;
112     }
113     offset += exMsgLen;
114 
115     *usedLen = offset;
116     return HITLS_SUCCESS;
117 }
118 #endif /* HITLS_TLS_HOST_SERVER */