11/* Provide SSL/TLS functions to ESP32 with Arduino IDE
22*
3- * Adapted from the ssl_client1 example in mbedtls.
3+ * Adapted from the ssl_client1 example of mbedtls.
44*
55* Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License.
66* Additions Copyright (C) 2017 Evandro Luis Copercini, Apache 2.0 License.
77*/
88
99#include " Arduino.h"
10+ #include < esp32-hal-log.h>
1011#include < lwip/sockets.h>
1112#include < lwip/err.h>
1213#include < lwip/sockets.h>
1314#include < lwip/sys.h>
1415#include < lwip/netdb.h>
15-
1616#include " ssl_client.h"
1717
18-
1918const char *pers = " esp32-tls" ;
2019
21- #define DEBUG // Comment to supress debug messages
22-
23- #ifdef DEBUG
24- #define DEBUG_PRINT (...) printf( __VA_ARGS__ )
25- #else
26- #define DEBUG_PRINT (x )
27- #endif
28-
29- #ifdef CONFIG_MBEDTLS_DEBUG
30-
31- #define MBEDTLS_DEBUG_LEVEL 4
32-
33- /* mbedtls debug function that translates mbedTLS debug output
34- to ESP_LOGx debug output.
35-
36- MBEDTLS_DEBUG_LEVEL 4 means all mbedTLS debug output gets sent here,
37- and then filtered to the ESP logging mechanism.
38- */
39- static void mbedtls_debug (void *ctx, int level,
40- const char *file, int line,
41- const char *str)
42- {
43- const char *MBTAG = " mbedtls" ;
44- char *file_sep;
45-
46- /* Shorten 'file' from the whole file path to just the filename
47-
48- This is a bit wasteful because the macros are compiled in with
49- the full _FILE_ path in each case.
50- */
51- file_sep = rindex (file, ' /' );
52- if (file_sep) {
53- file = file_sep + 1 ;
54- }
55-
56- switch (level) {
57- case 1 :
58- printf ( " %s:%d %s \n " , file, line, str);
59- break ;
60- case 2 :
61- case 3 :
62- printf ( " %s:%d %s \n " , file, line, str);
63- case 4 :
64- printf ( " %s:%d %s \n " , file, line, str);
65- break ;
66- default :
67- printf ( " Unexpected log level %d: %s \n " , level, str);
68- break ;
69- }
70- }
71-
72- #endif
73-
74-
7520static int handle_error (int err)
7621{
7722#ifdef MBEDTLS_ERROR_C
7823 char error_buf[100 ];
79-
8024 mbedtls_strerror (err, error_buf, 100 );
81- printf ( " \n %s \n " , error_buf);
25+ log_e ( " %s " , error_buf);
8226#endif
83- printf ( " \n MbedTLS message code: %d\n " , err);
27+ log_e ( " MbedTLS message code: %d" , err);
8428 return err;
8529}
8630
8731
88-
8932void ssl_init (sslclient_context *ssl_client)
9033{
91- /*
92- * Initialize the RNG and the session data
93- */
94-
9534 mbedtls_ssl_init (&ssl_client->ssl_ctx );
9635 mbedtls_ssl_config_init (&ssl_client->ssl_conf );
97-
9836 mbedtls_ctr_drbg_init (&ssl_client->drbg_ctx );
9937}
10038
10139
102-
10340int start_ssl_client (sslclient_context *ssl_client, uint32_t ipAddress, uint32_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key)
10441{
10542 char buf[512 ];
10643 int ret, flags, len, timeout;
10744 int enable = 1 ;
108- DEBUG_PRINT (" Free heap before TLS %u\n " , xPortGetFreeHeapSize ());
109-
45+ log_i (" Free heap before TLS %u" , xPortGetFreeHeapSize ());
11046
47+ log_i (" Starting socket" );
11148 ssl_client->socket = -1 ;
112-
49+
11350 ssl_client->socket = lwip_socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
11451 if (ssl_client->socket < 0 ) {
115- printf ( " \r\n ERROR opening socket\r\n " );
52+ log_e ( " ERROR opening socket" );
11653 return ssl_client->socket ;
11754 }
11855
@@ -129,69 +66,61 @@ int start_ssl_client(sslclient_context *ssl_client, uint32_t ipAddress, uint32_t
12966 lwip_setsockopt (ssl_client->socket , IPPROTO_TCP, TCP_NODELAY, &enable, sizeof (enable));
13067 lwip_setsockopt (ssl_client->socket , SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof (enable));
13168 } else {
132- printf ( " \r\n Connect to Server failed!\r\n " );
69+ log_e ( " Connect to Server failed!" );
13370 return -1 ;
134-
13571 }
13672
13773 fcntl ( ssl_client->socket , F_SETFL, fcntl ( ssl_client->socket , F_GETFL, 0 ) | O_NONBLOCK );
13874
139-
140- DEBUG_PRINT ( " Seeding the random number generator\n " );
75+ log_i (" Seeding the random number generator" );
14176 mbedtls_entropy_init (&ssl_client->entropy_ctx );
14277
14378 ret = mbedtls_ctr_drbg_seed (&ssl_client->drbg_ctx , mbedtls_entropy_func,
14479 &ssl_client->entropy_ctx , (const unsigned char *) pers, strlen (pers));
145-
146-
147-
148-
14980 if (ret < 0 ) {
15081 return handle_error (ret);
15182 }
15283
84+ log_i (" Setting up the SSL/TLS structure..." );
85+
86+ if ((ret = mbedtls_ssl_config_defaults (&ssl_client->ssl_conf ,
87+ MBEDTLS_SSL_IS_CLIENT,
88+ MBEDTLS_SSL_TRANSPORT_STREAM,
89+ MBEDTLS_SSL_PRESET_DEFAULT)) != 0 ) {
90+ return handle_error (ret);
91+ }
15392
15493 /* MBEDTLS_SSL_VERIFY_REQUIRED if a CA certificate is defined on Arduino IDE and
15594 MBEDTLS_SSL_VERIFY_NONE if not.
15695 */
15796 if (rootCABuff != NULL ) {
158- DEBUG_PRINT ( " Loading CA cert\n " );
97+ log_i ( " Loading CA cert" );
15998 mbedtls_x509_crt_init (&ssl_client->ca_cert );
16099 mbedtls_ssl_conf_authmode (&ssl_client->ssl_conf , MBEDTLS_SSL_VERIFY_REQUIRED);
161100 ret = mbedtls_x509_crt_parse (&ssl_client->ca_cert , (const unsigned char *)rootCABuff, strlen (rootCABuff) + 1 );
162101 mbedtls_ssl_conf_ca_chain (&ssl_client->ssl_conf , &ssl_client->ca_cert , NULL );
163102 // mbedtls_ssl_conf_verify(&ssl_client->ssl_ctx, my_verify, NULL );
164103 if (ret < 0 ) {
165104 return handle_error (ret);
166-
167-
168-
169-
170105 }
171106 } else {
172-
173107 mbedtls_ssl_conf_authmode (&ssl_client->ssl_conf , MBEDTLS_SSL_VERIFY_NONE);
108+ log_i (" WARNING: Use certificates for a more secure communication!" );
174109 }
175110
176111 if (cli_cert != NULL && cli_key != NULL ) {
177112 mbedtls_x509_crt_init (&ssl_client->client_cert );
178113 mbedtls_pk_init (&ssl_client->client_key );
179114
180- DEBUG_PRINT ( " Loading CRT cert\n " );
115+ log_i ( " Loading CRT cert" );
181116
182117 ret = mbedtls_x509_crt_parse (&ssl_client->client_cert , (const unsigned char *)cli_cert, strlen (cli_cert) + 1 );
183-
184-
185-
186-
187118 if (ret < 0 ) {
188119 return handle_error (ret);
189120 }
190121
191- DEBUG_PRINT ( " Loading private key\n " );
122+ log_i ( " Loading private key" );
192123 ret = mbedtls_pk_parse_key (&ssl_client->client_key , (const unsigned char *)cli_key, strlen (cli_key) + 1 , NULL , 0 );
193-
194-
195124
196125 if (ret != 0 ) {
197126 return handle_error (ret);
@@ -203,89 +132,66 @@ int start_ssl_client(sslclient_context *ssl_client, uint32_t ipAddress, uint32_t
203132 /*
204133 // TODO: implement match CN verification
205134
206- DEBUG_PRINT( "Setting hostname for TLS session...\n ");
135+ log_i( "Setting hostname for TLS session...");
207136
208137 // Hostname set here should match CN in server certificate
209138 if((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, host)) != 0)
210139 {
211140 return handle_error(ret);
212-
213- }
214- */
215141
216- DEBUG_PRINT ( " Setting up the SSL/TLS structure...\n " );
217-
218- if ((ret = mbedtls_ssl_config_defaults (&ssl_client->ssl_conf ,
219- MBEDTLS_SSL_IS_CLIENT,
220- MBEDTLS_SSL_TRANSPORT_STREAM,
221- MBEDTLS_SSL_PRESET_DEFAULT)) != 0 ) {
222- return handle_error (ret);
223-
224- }
142+ }
143+ */
225144
226145 mbedtls_ssl_conf_rng (&ssl_client->ssl_conf , mbedtls_ctr_drbg_random, &ssl_client->drbg_ctx );
227- #ifdef CONFIG_MBEDTLS_DEBUG
228- mbedtls_debug_set_threshold (MBEDTLS_DEBUG_LEVEL);
229- mbedtls_ssl_conf_dbg (&ssl_client->ssl_conf , mbedtls_debug, NULL );
230- #endif
231146
232147 if ((ret = mbedtls_ssl_setup (&ssl_client->ssl_ctx , &ssl_client->ssl_conf )) != 0 ) {
233148 return handle_error (ret);
234-
235149 }
236150
237151 mbedtls_ssl_set_bio (&ssl_client->ssl_ctx , &ssl_client->socket , mbedtls_net_send, mbedtls_net_recv, NULL );
238152
239- DEBUG_PRINT ( " Performing the SSL/TLS handshake...\n " );
153+ log_i ( " Performing the SSL/TLS handshake..." );
240154
241155 while ((ret = mbedtls_ssl_handshake (&ssl_client->ssl_ctx )) != 0 ) {
242- if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != -76 ) {
156+ if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != -76 ) { // workaround for bug: https://github.com/espressif/esp-idf/issues/434
243157 return handle_error (ret);
244-
245-
246-
247-
248158 }
249159 delay (10 );
250160 vPortYield ();
251161 }
252162
253163
254164 if (cli_cert != NULL && cli_key != NULL ) {
255- DEBUG_PRINT (" Protocol is %s \n Ciphersuite is %s\n " , mbedtls_ssl_get_version (&ssl_client->ssl_ctx ), mbedtls_ssl_get_ciphersuite (&ssl_client->ssl_ctx ));
165+ log_i (" Protocol is %s Ciphersuite is %s" , mbedtls_ssl_get_version (&ssl_client->ssl_ctx ), mbedtls_ssl_get_ciphersuite (&ssl_client->ssl_ctx ));
256166 if ((ret = mbedtls_ssl_get_record_expansion (&ssl_client->ssl_ctx )) >= 0 ) {
257- DEBUG_PRINT (" Record expansion is %d\n " , ret);
167+ log_i (" Record expansion is %d" , ret);
258168 } else {
259- DEBUG_PRINT (" Record expansion is unknown (compression)\n " );
260-
169+ log_i (" Record expansion is unknown (compression)" );
261170 }
262171 }
263172
264-
265- DEBUG_PRINT ( " Verifying peer X.509 certificate...\n " );
173+ log_i (" Verifying peer X.509 certificate..." );
266174
267175 if ((flags = mbedtls_ssl_get_verify_result (&ssl_client->ssl_ctx )) != 0 ) {
268- printf ( " Failed to verify peer certificate!\n " );
176+ log_e ( " Failed to verify peer certificate!" );
269177 bzero (buf, sizeof (buf));
270178 mbedtls_x509_crt_verify_info (buf, sizeof (buf), " ! " , flags);
271- printf ( " verification info: %s\n " , buf);
179+ log_e ( " verification info: %s" , buf);
272180 stop_ssl_socket (ssl_client, rootCABuff, cli_cert, cli_key); // It's not safe continue.
273181 return handle_error (ret);
274182 } else {
275- DEBUG_PRINT ( " Certificate verified.\n " );
183+ log_i ( " Certificate verified." );
276184 }
277185
278-
279-
280- DEBUG_PRINT (" Free heap after TLS %u\n " , xPortGetFreeHeapSize ());
186+ log_i (" Free heap after TLS %u" , xPortGetFreeHeapSize ());
281187
282188 return ssl_client->socket ;
283189}
284190
285191
286192void stop_ssl_socket (sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key)
287193{
288- DEBUG_PRINT ( " \n Cleaning SSL connection.\n " );
194+ log_i ( " Cleaning SSL connection." );
289195
290196 if (ssl_client->socket >= 0 ) {
291197 close (ssl_client->socket );
@@ -313,47 +219,43 @@ void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, cons
313219
314220int data_to_read (sslclient_context *ssl_client)
315221{
316-
317222 int ret, res;
318223 ret = mbedtls_ssl_read (&ssl_client->ssl_ctx , NULL , 0 );
319- // printf ("RET: %i\n ",ret); //for low level debug
224+ // log_e ("RET: %i",ret); //for low level debug
320225 res = mbedtls_ssl_get_bytes_avail (&ssl_client->ssl_ctx );
321- // printf ("RES: %i\n ",res);
322- if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0 && ret != -76 ) { // RC:76 sockets is not connected
226+ // log_e ("RES: %i",res);
227+ if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0 && ret != -76 ) {
323228 return handle_error (ret);
324229 }
325230
326231 return res;
327232}
328233
329234
330-
331235int send_ssl_data (sslclient_context *ssl_client, const uint8_t *data, uint16_t len)
332236{
333- // DEBUG_PRINT( "Writing HTTP request...\n "); //for low level debug
237+ // log_i( "Writing HTTP request..."); //for low level debug
334238 int ret = -1 ;
335239
336240 while ((ret = mbedtls_ssl_write (&ssl_client->ssl_ctx , data, len)) <= 0 ) {
337- if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != -76 ) { // RC:76 sockets is not connected
241+ if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != -76 ) {
338242 return handle_error (ret);
339-
340243 }
341244 }
342245
343246 len = ret;
344- // DEBUG_PRINT( "%d bytes written\n ", len); //for low level debug
247+ // log_i( "%d bytes written", len); //for low level debug
345248 return ret;
346249}
347250
348251
349-
350252int get_ssl_receive (sslclient_context *ssl_client, uint8_t *data, int length)
351253{
352- // DEBUG_PRINT ( "Reading HTTP response...\n "); //for low level debug
254+ // log_i ( "Reading HTTP response..."); //for low level debug
353255 int ret = -1 ;
354256
355257 ret = mbedtls_ssl_read (&ssl_client->ssl_ctx , data, length);
356258
357- // DEBUG_PRINT ( "%d bytes readed\n ", ret); //for low level debug
259+ // log_i ( "%d bytes readed", ret); //for low level debug
358260 return ret;
359261}
0 commit comments