Skip to content

Commit

Permalink
feat(websocket): Expanded example to demonstrate the transfer over TLS
Browse files Browse the repository at this point in the history
  • Loading branch information
suren-gabrielyan-espressif committed Feb 7, 2024
1 parent 891384c commit 59b643f
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 8 deletions.
16 changes: 16 additions & 0 deletions components/esp_websocket_client/examples/target/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ This example can be executed on any ESP32 board, the only required interface is
* Open the project configuration menu (`idf.py menuconfig`)
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu.
* Configure the websocket endpoint URI under "Example Configuration", if "WEBSOCKET_URI_FROM_STDIN" is selected then the example application will connect to the URI it reads from stdin (used for testing)
* In order to use websocket client over the TLS enable configuration `WS_OVER_TLS_SCHEME=y`

### Certificates

You can generate a new certificate using the OpenSSL command line tool:

```
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 3650 -out cert.pem
```

Expiry time and metadata fields can be adjusted in the invocation.

Please see the openssl man pages (man openssl-req) for more details.

It is **strongly recommended** to not reuse the example certificate in your application;
it is included only for demonstration.

### Build and Flash

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
idf_component_register(SRCS "websocket_example.c"
INCLUDE_DIRS ".")
INCLUDE_DIRS "."
EMBED_TXTFILES "certs/cert.pem"
"certs/key.pem")
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ menu "Example Configuration"
help
URL of websocket endpoint this example connects to and sends echo

config WS_OVER_TLS_SCHEME
bool "Use webscoket over the TLS scheme"
default 0
help
Use webscoket over the TLS scheme

if CONFIG_IDF_TARGET = "linux"
config GCOV_ENABLED
bool "Coverage analyzer"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUUJJvU5aje0roUMhf/isv1uOXrVYwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDAyMDYxMDE5NDNaFw0yNTAy
MDUxMDE5NDNaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDFQtDVC88EAv4r8uex14uf3KTxMugX8o5eMzTmN0l6
N3Ck+D/64r+9CiIDiaGQBbenGnBBXTH/w3Itiv6XX2lhUOgOusK6/JnTJx0sqN8q
0R9NRTi/2XOIgdWaKZipkbS9jIw2tiqMgh/8dt9VLbfGpnzdqyYFW6MBJI39IFib
diIta/SJYUTkEhBlewFk0WBB7w8gu/J1HQKUJ66w0tLsCxVGdqLeNlCRsWE2gzFZ
CmRGm+SqVwiqXGjAWZmv+F7LCeo9XmTt8PUEuOyaE+Pdn3o8RDaa6dMHuifdMC60
UVlUGQf42RrzCSiq/SCz4/KXVDjoU4hJvw3mbQsErg+/AgMBAAGjUzBRMB0GA1Ud
DgQWBBS3wFg8rTaidZ4Zis80C4EhjFbVtDAfBgNVHSMEGDAWgBS3wFg8rTaidZ4Z
is80C4EhjFbVtDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAw
gvAXomB7hjbhRagEmcS0omTyT01vJCqAfUJif6yfC8XTS2iPphKlY37t+FCLwyJ3
3in+NzivJBdBZLAMGvo1l9C/IhSGinKYJKMVFZzXxL24+5IQ0k5OIT3Mujbp8m+N
eVKKygAXX/onnc0JQppxcO98BdOIhq9xgWUakrtFvWzCHj/SOzrvB3maglHh7RHf
T4XFLU6in6rfr4gl2ffAs054zvsyQTWb2KwcldCcTAsCZKbesimbAocMwyoOEWhw
wA6UiUg2LkdVtoQ737WsvzW+Pu73tNGJeqXBTWPaq3rBrXN5hufwQPLkoQtFXKGb
gXYUy2Vaf78N22BpM1Vm
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions components/esp_websocket_client/examples/target/main/certs/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDFQtDVC88EAv4r
8uex14uf3KTxMugX8o5eMzTmN0l6N3Ck+D/64r+9CiIDiaGQBbenGnBBXTH/w3It
iv6XX2lhUOgOusK6/JnTJx0sqN8q0R9NRTi/2XOIgdWaKZipkbS9jIw2tiqMgh/8
dt9VLbfGpnzdqyYFW6MBJI39IFibdiIta/SJYUTkEhBlewFk0WBB7w8gu/J1HQKU
J66w0tLsCxVGdqLeNlCRsWE2gzFZCmRGm+SqVwiqXGjAWZmv+F7LCeo9XmTt8PUE
uOyaE+Pdn3o8RDaa6dMHuifdMC60UVlUGQf42RrzCSiq/SCz4/KXVDjoU4hJvw3m
bQsErg+/AgMBAAECggEAHICehyIZK/W4vyXud4JzEMrDZHycD5XDH3ZbruYPLmMj
Whrqt7gax1hW+NbiqtpAopsN3Ev4hQG7FjyOs9Wb9u1HUpWGvJjyKxHsQ780281y
reoSHJpxeKh18jwPbHT6via4PdGNjVbiA0sz0u1zr/bvdOIdcMnAYFJlV81cMD4c
tBDIGpfYtqYcp4lcGhTqFrRYRCbSGpPRfqIozbQp6/5c/Eyh08tFa50bjNix/Nvk
Hprfr7uV7s+w+wkyCyhCulrz14ol9E8Flc2sqq9OflzYXh1oSumdpzsjQNiVdhKV
InsLWMpaRSaNHYQCbBc/rhxfkpORhWD240LHnP62mQKBgQD7Dql0mDoHtNB62PNn
VfoF2yjxIfQzwZC7XfUXz0/Q3apJrP4EHjuTL4QVjJPV50wS71/evEsuGcv8kVZf
1klcOPE38vPtVJPPE50Xf00Tm2azfawkU6u1yYd2bmP1Bac1YoZNd/o4+E2wPgDB
JXFv7wn/i24iZ58Gi1ZrXGGU2QKBgQDJJQTBhEm9ZOx48VpsiLX2GfwzJknQGcCy
CduAIqbFVUtl+UN3sANbnhjvNU2P7f7nJpK6NEz89HctpcFh0wZmrNCawfYSXu4f
LKvl9tXd4RsdF7tTkhbU8blZxmSRatybioObikzXsV3NqaIz1uhisXroWzrL2BUS
nAUYbNQKVwKBgQCzgoxPvfjgQb0/2ZhQrv0S6t2fbPO7fhAKqOfyml0rrxNvkq4e
K6/VUghTkCy0qamPcHFQRbpLwE5GzXTBGeticaSoqKMZc3wseI2+m1t1RYxtktJf
NyRz2yFs4Qm/zMb+OPBmu/7CdWi3N946PJebvYOcoQmiuAzRFRg5s9hiIQKBgQCw
OEZaY9NWojyqGIjn3T3NRia1iS3Rqz4uvIQZVkJVT8ymoiKBkSrf8TpXF5PELPXM
/PY/O+LXGjXvP/CUC5ToDy8S5ir3HUPw++n9pqrnoHdonYn4RVzLYprIFA+3dq+f
dVKnyhpYPYO40ozQbc9Z57OOLZ7tR3nuu9Ga/H0oMQKBgQDKsiwfaQdiHZUZBN45
YuAfdbwbXi08f8mWLaZuQY6mSiNLaMmxQ6wfT1CC0NMvg/JCEnWu7YAmwen4rC4p
dd6xr+6XBODfyVVGnFmflIdilzBqFmwVWhsRceXVCWrGWk+qusKrFGaDcPRdqx0w
a5WeQBMriwoeq2Ajpyj2c6IPow==
-----END PRIVATE KEY-----
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
Expand Down Expand Up @@ -143,6 +143,15 @@ static void websocket_app_start(void)
websocket_cfg.uri = CONFIG_WEBSOCKET_URI;
#endif /* CONFIG_WEBSOCKET_URI_FROM_STDIN */

