1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/socket.h>
10
11 #include "aos/errno.h"
12 #include "aos/kernel.h"
13 #include "aos/kv.h"
14 #include "ulog/ulog.h"
15
16
17 #ifdef AOS_COMP_UND
18 #include "und/und.h"
19 #endif
20
21 #include "mbedtls/error.h"
22 #include "mbedtls/ssl.h"
23 #include "mbedtls/net.h"
24 #include "mbedtls/x509_crt.h"
25 #include "mbedtls/pk.h"
26 #include "mbedtls/debug.h"
27 #include "mbedtls/platform.h"
28 #include "linkkit/wrappers/wrappers_defs.h"
29 #include "linkkit/wrappers/wrappers_os.h"
30 #ifdef HAL_TLS_DNS_ENHANCE
31 #include "dns.h"
32 #endif
33 #define LOG_TAG "HAL_TLS"
34
35 #define platform_info(format, ...) LOGI(LOG_TAG, format, ##__VA_ARGS__)
36 #define platform_err(format, ...) LOGE(LOG_TAG, format, ##__VA_ARGS__)
37
38 #define SEND_TIMEOUT_SECONDS (10)
39
40 #define DEBUG_LEVEL 10
41
42 typedef struct _TLSDataParams {
43 mbedtls_ssl_context ssl; /**< mbed TLS control context. */
44 mbedtls_net_context fd; /**< mbed TLS network context. */
45 mbedtls_ssl_config conf; /**< mbed TLS configuration context. */
46 mbedtls_x509_crt cacertl; /**< mbed TLS CA certification. */
47 mbedtls_x509_crt clicert; /**< mbed TLS Client certification. */
48 mbedtls_pk_context pkey; /**< mbed TLS Client key. */
49 } TLSDataParams_t, *TLSDataParams_pt;
50
51 #ifdef HAL_TLS_DNS_ENHANCE
52 static char *g_fixed_list[3] = { "106.15.83.29", "106.15.100.2",
53 "139.196.135.135" };
54 #endif
55
56 #if defined(TLS_SAVE_TICKET)
57
58 #define KEY_MAX_LEN 64
59 #define TLS_MAX_SESSION_BUF 384
60 #define KV_SESSION_KEY_FMT "TLS_%s"
61
62 extern int HAL_Kv_Set(const char *key, const void *val, int len, int sync);
63
64 extern int HAL_Kv_Get(const char *key, void *val, int *buffer_len);
65
66 static mbedtls_ssl_session *saved_session = NULL;
67
ssl_serialize_session(const mbedtls_ssl_session * session,unsigned char * buf,size_t buf_len,size_t * olen)68 static int ssl_serialize_session(const mbedtls_ssl_session *session,
69 unsigned char *buf, size_t buf_len,
70 size_t *olen)
71 {
72 unsigned char *p = buf;
73 size_t left = buf_len;
74
75 if (left < sizeof(mbedtls_ssl_session)) {
76 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
77 }
78
79 memcpy(p, session, sizeof(mbedtls_ssl_session));
80 p += sizeof(mbedtls_ssl_session);
81 left -= sizeof(mbedtls_ssl_session);
82 #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
83 if (left < sizeof(mbedtls_ssl_session)) {
84 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
85 }
86 memcpy(p, session->ticket, session->ticket_len);
87 p += session->ticket_len;
88 left -= session->ticket_len;
89 #endif
90
91 *olen = p - buf;
92
93 return 0;
94 }
95
ssl_deserialize_session(mbedtls_ssl_session * session,const unsigned char * buf,size_t len)96 static int ssl_deserialize_session(mbedtls_ssl_session *session,
97 const unsigned char *buf, size_t len)
98 {
99 const unsigned char *p = buf;
100 const unsigned char *const end = buf + len;
101
102 if (sizeof(mbedtls_ssl_session) > (size_t)(end - p)) {
103 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
104 }
105
106 memcpy(session, p, sizeof(mbedtls_ssl_session));
107 p += sizeof(mbedtls_ssl_session);
108 #if defined(MBEDTLS_X509_CRT_PARSE_C)
109 session->peer_cert = NULL;
110 #endif
111
112 #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
113 if (session->ticket_len > 0) {
114 if (session->ticket_len > (size_t)(end - p)) {
115 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
116 }
117 session->ticket = HAL_Malloc(session->ticket_len);
118 if (session->ticket == NULL) {
119 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
120 }
121 memcpy(session->ticket, p, session->ticket_len);
122 p += session->ticket_len;
123 printf("saved ticket len = %d \r\n", (int)session->ticket_len);
124 }
125 #endif
126
127 if (p != end) {
128 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
129 }
130
131 return 0;
132 }
133 #endif
134
135 #ifdef HAL_TLS_DNS_ENHANCE
utils_str2uint(char * input,uint8_t input_len,uint32_t * output)136 static void utils_str2uint(char *input, uint8_t input_len, uint32_t *output)
137 {
138 uint8_t index = 0;
139 uint32_t temp = 0;
140
141 for (index = 0; index < input_len; index++) {
142 if (input[index] < '0' || input[index] > '9') {
143 return;
144 }
145 temp = temp * 10 + input[index] - '0';
146 }
147 *output = temp;
148 }
149
mbedtls_net_connect_timeout_backup(mbedtls_net_context * ctx,const char * host,const char * port,int proto,unsigned int timeout)150 static int mbedtls_net_connect_timeout_backup(mbedtls_net_context *ctx,
151 const char *host,
152 const char *port, int proto,
153 unsigned int timeout)
154 {
155 int ret;
156 struct sockaddr_in address;
157 size_t addr_len;
158 struct timeval sendtimeout;
159 uint8_t dns_retry = 0, dns_count = 0;
160 uint32_t uint_port = 0;
161 char *ip[DNS_RESULT_COUNT] = { 0 };
162
163 memset(&address, 0, sizeof(struct sockaddr_in));
164 utils_str2uint((char *)port, strlen(port), &uint_port);
165
166 while (dns_retry++ < 8) {
167 ret = dns_getaddrinfo((char *)host, ip);
168 if (ret != 0) {
169 platform_info(
170 "getaddrinfo error[%d], res: %d, host: %s, port: %s\n",
171 dns_retry, ret, host, port);
172 HAL_SleepMs(1000);
173 continue;
174 } else {
175 break;
176 }
177 }
178 if (ret != 0) {
179 // try fixed ip:
180 if (strstr(host, "iot-as-mqtt.cn-shanghai.aliyuncs.com") != NULL) {
181 int i;
182 for (i = 0; i < 3; i++) {
183 ip[i] = g_fixed_list[i];
184 }
185 platform_info("using fixed ip\n");
186 } else {
187 return MBEDTLS_ERR_NET_UNKNOWN_HOST;
188 }
189 }
190
191 /* Try the sockaddrs until a connection succeeds */
192 ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
193 for (dns_count = 0; dns_count < DNS_RESULT_COUNT; dns_count++) {
194 if (ip[dns_count] == NULL || strlen(ip[dns_count]) == 0) {
195 continue;
196 }
197 platform_info("ip address: %s\n", ip[dns_count]);
198
199 ctx->fd = (int)socket(AF_INET, SOCK_STREAM, 0);
200 if (ctx->fd < 0) {
201 ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
202 continue;
203 }
204
205 sendtimeout.tv_sec = timeout;
206 sendtimeout.tv_usec = 0;
207
208 if (0 != setsockopt(ctx->fd, SOL_SOCKET, SO_SNDTIMEO, &sendtimeout,
209 sizeof(sendtimeout))) {
210 platform_err("setsockopt error");
211 }
212 platform_info("setsockopt SO_SNDTIMEO timeout: %ds",
213 sendtimeout.tv_sec);
214
215 address.sin_family = AF_INET;
216 address.sin_addr.s_addr = inet_addr(ip[dns_count]);
217 address.sin_port = htons(uint_port);
218
219 addr_len = sizeof(address);
220
221 if (connect(ctx->fd, (struct sockaddr *)&address, addr_len) == 0) {
222 ret = 0;
223 break;
224 }
225
226 close(ctx->fd);
227 ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
228 }
229
230 return ret;
231 }
232 #endif
233
_avRandom()234 static unsigned int _avRandom()
235 {
236 return ((unsigned int)aos_rand() << 16) + aos_rand();
237 }
238
_ssl_random(void * p_rng,unsigned char * output,size_t output_len)239 static int _ssl_random(void *p_rng, unsigned char *output, size_t output_len)
240 {
241 uint32_t rnglen = output_len;
242 uint8_t rngoffset = 0;
243
244 while (rnglen > 0) {
245 *(output + rngoffset) = (unsigned char)_avRandom();
246 rngoffset++;
247 rnglen--;
248 }
249 return 0;
250 }
251
_aos_srand(unsigned int seed)252 static void _aos_srand(unsigned int seed)
253 {
254 #define SEED_MAGIC 0x123
255 int ret = 0;
256 int seed_len = 0;
257 unsigned int seed_val = 0;
258 static char *g_seed_key = "seed_key";
259
260 seed_len = sizeof(seed_val);
261 ret = aos_kv_get(g_seed_key, &seed_val, &seed_len);
262 if (ret) {
263 seed_val = SEED_MAGIC;
264 }
265 seed_val += seed;
266 srand(seed_val);
267
268 seed_val = rand();
269 aos_kv_set(g_seed_key, &seed_val, sizeof(seed_val), 1);
270 }
271
_ssl_debug(void * ctx,int level,const char * file,int line,const char * str)272 static void _ssl_debug(void *ctx, int level, const char *file, int line,
273 const char *str)
274 {
275 ((void)level);
276 if (NULL != ctx) {
277 platform_info("%s", str);
278 }
279 }
280
_real_confirm(int verify_result)281 static int _real_confirm(int verify_result)
282 {
283 platform_info("certificate verification result: 0x%02x", verify_result);
284
285 #if defined(FORCE_SSL_VERIFY)
286 if ((verify_result & MBEDTLS_X509_BADCERT_EXPIRED) != 0) {
287 platform_err("! fail ! ERROR_CERTIFICATE_EXPIRED");
288 return -1;
289 }
290
291 if ((verify_result & MBEDTLS_X509_BADCERT_REVOKED) != 0) {
292 platform_err("! fail ! server certificate has been revoked");
293 return -1;
294 }
295
296 if ((verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) != 0) {
297 platform_err("! fail ! CN mismatch");
298 return -1;
299 }
300
301 if ((verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) != 0) {
302 platform_err("! fail ! self-signed or not signed by a trusted CA");
303 return -1;
304 }
305 #endif
306
307 return 0;
308 }
309
_ssl_client_init(mbedtls_ssl_context * ssl,mbedtls_net_context * tcp_fd,mbedtls_ssl_config * conf,mbedtls_x509_crt * crt509_ca,const char * ca_crt,size_t ca_len,mbedtls_x509_crt * crt509_cli,const char * cli_crt,size_t cli_len,mbedtls_pk_context * pk_cli,const char * cli_key,size_t key_len,const char * cli_pwd,size_t pwd_len)310 static int _ssl_client_init(mbedtls_ssl_context *ssl,
311 mbedtls_net_context *tcp_fd,
312 mbedtls_ssl_config *conf,
313 mbedtls_x509_crt *crt509_ca, const char *ca_crt,
314 size_t ca_len, mbedtls_x509_crt *crt509_cli,
315 const char *cli_crt, size_t cli_len,
316 mbedtls_pk_context *pk_cli, const char *cli_key,
317 size_t key_len, const char *cli_pwd, size_t pwd_len)
318 {
319 int ret = -1;
320
321 /*
322 * 0. Initialize the RNG and the session data
323 */
324 #if defined(MBEDTLS_DEBUG_C)
325 mbedtls_debug_set_threshold((int)DEBUG_LEVEL);
326 #endif
327 aos_srand((uint32_t)aos_now_ms());
328
329 mbedtls_net_init(tcp_fd);
330 mbedtls_ssl_init(ssl);
331 mbedtls_ssl_config_init(conf);
332 mbedtls_x509_crt_init(crt509_ca);
333 _aos_srand(aos_now_ms());
334 /*verify_source->trusted_ca_crt==NULL
335 * 0. Initialize certificates
336 */
337 platform_info("Loading the CA root certificate ...");
338 if (NULL != ca_crt) {
339 ret = mbedtls_x509_crt_parse(
340 crt509_ca, (const unsigned char *)ca_crt, ca_len);
341 if (ret != 0) {
342 platform_err(" failed ! x509parse_crt returned -0x%04x", -ret);
343 return ret;
344 }
345 }
346 platform_info(" ok (%d skipped)", ret);
347
348 /* Setup Client Cert/Key */
349 #if defined(MBEDTLS_X509_CRT_PARSE_C)
350 #if defined(MBEDTLS_CERTS_C)
351 mbedtls_x509_crt_init(crt509_cli);
352 mbedtls_pk_init(pk_cli);
353 #endif
354 if (cli_crt != NULL && cli_key != NULL) {
355 #if defined(MBEDTLS_CERTS_C)
356 platform_info("start prepare client cert .");
357 ret = mbedtls_x509_crt_parse(crt509_cli, (const unsigned char *)cli_crt,
358 cli_len);
359 #else
360 {
361 ret = 1;
362 platform_err("MBEDTLS_CERTS_C not defined.");
363 }
364 #endif
365 if (ret != 0) {
366 platform_err(" failed! mbedtls_x509_crt_parse returned -0x%x\n",
367 -ret);
368 return ret;
369 }
370
371 #if defined(MBEDTLS_CERTS_C)
372 platform_info("start mbedtls_pk_parse_key[%s]", cli_pwd);
373 ret = mbedtls_pk_parse_key(pk_cli, (const unsigned char *)cli_key,
374 key_len, (const unsigned char *)cli_pwd,
375 pwd_len);
376 #else
377 {
378 ret = 1;
379 platform_err("MBEDTLS_CERTS_C not defined.");
380 }
381 #endif
382
383 if (ret != 0) {
384 platform_err(" failed\n ! mbedtls_pk_parse_key returned -0x%x\n",
385 -ret);
386 return ret;
387 }
388 }
389 #endif /* MBEDTLS_X509_CRT_PARSE_C */
390
391 return 0;
392 }
393
394 /**
395 * @brief This function connects to the specific SSL server with TLS, and
396 * returns a value that indicates whether the connection is create successfully
397 * or not. Call #NewNetwork() to initialize network structure before calling
398 * this function.
399 * @param[in] n is the the network structure pointer.
400 * @param[in] addr is the Server Host name or IP address.
401 * @param[in] port is the Server Port.
402 * @param[in] ca_crt is the Server's CA certification.
403 * @param[in] ca_crt_len is the length of Server's CA certification.
404 * @param[in] client_crt is the client certification.
405 * @param[in] client_crt_len is the length of client certification.
406 * @param[in] client_key is the client key.
407 * @param[in] client_key_len is the length of client key.
408 * @param[in] client_pwd is the password of client key.
409 * @param[in] client_pwd_len is the length of client key's password.
410 * @sa #NewNetwork();
411 * @return If the return value is 0, the connection is created successfully. If
412 * the return value is -1, then calling lwIP #socket() has failed. If the return
413 * value is -2, then calling lwIP #connect() has failed. Any other value
414 * indicates that calling lwIP #getaddrinfo() has failed.
415 */
_TLSConnectNetwork(TLSDataParams_t * pTlsData,const char * addr,const char * port,const char * ca_crt,size_t ca_crt_len,const char * client_crt,size_t client_crt_len,const char * client_key,size_t client_key_len,const char * client_pwd,size_t client_pwd_len)416 static int _TLSConnectNetwork(TLSDataParams_t *pTlsData, const char *addr,
417 const char *port, const char *ca_crt,
418 size_t ca_crt_len, const char *client_crt,
419 size_t client_crt_len, const char *client_key,
420 size_t client_key_len, const char *client_pwd,
421 size_t client_pwd_len)
422 {
423 int ret = -1;
424 /*
425 * 0. Init
426 */
427 ret = _ssl_client_init(&(pTlsData->ssl), &(pTlsData->fd),
428 &(pTlsData->conf), &(pTlsData->cacertl), ca_crt,
429 ca_crt_len, &(pTlsData->clicert), client_crt,
430 client_crt_len, &(pTlsData->pkey), client_key,
431 client_key_len, client_pwd, client_pwd_len);
432 if (ret != 0) {
433 platform_err(" failed ! ssl_client_init returned -0x%04x", -ret);
434 return ret;
435 }
436
437 /*
438 * 1. Start the connection
439 */
440 platform_info("Connecting to /%s/%s...", addr, port);
441 do {
442 ret = mbedtls_net_connect(&(pTlsData->fd), addr, port,
443 MBEDTLS_NET_PROTO_TCP);
444 if (ret == 0) {
445 break;
446 }
447
448 platform_err(" connect failed ! net_connect returned -0x%04x", -ret);
449 #if defined(HAL_TLS_DNS_ENHANCE)
450 ret = mbedtls_net_connect_timeout_backup(&(pTlsData->fd), addr, port,
451 MBEDTLS_NET_PROTO_TCP,
452 SEND_TIMEOUT_SECONDS);
453 if (ret == 0) {
454 break;
455 }
456 platform_err(" backup failed ! net_connect returned -0x%04x", -ret);
457 #endif
458
459 #ifdef AOS_COMP_UND
460 if (ret == MBEDTLS_ERR_NET_UNKNOWN_HOST) {
461 und_update_statis(UND_STATIS_NETWORK_FAIL_IDX,
462 UND_STATIS_NETWORK_DNS_FIAL_REASON);
463 } else {
464 und_update_statis(UND_STATIS_NETWORK_FAIL_IDX,
465 UND_STATIS_NETWORK_TCP_FAIL_REASON);
466 }
467 #endif
468 return ret;
469 } while (0);
470
471 platform_info(" ok");
472
473 /*
474 * 2. Setup stuff
475 */
476 platform_info(" . Setting up the SSL/TLS structure...");
477 ret = mbedtls_ssl_config_defaults(
478 &(pTlsData->conf), MBEDTLS_SSL_IS_CLIENT,
479 MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
480 if (ret != 0) {
481 platform_err(" failed! mbedtls_ssl_config_defaults returned %d", ret);
482 #ifdef AOS_COMP_UND
483 und_update_statis(UND_STATIS_NETWORK_FAIL_IDX,
484 UND_STATIS_NETWORK_TLS_FAIL_REASON);
485 #endif
486 return ret;
487 }
488
489 mbedtls_ssl_conf_max_version(&pTlsData->conf, MBEDTLS_SSL_MAJOR_VERSION_3,
490 MBEDTLS_SSL_MINOR_VERSION_3);
491 mbedtls_ssl_conf_min_version(&pTlsData->conf, MBEDTLS_SSL_MAJOR_VERSION_3,
492 MBEDTLS_SSL_MINOR_VERSION_3);
493
494 platform_info(" ok");
495
496 /* OPTIONAL is not optimal for security, but makes interop easier in this
497 * simplified example */
498 if (ca_crt != NULL) {
499 #if defined(FORCE_SSL_VERIFY)
500 mbedtls_ssl_conf_authmode(&(pTlsData->conf),
501 MBEDTLS_SSL_VERIFY_REQUIRED);
502 #else
503 mbedtls_ssl_conf_authmode(&(pTlsData->conf),
504 MBEDTLS_SSL_VERIFY_OPTIONAL);
505 #endif
506 } else {
507 mbedtls_ssl_conf_authmode(&(pTlsData->conf), MBEDTLS_SSL_VERIFY_NONE);
508 }
509
510 #if defined(MBEDTLS_X509_CRT_PARSE_C)
511 mbedtls_ssl_conf_ca_chain(&(pTlsData->conf), &(pTlsData->cacertl), NULL);
512
513 ret = mbedtls_ssl_conf_own_cert(
514 &(pTlsData->conf), &(pTlsData->clicert), &(pTlsData->pkey));
515 if (ret != 0) {
516 platform_err(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n",
517 ret);
518 #ifdef AOS_COMP_UND
519 und_update_statis(UND_STATIS_NETWORK_FAIL_IDX,
520 UND_STATIS_NETWORK_TLS_FAIL_REASON);
521 #endif
522 return ret;
523 }
524 #endif
525 mbedtls_ssl_conf_rng(&(pTlsData->conf), _ssl_random, NULL);
526 mbedtls_ssl_conf_dbg(&(pTlsData->conf), _ssl_debug, NULL);
527 /* mbedtls_ssl_conf_dbg( &(pTlsData->conf), _ssl_debug, stdout ); */
528
529 ret = mbedtls_ssl_setup(&(pTlsData->ssl), &(pTlsData->conf));
530 if (ret != 0) {
531 platform_err("failed! mbedtls_ssl_setup returned %d", ret);
532 #ifdef AOS_COMP_UND
533 und_update_statis(UND_STATIS_NETWORK_FAIL_IDX,
534 UND_STATIS_NETWORK_TLS_FAIL_REASON);
535 #endif
536 return ret;
537 }
538 #if defined(ON_PRE) || defined(ON_DAILY)
539 platform_err(
540 "SKIPPING mbedtls_ssl_set_hostname() when ON_PRE or ON_DAILY defined!");
541 #else
542 mbedtls_ssl_set_hostname(&(pTlsData->ssl), addr);
543 #endif
544 mbedtls_ssl_set_bio(&(pTlsData->ssl), &(pTlsData->fd), mbedtls_net_send,
545 mbedtls_net_recv, mbedtls_net_recv_timeout);
546
547 #if defined(TLS_SAVE_TICKET)
548 if (NULL == saved_session) {
549 do {
550 int len = TLS_MAX_SESSION_BUF;
551 unsigned char *save_buf = HAL_Malloc(TLS_MAX_SESSION_BUF);
552 char key_buf[KEY_MAX_LEN] = { 0 };
553 if (save_buf == NULL) {
554 printf(" malloc failed\r\n");
555 break;
556 }
557
558 saved_session = HAL_Malloc(sizeof(mbedtls_ssl_session));
559
560 if (saved_session == NULL) {
561 printf(" malloc failed\r\n");
562 HAL_Free(save_buf);
563 save_buf = NULL;
564 break;
565 }
566
567 memset(save_buf, 0x00, TLS_MAX_SESSION_BUF);
568 memset(saved_session, 0x00, sizeof(mbedtls_ssl_session));
569 HAL_Snprintf(key_buf, KEY_MAX_LEN - 1, KV_SESSION_KEY_FMT, addr);
570 ret = HAL_Kv_Get(key_buf, save_buf, &len);
571
572 if (ret != 0 || len == 0) {
573 printf(" kv get failed len=%d,ret = %d\r\n", len, ret);
574 HAL_Free(saved_session);
575 HAL_Free(save_buf);
576 save_buf = NULL;
577 saved_session = NULL;
578 break;
579 }
580 ret = ssl_deserialize_session(saved_session, save_buf, len);
581 if (ret < 0) {
582 printf("ssl_deserialize_session err,ret = %d\r\n", ret);
583 HAL_Free(saved_session);
584 HAL_Free(save_buf);
585 save_buf = NULL;
586 saved_session = NULL;
587 break;
588 }
589 HAL_Free(save_buf);
590 } while (0);
591 }
592
593 if (NULL != saved_session) {
594 mbedtls_ssl_set_session(&(pTlsData->ssl), saved_session);
595 printf("use saved session!!\r\n");
596 }
597 #endif
598 /*
599 * 4. Handshake
600 */
601 mbedtls_ssl_conf_read_timeout(&(pTlsData->conf), 10000);
602 platform_info("Performing the SSL/TLS handshake...");
603
604 while ((ret = mbedtls_ssl_handshake(&(pTlsData->ssl))) != 0) {
605 if ((ret != MBEDTLS_ERR_SSL_WANT_READ) &&
606 (ret != MBEDTLS_ERR_SSL_WANT_WRITE)) {
607 platform_err("failed ! mbedtls_ssl_handshake returned -0x%04x",
608 -ret);
609 #ifdef AOS_COMP_UND
610 und_update_statis(UND_STATIS_NETWORK_FAIL_IDX,
611 UND_STATIS_NETWORK_TLS_FAIL_REASON);
612 #endif
613 #if defined(TLS_SAVE_TICKET)
614 if (saved_session != NULL) {
615 mbedtls_ssl_session_free(saved_session);
616 HAL_Free(saved_session);
617 saved_session = NULL;
618 }
619 #endif
620 return ret;
621 }
622 }
623 platform_info(" ok");
624
625 #if defined(TLS_SAVE_TICKET)
626 do {
627 size_t real_session_len = 0;
628 mbedtls_ssl_session *new_session = NULL;
629
630 new_session = HAL_Malloc(sizeof(mbedtls_ssl_session));
631 if (NULL == new_session) {
632 break;
633 }
634
635 memset(new_session, 0x00, sizeof(mbedtls_ssl_session));
636
637 ret = mbedtls_ssl_get_session(&(pTlsData->ssl), new_session);
638 if (ret != 0) {
639 HAL_Free(new_session);
640 break;
641 }
642 if (saved_session == NULL) {
643 ret = 1;
644 } else if (new_session->ticket_len != saved_session->ticket_len) {
645 ret = 1;
646 } else {
647 ret = memcmp(new_session->ticket, saved_session->ticket,
648 new_session->ticket_len);
649 }
650 if (ret != 0) {
651 unsigned char *save_buf = HAL_Malloc(TLS_MAX_SESSION_BUF);
652 if (save_buf == NULL) {
653 mbedtls_ssl_session_free(new_session);
654 HAL_Free(new_session);
655 new_session = NULL;
656 break;
657 }
658 memset(save_buf, 0x00, sizeof(TLS_MAX_SESSION_BUF));
659 ret = ssl_serialize_session(new_session, save_buf,
660 TLS_MAX_SESSION_BUF, &real_session_len);
661 printf(
662 "mbedtls_ssl_get_session_session return 0x%04x real_len=%d\r\n",
663 ret, (int)real_session_len);
664 if (ret == 0) {
665 char key_buf[KEY_MAX_LEN] = { 0 };
666 HAL_Snprintf(key_buf, KEY_MAX_LEN - 1, KV_SESSION_KEY_FMT,
667 addr);
668 ret =
669 HAL_Kv_Set(key_buf, (void *)save_buf, real_session_len, 1);
670 if (ret < 0) {
671 printf("save ticket to kv failed ret =%d ,len = %d\r\n",
672 ret, (int)real_session_len);
673 }
674 }
675 HAL_Free(save_buf);
676 }
677 mbedtls_ssl_session_free(new_session);
678 HAL_Free(new_session);
679 } while (0);
680 if (saved_session != NULL) {
681 mbedtls_ssl_session_free(saved_session);
682 HAL_Free(saved_session);
683 saved_session = NULL;
684 }
685 #endif
686 /*
687 * 5. Verify the server certificate
688 */
689 platform_info(" . Verifying peer X.509 certificate..");
690 ret = _real_confirm(
691 mbedtls_ssl_get_verify_result(&(pTlsData->ssl)));
692 if (ret != 0) {
693 platform_err(" failed ! verify result not confirmed.");
694 #ifdef AOS_COMP_UND
695 und_update_statis(UND_STATIS_NETWORK_FAIL_IDX,
696 UND_STATIS_NETWORK_TLS_FAIL_REASON);
697 #endif
698 return ret;
699 }
700 /* n->my_socket = (int)((n->tlsdataparams.fd).fd); */
701 /* WRITE_IOT_DEBUG_LOG("my_socket=%d", n->my_socket); */
702
703 return 0;
704 }
705
_network_ssl_read(TLSDataParams_t * pTlsData,char * buffer,int len,int timeout_ms)706 static int _network_ssl_read(TLSDataParams_t *pTlsData, char *buffer, int len,
707 int timeout_ms)
708 {
709 uint32_t readLen = 0;
710 static int net_status = 0;
711 int ret = -1;
712
713 uint32_t cur_time = HAL_UptimeMs();
714 uint32_t expire_time = cur_time + timeout_ms;
715 mbedtls_ssl_conf_read_timeout(&(pTlsData->conf), timeout_ms);
716
717 while (readLen < len) {
718 ret = mbedtls_ssl_read(&(pTlsData->ssl),
719 (unsigned char *)(buffer + readLen),
720 (len - readLen));
721 if (ret > 0) {
722 readLen += ret;
723 net_status = 0;
724 } else if (ret == 0) {
725 /* if ret is 0 and net_status is -2, indicate the connection is
726 * closed during last call */
727 if (net_status == -2) {
728 #ifdef AOS_COMP_UND
729 und_update_statis(UND_STATIS_NETWORK_EXCEPTION_IDX,
730 UND_STATIS_NETWORK_RD_EXCEPTION_REASON);
731 #endif
732 }
733 return (net_status == -2) ? net_status : readLen;
734 } else {
735 if (MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY == ret) {
736 // mbedtls_strerror(ret, err_str, sizeof(err_str));
737 platform_err("ssl recv error: code = %d", ret);
738 net_status = -2; /* connection is closed */
739 #ifdef AOS_COMP_UND
740 und_update_statis(UND_STATIS_NETWORK_EXCEPTION_IDX,
741 UND_STATIS_NETWORK_RD_EXCEPTION_REASON);
742 #endif
743 break;
744 #ifdef CSP_LINUXHOST
745 } else if (MBEDTLS_ERR_SSL_WANT_READ == ret && errno == EINTR) {
746 cur_time = HAL_UptimeMs();
747 if ((cur_time - expire_time) < (UINT32_MAX / 2)) {
748 return readLen;
749 }
750 HAL_SleepMs(10);
751 continue;
752
753 #endif
754 } else if ((MBEDTLS_ERR_SSL_TIMEOUT == ret) ||
755 (MBEDTLS_ERR_SSL_CONN_EOF == ret) ||
756 (MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED == ret) ||
757 (MBEDTLS_ERR_SSL_WANT_READ == ret) ||
758 (MBEDTLS_ERR_SSL_NON_FATAL == ret)) {
759 /* read already complete */
760 /* if call mbedtls_ssl_read again, it will return 0 (means EOF)
761 */
762 return readLen;
763 }
764
765 else {
766 // mbedtls_strerror(ret, err_str, sizeof(err_str));
767 platform_err("ssl recv error: code = %d", ret);
768 #ifdef AOS_COMP_UND
769 und_update_statis(UND_STATIS_NETWORK_EXCEPTION_IDX,
770 UND_STATIS_NETWORK_RD_EXCEPTION_REASON);
771 #endif
772 net_status = -1;
773 return -1; /* Connection error */
774 }
775 }
776 }
777
778 return (readLen > 0) ? readLen : net_status;
779 }
780
_network_ssl_write(TLSDataParams_t * pTlsData,const char * buffer,int len,int timeout_ms)781 static int _network_ssl_write(TLSDataParams_t *pTlsData, const char *buffer,
782 int len, int timeout_ms)
783 {
784 uint32_t writtenLen = 0;
785 int ret = -1;
786
787 while (writtenLen < len) {
788 ret = mbedtls_ssl_write(&(pTlsData->ssl),
789 (unsigned char *)(buffer + writtenLen),
790 (len - writtenLen));
791 if (ret > 0) {
792 writtenLen += ret;
793 continue;
794 } else if (ret == 0) {
795 #ifdef AOS_COMP_UND
796 und_update_statis(UND_STATIS_NETWORK_EXCEPTION_IDX,
797 UND_STATIS_NETWORK_WR_EXCEPTION_REASON);
798 #endif
799 platform_err("ssl write timeout");
800 return 0;
801 } else {
802 // mbedtls_strerror(ret, err_str, sizeof(err_str));
803 #ifdef AOS_COMP_UND
804 und_update_statis(UND_STATIS_NETWORK_EXCEPTION_IDX,
805 UND_STATIS_NETWORK_WR_EXCEPTION_REASON);
806 #endif
807 platform_err("ssl write fail, code=%d", ret);
808 return -1; /* Connnection error */
809 }
810 }
811
812 return writtenLen;
813 }
814
_network_ssl_disconnect(TLSDataParams_t * pTlsData)815 static void _network_ssl_disconnect(TLSDataParams_t *pTlsData)
816 {
817 mbedtls_ssl_close_notify(&(pTlsData->ssl));
818 mbedtls_net_free(&(pTlsData->fd));
819 #if defined(MBEDTLS_X509_CRT_PARSE_C)
820 mbedtls_x509_crt_free(&(pTlsData->cacertl));
821 if ((pTlsData->pkey).pk_info != NULL) {
822 platform_info("need release client crt&key");
823 #if defined(MBEDTLS_CERTS_C)
824 mbedtls_x509_crt_free(&(pTlsData->clicert));
825 mbedtls_pk_free(&(pTlsData->pkey));
826 #endif
827 }
828 #endif
829 mbedtls_ssl_free(&(pTlsData->ssl));
830 mbedtls_ssl_config_free(&(pTlsData->conf));
831 platform_info("ssl_disconnect");
832 }
833
HAL_SSL_Read(uintptr_t handle,char * buf,int len,int timeout_ms)834 int32_t HAL_SSL_Read(uintptr_t handle, char *buf, int len, int timeout_ms)
835 {
836 return _network_ssl_read((TLSDataParams_t *)handle, buf, len, timeout_ms);
837 }
838
HAL_SSL_Write(uintptr_t handle,const char * buf,int len,int timeout_ms)839 int32_t HAL_SSL_Write(uintptr_t handle, const char *buf, int len,
840 int timeout_ms)
841 {
842 return _network_ssl_write((TLSDataParams_t *)handle, buf, len, timeout_ms);
843 }
844
HAL_SSL_Destroy(uintptr_t handle)845 int32_t HAL_SSL_Destroy(uintptr_t handle)
846 {
847 if ((uintptr_t)NULL == handle) {
848 platform_err("handle is NULL");
849 return 0;
850 }
851
852 #ifdef AOS_COMP_UND
853 und_update_statis(UND_STATIS_NETWORK_EXCEPTION_IDX,
854 UND_STATIS_NETWORK_PING_EXCEPTION_REASON);
855 #endif
856 _network_ssl_disconnect((TLSDataParams_t *)handle);
857 aos_free((void *)handle);
858 return 0;
859 }
860
HAL_SSL_Establish(const char * host,uint16_t port,const char * ca_crt,size_t ca_crt_len)861 uintptr_t HAL_SSL_Establish(const char *host, uint16_t port, const char *ca_crt,
862 size_t ca_crt_len)
863 {
864 char port_str[6];
865 TLSDataParams_pt pTlsData;
866
867 pTlsData = aos_malloc(sizeof(TLSDataParams_t));
868 if (NULL == pTlsData) {
869 return (uintptr_t)NULL;
870 }
871 memset(pTlsData, 0x0, sizeof(TLSDataParams_t));
872
873 sprintf(port_str, "%u", port);
874
875 if (0 != _TLSConnectNetwork(pTlsData, host, port_str, ca_crt, ca_crt_len,
876 NULL, 0, NULL, 0, NULL, 0)) {
877 _network_ssl_disconnect(pTlsData);
878 aos_free((void *)pTlsData);
879 return (uintptr_t)NULL;
880 }
881
882 return (uintptr_t)pTlsData;
883 }
884