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_CLIENT
17 #include "securec.h"
18 #include "tls_binlog_id.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_log.h"
21 #include "bsl_sal.h"
22 #include "bsl_err_internal.h"
23 #include "bsl_bytes.h"
24 #include "hitls_error.h"
25 #include "hs_msg.h"
26 #include "parse_common.h"
27 #include "parse_extensions.h"
28 #include "parse_msg.h"
29
ParseServerHelloCipherSuite(ParsePacket * pkt,ServerHelloMsg * msg)30 static int32_t ParseServerHelloCipherSuite(ParsePacket *pkt, ServerHelloMsg *msg)
31 {
32 int32_t ret = ParseBytesToUint16(pkt, &msg->cipherSuite);
33 if (ret != HITLS_SUCCESS) {
34 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15785,
35 BINGLOG_STR("parse cipherSuites failed."), ALERT_DECODE_ERROR);
36 }
37 return HITLS_SUCCESS;
38 }
39
ParseServerHelloCompressionMethod(ParsePacket * pkt)40 static int32_t ParseServerHelloCompressionMethod(ParsePacket *pkt)
41 {
42 uint8_t comMethod = 0;
43 int32_t ret = ParseBytesToUint8(pkt, &comMethod);
44 if (ret != HITLS_SUCCESS) {
45 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15786,
46 BINGLOG_STR("parse compression method failed."), ALERT_DECODE_ERROR);
47 }
48
49 if (comMethod != 0u) {
50 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_COMPRESSION_METHOD_ERR, BINLOG_ID15787,
51 BINGLOG_STR("client does not support compression format."), ALERT_ILLEGAL_PARAMETER);
52 }
53
54 return HITLS_SUCCESS;
55 }
56
ParseServerHelloExtensions(ParsePacket * pkt,ServerHelloMsg * msg)57 static int32_t ParseServerHelloExtensions(ParsePacket *pkt, ServerHelloMsg *msg)
58 {
59 uint16_t exMsgLen = 0;
60 const char *logStr = BINGLOG_STR("parse extension length failed.");
61 int32_t ret = ParseBytesToUint16(pkt, &exMsgLen);
62 if (ret != HITLS_SUCCESS) {
63 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15788,
64 logStr, ALERT_DECODE_ERROR);
65 }
66
67 if (exMsgLen != (pkt->bufLen - *pkt->bufOffset)) {
68 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID15789,
69 logStr, ALERT_DECODE_ERROR);
70 }
71
72 if (exMsgLen == 0u) {
73 return HITLS_SUCCESS;
74 }
75 return ParseServerExtension(pkt->ctx, &pkt->buf[*pkt->bufOffset], exMsgLen, msg);
76 }
77
ParseServerHello(TLS_Ctx * ctx,const uint8_t * buf,uint32_t bufLen,HS_Msg * hsMsg)78 int32_t ParseServerHello(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg)
79 {
80 int32_t ret = HITLS_SUCCESS;
81 ServerHelloMsg *msg = &hsMsg->body.serverHello;
82 uint32_t bufOffset = 0;
83 ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = bufLen, .bufOffset = &bufOffset};
84
85 ret = ParseVersion(&pkt, &msg->version);
86 if (ret != HITLS_SUCCESS) {
87 return ret;
88 }
89
90 ret = ParseRandom(&pkt, msg->randomValue, HS_RANDOM_SIZE);
91 if (ret != HITLS_SUCCESS) {
92 return ret;
93 }
94
95 ret = ParseSessionId(&pkt, &msg->sessionIdSize, &msg->sessionId);
96 if (ret != HITLS_SUCCESS) {
97 return ret;
98 }
99
100 ret = ParseServerHelloCipherSuite(&pkt, msg);
101 if (ret != HITLS_SUCCESS) {
102 return ret;
103 }
104
105 ret = ParseServerHelloCompressionMethod(&pkt);
106 if (ret != HITLS_SUCCESS) {
107 return ret;
108 }
109
110 /* If the buf length is equal to the offset length, return HITLS_SUCCESS. */
111 if (bufLen == bufOffset) {
112 // ServerHello is optionally followed by extension data
113 return HITLS_SUCCESS;
114 }
115
116 return ParseServerHelloExtensions(&pkt, msg);
117 }
118
CleanServerHello(ServerHelloMsg * msg)119 void CleanServerHello(ServerHelloMsg *msg)
120 {
121 if (msg == NULL) {
122 return;
123 }
124
125 BSL_SAL_FREE(msg->sessionId);
126
127 CleanServerHelloExtension(msg);
128
129 return;
130 }
131 #endif /* HITLS_TLS_HOST_CLIENT */