瀏覽代碼

esp_tls_wolfssl: Add support for PSK using wolfSSL,
enable SNI and ALPN

Aditya Patwardhan 5 年之前
父節點
當前提交
46643ab40f
共有 2 個文件被更改,包括 108 次插入42 次删除
  1. 7 7
      components/esp-tls/Kconfig
  2. 101 35
      components/esp-tls/esp_tls_wolfssl.c

+ 7 - 7
components/esp-tls/Kconfig

@@ -22,15 +22,15 @@ menu "ESP-TLS"
 
     config ESP_TLS_PSK_VERIFICATION
         bool "Enable PSK verification"
-        depends on ESP_TLS_USING_MBEDTLS
-        select MBEDTLS_PSK_MODES
-        select MBEDTLS_KEY_EXCHANGE_PSK
-        select MBEDTLS_KEY_EXCHANGE_DHE_PSK
-        select MBEDTLS_KEY_EXCHANGE_ECDHE_PSK
-        select MBEDTLS_KEY_EXCHANGE_RSA_PSK
+        select MBEDTLS_PSK_MODES if ESP_TLS_USING_MBEDTLS
+        select MBEDTLS_KEY_EXCHANGE_PSK if ESP_TLS_USING_MBEDTLS
+        select MBEDTLS_KEY_EXCHANGE_DHE_PSK if ESP_TLS_USING_MBEDTLS
+        select MBEDTLS_KEY_EXCHANGE_ECDHE_PSK if ESP_TLS_USING_MBEDTLS
+        select MBEDTLS_KEY_EXCHANGE_RSA_PSK if ESP_TLS_USING_MBEDTLS
         default n
         help
-            Enable support for pre shared key ciphers, uses the mbedtls crypto library
+            Enable support for pre shared key ciphers, supported for both mbedTLS as well as
+            wolfSSL TLS library.
 
     config ESP_WOLFSSL_SMALL_CERT_VERIFY
         bool "Enable SMALL_CERT_VERIFY"

+ 101 - 35
components/esp-tls/esp_tls_wolfssl.c

@@ -34,6 +34,22 @@ static const char *TAG = "esp-tls-wolfssl";
 /* Prototypes for the static functions */
 static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls);
 
+#if defined(CONFIG_ESP_TLS_PSK_VERIFICATION)
+static inline unsigned int 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);
+static esp_err_t esp_wolfssl_set_cipher_list(WOLFSSL_CTX *ctx);
+#ifdef WOLFSSL_TLS13
+#define PSK_MAX_ID_LEN 128
+#else
+#define PSK_MAX_ID_LEN 64
+#endif
+#define PSK_MAX_KEY_LEN 64
+
+static char psk_id_str[PSK_MAX_ID_LEN];
+static uint8_t psk_key_array[PSK_MAX_KEY_LEN];
+static uint8_t psk_key_max_len = 0;
+#endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */
+
 #ifdef CONFIG_ESP_TLS_SERVER
 static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls);
 #endif /* CONFIG_ESP_TLS_SERVER */
@@ -139,22 +155,6 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls
         return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED;
     }
 
-    if (cfg->alpn_protos) {
-#ifdef CONFIG_WOLFSSL_HAVE_ALPN
-        char **alpn_list = (char **)cfg->alpn_protos;
-        for (; *alpn_list != NULL; alpn_list ++) {
-            if ((ret = wolfSSL_UseALPN( (WOLFSSL *)tls->priv_ssl, *alpn_list, strlen(*alpn_list), WOLFSSL_ALPN_FAILED_ON_MISMATCH)) != WOLFSSL_SUCCESS) {
-                ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret);
-                ESP_LOGE(TAG, "Use wolfSSL ALPN failed");
-                return ESP_ERR_WOLFSSL_SSL_CONF_ALPN_PROTOCOLS_FAILED;
-            }
-        }
-#else
-    ESP_LOGE(TAG, "CONFIG_WOLFSSL_HAVE_ALPN not enabled in menuconfig");
-    return ESP_FAIL;
-#endif /* CONFIG_WOLFSSL_HAVE_ALPN */
-    }
-
     if (cfg->use_global_ca_store == true) {
         if ((esp_load_wolfssl_verify_buffer(tls, global_cacert, global_cacert_pem_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) {
             ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d", ret);
@@ -168,8 +168,31 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls
         }
         wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL);
     } else if (cfg->psk_hint_key) {
-        ESP_LOGE(TAG,"psk_hint_key not supported in wolfssl");
-        return ESP_FAIL;
+#if defined(CONFIG_ESP_TLS_PSK_VERIFICATION)
+        /*** PSK encryption mode is configured only if no certificate supplied and psk pointer not null ***/
+        if(cfg->psk_hint_key->key == NULL || cfg->psk_hint_key->hint == NULL || cfg->psk_hint_key->key_size <= 0) {
+            ESP_LOGE(TAG, "Please provide appropriate key, keysize and hint to use PSK");
+            return ESP_FAIL;
+        }
+        ESP_LOGI(TAG, "setting psk configurations");
+        if((cfg->psk_hint_key->key_size > PSK_MAX_KEY_LEN) || (strlen(cfg->psk_hint_key->hint) > PSK_MAX_ID_LEN)) {
+            ESP_LOGE(TAG, "psk key length should be <= %d and identity hint length should be <= %d", PSK_MAX_KEY_LEN, PSK_MAX_ID_LEN);
+            return ESP_ERR_INVALID_ARG;
+        }
+        psk_key_max_len = cfg->psk_hint_key->key_size;
+        memset(psk_key_array, 0, sizeof(psk_key_array));
+        memset(psk_id_str, 0, sizeof(psk_id_str));
+        memcpy(psk_key_array, cfg->psk_hint_key->key, psk_key_max_len);
+        memcpy(psk_id_str, cfg->psk_hint_key->hint, strlen(cfg->psk_hint_key->hint));
+        wolfSSL_CTX_set_psk_client_callback( (WOLFSSL_CTX *)tls->priv_ctx, esp_wolfssl_psk_client_cb);
+        if(esp_wolfssl_set_cipher_list( (WOLFSSL_CTX *)tls->priv_ctx) != ESP_OK) {
+            ESP_LOGE(TAG, "error in setting cipher-list");
+            return ESP_FAIL;
+        }
+#else
+        ESP_LOGE(TAG, "psk_hint_key configured but not enabled in menuconfig: Please enable ESP_TLS_PSK_VERIFICATION option");
+        return ESP_ERR_INVALID_STATE;
+#endif
     } else {
         wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL);
     }
