1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: TLS 客户端常用操作,包括会话的创建、销毁等(此文件为DEMO,需集成方适配修改)
15 * Note: 由于此文件在采用外部mbedtls编译的时候会打包到外部,所以修改本函数代码的时候
16 * 不应涉及引用hilink库编译要使用的宏以及非对外头文件函数
17 */
18
19 #include "hilink_tls_client.h"
20
21 #include <stdlib.h>
22 #include <errno.h>
23
24 #include "securec.h"
25
26 #include "hilink_sal_defines.h"
27 #include "hilink_str_adapter.h"
28 #include "hilink_mem_adapter.h"
29 #include "hilink_time_adapter.h"
30 #include "hilink_stdio_adapter.h"
31 #include "hilink_stdio_adapter.h"
32 #include "hilink_thread_adapter.h"
33
34 #include "mbedtls/ssl.h"
35 #include "hilink_sal_drbg.h"
36 #include "mbedtls/ctr_drbg.h"
37 #include "mbedtls/x509.h"
38 #include "mbedtls/platform_time.h"
39 #include "mbedtls/net_sockets.h"
40 #include "mbedtls/debug.h"
41 #include "mbedtls/platform.h"
42
43 /* 检查宏定义是否一致 */
44 #if (HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 != \
45 MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)
46 #error "HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
47 #endif
48 #if (HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 != \
49 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
50 #error "HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
51 #endif
52 #if (HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 != \
53 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
54 #error "HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
55 #endif
56 #if (HILINK_MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 != \
57 MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256)
58 #error "HILINK_MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256"
59 #endif
60 #if (HILINK_MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 != \
61 MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384)
62 #error "HILINK_MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384"
63 #endif
64
65 #if (HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_NONE != \
66 MBEDTLS_SSL_MAX_FRAG_LEN_NONE)
67 #error "HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_NONE"
68 #endif
69 #if (HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_512 != \
70 MBEDTLS_SSL_MAX_FRAG_LEN_512)
71 #error "HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_512"
72 #endif
73 #if (HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_1024 != \
74 MBEDTLS_SSL_MAX_FRAG_LEN_1024)
75 #error "HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_1024"
76 #endif
77 #if (HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_2048 != \
78 MBEDTLS_SSL_MAX_FRAG_LEN_2048)
79 #error "HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_2048"
80 #endif
81 #if (HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_4096 != \
82 MBEDTLS_SSL_MAX_FRAG_LEN_4096)
83 #error "HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_4096"
84 #endif
85
86 #ifndef MS_PER_SECOND
87 #define MS_PER_SECOND 1000
88 #endif
89 #ifndef US_PER_MS
90 #define US_PER_MS 1000
91 #endif
92 #define MAX_PORT_STR_LEN 20
93 #define MAX_CUSTOM_STR_LEN 32
94 #define MAX_HOSTNAME_STR_LEN 64
95
96 #ifdef MBEDTLS_DEBUG_C
97 #undef HILINK_TLS_DEBUG /* 用于调试tls通信,默认不开 */
98 #endif /* MBEDTLS_DEBUG_C */
99
100 #define MBEDTLS_DEBUG_LEVEL 4
101 #define TLS_READ_TIMEOUT_MS 10
102 #define TLS_HANDSHAKE_TIMEOUT 4000
103 #define TLS_WRITE_TIMEOUT_MS 10000
104
105 #ifndef TCP_COAP_MAX_PDU_SIZE
106 #define TCP_COAP_MAX_PDU_SIZE 65536
107 #endif
108
109 #ifdef MBEDTLS_VERSION_3
110 #define HILINK_MBEDTLS_ENTROPY_MIN_HARDCLOCK 4
111 #endif
112
113 struct HiLinkTlsClient {
114 char *custom;
115 /* 算法套件白名单相关数据 */
116 int *supportedCiphersuites;
117 /* 证书相关数据 */
118 const char **certs;
119 unsigned int certsNum;
120 mbedtls_x509_time validFrom;
121 mbedtls_x509_time validTo;
122 bool isDelayVerifyCert;
123 /* mbedtls相关数据 */
124 mbedtls_net_context serverFd;
125 mbedtls_ssl_context ssl;
126 mbedtls_ssl_config conf;
127 HiLinkDrbgContext drbg;
128 mbedtls_x509_crt caCert;
129 unsigned short port;
130 char *hostName;
131 };
132
133 static HiLinkMbedtlsGetTimeCb g_mbedtlsGetTimeCb = NULL;
134
135 typedef struct {
136 HiLinkTlsOption option;
137 int (*setOptionFunc)(HiLinkTlsClient *ctx, const void *value, unsigned int len);
138 } OptionItem;
139
GetTlsTimeoutTime(unsigned int packetLen)140 static unsigned int GetTlsTimeoutTime(unsigned int packetLen)
141 {
142 return ((packetLen / TCP_COAP_MAX_PDU_SIZE) + 1) * TLS_WRITE_TIMEOUT_MS;
143 }
144
GetOsTime(unsigned long * ms)145 static int GetOsTime(unsigned long *ms)
146 {
147 if (ms == NULL) {
148 return HILINK_SAL_NOK;
149 }
150 HiLinkTimeval cur = {0, 0};
151
152 if (HILINK_GetOsTime(&cur) != 0) {
153 return HILINK_SAL_TIME_ERR;
154 }
155
156 *ms = (cur.sec * MS_PER_SECOND) + (cur.usec / US_PER_MS);
157
158 return HILINK_SAL_OK;
159 }
160
DeltaTime(unsigned long timeNew,unsigned long timeOld)161 static unsigned long DeltaTime(unsigned long timeNew, unsigned long timeOld)
162 {
163 unsigned long deltaTime;
164
165 if (timeNew >= timeOld) {
166 deltaTime = timeNew - timeOld;
167 } else {
168 deltaTime = ((unsigned long)(-1) - timeOld) + timeNew + 1; /* 处理时间翻转 */
169 }
170
171 return deltaTime;
172 }
173
MbedtlsPlatformGetTime(mbedtls_time_t * timeNow)174 static mbedtls_time_t MbedtlsPlatformGetTime(mbedtls_time_t *timeNow)
175 {
176 (void)timeNow; /* 此参数可能为空 */
177
178 time_t rawSeconds = 0;
179 unsigned long long timeMs = 0;
180 if (g_mbedtlsGetTimeCb == NULL) {
181 HILINK_SAL_NOTICE("no cb\r\n");
182 return (mbedtls_time_t)rawSeconds;
183 }
184 int ret = g_mbedtlsGetTimeCb(&timeMs);
185 if (ret == HILINK_SAL_OK) {
186 rawSeconds = (time_t)(timeMs / MS_PER_SECOND);
187 } else {
188 HILINK_SAL_NOTICE("get local time failed, set rawSeconds=0\r\n");
189 }
190
191 return (mbedtls_time_t)rawSeconds;
192 }
193
MbedtlsPlatformCalloc(size_t n,size_t size)194 static void *MbedtlsPlatformCalloc(size_t n, size_t size)
195 {
196 if ((n == 0) || (size == 0)) {
197 return NULL;
198 }
199 if (n > (UINT_MAX / size)) {
200 return NULL;
201 }
202
203 /* 上层调用保证不会出现溢出 */
204 unsigned int len = (unsigned int)(n * size);
205 void *data = HILINK_Malloc(len);
206 if (data != NULL) {
207 (void)memset_s(data, len, 0, len);
208 }
209
210 return data;
211 }
212
InitMbedtls(void)213 static void InitMbedtls(void)
214 {
215 static bool isInitmbedtls = false;
216 if (!isInitmbedtls) {
217 mbedtls_platform_set_calloc_free(MbedtlsPlatformCalloc, HILINK_Free);
218 (void)mbedtls_platform_set_time(MbedtlsPlatformGetTime);
219 #if defined(HILINK_TLS_DEBUG)
220 mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LEVEL);
221 #endif /* HILINK_TLS_DEBUG */
222 isInitmbedtls = true;
223 }
224 }
225
226 #if defined(HILINK_TLS_DEBUG)
TlsDebug(void * context,int level,const char * file,int line,const char * str)227 static void TlsDebug(void *context, int level, const char *file, int line, const char *str)
228 {
229 (void) level;
230 (void) file;
231 (void) line;
232 HiLinkTlsClient *ctx = (HiLinkTlsClient *)(context);
233 HILINK_SAL_INFO("custom=%s,mbeddebug: %s", ctx->custom, str);
234 }
235 #endif /* HILINK_TLS_DEBUG */
236
InitTlsContextData(HiLinkTlsClient * context)237 static void InitTlsContextData(HiLinkTlsClient *context)
238 {
239 mbedtls_ssl_init((mbedtls_ssl_context *)&context->ssl);
240 mbedtls_x509_crt_init((mbedtls_x509_crt *)&context->caCert);
241 mbedtls_net_init((mbedtls_net_context *)&context->serverFd);
242 mbedtls_ssl_config_init((mbedtls_ssl_config *)&context->conf);
243 }
244
InitTlsContext(HiLinkTlsClient * context)245 static int InitTlsContext(HiLinkTlsClient *context)
246 {
247 InitTlsContextData(context);
248 #if defined(HILINK_TLS_DEBUG)
249 mbedtls_ssl_conf_dbg(&(context->conf), TlsDebug, context);
250 #endif /* HILINK_TLS_DEBUG */
251
252 return HILINK_SAL_OK;
253 }
254
255 /* 该函数为注册到mbedtls中获取随机数的回调 */
SslRngGenerater(void * param,unsigned char * output,size_t len)256 static int SslRngGenerater(void *param, unsigned char *output, size_t len)
257 {
258 HiLinkDrbgContext drbg = (HiLinkDrbgContext)param;
259 if ((drbg == NULL) || (output == NULL) || (len == 0)) {
260 HILINK_SAL_ERROR("param invalid\r\n");
261 return HILINK_SAL_PARAM_INVALID;
262 }
263
264 return HILINK_SAL_DrbgRandom(drbg, output, len);
265 }
266
SetTlsRandomMember(HiLinkTlsClient * context,const char * custom)267 static int SetTlsRandomMember(HiLinkTlsClient *context, const char *custom)
268 {
269 context->drbg = HILINK_SAL_DrbgInit(custom);
270 if (context->drbg == NULL) {
271 HILINK_SAL_ERROR("drbg init error\r\n");
272 return HILINK_SAL_NOK;
273 }
274
275 return HILINK_SAL_OK;
276 }
277
X509CheckTime(const mbedtls_x509_time * before,const mbedtls_x509_time * after)278 static bool X509CheckTime(const mbedtls_x509_time *before, const mbedtls_x509_time *after)
279 {
280 if (before->year > after->year) {
281 return true;
282 } else if (before->year < after->year) {
283 return false;
284 }
285 if (before->mon > after->mon) {
286 return true;
287 } else if (before->mon < after->mon) {
288 return false;
289 }
290 if (before->day > after->day) {
291 return true;
292 } else if (before->day < after->day) {
293 return false;
294 }
295 if (before->hour > after->hour) {
296 return true;
297 } else if (before->hour < after->hour) {
298 return false;
299 }
300 if (before->min > after->min) {
301 return true;
302 } else if (before->min < after->min) {
303 return false;
304 }
305 if (before->sec > after->sec) {
306 return true;
307 } else if (before->sec < after->sec) {
308 return false;
309 }
310
311 return true;
312 }
313
RecordVaildCertTime(HiLinkTlsClient * context,mbedtls_x509_crt * crt)314 static int RecordVaildCertTime(HiLinkTlsClient *context, mbedtls_x509_crt *crt)
315 {
316 HILINK_SAL_DEBUG("vaild cert validFrom=%04d/%02d/%02d %02d:%02d:%02d\r\n",
317 crt->valid_from.year, crt->valid_from.mon, crt->valid_from.day,
318 crt->valid_from.hour, crt->valid_from.min, crt->valid_from.sec);
319 HILINK_SAL_DEBUG("vaild cert validTo=%04d/%02d/%02d %02d:%02d:%02d\r\n",
320 crt->valid_to.year, crt->valid_to.mon, crt->valid_to.day,
321 crt->valid_to.hour, crt->valid_to.min, crt->valid_to.sec);
322 /* 取证书验证通过里面最大的有效时间 */
323 if (!X509CheckTime(&context->validTo, &crt->valid_to)) {
324 if ((memcpy_s(&context->validFrom, sizeof(mbedtls_x509_time),
325 &crt->valid_from, sizeof(mbedtls_x509_time)) != EOK) ||
326 (memcpy_s(&context->validTo, sizeof(mbedtls_x509_time),
327 &crt->valid_to, sizeof(mbedtls_x509_time)) != EOK)) {
328 HILINK_SAL_ERROR("memcpy_s\r\n");
329 return HILINK_SAL_NOK;
330 }
331 }
332 HILINK_SAL_DEBUG("record cert validFrom=%04d/%02d/%02d %02d:%02d:%02d\r\n",
333 context->validFrom.year, context->validFrom.mon, context->validFrom.day,
334 context->validFrom.hour, context->validFrom.min, context->validFrom.sec);
335 HILINK_SAL_DEBUG("record cert validTo=%04d/%02d/%02d %02d:%02d:%02d\r\n",
336 context->validTo.year, context->validTo.mon, context->validTo.day,
337 context->validTo.hour, context->validTo.min, context->validTo.sec);
338
339 return HILINK_SAL_OK;
340 }
341
VerifyCertProc(void * data,mbedtls_x509_crt * crt,uint32_t * flags)342 static int VerifyCertProc(void *data, mbedtls_x509_crt *crt, uint32_t *flags)
343 {
344 if (data == NULL) {
345 HILINK_SAL_ERROR("invaild context\r\n");
346 return HILINK_SAL_NOK;
347 }
348
349 int ret;
350 HiLinkTlsClient *context = (HiLinkTlsClient *)data;
351 for (unsigned int i = 0; i < context->certsNum; i++) {
352 mbedtls_x509_crt caCert;
353 mbedtls_x509_crt_init(&caCert);
354 ret = mbedtls_x509_crt_parse(&caCert, (const unsigned char *)context->certs[i],
355 HILINK_Strlen(context->certs[i]) + 1);
356 if (ret != 0) {
357 mbedtls_x509_crt_free(&caCert);
358 HILINK_SAL_WARN("i=%u,ret=[-0x%04x]\r\n", i, -ret);
359 continue;
360 }
361 ret = mbedtls_x509_crt_verify(crt, &caCert, NULL, NULL, flags, NULL, NULL);
362 mbedtls_x509_crt_free(&caCert);
363 HILINK_SAL_DEBUG("i=%u,flags=%08x,ret=[-0x%04x]\r\n", i, *flags, -ret);
364 if (ret == 0) {
365 if ((*flags) == 0) {
366 if (RecordVaildCertTime(context, crt) != HILINK_SAL_OK) {
367 HILINK_SAL_ERROR("record vaild cert time\r\n");
368 return HILINK_SAL_NOK;
369 }
370 HILINK_SAL_DEBUG("verify cert okay\r\n");
371 return HILINK_SAL_OK;
372 }
373 } else if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
374 /* 只处理校验时间的错误 */
375 if (((*flags) == MBEDTLS_X509_BADCERT_EXPIRED) || ((*flags) == MBEDTLS_X509_BADCERT_FUTURE) ||
376 ((*flags) == (MBEDTLS_X509_BADCERT_EXPIRED + MBEDTLS_X509_BADCERT_FUTURE))) {
377 if (RecordVaildCertTime(context, crt) != HILINK_SAL_OK) {
378 HILINK_SAL_ERROR("record vaild cert time\r\n");
379 return HILINK_SAL_NOK;
380 }
381 if (context->isDelayVerifyCert) {
382 /* 此时先不检查证书时间,待同步到时间后再校验 */
383 HILINK_SAL_NOTICE("delay verify cert\r\n");
384 *flags &= ~(MBEDTLS_X509_BADCERT_EXPIRED | MBEDTLS_X509_BADCERT_FUTURE);
385 return HILINK_SAL_OK;
386 }
387 }
388 }
389 }
390
391 return HILINK_SAL_NOK;
392 }
393
VerifyCertCb(void * data,mbedtls_x509_crt * crt,int depth,uint32_t * flags)394 static int VerifyCertCb(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
395 {
396 (void)depth;
397 if ((data == NULL) || (crt == NULL) || (flags == NULL)) {
398 HILINK_SAL_ERROR("param invaild\r\n");
399 return HILINK_SAL_NOK;
400 }
401
402 #if defined(HILINK_TLS_DEBUG)
403 char buf[64] = {0}; /* 64为缓冲buf大小 */
404 HILINK_SAL_NOTICE("\nVerify requested for (Depth %d):\n", depth);
405 mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
406 HILINK_SAL_NOTICE("%s", buf);
407 if ((*flags) == 0) {
408 HILINK_SAL_NOTICE("\n This certificate has no flags\n");
409 } else {
410 mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", *flags);
411 HILINK_SAL_NOTICE("%s\n", buf);
412 }
413 #endif /* HILINK_TLS_DEBUG */
414
415 if (VerifyCertProc(data, crt, flags) != HILINK_SAL_OK) {
416 HILINK_SAL_ERROR("verify cert\r\n");
417 }
418 return HILINK_SAL_OK;
419 }
420
SetTlsConfigMaxFragLen(HiLinkTlsClient * context,unsigned char maxFragLen)421 static int SetTlsConfigMaxFragLen(HiLinkTlsClient *context, unsigned char maxFragLen)
422 {
423 int ret;
424 if (maxFragLen != HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_DEFAULT) {
425 ret = mbedtls_ssl_conf_max_frag_len(&context->conf, maxFragLen);
426 if (ret != 0) {
427 HILINK_SAL_ERROR("ret=[-0x%04x]\r\n", -ret);
428 return HILINK_SAL_NOK;
429 }
430 }
431 return HILINK_SAL_OK;
432 }
433
SetTlsConfigBase(HiLinkTlsClient * context)434 static int SetTlsConfigBase(HiLinkTlsClient *context)
435 {
436 int ret = mbedtls_ssl_config_defaults(&context->conf, MBEDTLS_SSL_IS_CLIENT,
437 MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
438 if (ret != 0) {
439 HILINK_SAL_ERROR("ret=[-0x%04x]\r\n", -ret);
440 return HILINK_SAL_NOK;
441 }
442 mbedtls_ssl_conf_rng(&context->conf, SslRngGenerater, context->drbg);
443 mbedtls_ssl_conf_min_version(&context->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
444 mbedtls_ssl_conf_max_version(&context->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
445 mbedtls_ssl_conf_authmode(&context->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
446 return HILINK_SAL_OK;
447 }
448
SetTlsConfigCiphersuites(HiLinkTlsClient * context,const int * ciphersuiteWhiteList,const unsigned int ciphersuiteWhiteListNum)449 static int SetTlsConfigCiphersuites(HiLinkTlsClient *context,
450 const int *ciphersuiteWhiteList, const unsigned int ciphersuiteWhiteListNum)
451 {
452 if (ciphersuiteWhiteList != NULL && ciphersuiteWhiteListNum != 0 && context->supportedCiphersuites == NULL) {
453 /* 支持的白名单算法库肯定比白名单数量少,ciphersuites数组以0为结尾,需预留 */
454 unsigned int maxCiphersuitesNum = ciphersuiteWhiteListNum;
455 int maxSupportedCiphersuitesSize = (maxCiphersuitesNum + 1) * sizeof(int);
456 int *supportedCiphersuites = HILINK_Malloc(maxSupportedCiphersuitesSize);
457 if (supportedCiphersuites == NULL) {
458 HILINK_SAL_ERROR("malloc\r\n");
459 return HILINK_SAL_NOK;
460 }
461 (void)memset_s(supportedCiphersuites, maxSupportedCiphersuitesSize, 0, maxSupportedCiphersuitesSize);
462 /* 从白名单中找到库里支持的 */
463 int *supportSuite = supportedCiphersuites;
464 for (unsigned int i = 0; i < maxCiphersuitesNum; i++) {
465 if (mbedtls_ssl_ciphersuite_from_id(ciphersuiteWhiteList[i]) == NULL) {
466 HILINK_SAL_NOTICE("i=[%u],ciphersuiteWhiteList=[%04x]\r\n", i, ciphersuiteWhiteList[i]);
467 continue;
468 }
469 if (supportSuite < supportedCiphersuites + maxCiphersuitesNum) {
470 *supportSuite = ciphersuiteWhiteList[i];
471 ++supportSuite;
472 }
473 }
474 *supportSuite = 0;
475 if (supportSuite == supportedCiphersuites) {
476 HILINK_Free(supportedCiphersuites);
477 HILINK_SAL_ERROR("no support ciphersuites\r\n");
478 return HILINK_SAL_NOK;
479 }
480 context->supportedCiphersuites = supportedCiphersuites;
481 mbedtls_ssl_conf_ciphersuites(&context->conf, context->supportedCiphersuites);
482 }
483
484 return HILINK_SAL_OK;
485 }
486
SetTlsConfigCert(HiLinkTlsClient * context,const char ** caCerts,const unsigned int certsNum,const bool isDelayVerifyCert)487 static int SetTlsConfigCert(HiLinkTlsClient *context,
488 const char **caCerts, const unsigned int certsNum, const bool isDelayVerifyCert)
489 {
490 (void)context;
491 if ((caCerts != NULL) && (certsNum != 0)) {
492 /* 对于多个证书,这里只注入一个证书,其他证书在回调函数里验证 */
493 int ret = mbedtls_x509_crt_parse(&context->caCert, (const unsigned char *)caCerts[0], strlen(caCerts[0]) + 1);
494 if (ret < 0) {
495 HILINK_SAL_ERROR("ret=[-0x%04x]\r\n", -ret);
496 return HILINK_SAL_NOK;
497 }
498 mbedtls_ssl_conf_ca_chain(&context->conf, &context->caCert, NULL);
499 mbedtls_ssl_conf_verify(&context->conf, VerifyCertCb, context);
500 context->certs = caCerts;
501 context->certsNum = certsNum;
502 context->isDelayVerifyCert = isDelayVerifyCert;
503 }
504
505 return HILINK_SAL_OK;
506 }
507
SetTlsConfigPsk(HiLinkTlsClient * context,const unsigned char * psk,const size_t pskLen,const unsigned char * pskIdentity,const size_t pskIdentityLen)508 static int SetTlsConfigPsk(HiLinkTlsClient *context,
509 const unsigned char *psk, const size_t pskLen, const unsigned char *pskIdentity, const size_t pskIdentityLen)
510 {
511 (void)context;
512 if ((psk != NULL) && (pskLen != 0) && (pskIdentity != NULL) && (pskIdentityLen != 0)) {
513 /*
514 * 如下是配置psk加密的tls客户端,现在hilink用在与中枢的连接
515 */
516 #if (defined(HILINK_SDK_BUILD_IN) && defined(SUPPORT_CENTRAL_TLS)) || \
517 (!defined(HILINK_SDK_BUILD_IN))
518 int ret = mbedtls_ssl_conf_psk(&context->conf, psk, pskLen, pskIdentity, pskIdentityLen);
519 if (ret < 0) {
520 HILINK_SAL_ERROR("ret=[-0x%04x]\r\n", -ret);
521 return HILINK_SAL_NOK;
522 }
523 #endif
524 }
525 return HILINK_SAL_OK;
526 }
527
InitTlsSocket(HiLinkTlsClient * context)528 static int InitTlsSocket(HiLinkTlsClient *context)
529 {
530 int ret;
531 if (context->serverFd.fd < 0) {
532 if (context->hostName != NULL) {
533 char portStr[MAX_PORT_STR_LEN];
534 if (sprintf_s(portStr, sizeof(portStr), "%u", context->port) <= 0) {
535 HILINK_SAL_ERROR("sprintf_s error\r\n");
536 return HILINK_SAL_SPRINTF_ERR;
537 }
538 ret = mbedtls_net_connect(&context->serverFd, context->hostName, portStr,
539 MBEDTLS_NET_PROTO_TCP);
540 if (ret != 0) {
541 HILINK_SAL_ERROR("ret=[-0x%04x],errno=[%d]\r\n", -ret, errno);
542 return ret;
543 }
544 } else {
545 HILINK_SAL_ERROR("no hostname\r\n");
546 return HILINK_SAL_NOK;
547 }
548 }
549 mbedtls_ssl_conf_read_timeout(&context->conf, TLS_READ_TIMEOUT_MS);
550 mbedtls_ssl_set_bio(&context->ssl, &context->serverFd,
551 mbedtls_net_send, NULL, mbedtls_net_recv_timeout);
552
553 return HILINK_SAL_OK;
554 }
555
TlsHandshake(HiLinkTlsClient * context)556 static int TlsHandshake(HiLinkTlsClient *context)
557 {
558 int ret;
559 unsigned long curTime;
560 unsigned long startTime = 0;
561
562 if (GetOsTime(&startTime) != HILINK_SAL_OK) {
563 HILINK_SAL_ERROR("GetOsTime\r\n");
564 return HILINK_SAL_NOK;
565 }
566 do {
567 ret = mbedtls_ssl_handshake(&context->ssl);
568 if (GetOsTime(&curTime) != HILINK_SAL_OK) {
569 HILINK_SAL_ERROR("GetOsTime\r\n");
570 return HILINK_SAL_NOK;
571 }
572 } while (((ret == MBEDTLS_ERR_SSL_WANT_READ) || (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ||
573 (ret == MBEDTLS_ERR_SSL_TIMEOUT)) && (DeltaTime(curTime, startTime) < TLS_HANDSHAKE_TIMEOUT));
574 if (ret != 0) {
575 HILINK_SAL_ERROR("ret=[-0x%04x],errno=[%d]\r\n", -ret, errno);
576 return ret;
577 }
578
579 return HILINK_SAL_OK;
580 }
581
HILINK_TlsClientCreate(const char * custom)582 HiLinkTlsClient *HILINK_TlsClientCreate(const char *custom)
583 {
584 if ((custom == NULL) || (HILINK_Strlen(custom) > MAX_CUSTOM_STR_LEN)) {
585 HILINK_SAL_ERROR("param invaild\r\n");
586 return NULL;
587 }
588 HILINK_SAL_NOTICE("custom=[%s] start tls create\r\n", custom);
589 HiLinkTlsClient *ctx = (HiLinkTlsClient *)HILINK_Malloc(sizeof(HiLinkTlsClient));
590 if (ctx == NULL) {
591 HILINK_SAL_ERROR("malloc error\r\n");
592 return NULL;
593 }
594 (void)memset_s(ctx, sizeof(HiLinkTlsClient), 0, sizeof(HiLinkTlsClient));
595
596 int ret;
597 do {
598 int mallocSize = HILINK_Strlen(custom) + 1;
599 ctx->custom = (char *)HILINK_Malloc(mallocSize);
600 if (ctx->custom == NULL) {
601 HILINK_SAL_ERROR("malloc error\r\n");
602 break;
603 }
604 (void)memset_s(ctx->custom, mallocSize, 0, mallocSize);
605
606 ret = strcpy_s(ctx->custom, mallocSize, custom);
607 if (ret != EOK) {
608 HILINK_SAL_ERROR("strcpy error %d\r\n", ret);
609 break;
610 }
611
612 InitMbedtls();
613 ret = InitTlsContext(ctx);
614 if (ret != HILINK_SAL_OK) {
615 HILINK_SAL_ERROR("init error %d\r\n", ret);
616 break;
617 }
618
619 ret = SetTlsRandomMember(ctx, custom);
620 if (ret != HILINK_SAL_OK) {
621 HILINK_SAL_ERROR("set random error %d\r\n", ret);
622 break;
623 }
624
625 ret = SetTlsConfigBase(ctx);
626 if (ret != HILINK_SAL_OK) {
627 HILINK_SAL_ERROR("set config base error %d\r\n", ret);
628 break;
629 }
630
631 return ctx;
632 } while (0);
633 (void)HILINK_TlsClientFreeResource(ctx);
634 return NULL;
635 }
636
SetTlsClientOptionHost(HiLinkTlsClient * ctx,const void * value,unsigned int len)637 static int SetTlsClientOptionHost(HiLinkTlsClient *ctx, const void *value, unsigned int len)
638 {
639 if ((len != sizeof(HiLinkTlsHost) || (value == NULL))) {
640 HILINK_SAL_WARN("invalid param\r\n");
641 return HILINK_SAL_PARAM_INVALID;
642 }
643 const HiLinkTlsHost *host = (const HiLinkTlsHost *)value;
644 ctx->port = host->port;
645 if (host->hostname == NULL) {
646 HILINK_SAL_INFO("no host name for [%s]\r\n", ctx->custom);
647 return HILINK_SAL_OK;
648 }
649
650 unsigned int hostNameLen = HILINK_Strlen(host->hostname);
651 if (hostNameLen > MAX_HOSTNAME_STR_LEN) {
652 HILINK_SAL_WARN("host name too long [%u]\r\n", hostNameLen);
653 return HILINK_SAL_PARAM_INVALID;
654 }
655 int ret = mbedtls_ssl_set_hostname(&ctx->ssl, host->hostname);
656 if (ret != 0) {
657 HILINK_SAL_ERROR("set host name error, ret=[-0x%04x]\r\n", -ret);
658 return HILINK_SAL_NOK;
659 }
660 if (ctx->hostName != NULL) {
661 HILINK_Free(ctx->hostName);
662 ctx->hostName = NULL;
663 }
664 ctx->hostName = (char *)HILINK_Malloc(hostNameLen + 1);
665 if (ctx->hostName == NULL) {
666 HILINK_SAL_ERROR("malloc error\r\n");
667 return HILINK_SAL_NOK;
668 }
669 (void)memset_s(ctx->hostName, hostNameLen + 1, 0, hostNameLen + 1);
670 ret = strcpy_s(ctx->hostName, hostNameLen + 1, host->hostname);
671 if (ret != EOK) {
672 HILINK_SAL_ERROR("strcpy error %d\r\n", ret);
673 HILINK_Free(ctx->hostName);
674 ctx->hostName = NULL;
675 return HILINK_SAL_NOK;
676 }
677
678 return HILINK_SAL_OK;
679 }
680
SetTlsClientOptionFd(HiLinkTlsClient * ctx,const void * value,unsigned int len)681 static int SetTlsClientOptionFd(HiLinkTlsClient *ctx, const void *value, unsigned int len)
682 {
683 if ((len != sizeof(int) || (value == NULL))) {
684 HILINK_SAL_WARN("invalid param");
685 return HILINK_SAL_PARAM_INVALID;
686 }
687
688 int fd = *(const int *)value;
689 if (fd < 0) {
690 HILINK_SAL_WARN("invalid fd");
691 return HILINK_SAL_PARAM_INVALID;
692 }
693 ctx->serverFd.fd = fd;
694
695 return HILINK_SAL_OK;
696 }
697
SetTlsClientOptiontTimeCallback(HiLinkTlsClient * ctx,const void * value,unsigned int len)698 static int SetTlsClientOptiontTimeCallback(HiLinkTlsClient *ctx, const void *value, unsigned int len)
699 {
700 (void)ctx;
701 if ((len != sizeof(HiLinkMbedtlsGetTimeCb)) || (value == NULL)) {
702 HILINK_SAL_WARN("invalid param");
703 return HILINK_SAL_PARAM_INVALID;
704 }
705
706 g_mbedtlsGetTimeCb = (HiLinkMbedtlsGetTimeCb)value;
707 return HILINK_SAL_OK;
708 }
709
SetTlsClientOptiontCiphersuite(HiLinkTlsClient * ctx,const void * value,unsigned int len)710 static int SetTlsClientOptiontCiphersuite(HiLinkTlsClient *ctx, const void *value, unsigned int len)
711 {
712 if ((len != sizeof(HiLinkTlsCiphersuites)) || (value == NULL)) {
713 HILINK_SAL_WARN("invalid param\r\n");
714 return HILINK_SAL_PARAM_INVALID;
715 }
716
717 const HiLinkTlsCiphersuites *suites = (const HiLinkTlsCiphersuites *)value;
718 if ((suites->ciphersuites == NULL) || (suites->num == 0)) {
719 HILINK_SAL_WARN("invalid suites\r\n");
720 return HILINK_SAL_PARAM_INVALID;
721 }
722 return SetTlsConfigCiphersuites(ctx, suites->ciphersuites, suites->num);
723 }
724
SetTlsClientOptiontCert(HiLinkTlsClient * ctx,const void * value,unsigned int len)725 static int SetTlsClientOptiontCert(HiLinkTlsClient *ctx, const void *value, unsigned int len)
726 {
727 if ((len != sizeof(HiLlinkTlsCerts)) || (value == NULL)) {
728 HILINK_SAL_WARN("invalid param\r\n");
729 return HILINK_SAL_PARAM_INVALID;
730 }
731
732 const HiLlinkTlsCerts *certs = (const HiLlinkTlsCerts *)value;
733 if ((certs->certs == NULL) || (certs->num == 0)) {
734 HILINK_SAL_WARN("invalid certs\r\n");
735 return HILINK_SAL_PARAM_INVALID;
736 }
737 return SetTlsConfigCert(ctx, certs->certs, certs->num, certs->num);
738 }
739
SetTlsClientOptiontPsk(HiLinkTlsClient * ctx,const void * value,unsigned int len)740 static int SetTlsClientOptiontPsk(HiLinkTlsClient *ctx, const void *value, unsigned int len)
741 {
742 if ((len != sizeof(HiLlinkTlsPsk)) || (value == NULL)) {
743 HILINK_SAL_WARN("invalid param\r\n");
744 return HILINK_SAL_PARAM_INVALID;
745 }
746
747 const HiLlinkTlsPsk *psk = (const HiLlinkTlsPsk *)value;
748 if ((psk->psk == NULL) || (psk->pskLen == 0) || (psk->pskIdentity == NULL) ||
749 (psk->pskIdentityLen == 0)) {
750 HILINK_SAL_WARN("invalid psk\r\n");
751 return HILINK_SAL_PARAM_INVALID;
752 }
753 return SetTlsConfigPsk(ctx, psk->psk, psk->pskLen, psk->pskIdentity, psk->pskIdentityLen);
754 }
755
SetTlsClientOptiontMaxFragLen(HiLinkTlsClient * ctx,const void * value,unsigned int len)756 static int SetTlsClientOptiontMaxFragLen(HiLinkTlsClient *ctx, const void *value, unsigned int len)
757 {
758 if ((len != sizeof(unsigned char)) || (value == NULL)) {
759 HILINK_SAL_WARN("invalid param\r\n");
760 return HILINK_SAL_PARAM_INVALID;
761 }
762
763 unsigned char fragLenType = *(const unsigned char *)value;
764
765 return SetTlsConfigMaxFragLen(ctx, fragLenType);
766 }
767
HILINK_SetTlsClientOption(HiLinkTlsClient * ctx,HiLinkTlsOption option,const void * value,unsigned int len)768 int HILINK_SetTlsClientOption(HiLinkTlsClient *ctx, HiLinkTlsOption option, const void *value, unsigned int len)
769 {
770 if (ctx == NULL) {
771 HILINK_SAL_ERROR("param invaild\r\n");
772 return HILINK_SAL_NOK;
773 }
774
775 static const OptionItem optionList[] = {
776 {HILINK_TLS_OPTION_FD, SetTlsClientOptionFd},
777 {HILINK_TLS_OPTION_REG_TIME_CB, SetTlsClientOptiontTimeCallback},
778 {HILINK_TLS_OPTION_HOST, SetTlsClientOptionHost},
779 {HILINK_TLS_OPTION_CIPHERSUITE, SetTlsClientOptiontCiphersuite},
780 {HILINK_TLS_OPTION_CERT, SetTlsClientOptiontCert},
781 {HILINK_TLS_OPTION_PSK, SetTlsClientOptiontPsk},
782 {HILINK_TLS_OPTION_MAX_FRAG_LEN, SetTlsClientOptiontMaxFragLen},
783 };
784 for (unsigned int i = 0; i < (sizeof(optionList) / sizeof(OptionItem)); ++i) {
785 if (option == optionList[i].option) {
786 return optionList[i].setOptionFunc(ctx, value, len);
787 }
788 }
789 HILINK_SAL_WARN("unsupport option %d\r\n", option);
790 return HILINK_SAL_NOT_SUPPORT;
791 }
792
HILINK_TlsClientConnect(HiLinkTlsClient * ctx)793 int HILINK_TlsClientConnect(HiLinkTlsClient *ctx)
794 {
795 if (ctx == NULL) {
796 HILINK_SAL_ERROR("param invaild\r\n");
797 return HILINK_SAL_PARAM_INVALID;
798 }
799
800 int ret = InitTlsSocket(ctx);
801 if (ret != HILINK_SAL_OK) {
802 HILINK_SAL_ERROR("init socket error\r\n");
803 return ret;
804 }
805
806 ret = mbedtls_ssl_setup(&ctx->ssl, &ctx->conf);
807 if (ret != 0) {
808 HILINK_SAL_ERROR("ret=[-0x%04x]\r\n", -ret);
809 return ret;
810 }
811
812 ret = TlsHandshake(ctx);
813 if (ret != HILINK_SAL_OK) {
814 HILINK_SAL_ERROR("handshake\r\n");
815 return ret;
816 }
817
818 return HILINK_SAL_OK;
819 }
820
HILINK_TlsClientGetContextFd(HiLinkTlsClient * ctx)821 int HILINK_TlsClientGetContextFd(HiLinkTlsClient *ctx)
822 {
823 if (ctx == NULL) {
824 HILINK_SAL_DEBUG("param invaild\r\n");
825 return -1;
826 }
827
828 return ctx->serverFd.fd;
829 }
830
HILINK_TlsClientRead(HiLinkTlsClient * ctx,unsigned char * buf,size_t len)831 int HILINK_TlsClientRead(HiLinkTlsClient *ctx, unsigned char *buf, size_t len)
832 {
833 if ((ctx == NULL) || (buf == NULL) || (len == 0)) {
834 HILINK_SAL_ERROR("param invaild\r\n");
835 return HILINK_SAL_PARAM_INVALID;
836 }
837
838 if (ctx->serverFd.fd < 0) {
839 HILINK_SAL_ERROR("context invaild\r\n");
840 return HILINK_SAL_FD_INVALID;
841 }
842
843 int ret = mbedtls_ssl_read(&ctx->ssl, buf, len);
844 if (ret > 0) {
845 HILINK_SAL_DEBUG("read exit,custom=[%s],len=[%d]\r\n", ctx->custom, ret);
846 return ret;
847 } else if (ret == 0) {
848 HILINK_SAL_ERROR("custom=[%s],ret=[%d],errno=[%d]\r\n", ctx->custom, ret, errno);
849 return HILINK_SAL_NOK;
850 } else if ((ret == MBEDTLS_ERR_SSL_TIMEOUT) ||
851 (ret == MBEDTLS_ERR_SSL_WANT_WRITE) || (ret == MBEDTLS_ERR_SSL_WANT_READ)) {
852 return HILINK_SAL_OK;
853 }
854
855 HILINK_SAL_ERROR("custom=[%s],ret=[-0x%04x],errno=[%d]\r\n", ctx->custom, -ret, errno);
856 return ret;
857 }
858
HILINK_TlsClientWrite(HiLinkTlsClient * ctx,const unsigned char * buf,size_t len)859 int HILINK_TlsClientWrite(HiLinkTlsClient *ctx, const unsigned char *buf, size_t len)
860 {
861 if ((ctx == NULL) || (buf == NULL) || (len == 0)) {
862 HILINK_SAL_ERROR("param invaild\r\n");
863 return HILINK_SAL_PARAM_INVALID;
864 }
865
866 if (ctx->serverFd.fd < 0) {
867 HILINK_SAL_ERROR("context invaild\r\n");
868 return HILINK_SAL_FD_INVALID;
869 }
870
871 unsigned long curTime = 0;
872 unsigned long startTime = 0;
873 if (GetOsTime(&startTime) != HILINK_SAL_OK) {
874 return HILINK_SAL_TIME_ERR;
875 }
876
877 int writeLen = 0;
878 while ((size_t)writeLen < len) {
879 if (GetOsTime(&curTime) != HILINK_SAL_OK) {
880 return HILINK_SAL_TIME_ERR;
881 }
882
883 if (DeltaTime(curTime, startTime) > GetTlsTimeoutTime(len)) {
884 HILINK_SAL_ERROR("tls write timeout,writeLen=[%d],len=[%u]\r\n", writeLen, len);
885 return HILINK_SAL_TIMEOUT;
886 }
887
888 int ret = mbedtls_ssl_write(&ctx->ssl, buf + writeLen, len - writeLen);
889 if (ret > 0) {
890 writeLen += ret;
891 HILINK_SAL_DEBUG("custom=[%s],writeLen=[%d]\r\n", ctx->custom, writeLen);
892 continue;
893 } else if (ret == 0) {
894 HILINK_SAL_ERROR("custom=[%s],ret=[%d],errno=[%d]\r\n", ctx->custom, ret, errno);
895 return HILINK_SAL_NOK;
896 } else if ((ret == MBEDTLS_ERR_SSL_TIMEOUT) ||
897 (ret == MBEDTLS_ERR_SSL_WANT_WRITE) || (ret == MBEDTLS_ERR_SSL_WANT_READ)) {
898 HILINK_MilliSleep(1);
899 continue;
900 } else {
901 HILINK_SAL_ERROR("custom=[%s],ret=[-0x%04x],errno=[%d]\r\n", ctx->custom, -ret, errno);
902 return ret;
903 }
904 }
905
906 return writeLen;
907 }
908
HILINK_TlsClientIsValidCert(HiLinkTlsClient * ctx)909 bool HILINK_TlsClientIsValidCert(HiLinkTlsClient *ctx)
910 {
911 if (ctx == NULL) {
912 HILINK_SAL_NOTICE("param invaild\r\n");
913 return false;
914 }
915
916 int ret;
917 ret = mbedtls_x509_time_is_future(&ctx->validFrom);
918 if (ret != 0) {
919 HILINK_SAL_ERROR("ret=[%d]\r\n", ret);
920 return false;
921 }
922 ret = mbedtls_x509_time_is_past(&ctx->validTo);
923 if (ret != 0) {
924 HILINK_SAL_ERROR("ret=[%d]\r\n", ret);
925 return false;
926 }
927
928 return true;
929 }
930
HILINK_TlsClientFreeResource(HiLinkTlsClient * ctx)931 int HILINK_TlsClientFreeResource(HiLinkTlsClient *ctx)
932 {
933 if (ctx == NULL) {
934 HILINK_SAL_NOTICE("param invaild\r\n");
935 return HILINK_SAL_NOK;
936 }
937
938 mbedtls_ssl_free(&ctx->ssl);
939 mbedtls_net_free(&ctx->serverFd);
940 mbedtls_ssl_config_free(&ctx->conf);
941 mbedtls_x509_crt_free(&ctx->caCert);
942 HILINK_SAL_DrbgDeinit(ctx->drbg);
943 ctx->drbg = NULL;
944 HILINK_Free(ctx->supportedCiphersuites);
945 ctx->supportedCiphersuites = NULL;
946 if (ctx->custom != NULL) {
947 HILINK_SAL_NOTICE("custom=[%s] free resource success\r\n", ctx->custom);
948 HILINK_Free(ctx->custom);
949 ctx->custom = NULL;
950 }
951 if (ctx->hostName != NULL) {
952 HILINK_Free(ctx->hostName);
953 ctx->hostName = NULL;
954 }
955 HILINK_Free(ctx);
956 return HILINK_SAL_OK;
957 }