#if CONFIG_WS_OVER_TLS_SCHEME
extern const char cert_start[] asm("_binary_cert_pem_start");
extern const char cert_end[] asm("_binary_cert_pem_end");

websocket_cfg.skip_cert_common_name_check = true;
websocket_cfg.cert_pem = cert_start;
websocket_cfg.cert_len = cert_end - cert_start;
#endif

ESP_LOGI(TAG, "Connecting to %s...", websocket_cfg.uri);

esp_websocket_client_handle_t client = esp_websocket_client_init(&websocket_cfg);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import json
import random
import re
import socket
import ssl
import string
from threading import Event, Thread

from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
from SimpleWebSocketServer import (SimpleSSLWebSocketServer,
SimpleWebSocketServer, WebSocket)


def get_my_ip():
Expand Down Expand Up @@ -44,12 +46,21 @@ def send_data(self, data):
conn.sendMessage(data)

def run(self):
self.server = SimpleWebSocketServer('', self.port, WebsocketTestEcho)
if self.use_tls is True:
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain(certfile='main/certs/cert.pem', keyfile='main/certs/key.pem')
# Set verify_mode to CERT_NONE to not require client certificates
ssl_context.verify_mode = ssl.CERT_NONE
ssl_context.check_hostname = False
self.server = SimpleSSLWebSocketServer('', self.port, WebsocketTestEcho, ssl_context=ssl_context)
else:
self.server = SimpleWebSocketServer('', self.port, WebsocketTestEcho)
while not self.exit_event.is_set():
self.server.serveonce()

def __init__(self, port):
def __init__(self, port, use_tls):
self.port = port
self.use_tls = use_tls
self.exit_event = Event()
self.thread = Thread(target=self.run)
self.thread.start()
Expand Down Expand Up @@ -145,14 +156,22 @@ def test_fragmented_msg(dut):
uri = dut.app.sdkconfig['WEBSOCKET_URI']
uri_from_stdin = False

if dut.app.sdkconfig.get('WS_OVER_TLS_SCHEME') is True:
use_tls = True
else:
use_tls = False

except Exception:
print('ENV_TEST_FAILURE: Cannot find uri settings in sdkconfig')
raise

if uri_from_stdin:
server_port = 8080
with Websocket(server_port) as ws:
uri = 'ws://{}:{}'.format(get_my_ip(), server_port)
with Websocket(server_port, use_tls) as ws:
if use_tls is True:
uri = 'wss://{}:{}'.format(get_my_ip(), server_port)
else:
uri = 'ws://{}:{}'.format(get_my_ip(), server_port)
print('DUT connecting to {}'.format(uri))
dut.expect('Please enter uri of websocket endpoint', timeout=30)
dut.write(uri)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_IDF_TARGET_LINUX=n
CONFIG_WEBSOCKET_URI_FROM_STDIN=y
CONFIG_WEBSOCKET_URI_FROM_STRING=n
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
CONFIG_EXAMPLE_CONNECT_WIFI=n
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
CONFIG_EXAMPLE_ETH_PHY_IP101=y
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
CONFIG_EXAMPLE_CONNECT_IPV6=y
CONFIG_WS_OVER_TLS_SCHEME=y
# CONFIG_ESP_TLS_INSECURE=y
# CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY=y
# CONFIG_ESP_TLS_USING_MBEDTLS=y
# CONFIG_ESP_TLS_PSK_VERIFICATION=y

0 comments on commit 59b643f

Please sign in to comment.