@@ -200,7 +223,6 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls
         return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED;
     }
 
-#ifdef HAVE_SNI
     if (!cfg->skip_common_name) {
         char *use_host = NULL;
         if (cfg->common_name != NULL) {
@@ -220,28 +242,15 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls
         }
         free(use_host);
     }
-#endif
-    wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd);
-    return ESP_OK;
-}
-
-#ifdef CONFIG_ESP_TLS_SERVER
-static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
-{
-    int ret = WOLFSSL_FAILURE;
-    tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_server_method());
-    if (!tls->priv_ctx) {
-        ESP_LOGE(TAG, "Set wolfSSL ctx failed");
-        return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED;
-    }
 
     if (cfg->alpn_protos) {
 #ifdef CONFIG_WOLFSSL_HAVE_ALPN
         char **alpn_list = (char **)cfg->alpn_protos;
         for (; *alpn_list != NULL; alpn_list ++) {
+            ESP_LOGD(TAG, "alpn protocol is %s", *alpn_list);
             if ((ret = wolfSSL_UseALPN( (WOLFSSL *)tls->priv_ssl, *alpn_list, strlen(*alpn_list), WOLFSSL_ALPN_FAILED_ON_MISMATCH)) != WOLFSSL_SUCCESS) {
-                ESP_LOGE(TAG, "Use wolfSSL ALPN failed");
                 ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret);
+                ESP_LOGE(TAG, "wolfSSL UseALPN failed, returned %d", ret);
                 return ESP_ERR_WOLFSSL_SSL_CONF_ALPN_PROTOCOLS_FAILED;
             }
         }
@@ -251,6 +260,20 @@ static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
 #endif /* CONFIG_WOLFSSL_HAVE_ALPN */
     }
 
+    wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd);
+    return ESP_OK;
+}
+
+#ifdef CONFIG_ESP_TLS_SERVER
+static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
+{
+    int ret = WOLFSSL_FAILURE;
+    tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_server_method());
+    if (!tls->priv_ctx) {
+        ESP_LOGE(TAG, "Set wolfSSL ctx failed");
+        return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED;
+    }
+
     if (cfg->cacert_buf != NULL) {
         if ((esp_load_wolfssl_verify_buffer(tls,cfg->cacert_buf, cfg->cacert_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) {
             ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d", ret);
@@ -351,7 +374,7 @@ void esp_wolfssl_verify_certificate(esp_tls_t *tls)
 {
     int flags;
     if ((flags = wolfSSL_get_verify_result( (WOLFSSL *)tls->priv_ssl)) != WOLFSSL_SUCCESS) {
-        ESP_LOGE(TAG, "Failed to verify peer certificate %d!", flags);
+        ESP_LOGE(TAG, "Failed to verify peer certificate , returned %d!", flags);
         ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL_CERT_FLAGS, flags);
     } else {
         ESP_LOGI(TAG, "Certificate verified.");
@@ -465,3 +488,46 @@ void esp_wolfssl_free_global_ca_store(void)
         global_cacert_pem_bytes = 0;
     }
 }
+
+#if defined(CONFIG_ESP_TLS_PSK_VERIFICATION)
+static esp_err_t esp_wolfssl_set_cipher_list(WOLFSSL_CTX *ctx)
+{
+    const char *defaultCipherList;
+    int ret;
+#if defined(HAVE_AESGCM) && !defined(NO_DH)
+#ifdef WOLFSSL_TLS13
+    defaultCipherList = "DHE-PSK-AES128-GCM-SHA256:"
+                                    "TLS13-AES128-GCM-SHA256";
+#else
+    defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
+#endif
+#elif defined(HAVE_NULL_CIPHER)
+    defaultCipherList = "PSK-NULL-SHA256";
+#else
+    defaultCipherList = "PSK-AES128-CBC-SHA256";
+#endif
+    ESP_LOGD(TAG, "cipher list is %s", defaultCipherList);
+    if ((ret = wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList)) != WOLFSSL_SUCCESS) {
+        wolfSSL_CTX_free(ctx);
+        ESP_LOGE(TAG, "can't set cipher list, returned %02x", ret);
+        return ESP_FAIL;
+    }
+    return ESP_OK;
+}
+
+/* Some callback functions required by PSK */
+static inline unsigned int 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)
+{
+    (void)key_max_len;
+
+    /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
+    memcpy(identity, psk_id_str, id_max_len);
+    for(int count = 0; count < psk_key_max_len; count ++) {
+         key[count] = psk_key_array[count];
+    }
+    return psk_key_max_len;
+    /* return length of key in octets or 0 or for error */
+}
+#endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */