1 /*
2  * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 
12 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <netdb.h>
15 
16 #include <http_parser.h>
17 #include "esp_tls_wolfssl.h"
18 #include "esp_tls_error_capture_internal.h"
19 #include <errno.h>
20 #include "esp_log.h"
21 
22 static unsigned char *global_cacert = NULL;
23 static unsigned int global_cacert_pem_bytes = 0;
24 static const char *TAG = "esp-tls-wolfssl";
25 
26 /* Prototypes for the static functions */
27 static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls);
28 
29 #if defined(CONFIG_ESP_TLS_PSK_VERIFICATION)
30 #include "freertos/semphr.h"
31 static SemaphoreHandle_t tls_conn_lock;
32 static inline unsigned int esp_wolfssl_psk_client_cb(WOLFSSL* ssl, const char* hint, char* identity,
33         unsigned int id_max_len, unsigned char* key,unsigned int key_max_len);
34 static esp_err_t esp_wolfssl_set_cipher_list(WOLFSSL_CTX *ctx);
35 #ifdef WOLFSSL_TLS13
36 #define PSK_MAX_ID_LEN 128
37 #else
38 #define PSK_MAX_ID_LEN 64
39 #endif
40 #define PSK_MAX_KEY_LEN 64
41 
42 static char psk_id_str[PSK_MAX_ID_LEN];
43 static uint8_t psk_key_array[PSK_MAX_KEY_LEN];
44 static uint8_t psk_key_max_len = 0;
45 #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */
46 
47 #ifdef CONFIG_ESP_TLS_SERVER
48 static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls);
49 #endif /* CONFIG_ESP_TLS_SERVER */
50 
51 
52 /* This function shall return the error message when appropriate log level has been set otherwise this function shall do nothing */
wolfssl_print_error_msg(int error)53 static void wolfssl_print_error_msg(int error)
54 {
55 #if (CONFIG_LOG_DEFAULT_LEVEL_DEBUG || CONFIG_LOG_DEFAULT_LEVEL_VERBOSE)
56     static char error_buf[100];
57     ESP_LOGE(TAG, "(%d) : %s", error, ERR_error_string(error, error_buf));
58 #endif
59 }
60 
61 typedef enum x509_file_type {
62     FILE_TYPE_CA_CERT = 0, /* CA certificate to authenticate entity at other end */
63     FILE_TYPE_SELF_CERT, /* Self certificate of the entity */
64     FILE_TYPE_SELF_KEY, /* Private key in the self cert-key pair */
65 } x509_file_type_t;
66 
67 /* Error type conversion utility so that esp-tls read/write API to return negative number on error */
esp_tls_convert_wolfssl_err_to_ssize(int wolfssl_error)68 static inline ssize_t esp_tls_convert_wolfssl_err_to_ssize(int wolfssl_error)
69 {
70     switch (wolfssl_error) {
71         case WOLFSSL_ERROR_WANT_READ:
72             return ESP_TLS_ERR_SSL_WANT_READ;
73         case WOLFSSL_ERROR_WANT_WRITE:
74             return ESP_TLS_ERR_SSL_WANT_WRITE;
75         default:
76             // Make sure we return a negative number
77             return wolfssl_error>0 ? -wolfssl_error: wolfssl_error;
78     }
79 }
80 
81 /* Checks whether the certificate provided is in pem format or not */
esp_load_wolfssl_verify_buffer(esp_tls_t * tls,const unsigned char * cert_buf,unsigned int cert_len,x509_file_type_t type,int * err_ret)82 static esp_err_t esp_load_wolfssl_verify_buffer(esp_tls_t *tls, const unsigned char *cert_buf, unsigned int cert_len, x509_file_type_t type, int *err_ret)
83 {
84     int wolf_fileformat = WOLFSSL_FILETYPE_DEFAULT;
85     if (type == FILE_TYPE_SELF_KEY) {
86         if (cert_buf[cert_len - 1] == '\0' && strstr( (const char *) cert_buf, "-----BEGIN " )) {
87             wolf_fileformat = WOLFSSL_FILETYPE_PEM;
88         } else {
89             wolf_fileformat = WOLFSSL_FILETYPE_ASN1;
90         }
91         if ((*err_ret = wolfSSL_CTX_use_PrivateKey_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) {
92             return ESP_OK;
93         }
94         return ESP_FAIL;
95     } else {
96         if (cert_buf[cert_len - 1] == '\0' && strstr( (const char *) cert_buf, "-----BEGIN CERTIFICATE-----" )) {
97             wolf_fileformat = WOLFSSL_FILETYPE_PEM;
98         } else {
99             wolf_fileformat = WOLFSSL_FILETYPE_ASN1;
100         }
101         if (type == FILE_TYPE_SELF_CERT) {
102             if ((*err_ret = wolfSSL_CTX_use_certificate_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) {
103                 return ESP_OK;
104             }
105             return ESP_FAIL;
106         } else if (type == FILE_TYPE_CA_CERT) {
107             if ((*err_ret = wolfSSL_CTX_load_verify_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) {
108                 return ESP_OK;
109             }
110             return ESP_FAIL;
111         } else {
112             /* Wrong file type provided */
113             return ESP_FAIL;
114         }
115     }
116 }
117 
esp_create_wolfssl_handle(const char * hostname,size_t hostlen,const void * cfg,esp_tls_t * tls)118 esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls)
119 {
120 #ifdef CONFIG_ESP_DEBUG_WOLFSSL
121     wolfSSL_Debugging_ON();
122 #endif
123 
124     assert(cfg != NULL);
125     assert(tls != NULL);
126 
127     esp_err_t esp_ret = ESP_FAIL;
128     int ret;
129 
130     ret = wolfSSL_Init();
131     if (ret != WOLFSSL_SUCCESS) {
132         ESP_LOGE(TAG, "Init wolfSSL failed: 0x%04X", ret);
133         wolfssl_print_error_msg(ret);
134         int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
135         ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
136         goto exit;
137     }
138 
139     if (tls->role == ESP_TLS_CLIENT) {
140         esp_ret = set_client_config(hostname, hostlen, (esp_tls_cfg_t *)cfg, tls);
141         if (esp_ret != ESP_OK) {
142             ESP_LOGE(TAG, "Failed to set client configurations, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret));
143             goto exit;
144         }
145     } else if (tls->role == ESP_TLS_SERVER) {
146 #ifdef CONFIG_ESP_TLS_SERVER
147         esp_ret = set_server_config((esp_tls_cfg_server_t *) cfg, tls);
148         if (esp_ret != ESP_OK) {
149             ESP_LOGE(TAG, "Failed to set server configurations, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret));
150             goto exit;
151         }
152 #else
153         ESP_LOGE(TAG, "ESP_TLS_SERVER Not enabled in menuconfig");
154         goto exit;
155 #endif
156     }
157     else {
158         ESP_LOGE(TAG, "tls->role is not valid");
159         goto exit;
160     }
161 
162     return ESP_OK;
163 exit:
164     esp_wolfssl_cleanup(tls);
165     return esp_ret;
166 }
167 
set_client_config(const char * hostname,size_t hostlen,esp_tls_cfg_t * cfg,esp_tls_t * tls)168 static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls)
169 {
170     int ret = WOLFSSL_FAILURE;
171     tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_client_method());
172     if (!tls->priv_ctx) {
173         ESP_LOGE(TAG, "Set wolfSSL ctx failed");
174         ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, ret);
175         return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED;
176     }
177 
178     if (cfg->crt_bundle_attach != NULL) {
179         ESP_LOGE(TAG,"use_crt_bundle not supported in wolfssl");
180         return ESP_FAIL;
181     }
182 
183     if (cfg->use_global_ca_store == true) {
184         if ((esp_load_wolfssl_verify_buffer(tls, global_cacert, global_cacert_pem_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) {
185             int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
186             ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err);
187             wolfssl_print_error_msg(err);
188             return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
189         }
190         wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL);
191     } else if (cfg->cacert_buf != NULL) {
192         if ((esp_load_wolfssl_verify_buffer(tls, cfg->cacert_buf, cfg->cacert_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) {
193             int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
194             ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err);
195             wolfssl_print_error_msg(err);
196             return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
197         }
198         wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL);
199     } else if (cfg->psk_hint_key) {
200 #if defined(CONFIG_ESP_TLS_PSK_VERIFICATION)
201         /*** PSK encryption mode is configured only if no certificate supplied and psk pointer not null ***/
202         if(cfg->psk_hint_key->key == NULL || cfg->psk_hint_key->hint == NULL || cfg->psk_hint_key->key_size <= 0) {
203             ESP_LOGE(TAG, "Please provide appropriate key, keysize and hint to use PSK");
204             return ESP_FAIL;
205         }
206         /* mutex is given back when call back function executes or in case of failure (at cleanup) */
207         if ((xSemaphoreTake(tls_conn_lock, 1000/portTICK_PERIOD_MS) != pdTRUE)) {
208             ESP_LOGE(TAG, "tls_conn_lock could not be obtained in specified time");
209             return -1;
210         }
211         ESP_LOGI(TAG, "setting psk configurations");
212         if((cfg->psk_hint_key->key_size > PSK_MAX_KEY_LEN) || (strlen(cfg->psk_hint_key->hint) > PSK_MAX_ID_LEN)) {
213             ESP_LOGE(TAG, "psk key length should be <= %d and identity hint length should be <= %d", PSK_MAX_KEY_LEN, PSK_MAX_ID_LEN);
214             return ESP_ERR_INVALID_ARG;
215         }
216         psk_key_max_len = cfg->psk_hint_key->key_size;
217         memset(psk_key_array, 0, sizeof(psk_key_array));
218         memset(psk_id_str, 0, sizeof(psk_id_str));
219         memcpy(psk_key_array, cfg->psk_hint_key->key, psk_key_max_len);
220         memcpy(psk_id_str, cfg->psk_hint_key->hint, strlen(cfg->psk_hint_key->hint));
221         wolfSSL_CTX_set_psk_client_callback( (WOLFSSL_CTX *)tls->priv_ctx, esp_wolfssl_psk_client_cb);
222         if(esp_wolfssl_set_cipher_list( (WOLFSSL_CTX *)tls->priv_ctx) != ESP_OK) {
223             ESP_LOGE(TAG, "error in setting cipher-list");
224             return ESP_FAIL;
225         }
226 #else
227         ESP_LOGE(TAG, "psk_hint_key configured but not enabled in menuconfig: Please enable ESP_TLS_PSK_VERIFICATION option");
228         return ESP_ERR_INVALID_STATE;
229 #endif
230     } else {
231 #ifdef CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY
232         wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL);
233 #else
234         ESP_LOGE(TAG, "No server verification option set in esp_tls_cfg_t structure. Check esp_tls API reference");
235         return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED;
236 #endif
237     }
238 
239     if (cfg->clientcert_buf != NULL && cfg->clientkey_buf != NULL) {
240         if ((esp_load_wolfssl_verify_buffer(tls,cfg->clientcert_buf, cfg->clientcert_bytes, FILE_TYPE_SELF_CERT, &ret)) != ESP_OK) {
241             int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
242             ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err);
243             wolfssl_print_error_msg(err);
244             return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
245         }
246         if ((esp_load_wolfssl_verify_buffer(tls,cfg->clientkey_buf, cfg->clientkey_bytes, FILE_TYPE_SELF_KEY, &ret)) != ESP_OK) {
247             int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
248             ESP_LOGE(TAG, "Error in loading private key verify buffer, returned %d, error code: %d", ret, err);
249             wolfssl_print_error_msg(err);
250             return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
251         }
252     } else if (cfg->clientcert_buf != NULL || cfg->clientkey_buf != NULL) {
253         ESP_LOGE(TAG, "You have to provide both clientcert_buf and clientkey_buf for mutual authentication\n\n");
254         return ESP_FAIL;
255     }
256 
257     tls->priv_ssl =(void *)wolfSSL_new( (WOLFSSL_CTX *)tls->priv_ctx);
258     if (!tls->priv_ssl) {
259         ESP_LOGE(TAG, "Create wolfSSL failed");
260         int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
261         ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
262         return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED;
263     }
264 
265     if (!cfg->skip_common_name) {
266         char *use_host = NULL;
267         if (cfg->common_name != NULL) {
268             use_host = strdup(cfg->common_name);
269         } else {
270             use_host = strndup(hostname, hostlen);
271         }
272         if (use_host == NULL) {
273             return ESP_ERR_NO_MEM;
274         }
275         /* Hostname set here should match CN in server certificate */
276         if ((ret = (wolfSSL_check_domain_name( (WOLFSSL *)tls->priv_ssl, use_host))) != WOLFSSL_SUCCESS) {
277             int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
278             ESP_LOGE(TAG, "wolfSSL_check_domain_name returned %d, error code: %d", ret, err);
279             ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
280             free(use_host);
281             return ESP_ERR_WOLFSSL_SSL_SET_HOSTNAME_FAILED;
282         }
283         free(use_host);
284     }
285 
286     if (cfg->alpn_protos) {
287 #ifdef CONFIG_WOLFSSL_HAVE_ALPN
288         char **alpn_list = (char **)cfg->alpn_protos;
289         for (; *alpn_list != NULL; alpn_list ++) {
290             ESP_LOGD(TAG, "alpn protocol is %s", *alpn_list);
291             if ((ret = wolfSSL_UseALPN( (WOLFSSL *)tls->priv_ssl, *alpn_list, strlen(*alpn_list), WOLFSSL_ALPN_FAILED_ON_MISMATCH)) != WOLFSSL_SUCCESS) {
292                 int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
293                 ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
294                 ESP_LOGE(TAG, "wolfSSL UseALPN failed, returned %d, error code: %d", ret, err);
295                 wolfssl_print_error_msg(err);
296                 return ESP_ERR_WOLFSSL_SSL_CONF_ALPN_PROTOCOLS_FAILED;
297             }
298         }
299 #else
300     ESP_LOGE(TAG, "CONFIG_WOLFSSL_HAVE_ALPN not enabled in menuconfig");
301     return ESP_FAIL;
302 #endif /* CONFIG_WOLFSSL_HAVE_ALPN */
303     }
304 
305     wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd);
306     return ESP_OK;
307 }
308 
309 #ifdef CONFIG_ESP_TLS_SERVER
set_server_config(esp_tls_cfg_server_t * cfg,esp_tls_t * tls)310 static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
311 {
312     int ret = WOLFSSL_FAILURE;
313     tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_server_method());
314     if (!tls->priv_ctx) {
315         ESP_LOGE(TAG, "Set wolfSSL ctx failed");
316         return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED;
317     }
318 
319     if (cfg->cacert_buf != NULL) {
320         if ((esp_load_wolfssl_verify_buffer(tls,cfg->cacert_buf, cfg->cacert_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) {
321             int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
322             ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err);
323             wolfssl_print_error_msg(err);
324             return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
325         }
326         wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
327         ESP_LOGD(TAG," Verify Client for Mutual Auth");
328     } else {
329         ESP_LOGD(TAG," Not verifying Client ");
330         wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL);
331     }
332 
333     if (cfg->servercert_buf != NULL && cfg->serverkey_buf != NULL) {
334         if ((esp_load_wolfssl_verify_buffer(tls,cfg->servercert_buf, cfg->servercert_bytes, FILE_TYPE_SELF_CERT, &ret)) != ESP_OK) {
335             int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
336             ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err);
337             wolfssl_print_error_msg(err);
338             return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
339         }
340         if ((esp_load_wolfssl_verify_buffer(tls,cfg->serverkey_buf, cfg->serverkey_bytes, FILE_TYPE_SELF_KEY, &ret)) != ESP_OK) {
341             int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
342             ESP_LOGE(TAG, "Error in loading private key verify buffer, returned %d, error code: %d", ret, err);
343             wolfssl_print_error_msg(err);
344             return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
345         }
346     } else {
347         ESP_LOGE(TAG, "You have to provide both servercert_buf and serverkey_buf for https_server");
348         return ESP_FAIL;
349     }
350 
351     tls->priv_ssl =(void *)wolfSSL_new( (WOLFSSL_CTX *)tls->priv_ctx);
352     if (!tls->priv_ssl) {
353         ESP_LOGE(TAG, "Create wolfSSL failed");
354         return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED;
355     }
356 
357     wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd);
358     return ESP_OK;
359 }
360 #endif
361 
esp_wolfssl_handshake(esp_tls_t * tls,const esp_tls_cfg_t * cfg)362 int esp_wolfssl_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg)
363 {
364     int ret;
365     ret = wolfSSL_connect( (WOLFSSL *)tls->priv_ssl);
366     if (ret == WOLFSSL_SUCCESS) {
367         tls->conn_state = ESP_TLS_DONE;
368         return 1;
369     } else {
370         int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
371         if (err != WOLFSSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_WANT_WRITE) {
372             ESP_LOGE(TAG, "wolfSSL_connect returned %d, error code: %d", ret, err);
373             wolfssl_print_error_msg(err);
374             ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
375             ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, ESP_ERR_WOLFSSL_SSL_HANDSHAKE_FAILED);
376             if (cfg->cacert_buf != NULL || cfg->use_global_ca_store == true) {
377                 /* This is to check whether handshake failed due to invalid certificate*/
378                 esp_wolfssl_verify_certificate(tls);
379             }
380             tls->conn_state = ESP_TLS_FAIL;
381             return -1;
382         }
383         /* Irrespective of blocking or non-blocking I/O, we return on getting wolfSSL_want_read
384         or wolfSSL_want_write during handshake */
385         return 0;
386     }
387 }
388 
esp_wolfssl_read(esp_tls_t * tls,char * data,size_t datalen)389 ssize_t esp_wolfssl_read(esp_tls_t *tls, char *data, size_t datalen)
390 {
391     ssize_t ret = wolfSSL_read( (WOLFSSL *)tls->priv_ssl, (unsigned char *)data, datalen);
392     if (ret < 0) {
393         int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
394         /* peer sent close notify */
395         if (err == WOLFSSL_ERROR_ZERO_RETURN) {
396             return 0;
397         }
398 
399         if (ret != WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_ERROR_WANT_WRITE) {
400             ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, -ret);
401             ESP_LOGE(TAG, "read error :%d:", ret);
402             wolfssl_print_error_msg(ret);
403         }
404         return esp_tls_convert_wolfssl_err_to_ssize(ret);
405     }
406     return ret;
407 }
408 
esp_wolfssl_write(esp_tls_t * tls,const char * data,size_t datalen)409 ssize_t esp_wolfssl_write(esp_tls_t *tls, const char *data, size_t datalen)
410 {
411     ssize_t ret = wolfSSL_write( (WOLFSSL *)tls->priv_ssl, (unsigned char *) data, datalen);
412     if (ret <= 0) {
413         int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
414         if (err != WOLFSSL_ERROR_WANT_READ  && err != WOLFSSL_ERROR_WANT_WRITE) {
415             ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, -err);
416             ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, ESP_ERR_WOLFSSL_SSL_WRITE_FAILED);
417             ESP_LOGE(TAG, "write error :%d:", err);
418             wolfssl_print_error_msg(err);
419         }
420         return esp_tls_convert_wolfssl_err_to_ssize(ret);
421     }
422     return ret;
423 }
424 
esp_wolfssl_verify_certificate(esp_tls_t * tls)425 void esp_wolfssl_verify_certificate(esp_tls_t *tls)
426 {
427     int flags;
428     if ((flags = wolfSSL_get_verify_result( (WOLFSSL *)tls->priv_ssl)) != X509_V_OK) {
429         ESP_LOGE(TAG, "Failed to verify peer certificate , returned %d", flags);
430         ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL_CERT_FLAGS, flags);
431     } else {
432         ESP_LOGI(TAG, "Certificate verified.");
433     }
434 }
435 
esp_wolfssl_get_bytes_avail(esp_tls_t * tls)436 ssize_t esp_wolfssl_get_bytes_avail(esp_tls_t *tls)
437 {
438     if (!tls) {
439         ESP_LOGE(TAG, "empty arg passed to esp_tls_get_bytes_avail()");
440         return ESP_FAIL;
441     }
442     return wolfSSL_pending( (WOLFSSL *)tls->priv_ssl);
443 }
444 
esp_wolfssl_conn_delete(esp_tls_t * tls)445 void esp_wolfssl_conn_delete(esp_tls_t *tls)
446 {
447     if (tls != NULL) {
448         esp_wolfssl_cleanup(tls);
449     }
450 }
451 
esp_wolfssl_cleanup(esp_tls_t * tls)452 void esp_wolfssl_cleanup(esp_tls_t *tls)
453 {
454     if (!tls) {
455         return;
456     }
457 #ifdef CONFIG_ESP_TLS_PSK_VERIFICATION
458     xSemaphoreGive(tls_conn_lock);
459 #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */
460     wolfSSL_shutdown( (WOLFSSL *)tls->priv_ssl);
461     wolfSSL_free( (WOLFSSL *)tls->priv_ssl);
462     tls->priv_ssl = NULL;
463     wolfSSL_CTX_free( (WOLFSSL_CTX *)tls->priv_ctx);
464     tls->priv_ctx = NULL;
465     wolfSSL_Cleanup();
466 }
467 
468 #ifdef CONFIG_ESP_TLS_SERVER
469 /**
470  * @brief       Create TLS/SSL server session
471  */
esp_wolfssl_server_session_create(esp_tls_cfg_server_t * cfg,int sockfd,esp_tls_t * tls)472 int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls_t *tls)
473 {
474     if (tls == NULL || cfg == NULL) {
475         return -1;
476     }
477     tls->role = ESP_TLS_SERVER;
478     tls->sockfd = sockfd;
479     esp_err_t esp_ret = esp_create_wolfssl_handle(NULL, 0, cfg, tls);
480     if (esp_ret != ESP_OK) {
481         ESP_LOGE(TAG, "create_ssl_handle failed, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret));
482         ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, esp_ret);
483         tls->conn_state = ESP_TLS_FAIL;
484         return -1;
485     }
486     tls->read = esp_wolfssl_read;
487     tls->write = esp_wolfssl_write;
488     int ret;
489     while ((ret = wolfSSL_accept((WOLFSSL *)tls->priv_ssl)) != WOLFSSL_SUCCESS) {
490         int err = wolfSSL_get_error((WOLFSSL *)tls->priv_ssl, ret);
491         if (err != WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_ERROR_WANT_WRITE) {
492             ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
493             ESP_LOGE(TAG, "wolfSSL_accept returned %d, error code: %d", ret, err);
494             wolfssl_print_error_msg(err);
495             tls->conn_state = ESP_TLS_FAIL;
496             return -1;
497         }
498     }
499     return 0;
500 }
501 
502 /**
503  * @brief       Close the server side TLS/SSL connection and free any allocated resources.
504  */
esp_wolfssl_server_session_delete(esp_tls_t * tls)505 void esp_wolfssl_server_session_delete(esp_tls_t *tls)
506 {
507     if (tls != NULL) {
508         esp_wolfssl_cleanup(tls);
509         esp_tls_internal_event_tracker_destroy(tls->error_handle);
510         free(tls);
511     }
512 }
513 #endif /* CONFIG_ESP_TLS_SERVER */
514 
esp_wolfssl_init_global_ca_store(void)515 esp_err_t esp_wolfssl_init_global_ca_store(void)
516 {
517     /* This function is just to provide consistancy between function calls of esp_tls.h and wolfssl */
518     return ESP_OK;
519 }
520 
esp_wolfssl_set_global_ca_store(const unsigned char * cacert_pem_buf,const unsigned int cacert_pem_bytes)521 esp_err_t esp_wolfssl_set_global_ca_store(const unsigned char *cacert_pem_buf, const unsigned int cacert_pem_bytes)
522 {
523     if (cacert_pem_buf == NULL) {
524         ESP_LOGE(TAG, "cacert_pem_buf is null");
525         return ESP_ERR_INVALID_ARG;
526     }
527     if (global_cacert != NULL) {
528         esp_wolfssl_free_global_ca_store();
529     }
530 
531     global_cacert = (unsigned char *)strndup((const char *)cacert_pem_buf, cacert_pem_bytes);
532     if (!global_cacert) {
533         return ESP_FAIL;
534     }
535 
536     global_cacert_pem_bytes  = cacert_pem_bytes;
537 
538     return ESP_OK;
539 }
540 
esp_wolfssl_free_global_ca_store(void)541 void esp_wolfssl_free_global_ca_store(void)
542 {
543     if (global_cacert) {
544         free(global_cacert);
545         global_cacert = NULL;
546         global_cacert_pem_bytes = 0;
547     }
548 }
549 
550 #if defined(CONFIG_ESP_TLS_PSK_VERIFICATION)
esp_wolfssl_set_cipher_list(WOLFSSL_CTX * ctx)551 static esp_err_t esp_wolfssl_set_cipher_list(WOLFSSL_CTX *ctx)
552 {
553     const char *defaultCipherList;
554     int ret;
555 #if defined(HAVE_AESGCM) && !defined(NO_DH)
556 #ifdef WOLFSSL_TLS13
557     defaultCipherList = "DHE-PSK-AES128-GCM-SHA256:"
558                                     "TLS13-AES128-GCM-SHA256";
559 #else
560     defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
561 #endif
562 #elif defined(HAVE_NULL_CIPHER)
563     defaultCipherList = "PSK-NULL-SHA256";
564 #else
565     defaultCipherList = "PSK-AES128-CBC-SHA256";
566 #endif
567     ESP_LOGD(TAG, "cipher list is %s", defaultCipherList);
568     if ((ret = wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList)) != WOLFSSL_SUCCESS) {
569         wolfSSL_CTX_free(ctx);
570         int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
571         ESP_LOGE(TAG, "can't set cipher list, returned %d, error code: %d", ret, err);
572         wolfssl_print_error_msg(err);
573         return ESP_FAIL;
574     }
575     return ESP_OK;
576 }
577 
578 /* initialize the mutex before app_main() when using PSK */
579 static void __attribute__((constructor))
espt_tls_wolfssl_init_conn_lock(void)580 espt_tls_wolfssl_init_conn_lock (void)
581 {
582     if ((tls_conn_lock = xSemaphoreCreateMutex()) == NULL) {
583         ESP_EARLY_LOGE(TAG, "mutex for tls psk connection could not be created");
584     }
585 }
586 
587 /* Some callback functions required by PSK */
esp_wolfssl_psk_client_cb(WOLFSSL * ssl,const char * hint,char * identity,unsigned int id_max_len,unsigned char * key,unsigned int key_max_len)588 static inline unsigned int esp_wolfssl_psk_client_cb(WOLFSSL* ssl, const char* hint,
589         char* identity, unsigned int id_max_len, unsigned char* key,
590         unsigned int key_max_len)
591 {
592     (void)key_max_len;
593 
594     /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
595     memcpy(identity, psk_id_str, id_max_len);
596     for(int count = 0; count < psk_key_max_len; count ++) {
597          key[count] = psk_key_array[count];
598     }
599     xSemaphoreGive(tls_conn_lock);
600     return psk_key_max_len;
601     /* return length of key in octets or 0 or for error */
602 }
603 #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */
604