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
16 #include <stdbool.h>
17 #include <stdint.h>
18 #include "hitls_build.h"
19 #include "bsl_err_internal.h"
20 #include "tls_binlog_id.h"
21 #include "bsl_log_internal.h"
22 #include "bsl_log.h"
23 #include "hitls_crypt_type.h"
24 #include "hitls_cert_type.h"
25 #include "hitls_error.h"
26 #include "hitls_config.h"
27 #include "tls.h"
28 #include "tls_config.h"
29 #include "cipher_suite.h"
30 #include "config_type.h"
31
CFG_IsValidVersion(uint16_t version)32 static bool CFG_IsValidVersion(uint16_t version)
33 {
34 switch (version) {
35 case HITLS_VERSION_TLS12:
36 case HITLS_VERSION_TLS13:
37 case HITLS_VERSION_DTLS12:
38 case HITLS_VERSION_TLCP_DTLCP11:
39 return true;
40 default:
41 break;
42 }
43 return false;
44 }
45
HaveMatchSignAlg(const TLS_Config * config,HITLS_AuthAlgo authAlg,const uint16_t * signatureAlgorithms,uint32_t signatureAlgorithmsSize)46 static bool HaveMatchSignAlg(const TLS_Config *config, HITLS_AuthAlgo authAlg, const uint16_t *signatureAlgorithms,
47 uint32_t signatureAlgorithmsSize)
48 {
49 HITLS_SignAlgo signAlg = HITLS_SIGN_BUTT;
50
51 /** Traverse the signature algorithms. If the matching is successful, return true */
52 for (uint32_t i = 0u; i < signatureAlgorithmsSize; i++) {
53 const TLS_SigSchemeInfo *info = ConfigGetSignatureSchemeInfo(config, signatureAlgorithms[i]);
54 if (info == NULL) {
55 continue;
56 }
57 signAlg = info->signAlgId;
58 if (((signAlg == HITLS_SIGN_RSA_PKCS1_V15) || (signAlg == HITLS_SIGN_RSA_PSS)) &&
59 (authAlg == HITLS_AUTH_RSA)) {
60 return true;
61 }
62
63 if (((signAlg == HITLS_SIGN_ECDSA) || (signAlg == HITLS_SIGN_ED25519)) &&
64 (authAlg == HITLS_AUTH_ECDSA)) {
65 return true;
66 }
67
68 if (signAlg == HITLS_SIGN_DSA && authAlg == HITLS_AUTH_DSS) {
69 return true;
70 }
71
72 if (signAlg == HITLS_SIGN_SM2 && authAlg == HITLS_AUTH_SM2) {
73 return true;
74 }
75 }
76
77 return false;
78 }
79
CheckPointFormats(const TLS_Config * config)80 static int32_t CheckPointFormats(const TLS_Config *config)
81 {
82 if ((config->pointFormats == NULL) || (config->pointFormatsSize == 0)) {
83 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16561, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
84 "pointFormats null", 0, 0, 0, 0);
85 BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_SET);
86 return HITLS_CONFIG_INVALID_SET;
87 }
88
89 /** Currently, only one point format is supported */
90 if ((config->pointFormatsSize != 1) || (config->pointFormats[0] != HITLS_POINT_FORMAT_UNCOMPRESSED)) {
91 BSL_ERR_PUSH_ERROR(HITLS_CONFIG_UNSUPPORT_POINT_FORMATS);
92 return HITLS_CONFIG_UNSUPPORT_POINT_FORMATS;
93 }
94
95 return HITLS_SUCCESS;
96 }
97
IsCipherSuiteValid(const TLS_Config * config,uint16_t cipherSuite)98 static bool IsCipherSuiteValid(const TLS_Config *config, uint16_t cipherSuite)
99 {
100 if ((CFG_CheckCipherSuiteSupported(cipherSuite) != true) ||
101 (CFG_CheckCipherSuiteVersion(cipherSuite, config->minVersion, config->maxVersion) != true)) {
102 /* The cipher suite must match the configured version */
103 return false;
104 }
105 return true;
106 }
107
CheckSign(const TLS_Config * config)108 static int32_t CheckSign(const TLS_Config *config)
109 {
110 uint16_t *signAlgorithms = config->signAlgorithms;
111 uint32_t signAlgorithmsSize = config->signAlgorithmsSize;
112 /** If the signature algorithm is empty, the default signature algorithm in the cipher suite is used and no further
113 * check is required */
114 if ((signAlgorithms == NULL) || (signAlgorithmsSize == 0)) {
115 return HITLS_SUCCESS;
116 }
117
118 /** Check the validity of the signature algorithms one by one */
119 for (uint32_t i = 0; i < signAlgorithmsSize; i++) {
120 if (ConfigGetSignatureSchemeInfo(config, signAlgorithms[i]) == NULL) {
121 BSL_ERR_PUSH_ERROR(HITLS_CONFIG_UNSUPPORT_SIGNATURE_ALGORITHM);
122 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15779, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN,
123 "Unsupported signature algorithms: 0x%04x.", signAlgorithms[i], 0, 0, 0);
124 return HITLS_CONFIG_UNSUPPORT_SIGNATURE_ALGORITHM;
125 }
126 }
127
128 /*
129 In this case, only the 1.3 cipher suite is configured, or only TLS1.3 is supported.
130 The authentication algorithm is not specified in the TLS 1.3 cipher suite and therefore does not need to be
131 checked.
132 */
133 if (config->cipherSuitesSize == 0 || ((config->minVersion == HITLS_VERSION_TLS13) &&
134 (config->maxVersion == HITLS_VERSION_TLS13))) {
135 return HITLS_SUCCESS;
136 }
137
138 /** Check the compatibility between the signature algorithm and the cipher suite */
139 for (uint32_t i = 0; i < config->cipherSuitesSize; i++) {
140 CipherSuiteInfo info = {0};
141 if (IsCipherSuiteValid(config, config->cipherSuites[i]) == false) {
142 continue;
143 }
144
145 (void)CFG_GetCipherSuiteInfo(config->cipherSuites[i], &info);
146
147 /** PSK does not require the signature algorithm */
148 if ((info.kxAlg == HITLS_KEY_EXCH_PSK) || (info.kxAlg == HITLS_KEY_EXCH_DHE_PSK) ||
149 (info.kxAlg == HITLS_KEY_EXCH_ECDHE_PSK)) {
150 return HITLS_SUCCESS;
151 }
152
153 /* Anon does not require the signature algorithm */
154 if (info.authAlg == HITLS_AUTH_NULL) {
155 return HITLS_SUCCESS;
156 }
157
158 /** Check whether a signature algorithm matching the cipher suite exists */
159 if (HaveMatchSignAlg(config, info.authAlg, signAlgorithms, signAlgorithmsSize)) {
160 return HITLS_SUCCESS;
161 }
162 }
163 BSL_ERR_PUSH_ERROR(HITLS_CONFIG_NO_SUITABLE_SIGNATURE_ALGORITHM);
164 return HITLS_CONFIG_NO_SUITABLE_SIGNATURE_ALGORITHM;
165 }
166
IsHaveEccCipherSuite(const TLS_Config * config)167 static bool IsHaveEccCipherSuite(const TLS_Config *config)
168 {
169 for (uint32_t i = 0u; i < config->cipherSuitesSize; i++) {
170 CipherSuiteInfo info = {0};
171 if (IsCipherSuiteValid(config, config->cipherSuites[i]) == false) {
172 continue;
173 }
174 (void)CFG_GetCipherSuiteInfo(config->cipherSuites[i], &info);
175
176 /* The ECC cipher suite exists */
177 if ((info.authAlg == HITLS_AUTH_ECDSA) ||
178 (info.kxAlg == HITLS_KEY_EXCH_ECDHE) ||
179 (info.kxAlg == HITLS_KEY_EXCH_ECDH) ||
180 (info.kxAlg == HITLS_KEY_EXCH_ECDHE_PSK)) {
181 return true;
182 }
183 }
184
185 return false;
186 }
187
CheckGroup(const TLS_Config * config)188 static int32_t CheckGroup(const TLS_Config *config)
189 {
190 if (config->groupsSize == 0u) {
191 BSL_ERR_PUSH_ERROR(HITLS_CONFIG_NO_GROUPS);
192 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15780, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN,
193 "Set ecdhe cipher with no group id", 0, 0, 0, 0);
194 return HITLS_CONFIG_NO_GROUPS;
195 }
196
197 return HITLS_SUCCESS;
198 }
199
CheckVersion(uint16_t minVersion,uint16_t maxVersion)200 int32_t CheckVersion(uint16_t minVersion, uint16_t maxVersion)
201 {
202 if ((CFG_IsValidVersion(minVersion) == false) || (CFG_IsValidVersion(maxVersion) == false) ||
203 (IS_DTLS_VERSION(minVersion) != IS_DTLS_VERSION(maxVersion))) {
204 BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION);
205 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15781, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
206 "Config max version [0x%x] or min version [0x%x] is invalid.", maxVersion, minVersion, 0, 0);
207 return HITLS_CONFIG_INVALID_VERSION;
208 }
209
210 if ((IS_DTLS_VERSION(maxVersion) && (maxVersion > minVersion))) {
211 BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION);
212 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15782, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
213 "Config max version [0x%x] or min version [0x%x] is invalid.", maxVersion, minVersion, 0, 0);
214 return HITLS_CONFIG_INVALID_VERSION;
215 }
216
217 if ((IS_DTLS_VERSION(maxVersion) == false) && (maxVersion < minVersion)) {
218 BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION);
219 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15783, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
220 "Config max version [0x%x] or min version [0x%x] is invalid.", maxVersion, minVersion, 0, 0);
221 return HITLS_CONFIG_INVALID_VERSION;
222 }
223 #ifdef HITLS_TLS_PROTO_TLCP11
224 if (minVersion == HITLS_VERSION_TLCP_DTLCP11 || maxVersion == HITLS_VERSION_TLCP_DTLCP11) {
225 if (minVersion != maxVersion) {
226 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16233, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
227 "Config max version [0x%x] or min version [0x%x] is invalid.", maxVersion,
228 minVersion, 0, 0);
229 return HITLS_CONFIG_INVALID_VERSION;
230 }
231 }
232 #endif
233 return HITLS_SUCCESS;
234 }
235
236 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
CheckCallbackFunc(const TLS_Config * config)237 static int32_t CheckCallbackFunc(const TLS_Config *config)
238 {
239 /* Check the cookie callback. The user must register the cookie callback at the same time or
240 not register the cookie callback */
241 if ((config->appGenCookieCb != NULL && config->appVerifyCookieCb == NULL) ||
242 (config->appGenCookieCb == NULL && config->appVerifyCookieCb != NULL)) {
243 BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_SET);
244 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15784, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
245 "cannot register only one cookie callback, either appGenCookieCb or appVerifyCookieCb is NULL.",
246 0, 0, 0, 0);
247 return HITLS_CONFIG_INVALID_SET;
248 }
249 return HITLS_SUCCESS;
250 }
251 #endif
252
CheckConfig(const TLS_Config * config)253 int32_t CheckConfig(const TLS_Config *config)
254 {
255 int32_t ret;
256
257 /** The check of the cipher suite is checked during setting. The algorithm suite needs to be sorted and the memory
258 * overhead increases. Therefore, the algorithm suite is still placed in the Set interface */
259 if (config->cipherSuitesSize == 0
260 #ifdef HITLS_TLS_PROTO_TLS13
261 && config->tls13cipherSuitesSize == 0
262 #endif
263 ) {
264 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16562, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN,
265 "cipherSuitesSize is 0", 0, 0, 0, 0);
266 BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_SET);
267 return HITLS_CONFIG_INVALID_SET;
268 }
269
270 /* The checkpoint format and group are required only when the ecdhe cipher suite is available */
271 if (IsHaveEccCipherSuite(config)) {
272 ret = CheckPointFormats(config);
273 if (ret != HITLS_SUCCESS) {
274 return ret;
275 }
276
277 ret = CheckGroup(config);
278 if (ret != HITLS_SUCCESS) {
279 return ret;
280 }
281 }
282 ret = CheckSign(config);
283 if (ret != HITLS_SUCCESS) {
284 return ret;
285 }
286 #if defined(HITLS_TLS_PROTO_DTLS12) && defined(HITLS_BSL_UIO_UDP)
287 ret = CheckCallbackFunc(config);
288 #endif
289 return ret;
290 }
291