mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-16 20:12:13 +02:00
feat(websocket): Expanded example to demonstrate the transfer over TLS
This commit is contained in:
@ -13,6 +13,55 @@ This example can be executed on any ESP32 board, the only required interface is
|
|||||||
* Open the project configuration menu (`idf.py menuconfig`)
|
* Open the project configuration menu (`idf.py menuconfig`)
|
||||||
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu.
|
* 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)
|
* 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)
|
||||||
|
* To test a WebSocket client example over TLS, please enable one of the following configurations: `CONFIG_WS_OVER_TLS_MUTUAL_AUTH` or `CONFIG_WS_OVER_TLS_SERVER_AUTH`. See the sections below for more details.
|
||||||
|
|
||||||
|
### Server Certificate Verification
|
||||||
|
|
||||||
|
* Mutual Authentication: When `CONFIG_WS_OVER_TLS_MUTUAL_AUTH=y` is enabled, it's essential to provide valid certificates for both the server and client.
|
||||||
|
This ensures a secure two-way verification process.
|
||||||
|
* Server-Only Authentication: To perform verification of the server's certificate only (without requiring a client certificate), set `CONFIG_WS_OVER_TLS_SERVER_AUTH=y`.
|
||||||
|
This method skips client certificate verification.
|
||||||
|
* Example below demonstrates how to generate a new self signed certificates for the server and client using the OpenSSL command line tool
|
||||||
|
|
||||||
|
Please note: This example represents an extremely simplified approach to generating self-signed certificates/keys with a single common CA, devoid of CN checks, lacking password protection, and featuring hardcoded key sizes and types. It is intended solely for testing purposes.
|
||||||
|
In the outlined steps, we are omitting the configuration of the CN (Common Name) field due to the context of a testing environment. However, it's important to recognize that the CN field is a critical element of SSL/TLS certificates, significantly influencing the security and efficacy of HTTPS communications. This field facilitates the verification of a website's identity, enhancing trust and security in web interactions. In practical deployments beyond testing scenarios, ensuring the CN field is accurately set is paramount for maintaining the integrity and reliability of secure communications
|
||||||
|
|
||||||
|
### Generating a self signed Certificates with OpenSSL
|
||||||
|
* The example below outlines the process for creating new certificates for both the server and client using OpenSSL, a widely-used command line tool for implementing TLS protocol:
|
||||||
|
|
||||||
|
```
|
||||||
|
Generate the CA's Private Key;
|
||||||
|
openssl genrsa -out ca_key.pem 2048
|
||||||
|
|
||||||
|
Create the CA's Certificate
|
||||||
|
openssl req -new -x509 -days 3650 -key ca_key.pem -out ca_cert.pem
|
||||||
|
|
||||||
|
Generate the Server's Private Key
|
||||||
|
openssl genrsa -out server_key.pem 2048
|
||||||
|
|
||||||
|
Generate a Certificate Signing Request (CSR) for the Server
|
||||||
|
openssl req -new -key server_key.pem -out server_csr.pem
|
||||||
|
|
||||||
|
Sign the Server's CSR with the CA's Certificate
|
||||||
|
openssl x509 -req -days 3650 -in server_csr.pem -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -out server_cert.pem
|
||||||
|
|
||||||
|
Generate the Client's Private Key
|
||||||
|
openssl genrsa -out client_key.pem 2048
|
||||||
|
|
||||||
|
Generate a Certificate Signing Request (CSR) for the Client
|
||||||
|
openssl req -new -key client_key.pem -out client_csr.pem
|
||||||
|
|
||||||
|
Sign the Client's CSR with the CA's Certificate
|
||||||
|
openssl x509 -req -days 3650 -in client_csr.pem -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -out client_cert.pem
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Expiry time and metadata fields can be adjusted in the invocation.
|
||||||
|
|
||||||
|
Please see the openssl man pages (man openssl) 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
|
### Build and Flash
|
||||||
|
|
||||||
|
@ -1,2 +1,22 @@
|
|||||||
idf_component_register(SRCS "websocket_example.c"
|
set(SRC_FILES "websocket_example.c") # Define source files
|
||||||
INCLUDE_DIRS ".")
|
set(INCLUDE_DIRS ".") # Define include directories
|
||||||
|
set(EMBED_FILES "") # Initialize an empty list for files to embed
|
||||||
|
|
||||||
|
# Conditionally append files to the list based on configuration
|
||||||
|
#if(CONFIG_WS_OVER_TLS_MUTAL_AUTH)
|
||||||
|
list(APPEND EMBED_FILES
|
||||||
|
"certs/client_cert.pem"
|
||||||
|
"certs/ca_cert.pem"
|
||||||
|
"certs/client_key.pem")
|
||||||
|
#endif()
|
||||||
|
|
||||||
|
# For testing purpose we are using CA of wss://echo.websocket.events
|
||||||
|
#if(CONFIG_WS_OVER_TLS_SERVER_AUTH)
|
||||||
|
list(APPEND EMBED_FILES
|
||||||
|
"certs/ca_certificate_public_domain.pem")
|
||||||
|
#endif()
|
||||||
|
|
||||||
|
# Register the component with source files, include dirs, and any conditionally added embedded files
|
||||||
|
idf_component_register(SRCS "${SRC_FILES}"
|
||||||
|
INCLUDE_DIRS "${INCLUDE_DIRS}"
|
||||||
|
EMBED_TXTFILES "${EMBED_FILES}")
|
||||||
|
@ -16,10 +16,30 @@ menu "Example Configuration"
|
|||||||
config WEBSOCKET_URI
|
config WEBSOCKET_URI
|
||||||
string "Websocket endpoint URI"
|
string "Websocket endpoint URI"
|
||||||
depends on WEBSOCKET_URI_FROM_STRING
|
depends on WEBSOCKET_URI_FROM_STRING
|
||||||
default "ws://echo.websocket.events"
|
default "wss://echo.websocket.events"
|
||||||
help
|
help
|
||||||
URL of websocket endpoint this example connects to and sends echo
|
URL of websocket endpoint this example connects to and sends echo
|
||||||
|
|
||||||
|
config WS_OVER_TLS_SERVER_AUTH
|
||||||
|
bool "Enable WebSocket over TLS with Server Certificate Verification Only"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enables WebSocket connections over TLS (WSS) with server certificate verification.
|
||||||
|
This setting mandates the client to verify the servers certificate, while the server
|
||||||
|
does not require client certificate verification.
|
||||||
|
|
||||||
|
config WS_OVER_TLS_MUTUAL_AUTH
|
||||||
|
bool "Enable WebSocket over TLS with Server Client Mutual Authentification"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enables WebSocket connections over TLS (WSS) with server and client mutual certificate verification.
|
||||||
|
|
||||||
|
config WS_OVER_TLS_SKIP_COMMON_NAME_CHECK
|
||||||
|
bool "Skip common name(CN) check during TLS authentification"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Skipping Common Name(CN) check during TLS(WSS) authentificatio
|
||||||
|
|
||||||
if CONFIG_IDF_TARGET = "linux"
|
if CONFIG_IDF_TARGET = "linux"
|
||||||
config GCOV_ENABLED
|
config GCOV_ENABLED
|
||||||
bool "Coverage analyzer"
|
bool "Coverage analyzer"
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDazCCAlOgAwIBAgIUL04QhbSEt5oNbV4f7CeLLqTCw2gwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||||
|
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDAyMjMwODA2MjVaFw0zNDAy
|
||||||
|
MjAwODA2MjVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
|
||||||
|
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4IBDwAwggEKAoIBAQDjc78SuXAmJeBc0el2/m+2lwtk3J/VrNxHYkhjHa8K
|
||||||
|
/ybU89VvKGuv9+L3IP67WMguFTaMgivJYUePjfMchtNJLJ+4cR9BkBKH4JnyXDae
|
||||||
|
s0a5181LxRo8rqcaOw9hmJTgt9R4dIRTR3GN2/VLhlR+L9OTYA54RUtMyMMpyk5M
|
||||||
|
YIJbcOwiwkVLsIYnexXDfgz9vQGl/2vBQ/RBtDBvbSyBiWox9SuzOrya1HUBzJkM
|
||||||
|
Iu5L0bSa0LAeXHT3i3P1Y4WPt9ub70OhUNfJtHC+XbGFSEkkQG+lfbXU75XLoMWa
|
||||||
|
iATMREOcb3Mq+pn1G8o1ZHVc6lBHUkfrNfxs5P/GQcSvAgMBAAGjUzBRMB0GA1Ud
|
||||||
|
DgQWBBQGkdK2gR2HrQTnZnbuWO7I1+wdxDAfBgNVHSMEGDAWgBQGkdK2gR2HrQTn
|
||||||
|
ZnbuWO7I1+wdxDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBx
|
||||||
|
G0hFtMwV/agIwC3ZaYC36ZWiijFzWkJSZG+fqAy32mSoVL2uQvOT8vEfF0ZnAcPc
|
||||||
|
JI4oI059dBhAVlwqv6uLHyD4Gf2bF4oSLljdTz3X23llF+/wrTC2LLqMrm09aUC0
|
||||||
|
ac74Q0FVwVJJcqH1HgemCMVjna5MkwNA6B+q7uR3eQ692VqXk6vjd4fRLBg1bBO1
|
||||||
|
hXjasfNxA8A9quORF5+rjYrwyUZHuzcs0FfSClckIt4tHKtt4moLufOW6/PM4fRe
|
||||||
|
AgdDfiTupxYLJFz4hFPhfgCh4TjQ+f9+uP4IAjW42dJmTVZjLEku/hm5lxCFObAq
|
||||||
|
RgfaNwH8Ug1r1xswjSZG
|
||||||
|
-----END CERTIFICATE-----
|
@ -0,0 +1,30 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
nLRbwHOoq7hHwg==
|
||||||
|
-----END CERTIFICATE-----
|
@ -0,0 +1,20 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDWjCCAkKgAwIBAgIUUPCOgMA2v09E29fCkogx3RUBRtEwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||||
|
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDAyMjMwODA3MzFaFw0zNDAy
|
||||||
|
MjAwODA3MzFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
|
||||||
|
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4IBDwAwggEKAoIBAQCrNeomxI2aoP+4iUy5SiA+41oHUDZDFeJOBjv5JCsK
|
||||||
|
mlvFqxE9zynmPOVpuABErOJwzerPTa4NYKvuvs5CxVJUV5CXtWANuu9majioZNzj
|
||||||
|
f877MDNX/GnZHK2gnkxVrZCPaDmx9yiMsFMXgmfdrDhwoUpXbdgSyeU/al9Ds2kF
|
||||||
|
0hrHOH2LBWt/mVeLbONU5CC1HOdVVw+uRlhVlxnfhTPd/Nru3rJx7R0sN7qXcZpJ
|
||||||
|
PL87WvrszLVOux24DeaOz9oiD2b7egFyUuq1BM25iCwi8s/Ths8xd0Ca1d8mEcHW
|
||||||
|
FVd4w2+nUMXFE+IbP+wo6FXuiSaOBNri3rztpvCCMaWjAgMBAAGjQjBAMB0GA1Ud
|
||||||
|
DgQWBBSOlA+9Vfbcfy8iS4HSd4V0KPtm4jAfBgNVHSMEGDAWgBQGkdK2gR2HrQTn
|
||||||
|
ZnbuWO7I1+wdxDANBgkqhkiG9w0BAQsFAAOCAQEAOmzm/MwowKTrSpMSrmfA3MmW
|
||||||
|
ULzsfa25WyAoTl90ATlg4653Y7pRaNfdvVvyi2V2LlPcmc7E0rfD53t1NxjDH1uM
|
||||||
|
LgFMTNEaZ9nMRSW0kMiwaRpvmXS8Eb9PXfvIM/Mw0co/aMOtAQnfTGIqsgkQwKyk
|
||||||
|
1GG7QKQq3p4QGu5ZaTnjnaoa79hODt+0xQDD1wp6C9xwBY0M4gndAi3wkOeFkGv+
|
||||||
|
OmGPtaCBu5V9tJCZ9dfZvjkaK44NGwDw0urAcYRK2h7asnlflu7cnlGMBB0qY4kQ
|
||||||
|
BX5WI8UjN6rECBHbtNRvEh06ogDdHbxYV+TibrqkkeDRw6HX1qqiEJ+iCgWEDQ==
|
||||||
|
-----END CERTIFICATE-----
|
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCrNeomxI2aoP+4
|
||||||
|
iUy5SiA+41oHUDZDFeJOBjv5JCsKmlvFqxE9zynmPOVpuABErOJwzerPTa4NYKvu
|
||||||
|
vs5CxVJUV5CXtWANuu9majioZNzjf877MDNX/GnZHK2gnkxVrZCPaDmx9yiMsFMX
|
||||||
|
gmfdrDhwoUpXbdgSyeU/al9Ds2kF0hrHOH2LBWt/mVeLbONU5CC1HOdVVw+uRlhV
|
||||||
|
lxnfhTPd/Nru3rJx7R0sN7qXcZpJPL87WvrszLVOux24DeaOz9oiD2b7egFyUuq1
|
||||||
|
BM25iCwi8s/Ths8xd0Ca1d8mEcHWFVd4w2+nUMXFE+IbP+wo6FXuiSaOBNri3rzt
|
||||||
|
pvCCMaWjAgMBAAECggEAOTWjz16AXroLmRMv8v5E9h6sN6Ni7lnCrAXDRoYCZ+Ga
|
||||||
|
Ztu5wCiYPJn+oqvcUxZd+Ammu6yeS1QRP468h20+DHbSFw+BUDU1x8gYtJQ3h0Fu
|
||||||
|
3VqG3ZC3odfGYNRkd4CuvGy8Uq5e+1vz9/gYUuc4WNJccAiBWg3ir6UQviOWJV46
|
||||||
|
LGfdEd9hVvIGl5pmArMBVYdpj9+JHunDtG4uQxiWla5pdLjlkC2mGexD18T9d718
|
||||||
|
6I+o3YHv1Y9RPT1d4rNhYQWx6YdTTD2rmS7nTrzroj/4fXsblpXzR+/l7crlNERY
|
||||||
|
67RMPwgDR1NiAbCAJKsSbMS66lRCNlhTM4YffGAN6QKBgQDkIdcNm9j49SK5Wbl5
|
||||||
|
j8U6UbcVYPzPG+2ea+fDfUIafA0VQHIuX6FgA17Kp7BDX9ldKtSBpr0Z8vetVswr
|
||||||
|
agmXVMR/7QdvnZ9NpL66YA/BRs67CvsryVu4AVAzThFGySmlcXGlPq47doWDQ3B9
|
||||||
|
0BOEnVoeDXR3SabaNsEbhDYn1wKBgQDAIAUyhJcgz+LcgaAtBwdnEN57y66JlRVZ
|
||||||
|
bsb6cEG/MNmnLjQYsplJjNbz4yrB5ukTChPTGRF/JQRqHoXh6DGQFHvobukwwA6x
|
||||||
|
RAIIq0NLJ5HUipfOi+VpCbWUHdoUNhwjAB2qVtD4LXE2Lyn46C8ET5eRtRjUKpzV
|
||||||
|
lpsq63KHFQKBgFB+cDbpCoGtXPcxZXQy+lA9jPAKLKmXHRyMzlX32F8n7iXVe3RJ
|
||||||
|
YdNS3Rt8V4EuTK/G8PxeLNL/G80ZlyiqXX/79Ol+ZOVJJHBs9K8mPejgZwkwMrec
|
||||||
|
cLRYIkg3/3iOehdaE9NOboOkqi9KmGKMDJb6PlXkQXflkO3l6/UdjU45AoGAen0v
|
||||||
|
sxiTncjMU1eVfn+nuY8ouXaPbYoOFXmqBItDb5i+e3baohBj6F+Rv+ZKIVuNp6Ta
|
||||||
|
JNErtYstOFcDdpbp2nkk0ni71WftNhkszsgZ3DV7JS3DQV0xwvj8ulUZ757b63is
|
||||||
|
cShujHu0XR5OvTGSoEX6VVxHWyVb3lTp0sBPwU0CgYBe2Ieuya0X8mAbputFN64S
|
||||||
|
Kv++dqktTUT8i+tp07sIrpDeYwO3D89x9kVSJj4ImlmhiBVGkxFWPkpGyBLotdse
|
||||||
|
Ai/E6f5I7CDSZZC0ZucgcItNd4Yy459QY+dFwFtT3kIaD9ml8fnqQ83J9W8DWtv9
|
||||||
|
6mY9FnUUufbJcpHxN58RTw==
|
||||||
|
-----END PRIVATE KEY-----
|
@ -0,0 +1,20 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDWjCCAkKgAwIBAgIUUPCOgMA2v09E29fCkogx3RUBRtAwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||||
|
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDAyMjMwODA2NTlaFw0zNDAy
|
||||||
|
MjAwODA2NTlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
|
||||||
|
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4IBDwAwggEKAoIBAQC8WWbDxnLzTSfuQaO+kQnnzbwjhUHWn58s+BIEaO8M
|
||||||
|
GG6bX+8r/SH9XjMfFS36qAN3qxgRun3YoRTaHc2QByiGjf5IL4EAPDnLN+NzUIL5
|
||||||
|
7Gi2QPQP/GksAsOGKWk/nMRPk1vcMptkFVIWSp474SQ0A92Z9z0dUIqBpjRa34kr
|
||||||
|
HsAIcT59/EG7YBBadMk0fQIxQVLh3Vosky85q+0waFihe47Ef5U2UftexoUx4Vcz
|
||||||
|
6EtP60Wx+4qN+FLsr+n2B7Oz2ITqfwgqLzjNLZwm9bMjcLZ0fWm1A/W1C989MXwI
|
||||||
|
w6DAPEZv7pbgp8r9phyrNieSDuuRaCvFsaXh6troAjLxAgMBAAGjQjBAMB0GA1Ud
|
||||||
|
DgQWBBRJCYAQG2+1FN5P/wyAR1AsrAyb4DAfBgNVHSMEGDAWgBQGkdK2gR2HrQTn
|
||||||
|
ZnbuWO7I1+wdxDANBgkqhkiG9w0BAQsFAAOCAQEAmllul/GIH7RVq85mM/SxP47J
|
||||||
|
M7Z7T032KuR3n/Psyv2iq/uEV2CUje3XrKNwR2PaJL4Q6CtoWy7xgIP+9CBbjddR
|
||||||
|
M7sdNQab8P2crAUtBKnkNOl/na/5KnXnjwi/PmWJJ9i2Cqt0PPkaykTWp/MLfYIw
|
||||||
|
RPkY2Yo8f8gEiqXQd+0qTuMgumbgkPq3V8Lk1ocy62F5/qUhXxH+ifAXEoUQS6EG
|
||||||
|
8DlgwdZlfUY+jeM6N56WzYmxD1syjNW7faPio+qXINfpYatROhqphaMQ5SA6TRj6
|
||||||
|
jcnLa31TdDdWmWYDcYgZntAv6yGi3rh0MdYqeNS0FKlMKmaH81VHs7V1UUXwUQ==
|
||||||
|
-----END CERTIFICATE-----
|
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8WWbDxnLzTSfu
|
||||||
|
QaO+kQnnzbwjhUHWn58s+BIEaO8MGG6bX+8r/SH9XjMfFS36qAN3qxgRun3YoRTa
|
||||||
|
Hc2QByiGjf5IL4EAPDnLN+NzUIL57Gi2QPQP/GksAsOGKWk/nMRPk1vcMptkFVIW
|
||||||
|
Sp474SQ0A92Z9z0dUIqBpjRa34krHsAIcT59/EG7YBBadMk0fQIxQVLh3Vosky85
|
||||||
|
q+0waFihe47Ef5U2UftexoUx4Vcz6EtP60Wx+4qN+FLsr+n2B7Oz2ITqfwgqLzjN
|
||||||
|
LZwm9bMjcLZ0fWm1A/W1C989MXwIw6DAPEZv7pbgp8r9phyrNieSDuuRaCvFsaXh
|
||||||
|
6troAjLxAgMBAAECggEACNVCggTxCCMCr+RJKxs/NS1LWPkbZNbYjrHVmnpXV6Bf
|
||||||
|
s460t0HoUasUx6zlGp+9heOyvcYat8maIj6KkOodBu5q0fTUXm/0n+ivlI1ejxz8
|
||||||
|
ritupr9GKWe5xrVzd6XA+SBmivWenvt2/Y+jSxica4oQ3vMe3RyVWk4yn15jXu+9
|
||||||
|
7B9lNyNeZtOBr6OozHGLYw4dwWcBNv2S6wevRKfHPwn/Ch5yTH1uAskgoMxUuyK2
|
||||||
|
ynNVHWUhyS4pFU7Tex5ENDel15VYdbxV/2lQ2W6fHMLtC5GWKJXXbigCX7pfOpzC
|
||||||
|
BFJEfZl7ze/qptE9AR7DkLFYyMtrS7OlebYbLDOM9wKBgQD+rTdwULZibpKwlI3a
|
||||||
|
9Y22d4N/EDFvuu8LnuEiVQnXgwg9M+tlaa2liP18j1a7y/FCfoXf5sjUWCsdYR6d
|
||||||
|
C0TuiOGI59hYGI94NvVLAmOutR+vJ/3jhbv5wyqEQLhJ42Yz9kWBrDCI+V3q3TdO
|
||||||
|
H7wcH6suUIZpeLEJF4qHzY/1dwKBgQC9U/Pvswiww8sfysmd5shUNo4ofAZnTM1A
|
||||||
|
ak6pWE3lSyiOkSm+3B2GqxYWLRoo1v+pTyhhXDtRRmxGtMNrKCsmlHef/o3c6kkG
|
||||||
|
cuC2h/DiSmoITHy3BYKJoDeE54E8ubXUUKqHo41LYUs+D7M/IGxeiO13MUoIrEtF
|
||||||
|
AwzVWPBU1wKBgH8barD2x6Bm+XWCHy6qIZlxGsMfDN1r2gTdvhWJhcj3D/Sj5heO
|
||||||
|
X+lfbsxtKee+yOHcDesK3y8D9jjKkSHmTvgSfyX6OML3NxvTqidOwPugUHj2J8QX
|
||||||
|
qhLk8mJhftj50reacWRf0TV76ADhecnXEuaic6hA7mTTpOAZzL0svm3PAoGBALWF
|
||||||
|
r6VLX3KzVqZVtLb7FWmAoQ35093pCgXPpznAW3cTd4Axd/fxbTG4CUYb2i/760X2
|
||||||
|
ij3Gw2yqe5fTKmYsLisgQA2bb4K28msHa6I2dmNQe5cXVp/X3Y98mJ6JpCSH3ekB
|
||||||
|
qm7ABfGXCCApx28n9B8zY5JbJKNqJgS15vELA+ojAoGAAkaV2w46+3iQ6gJtQepr
|
||||||
|
zGNybiYBx/Wo5fDdTS5u0xN+ZdC9fl2Zs0n7sMmUT8bWdDLcMnntHHO+oDIKyRHs
|
||||||
|
TQh1n68vQ4JoegQv3Z9Z/TLEKqr9gyJC1Ao6M4bZpPhUWQwupfHColtsr2TskcnJ
|
||||||
|
Nf2FpJZ7z6fQEShGlK1yTXM=
|
||||||
|
-----END PRIVATE KEY-----
|
@ -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
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
*/
|
*/
|
||||||
@ -91,7 +91,7 @@ static void websocket_event_handler(void *handler_args, esp_event_base_t base, i
|
|||||||
if (data->op_code == 0x08 && data->data_len == 2) {
|
if (data->op_code == 0x08 && data->data_len == 2) {
|
||||||
ESP_LOGW(TAG, "Received closed message with code=%d", 256 * data->data_ptr[0] + data->data_ptr[1]);
|
ESP_LOGW(TAG, "Received closed message with code=%d", 256 * data->data_ptr[0] + data->data_ptr[1]);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "Received=%.*s", data->data_len, (char *)data->data_ptr);
|
ESP_LOGW(TAG, "Received=%.*s\n\n", data->data_len, (char *)data->data_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If received data contains json structure it succeed to parse
|
// If received data contains json structure it succeed to parse
|
||||||
@ -143,6 +143,28 @@ static void websocket_app_start(void)
|
|||||||
websocket_cfg.uri = CONFIG_WEBSOCKET_URI;
|
websocket_cfg.uri = CONFIG_WEBSOCKET_URI;
|
||||||
#endif /* CONFIG_WEBSOCKET_URI_FROM_STDIN */
|
#endif /* CONFIG_WEBSOCKET_URI_FROM_STDIN */
|
||||||
|
|
||||||
|
#if CONFIG_WS_OVER_TLS_MUTUAL_AUTH
|
||||||
|
/* Configuring client certificates for mutual authentification */
|
||||||
|
extern const char cacert_start[] asm("_binary_ca_cert_pem_start"); // CA certificate
|
||||||
|
extern const char cert_start[] asm("_binary_client_cert_pem_start"); // Client certificate
|
||||||
|
extern const char cert_end[] asm("_binary_client_cert_pem_end");
|
||||||
|
extern const char key_start[] asm("_binary_client_key_pem_start"); // Client private key
|
||||||
|
extern const char key_end[] asm("_binary_client_key_pem_end");
|
||||||
|
|
||||||
|
websocket_cfg.cert_pem = cacert_start;
|
||||||
|
websocket_cfg.client_cert = cert_start;
|
||||||
|
websocket_cfg.client_cert_len = cert_end - cert_start;
|
||||||
|
websocket_cfg.client_key = key_start;
|
||||||
|
websocket_cfg.client_key_len = key_end - key_start;
|
||||||
|
#elif CONFIG_WS_OVER_TLS_SERVER_AUTH
|
||||||
|
extern const char cacert_start[] asm("_binary_ca_certificate_public_domain_pem_start"); // CA cert of wss://echo.websocket.event, modify it if using another server
|
||||||
|
websocket_cfg.cert_pem = cacert_start;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_WS_OVER_TLS_SKIP_COMMON_NAME_CHECK
|
||||||
|
websocket_cfg.skip_cert_common_name_check = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Connecting to %s...", websocket_cfg.uri);
|
ESP_LOGI(TAG, "Connecting to %s...", websocket_cfg.uri);
|
||||||
|
|
||||||
esp_websocket_client_handle_t client = esp_websocket_client_init(&websocket_cfg);
|
esp_websocket_client_handle_t client = esp_websocket_client_init(&websocket_cfg);
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
# 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
|
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
import ssl
|
||||||
import string
|
import string
|
||||||
|
import sys
|
||||||
from threading import Event, Thread
|
from threading import Event, Thread
|
||||||
|
|
||||||
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
|
from SimpleWebSocketServer import (SimpleSSLWebSocketServer,
|
||||||
|
SimpleWebSocketServer, WebSocket)
|
||||||
|
|
||||||
|
|
||||||
def get_my_ip():
|
def get_my_ip():
|
||||||
@ -27,7 +30,7 @@ class WebsocketTestEcho(WebSocket):
|
|||||||
|
|
||||||
def handleMessage(self):
|
def handleMessage(self):
|
||||||
self.sendMessage(self.data)
|
self.sendMessage(self.data)
|
||||||
print('Server sent: {}'.format(self.data))
|
print('\n Server sent: {}\n'.format(self.data))
|
||||||
|
|
||||||
def handleConnected(self):
|
def handleConnected(self):
|
||||||
print('Connection from: {}'.format(self.address))
|
print('Connection from: {}'.format(self.address))
|
||||||
@ -44,12 +47,23 @@ class Websocket(object):
|
|||||||
conn.sendMessage(data)
|
conn.sendMessage(data)
|
||||||
|
|
||||||
def run(self):
|
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/server_cert.pem', keyfile='main/certs/server_key.pem')
|
||||||
|
if self.client_verify is True:
|
||||||
|
ssl_context.load_verify_locations(cafile='main/certs/ca_cert.pem')
|
||||||
|
ssl_context.verify = ssl.CERT_REQUIRED
|
||||||
|
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():
|
while not self.exit_event.is_set():
|
||||||
self.server.serveonce()
|
self.server.serveonce()
|
||||||
|
|
||||||
def __init__(self, port):
|
def __init__(self, port, use_tls, verify):
|
||||||
self.port = port
|
self.port = port
|
||||||
|
self.use_tls = use_tls
|
||||||
|
self.client_verify = verify
|
||||||
self.exit_event = Event()
|
self.exit_event = Event()
|
||||||
self.thread = Thread(target=self.run)
|
self.thread = Thread(target=self.run)
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
@ -77,6 +91,7 @@ def test_examples_protocol_websocket(dut):
|
|||||||
for i in range(0, 5):
|
for i in range(0, 5):
|
||||||
dut.expect(re.compile(b'Received=hello (\\d)'))
|
dut.expect(re.compile(b'Received=hello (\\d)'))
|
||||||
print('All echos received')
|
print('All echos received')
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
def test_close(dut):
|
def test_close(dut):
|
||||||
code = dut.expect(
|
code = dut.expect(
|
||||||
@ -103,7 +118,8 @@ def test_examples_protocol_websocket(dut):
|
|||||||
match = dut.expect(
|
match = dut.expect(
|
||||||
re.compile(b'Json=({[a-zA-Z0-9]*).*}')).group(0).decode()[5:]
|
re.compile(b'Json=({[a-zA-Z0-9]*).*}')).group(0).decode()[5:]
|
||||||
if match == str(data[0]):
|
if match == str(data[0]):
|
||||||
print('Sent message and received message are equal')
|
print('Sent message and received message are equal \n')
|
||||||
|
sys.stdout.flush()
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'DUT received string do not match sent string, \nexpected: {}\nwith length {}\
|
'DUT received string do not match sent string, \nexpected: {}\nwith length {}\
|
||||||
@ -126,7 +142,8 @@ def test_examples_protocol_websocket(dut):
|
|||||||
recv_msg += match
|
recv_msg += match
|
||||||
|
|
||||||
if recv_msg == send_msg:
|
if recv_msg == send_msg:
|
||||||
print('Sent message and received message are equal')
|
print('Sent message and received message are equal \n')
|
||||||
|
sys.stdout.flush()
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'DUT received string do not match sent string, \nexpected: {}\nwith length {}\
|
'DUT received string do not match sent string, \nexpected: {}\nwith length {}\
|
||||||
@ -145,14 +162,24 @@ def test_examples_protocol_websocket(dut):
|
|||||||
uri = dut.app.sdkconfig['WEBSOCKET_URI']
|
uri = dut.app.sdkconfig['WEBSOCKET_URI']
|
||||||
uri_from_stdin = False
|
uri_from_stdin = False
|
||||||
|
|
||||||
|
if dut.app.sdkconfig.get('WS_OVER_TLS_MUTUAL_AUTH') is True:
|
||||||
|
use_tls = True
|
||||||
|
client_verify = True
|
||||||
|
else:
|
||||||
|
use_tls = False
|
||||||
|
client_verify = False
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
print('ENV_TEST_FAILURE: Cannot find uri settings in sdkconfig')
|
print('ENV_TEST_FAILURE: Cannot find uri settings in sdkconfig')
|
||||||
raise
|
raise
|
||||||
|
|
||||||
if uri_from_stdin:
|
if uri_from_stdin:
|
||||||
server_port = 8080
|
server_port = 8080
|
||||||
with Websocket(server_port) as ws:
|
with Websocket(server_port, use_tls, client_verify) as ws:
|
||||||
uri = 'ws://{}:{}'.format(get_my_ip(), server_port)
|
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))
|
print('DUT connecting to {}'.format(uri))
|
||||||
dut.expect('Please enter uri of websocket endpoint', timeout=30)
|
dut.expect('Please enter uri of websocket endpoint', timeout=30)
|
||||||
dut.write(uri)
|
dut.write(uri)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
CONFIG_IDF_TARGET="esp32"
|
CONFIG_IDF_TARGET="esp32"
|
||||||
CONFIG_IDF_TARGET_LINUX=n
|
CONFIG_IDF_TARGET_LINUX=n
|
||||||
CONFIG_WEBSOCKET_URI_FROM_STDIN=y
|
CONFIG_WEBSOCKET_URI_FROM_STDIN=n
|
||||||
CONFIG_WEBSOCKET_URI_FROM_STRING=n
|
CONFIG_WEBSOCKET_URI_FROM_STRING=y
|
||||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||||
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
|
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
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_MUTUAL_AUTH=y
|
||||||
|
CONFIG_WS_OVER_TLS_SKIP_COMMON_NAME_CHECK=y
|
@ -0,0 +1,15 @@
|
|||||||
|
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_MUTUAL_AUTH=n
|
||||||
|
CONFIG_WS_OVER_TLS_SERVER_AUTH=n
|
Reference in New Issue
Block a user