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 */