diff --git a/components/esp_websocket_client/esp_websocket_client.c b/components/esp_websocket_client/esp_websocket_client.c index 8f3eb106ed..b76a6aa4c5 100644 --- a/components/esp_websocket_client/esp_websocket_client.c +++ b/components/esp_websocket_client/esp_websocket_client.c @@ -93,6 +93,9 @@ typedef struct { size_t client_cert_len; const char *client_key; size_t client_key_len; +#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL + void *client_ds_data; +#endif bool use_global_ca_store; bool skip_cert_common_name_check; const char *cert_common_name; @@ -531,6 +534,10 @@ static esp_err_t esp_websocket_client_create_transport(esp_websocket_client_hand } else { esp_transport_ssl_set_client_key_data_der(ssl, client->config->client_key, client->config->client_key_len); } +#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL + } else if (client->config->client_ds_data) { + esp_transport_ssl_set_ds_data(ssl, client->config->client_ds_data); +#endif } if (client->config->crt_bundle_attach) { #ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE @@ -696,6 +703,9 @@ esp_websocket_client_handle_t esp_websocket_client_init(const esp_websocket_clie client->config->client_cert_len = config->client_cert_len; client->config->client_key = config->client_key; client->config->client_key_len = config->client_key_len; +#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL + client->config->client_ds_data = config->client_ds_data; +#endif client->config->skip_cert_common_name_check = config->skip_cert_common_name_check; client->config->cert_common_name = config->cert_common_name; client->config->crt_bundle_attach = config->crt_bundle_attach; diff --git a/components/esp_websocket_client/include/esp_websocket_client.h b/components/esp_websocket_client/include/esp_websocket_client.h index 15fb63b7ca..07093119dd 100644 --- a/components/esp_websocket_client/include/esp_websocket_client.h +++ b/components/esp_websocket_client/include/esp_websocket_client.h @@ -108,10 +108,13 @@ typedef struct { int buffer_size; /*!< Websocket buffer size */ const char *cert_pem; /*!< Pointer to certificate data in PEM or DER format for server verify (with SSL), default is NULL, not required to verify the server. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in cert_len. */ size_t cert_len; /*!< Length of the buffer pointed to by cert_pem. May be 0 for null-terminated pem */ - const char *client_cert; /*!< Pointer to certificate data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_key` has to be provided. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_cert_len. */ + const char *client_cert; /*!< Pointer to certificate data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_key` or `client_ds_data` (if supported) has to be provided. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_cert_len. */ size_t client_cert_len; /*!< Length of the buffer pointed to by client_cert. May be 0 for null-terminated pem */ - const char *client_key; /*!< Pointer to private key data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_cert` has to be provided. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_key_len */ + const char *client_key; /*!< Pointer to private key data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_cert` has to be provided and `client_ds_data` (if supported) gets ignored. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_key_len */ size_t client_key_len; /*!< Length of the buffer pointed to by client_key_pem. May be 0 for null-terminated pem */ +#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL + void *client_ds_data; /*!< Pointer to the encrypted private key data for SSL mutual authentication using the DS peripheral, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_cert` has to be provided. It is ignored if `client_key` is provided */ +#endif esp_websocket_transport_t transport; /*!< Websocket transport type, see `esp_websocket_transport_t */ const char *subprotocol; /*!< Websocket subprotocol */ const char *user_agent; /*!< Websocket user-agent */ diff --git a/docs/esp_websocket_client/en/index.rst b/docs/esp_websocket_client/en/index.rst index c4444d43c5..e73ff394a4 100644 --- a/docs/esp_websocket_client/en/index.rst +++ b/docs/esp_websocket_client/en/index.rst @@ -73,6 +73,34 @@ echo "" | openssl s_client -showcerts -connect websocket.org:443 | sed -n "1,/Ro This command will extract the second certificate in the chain and save it as a pem-file. +Mutual TLS with DS Peripheral +""""""""""""""""""""""""""""" + +To leverage the Digital Signature (DS) peripheral on supported targets, use `esp_secure_cert_mgr `_ to flash an encrypted client certificate. In your project, add the dependency: :: + + idf.py add-dependency esp_secure_cert_mgr + +Set ``client_cert`` and ``client_ds_data`` in the config struct: + +.. code:: c + + char *client_cert = NULL; + uint32_t client_cert_len = 0; + esp_err_t err = esp_secure_cert_get_device_cert(&client_cert, &client_cert_len); + assert(err == ESP_OK); + + esp_ds_data_ctx_t *ds_data = esp_secure_cert_get_ds_ctx(); + assert(ds_data != NULL); + + esp_websocket_client_config_t config = { + .uri = "wss://echo.websocket.org", + .cert_pem = (const char *)websocket_org_pem_start, + .client_cert = client_cert, + .client_ds_data = ds_data, + }; + +.. note:: ``client_cert`` provided by `esp_secure_cert_mgr` is a null-terminated PEM; so ``client_cert_len`` (DER format) should not be set. + Subprotocol ^^^^^^^^^^^