• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }