• 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 
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