2020#include <sys/socket.h>
2121#include <netdb.h>
2222
23+ #include <http_parser.h>
2324#include "esp_tls.h"
2425#include <errno.h>
2526
@@ -123,7 +124,6 @@ static int esp_tcp_connect(const char *host, int hostlen, int port, int *sockfd,
123124 ESP_LOGE (TAG , "Failed to create socket (family %d socktype %d protocol %d)" , res -> ai_family , res -> ai_socktype , res -> ai_protocol );
124125 goto err_freeaddr ;
125126 }
126- * sockfd = fd ;
127127
128128 void * addr_ptr ;
129129 if (res -> ai_family == AF_INET ) {
@@ -155,12 +155,13 @@ static int esp_tcp_connect(const char *host, int hostlen, int port, int *sockfd,
155155 }
156156
157157 ret = connect (fd , addr_ptr , res -> ai_addrlen );
158- if (ret < 0 && !(errno == EINPROGRESS && cfg -> non_block )) {
158+ if (ret < 0 && !(errno == EINPROGRESS && cfg && cfg -> non_block )) {
159159
160- ESP_LOGE (TAG , "Failed to connnect to host (errno %d)" , errno );
160+ ESP_LOGE (TAG , "Failed to connect to host (errno %d)" , errno );
161161 goto err_freesocket ;
162162 }
163163
164+ * sockfd = fd ;
164165 freeaddrinfo (res );
165166 return 0 ;
166167
@@ -171,24 +172,38 @@ static int esp_tcp_connect(const char *host, int hostlen, int port, int *sockfd,
171172 return ret ;
172173}
173174
175+ #if CONFIG_SSL_USING_MBEDTLS
176+ esp_err_t esp_tls_init_global_ca_store ()
177+ {
178+ if (global_cacert == NULL ) {
179+ global_cacert = (mbedtls_x509_crt * )calloc (1 , sizeof (mbedtls_x509_crt ));
180+ if (global_cacert == NULL ) {
181+ ESP_LOGE (TAG , "global_cacert not allocated" );
182+ return ESP_ERR_NO_MEM ;
183+ }
184+ mbedtls_x509_crt_init (global_cacert );
185+ }
186+ return ESP_OK ;
187+ }
188+ #endif
174189
175190esp_err_t esp_tls_set_global_ca_store (const unsigned char * cacert_pem_buf , const unsigned int cacert_pem_bytes )
176191{
177192 if (cacert_pem_buf == NULL ) {
178193 ESP_LOGE (TAG , "cacert_pem_buf is null" );
179194 return ESP_ERR_INVALID_ARG ;
180195 }
196+
181197#if CONFIG_SSL_USING_MBEDTLS
182- if (global_cacert != NULL ) {
183- mbedtls_x509_crt_free (global_cacert );
184- }
185- global_cacert = (mbedtls_x509_crt * )calloc (1 , sizeof (mbedtls_x509_crt ));
198+ int ret ;
199+
186200 if (global_cacert == NULL ) {
187- ESP_LOGE (TAG , "global_cacert not allocated" );
188- return ESP_ERR_NO_MEM ;
201+ ret = esp_tls_init_global_ca_store ();
202+ if (ret != ESP_OK ) {
203+ return ret ;
204+ }
189205 }
190- mbedtls_x509_crt_init (global_cacert );
191- int ret = mbedtls_x509_crt_parse (global_cacert , cacert_pem_buf , cacert_pem_bytes );
206+ ret = mbedtls_x509_crt_parse (global_cacert , cacert_pem_buf , cacert_pem_bytes );
192207 if (ret < 0 ) {
193208 ESP_LOGE (TAG , "mbedtls_x509_crt_parse returned -0x%x\n\n" , - ret );
194209 mbedtls_x509_crt_free (global_cacert );
@@ -272,11 +287,9 @@ static void esp_tls_cleanup(esp_tls_t *tls)
272287 mbedtls_ssl_config_free (& tls -> conf );
273288 mbedtls_ctr_drbg_free (& tls -> ctr_drbg );
274289 mbedtls_ssl_free (& tls -> ssl );
275- mbedtls_net_free (& tls -> server_fd );
276290#elif CONFIG_SSL_USING_WOLFSSL
277291 wolfSSL_shutdown (tls -> ssl );
278292 wolfSSL_free (tls -> ssl );
279- close (tls -> sockfd );
280293 wolfSSL_CTX_free (tls -> ctx );
281294 wolfSSL_Cleanup ();
282295#endif
@@ -285,8 +298,8 @@ static void esp_tls_cleanup(esp_tls_t *tls)
285298static int create_ssl_handle (esp_tls_t * tls , const char * hostname , size_t hostlen , const esp_tls_cfg_t * cfg )
286299{
287300 int ret ;
301+
288302#if CONFIG_SSL_USING_MBEDTLS
289- mbedtls_net_init (& tls -> server_fd );
290303 tls -> server_fd .fd = tls -> sockfd ;
291304 mbedtls_ssl_init (& tls -> ssl );
292305 mbedtls_ctr_drbg_init (& tls -> ctr_drbg );
@@ -299,18 +312,26 @@ static int create_ssl_handle(esp_tls_t *tls, const char *hostname, size_t hostle
299312 goto exit ;
300313 }
301314
302- /* Hostname set here should match CN in server certificate */
303- char * use_host = strndup (hostname , hostlen );
304- if (!use_host ) {
305- goto exit ;
306- }
315+ if (!cfg -> skip_common_name ) {
316+ char * use_host = NULL ;
317+ if (cfg -> common_name != NULL ) {
318+ use_host = strndup (cfg -> common_name , strlen (cfg -> common_name ));
319+ } else {
320+ use_host = strndup (hostname , hostlen );
321+ }
307322
308- if ((ret = mbedtls_ssl_set_hostname (& tls -> ssl , use_host )) != 0 ) {
309- ESP_LOGE (TAG , "mbedtls_ssl_set_hostname returned -0x%x" , - ret );
323+ if (use_host == NULL ) {
324+ goto exit ;
325+ }
326+
327+ /* Hostname set here should match CN in server certificate */
328+ if ((ret = mbedtls_ssl_set_hostname (& tls -> ssl , use_host )) != 0 ) {
329+ ESP_LOGE (TAG , "mbedtls_ssl_set_hostname returned -0x%x" , - ret );
330+ free (use_host );
331+ goto exit ;
332+ }
310333 free (use_host );
311- goto exit ;
312334 }
313- free (use_host );
314335
315336 if ((ret = mbedtls_ssl_config_defaults (& tls -> conf ,
316337 MBEDTLS_SSL_IS_CLIENT ,
@@ -466,7 +487,12 @@ void esp_tls_conn_delete(esp_tls_t *tls)
466487{
467488 if (tls != NULL ) {
468489 esp_tls_cleanup (tls );
469- if (tls -> sockfd ) {
490+ #if CONFIG_SSL_USING_MBEDTLS
491+ if (tls -> is_tls ) {
492+ mbedtls_net_free (& tls -> server_fd );
493+ } else
494+ #endif
495+ if (tls -> sockfd >= 0 ) {
470496 close (tls -> sockfd );
471497 }
472498 free (tls );
@@ -514,16 +540,20 @@ static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, c
514540 and in case of blocking connect these cases will get executed one after the other */
515541 switch (tls -> conn_state ) {
516542 case ESP_TLS_INIT :
517- ;
518- int sockfd ;
519- int ret = esp_tcp_connect (hostname , hostlen , port , & sockfd , cfg );
543+ tls -> sockfd = -1 ;
544+ if (cfg != NULL ) {
545+ #if CONFIG_SSL_USING_MBEDTLS
546+ mbedtls_net_init (& tls -> server_fd );
547+ #endif
548+ tls -> is_tls = true;
549+ }
550+ int ret = esp_tcp_connect (hostname , hostlen , port , & tls -> sockfd , cfg );
520551 if (ret < 0 ) {
521552 return -1 ;
522553 }
523- tls -> sockfd = sockfd ;
524554 if (!cfg ) {
525- tls -> esp_tls_read = tcp_read ;
526- tls -> esp_tls_write = tcp_write ;
555+ tls -> _read = tcp_read ;
556+ tls -> _write = tcp_write ;
527557 ESP_LOGD (TAG , "non-tls connection established" );
528558 return 1 ;
529559 }
@@ -565,8 +595,8 @@ static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, c
565595 tls -> conn_state = ESP_TLS_FAIL ;
566596 return -1 ;
567597 }
568- tls -> esp_tls_read = tls_read ;
569- tls -> esp_tls_write = tls_write ;
598+ tls -> _read = tls_read ;
599+ tls -> _write = tls_write ;
570600 tls -> conn_state = ESP_TLS_HANDSHAKE ;
571601 /* falls through */
572602 case ESP_TLS_HANDSHAKE :
@@ -654,6 +684,35 @@ int esp_tls_conn_new_async(const char *hostname, int hostlen, int port, const es
654684 return esp_tls_low_level_conn (hostname , hostlen , port , cfg , tls );
655685}
656686
687+ static int get_port (const char * url , struct http_parser_url * u )
688+ {
689+ if (u -> field_data [UF_PORT ].len ) {
690+ return strtol (& url [u -> field_data [UF_PORT ].off ], NULL , 10 );
691+ } else {
692+ if (strncasecmp (& url [u -> field_data [UF_SCHEMA ].off ], "http" , u -> field_data [UF_SCHEMA ].len ) == 0 ) {
693+ return 80 ;
694+ } else if (strncasecmp (& url [u -> field_data [UF_SCHEMA ].off ], "https" , u -> field_data [UF_SCHEMA ].len ) == 0 ) {
695+ return 443 ;
696+ }
697+ }
698+ return 0 ;
699+ }
700+
701+ /**
702+ * @brief Create a new TLS/SSL connection with a given "HTTP" url
703+ */
704+ esp_tls_t * esp_tls_conn_http_new (const char * url , const esp_tls_cfg_t * cfg )
705+ {
706+ /* Parse URI */
707+ struct http_parser_url u ;
708+ http_parser_url_init (& u );
709+ http_parser_parse_url (url , strlen (url ), 0 , & u );
710+
711+ /* Connect to host */
712+ return esp_tls_conn_new (& url [u .field_data [UF_HOST ].off ], u .field_data [UF_HOST ].len ,
713+ get_port (url , & u ), cfg );
714+ }
715+
657716size_t esp_tls_get_bytes_avail (esp_tls_t * tls )
658717{
659718 if (!tls ) {
@@ -666,3 +725,18 @@ size_t esp_tls_get_bytes_avail(esp_tls_t *tls)
666725 return wolfSSL_pending (tls -> ssl );
667726#endif
668727}
728+
729+ /**
730+ * @brief Create a new non-blocking TLS/SSL connection with a given "HTTP" url
731+ */
732+ int esp_tls_conn_http_new_async (const char * url , const esp_tls_cfg_t * cfg , esp_tls_t * tls )
733+ {
734+ /* Parse URI */
735+ struct http_parser_url u ;
736+ http_parser_url_init (& u );
737+ http_parser_parse_url (url , strlen (url ), 0 , & u );
738+
739+ /* Connect to host */
740+ return esp_tls_conn_new_async (& url [u .field_data [UF_HOST ].off ], u .field_data [UF_HOST ].len ,
741+ get_port (url , & u ), cfg , tls );
742+ }
0 commit comments