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