1
1
/* Provide SSL/TLS functions to ESP32 with Arduino IDE
2
2
*
3
- * Adapted from the ssl_client1 example in mbedtls.
3
+ * Adapted from the ssl_client1 example of mbedtls.
4
4
*
5
5
* Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License.
6
6
* Additions Copyright (C) 2017 Evandro Luis Copercini, Apache 2.0 License.
7
7
*/
8
8
9
9
#include " Arduino.h"
10
+ #include < esp32-hal-log.h>
10
11
#include < lwip/sockets.h>
11
12
#include < lwip/err.h>
12
13
#include < lwip/sockets.h>
13
14
#include < lwip/sys.h>
14
15
#include < lwip/netdb.h>
15
-
16
16
#include " ssl_client.h"
17
17
18
-
19
18
const char *pers = " esp32-tls" ;
20
19
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
-
75
20
static int handle_error (int err)
76
21
{
77
22
#ifdef MBEDTLS_ERROR_C
78
23
char error_buf[100 ];
79
-
80
24
mbedtls_strerror (err, error_buf, 100 );
81
- printf ( " \n %s \n " , error_buf);
25
+ log_e ( " %s " , error_buf);
82
26
#endif
83
- printf ( " \n MbedTLS message code: %d\n " , err);
27
+ log_e ( " MbedTLS message code: %d" , err);
84
28
return err;
85
29
}
86
30
87
31
88
-
89
32
void ssl_init (sslclient_context *ssl_client)
90
33
{
91
- /*
92
- * Initialize the RNG and the session data
93
- */
94
-
95
34
mbedtls_ssl_init (&ssl_client->ssl_ctx );
96
35
mbedtls_ssl_config_init (&ssl_client->ssl_conf );
97
-
98
36
mbedtls_ctr_drbg_init (&ssl_client->drbg_ctx );
99
37
}
100
38
101
39
102
-
103
40
int start_ssl_client (sslclient_context *ssl_client, uint32_t ipAddress, uint32_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key)
104
41
{
105
42
char buf[512 ];
106
43
int ret, flags, len, timeout;
107
44
int enable = 1 ;
108
- DEBUG_PRINT (" Free heap before TLS %u\n " , xPortGetFreeHeapSize ());
109
-
45
+ log_i (" Free heap before TLS %u" , xPortGetFreeHeapSize ());
110
46
47
+ log_i (" Starting socket" );
111
48
ssl_client->socket = -1 ;
112
-
49
+
113
50
ssl_client->socket = lwip_socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
114
51
if (ssl_client->socket < 0 ) {
115
- printf ( " \r\n ERROR opening socket\r\n " );
52
+ log_e ( " ERROR opening socket" );
116
53
return ssl_client->socket ;
117
54
}
118
55
@@ -129,69 +66,61 @@ int start_ssl_client(sslclient_context *ssl_client, uint32_t ipAddress, uint32_t
129
66
lwip_setsockopt (ssl_client->socket , IPPROTO_TCP, TCP_NODELAY, &enable, sizeof (enable));
130
67
lwip_setsockopt (ssl_client->socket , SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof (enable));
131
68
} else {
132
- printf ( " \r\n Connect to Server failed!\r\n " );
69
+ log_e ( " Connect to Server failed!" );
133
70
return -1 ;
134
-
135
71
}
136
72
137
73
fcntl ( ssl_client->socket , F_SETFL, fcntl ( ssl_client->socket , F_GETFL, 0 ) | O_NONBLOCK );
138
74
139
-
140
- DEBUG_PRINT ( " Seeding the random number generator\n " );
75
+ log_i (" Seeding the random number generator" );
141
76
mbedtls_entropy_init (&ssl_client->entropy_ctx );
142
77
143
78
ret = mbedtls_ctr_drbg_seed (&ssl_client->drbg_ctx , mbedtls_entropy_func,
144
79
&ssl_client->entropy_ctx , (const unsigned char *) pers, strlen (pers));
145
-
146
-
147
-
148
-
149
80
if (ret < 0 ) {
150
81
return handle_error (ret);
151
82
}
152
83
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
+ }
153
92
154
93
/* MBEDTLS_SSL_VERIFY_REQUIRED if a CA certificate is defined on Arduino IDE and
155
94
MBEDTLS_SSL_VERIFY_NONE if not.
156
95
*/
157
96
if (rootCABuff != NULL ) {
158
- DEBUG_PRINT ( " Loading CA cert\n " );
97
+ log_i ( " Loading CA cert" );
159
98
mbedtls_x509_crt_init (&ssl_client->ca_cert );
160
99
mbedtls_ssl_conf_authmode (&ssl_client->ssl_conf , MBEDTLS_SSL_VERIFY_REQUIRED);
161
100
ret = mbedtls_x509_crt_parse (&ssl_client->ca_cert , (const unsigned char *)rootCABuff, strlen (rootCABuff) + 1 );
162
101
mbedtls_ssl_conf_ca_chain (&ssl_client->ssl_conf , &ssl_client->ca_cert , NULL );
163
102
// mbedtls_ssl_conf_verify(&ssl_client->ssl_ctx, my_verify, NULL );
164
103
if (ret < 0 ) {
165
104
return handle_error (ret);
166
-
167
-
168
-
169
-
170
105
}
171
106
} else {
172
-
173
107
mbedtls_ssl_conf_authmode (&ssl_client->ssl_conf , MBEDTLS_SSL_VERIFY_NONE);
108
+ log_i (" WARNING: Use certificates for a more secure communication!" );
174
109
}
175
110
176
111
if (cli_cert != NULL && cli_key != NULL ) {
177
112
mbedtls_x509_crt_init (&ssl_client->client_cert );
178
113
mbedtls_pk_init (&ssl_client->client_key );
179
114
180
- DEBUG_PRINT ( " Loading CRT cert\n " );
115
+ log_i ( " Loading CRT cert" );
181
116
182
117
ret = mbedtls_x509_crt_parse (&ssl_client->client_cert , (const unsigned char *)cli_cert, strlen (cli_cert) + 1 );
183
-
184
-
185
-
186
-
187
118
if (ret < 0 ) {
188
119
return handle_error (ret);
189
120
}
190
121
191
- DEBUG_PRINT ( " Loading private key\n " );
122
+ log_i ( " Loading private key" );
192
123
ret = mbedtls_pk_parse_key (&ssl_client->client_key , (const unsigned char *)cli_key, strlen (cli_key) + 1 , NULL , 0 );
193
-
194
-
195
124
196
125
if (ret != 0 ) {
197
126
return handle_error (ret);
@@ -203,89 +132,66 @@ int start_ssl_client(sslclient_context *ssl_client, uint32_t ipAddress, uint32_t
203
132
/*
204
133
// TODO: implement match CN verification
205
134
206
- DEBUG_PRINT( "Setting hostname for TLS session...\n ");
135
+ log_i( "Setting hostname for TLS session...");
207
136
208
137
// Hostname set here should match CN in server certificate
209
138
if((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, host)) != 0)
210
139
{
211
140
return handle_error(ret);
212
-
213
- }
214
- */
215
141
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
+ */
225
144
226
145
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
231
146
232
147
if ((ret = mbedtls_ssl_setup (&ssl_client->ssl_ctx , &ssl_client->ssl_conf )) != 0 ) {
233
148
return handle_error (ret);
234
-
235
149
}
236
150
237
151
mbedtls_ssl_set_bio (&ssl_client->ssl_ctx , &ssl_client->socket , mbedtls_net_send, mbedtls_net_recv, NULL );
238
152
239
- DEBUG_PRINT ( " Performing the SSL/TLS handshake...\n " );
153
+ log_i ( " Performing the SSL/TLS handshake..." );
240
154
241
155
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
243
157
return handle_error (ret);
244
-
245
-
246
-
247
-
248
158
}
249
159
delay (10 );
250
160
vPortYield ();
251
161
}
252
162
253
163
254
164
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 ));
256
166
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);
258
168
} else {
259
- DEBUG_PRINT (" Record expansion is unknown (compression)\n " );
260
-
169
+ log_i (" Record expansion is unknown (compression)" );
261
170
}
262
171
}
263
172
264
-
265
- DEBUG_PRINT ( " Verifying peer X.509 certificate...\n " );
173
+ log_i (" Verifying peer X.509 certificate..." );
266
174
267
175
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!" );
269
177
bzero (buf, sizeof (buf));
270
178
mbedtls_x509_crt_verify_info (buf, sizeof (buf), " ! " , flags);
271
- printf ( " verification info: %s\n " , buf);
179
+ log_e ( " verification info: %s" , buf);
272
180
stop_ssl_socket (ssl_client, rootCABuff, cli_cert, cli_key); // It's not safe continue.
273
181
return handle_error (ret);
274
182
} else {
275
- DEBUG_PRINT ( " Certificate verified.\n " );
183
+ log_i ( " Certificate verified." );
276
184
}
277
185
278
-
279
-
280
- DEBUG_PRINT (" Free heap after TLS %u\n " , xPortGetFreeHeapSize ());
186
+ log_i (" Free heap after TLS %u" , xPortGetFreeHeapSize ());
281
187
282
188
return ssl_client->socket ;
283
189
}
284
190
285
191
286
192
void stop_ssl_socket (sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key)
287
193
{
288
- DEBUG_PRINT ( " \n Cleaning SSL connection.\n " );
194
+ log_i ( " Cleaning SSL connection." );
289
195
290
196
if (ssl_client->socket >= 0 ) {
291
197
close (ssl_client->socket );
@@ -313,47 +219,43 @@ void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, cons
313
219
314
220
int data_to_read (sslclient_context *ssl_client)
315
221
{
316
-
317
222
int ret, res;
318
223
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
320
225
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 ) {
323
228
return handle_error (ret);
324
229
}
325
230
326
231
return res;
327
232
}
328
233
329
234
330
-
331
235
int send_ssl_data (sslclient_context *ssl_client, const uint8_t *data, uint16_t len)
332
236
{
333
- // DEBUG_PRINT( "Writing HTTP request...\n "); //for low level debug
237
+ // log_i( "Writing HTTP request..."); //for low level debug
334
238
int ret = -1 ;
335
239
336
240
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 ) {
338
242
return handle_error (ret);
339
-
340
243
}
341
244
}
342
245
343
246
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
345
248
return ret;
346
249
}
347
250
348
251
349
-
350
252
int get_ssl_receive (sslclient_context *ssl_client, uint8_t *data, int length)
351
253
{
352
- // DEBUG_PRINT ( "Reading HTTP response...\n "); //for low level debug
254
+ // log_i ( "Reading HTTP response..."); //for low level debug
353
255
int ret = -1 ;
354
256
355
257
ret = mbedtls_ssl_read (&ssl_client->ssl_ctx , data, length);
356
258
357
- // DEBUG_PRINT ( "%d bytes readed\n ", ret); //for low level debug
259
+ // log_i ( "%d bytes readed", ret); //for low level debug
358
260
return ret;
359
261
}
0 commit comments