chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:04:25 +08:00
commit 548b49ebc0
20937 changed files with 5455372 additions and 0 deletions
@@ -0,0 +1,16 @@
set(requires esp_https_server nvs_flash)
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "linux")
list(APPEND requires esp_stubs protocol_examples_common)
else()
list(APPEND requires esp_wifi esp_eth)
endif()
idf_component_register(SRCS "main.c"
INCLUDE_DIRS "."
PRIV_REQUIRES ${requires}
EMBED_TXTFILES "certs/servercert.pem"
"certs/prvtkey.pem"
"certs/cacert.pem"
"certs/cakey.pem")
@@ -0,0 +1,45 @@
menu "Example Configuration"
config EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
bool "Enable user callback with HTTPS Server"
help
Enable user callback for esp_https_server which can be used to get SSL context (connection information)
E.g. Certificate of the connected client
choice EXAMPLE_ENABLE_HTTPS_SERVER_TLS_VERSION
prompt "Choose TLS version"
default EXAMPLE_ENABLE_HTTPS_SERVER_TLS_1_2_ONLY
config EXAMPLE_ENABLE_HTTPS_SERVER_TLS_1_2_ONLY
bool "TLS 1.2"
select MBEDTLS_SSL_PROTO_TLS1_2
help
Enable HTTPS server TLS 1.2
config EXAMPLE_ENABLE_HTTPS_SERVER_TLS_1_3_ONLY
bool "TLS 1.3"
select MBEDTLS_SSL_PROTO_TLS1_3
help
Enable HTTPS server TLS 1.3
config EXAMPLE_ENABLE_HTTPS_SERVER_TLS_ANY
bool "TLS 1.3 and 1.2"
select MBEDTLS_SSL_PROTO_TLS1_3
select MBEDTLS_SSL_PROTO_TLS1_2
help
Enable HTTPS server TLS 1.3 and 1.2
endchoice
config EXAMPLE_ENABLE_HTTPS_SERVER_CUSTOM_CIPHERSUITES
bool "Enable HTTPS server custom ciphersuites"
default n
help
Enable HTTPS server custom ciphersuites
config EXAMPLE_ENABLE_SKIP_CLIENT_CERT
bool "Skip client certificate (WARNING: ONLY FOR TESTING PURPOSE, READ HELP)"
default n
select ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL
help
Allow clients to connect without providing a client certificate.
This is useful for testing purposes. When enabled, the server request
client certificates but does not require them for the connection to be established.
If a client certificate is provided, it will be verified.
endmenu
@@ -0,0 +1,120 @@
# Certificate Generation Guide
This directory contains certificates for the HTTPS server example. This guide explains how to generate new server and client certificates signed by the existing CA certificate.
## Prerequisites
- OpenSSL installed on your system
- Existing CA certificate (`cacert.pem`) and CA private key (`cakey.pem`)
- Configuration files for certificate extensions (`server_cert.conf` and `client_cert.conf`)
## Generating Server Certificate
Follow these steps to create a new server certificate signed by the CA:
### 1. Generate Server Private Key
```bash
openssl genpkey -algorithm RSA -out new_server.key -pkeyopt rsa_keygen_bits:2048
```
This creates a 2048-bit RSA private key for the server.
### 2. Create Certificate Signing Request (CSR)
```bash
openssl req -new -key new_server.key -out new_server.csr -config server_cert.conf
```
This generates a CSR using the server's private key and the configuration specified in `server_cert.conf`.
### 3. Sign the Server Certificate with CA
```bash
openssl x509 -req -in new_server.csr -CA cacert.pem -CAkey cakey.pem -CAcreateserial -out new_server.pem -days 3650 -extensions v3_req -extfile server_cert.conf
```
This creates the server certificate (`new_server.pem`) valid for 10 years (3650 days), signed by the CA certificate.
## Generating Client Certificate
Follow these steps to create a new client certificate signed by the CA:
### 4. Generate Client Private Key
```bash
openssl genpkey -algorithm RSA -out new_client.key -pkeyopt rsa_keygen_bits:2048
```
This creates a 2048-bit RSA private key for the client.
### 5. Create Certificate Signing Request (CSR)
```bash
openssl req -new -key new_client.key -out new_client.csr -config client_cert.conf
```
This generates a CSR using the client's private key and the configuration specified in `client_cert.conf`.
### 6. Sign the Client Certificate with CA
```bash
openssl x509 -req -in new_client.csr -CA cacert.pem -CAkey cakey.pem -CAcreateserial -out new_client.pem -days 3650 -extensions v3_req -extfile client_cert.conf
```
This creates the client certificate (`new_client.pem`) valid for 10 years (3650 days), signed by the CA certificate.
## Installing the Certificates
### 7. Copy Certificates to Expected Locations
```bash
cp new_server.pem servercert.pem && \
cp new_server.key prvtkey.pem && \
cp new_client.pem client_cert.pem && \
cp new_client.key client_key.pem
```
This copies the newly generated certificates and keys to the filenames expected by the example application.
## File Naming Convention
The example application expects the following files:
- `servercert.pem` - Server certificate
- `prvtkey.pem` - Server private key
- `client_cert.pem` - Client certificate
- `client_key.pem` - Client private key
- `cacert.pem` - CA certificate (for verification)
## Security Notes
⚠️ **Important Security Considerations:**
- The private keys (`prvtkey.pem`, `client_key.pem`, `cakey.pem`) should be kept secure. As these are for demonstration purposes, they are included here, but in a production environment, ensure they are stored securely and access is restricted.
- The certificates in this example directory are for **demonstration purposes only**
- For production use, generate new certificates with appropriate security parameters
- Consider using shorter validity periods for production certificates
- Store private keys with restricted file permissions (e.g., `chmod 600`)
## Verifying Generated Certificates
You can verify the generated certificates using:
```bash
# Verify server certificate
openssl x509 -in servercert.pem -text -noout
# Verify client certificate
openssl x509 -in client_cert.pem -text -noout
# Verify certificate chain
openssl verify -CAfile cacert.pem servercert.pem
openssl verify -CAfile cacert.pem client_cert.pem
```
## Troubleshooting
- If certificate verification fails, ensure the CA certificate and key are valid and match
- Check that the configuration files (`server_cert.conf`, `client_cert.conf`) contain appropriate Subject Alternative Names (SANs) and extensions
- Ensure OpenSSL version is up to date for best compatibility
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDOzCCAiOgAwIBAgIUG/S51QF4EeUkdaqg54oogqIKBZkwDQYJKoZIhvcNAQEL
BQAwJTEjMCEGA1UEAwwaRVNQMzIgSFRUUFMgc2VydmVyIGV4YW1wbGUwHhcNMjUw
NDAyMDcwMzI2WhcNMzUwMzMxMDcwMzI2WjAlMSMwIQYDVQQDDBpFU1AzMiBIVFRQ
UyBzZXJ2ZXIgZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ALBint6nP77RCQcmKgwPtTsGK0uClxg+LwKJ3WXuye3oqnnjqJCwMEneXzGdG09T
sA0SyNPwrEgebLCH80an3gWU4pHDdqGHfJQa2jBL290e/5L5MB+6PTs2NKcojK/k
qcZkn58MWXhDW1NpAnJtjVniK2Ksvr/YIYSbyD+JiEs0MGxEx+kOl9d7hRHJaIzd
GF/vO2pl295v1qXekAlkgNMtYIVAjUy9CMpqaQBCQRL+BmPSJRkXBsYk8GPnieS4
sUsp53DsNvCCtWDT6fd9D1v+BB6nDk/FCPKhtjYOwOAZlX4wWNSZpRNr5dfrxKsb
jAn4PCuR2akdF4G8WLUeDWECAwEAAaNjMGEwHQYDVR0OBBYEFMnmdJKOEepXrHI/
ivM6mVqJgAX8MB8GA1UdIwQYMBaAFMnmdJKOEepXrHI/ivM6mVqJgAX8MA8GA1Ud
EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgKEMA0GCSqGSIb3DQEBCwUAA4IBAQBP
AgAagM33DqsDi+UArUxEoqmov1rH0PHXnd/a6Ct/IvNzr0qUH8hW4Lv0tWHfOJY8
pCf7bkejxXlhP/QHb6M+sobN9tN/WupEaeqNg4pCWi+6Caj2uFW9vkQQf2j50lMg
R0oxnd6SMEQArzy3f3yYRp8rliPERY6F2Rtb9HJNh53K51FE60xONPLZ/1dtSgDB
KcJseZfhg6oAUSLjFCYJEn5xa7CsIuQ8Jx2xMo4IkU44BJ8TJS4zw/hP1/vVjjvS
uU2Z0ZOUCQ78/3eMnsFfLMtDUYqXPyhNogm51GeHOR6dk+ICQ+c5gCDkJUnOTqzg
G2JUmXAXxJoUZDfalijl
-----END CERTIFICATE-----
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCwYp7epz++0QkH
JioMD7U7BitLgpcYPi8Cid1l7snt6Kp546iQsDBJ3l8xnRtPU7ANEsjT8KxIHmyw
h/NGp94FlOKRw3ahh3yUGtowS9vdHv+S+TAfuj07NjSnKIyv5KnGZJ+fDFl4Q1tT
aQJybY1Z4itirL6/2CGEm8g/iYhLNDBsRMfpDpfXe4URyWiM3Rhf7ztqZdveb9al
3pAJZIDTLWCFQI1MvQjKamkAQkES/gZj0iUZFwbGJPBj54nkuLFLKedw7DbwgrVg
0+n3fQ9b/gQepw5PxQjyobY2DsDgGZV+MFjUmaUTa+XX68SrG4wJ+DwrkdmpHReB
vFi1Hg1hAgMBAAECggEAaTCnZkl/7qBjLexIryC/CBBJyaJ70W1kQ7NMYfniWwui
f0aRxJgOdD81rjTvkINsPp+xPRQO6oOadjzdjImYEuQTqrJTEUnntbu924eh+2D9
Mf2CAanj0mglRnscS9mmljZ0KzoGMX6Z/EhnuS40WiJTlWlH6MlQU/FDnwC6U34y
JKy6/jGryfsx+kGU/NRvKSru6JYJWt5v7sOrymHWD62IT59h3blOiP8GMtYKeQlX
49om9Mo1VTIFASY3lrxmexbY+6FG8YO+tfIe0tTAiGrkb9Pz6tYbaj9FjEWOv4Vc
+3VMBUVdGJjgqvE8fx+/+mHo4Rg69BUPfPSrpEg7sQKBgQDlL85G04VZgrNZgOx6
pTlCCl/NkfNb1OYa0BELqWINoWaWQHnm6lX8YjrUjwRpBF5s7mFhguFjUjp/NW6D
0EEg5BmO0ePJ3dLKSeOA7gMo7y7kAcD/YGToqAaGljkBI+IAWK5Su5yldrECTQKG
YnMKyQ1MWUfCYEwHtPvFvE5aPwKBgQDFBWXekpxHIvt/B41Cl/TftAzE7/f58JjV
MFo/JCh9TDcH6N5TMTRS1/iQrv5M6kJSSrHnq8pqDXOwfHLwxetpk9tr937VRzoL
CuG1Ar7c1AO6ujNnAEmUVC2DppL/ck5mRPWK/kgLwZSaNcZf8sydRgphsW1ogJin
7g0nGbFwXwKBgQCPoZY07Pr1TeP4g8OwWTu5F6dSvdU2CAbtZthH5q98u1n/cAj1
noak1Srpa3foGMTUn9CHu+5kwHPIpUPNeAZZBpq91uxa5pnkDMp3UrLIRJ2uZyr8
4PxcknEEh8DR5hsM/IbDcrCJQglM19ZtQeW3LKkY4BsIxjDf45ymH407IQKBgE/g
Ul6cPfOxQRlNLH4VMVgInSyyxWx1mODFy7DRrgCuh5kTVh+QUVBM8x9lcwAn8V9/
nQT55wR8E603pznqY/jX0xvAqZE6YVPcw4kpZcwNwL1RhEl8GliikBlRzUL3SsW3
q30AfqEViHPE3XpE66PPo6Hb1ymJCVr77iUuC3wtAoGBAIBrOGunv1qZMfqmwAY2
lxlzRgxgSiaev0lTNxDzZkmU/u3dgdTwJ5DDANqPwJc6b8SGYTp9rQ0mbgVHnhIB
jcJQBQkTfq6Z0H6OoTVi7dPs3ibQJFrtkoyvYAbyk36quBmNRjVh6rc8468bhXYr
v/t+MeGJP/0Zw8v/X2CFll96
-----END PRIVATE KEY-----
@@ -0,0 +1,16 @@
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = SG
ST = SG
L = SG
O = ESP32 Client
CN = ESP32 Test Client
[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDfDCCAmSgAwIBAgIUeWALux8MJqS983GSSUHotYp9OxgwDQYJKoZIhvcNAQEL
BQAwJTEjMCEGA1UEAwwaRVNQMzIgSFRUUFMgc2VydmVyIGV4YW1wbGUwHhcNMjUx
MDEwMDIzOTIxWhcNMzUxMDA4MDIzOTIxWjBaMQswCQYDVQQGEwJTRzELMAkGA1UE
CAwCU0cxCzAJBgNVBAcMAlNHMRUwEwYDVQQKDAxFU1AzMiBDbGllbnQxGjAYBgNV
BAMMEUVTUDMyIFRlc3QgQ2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAsWm6XLeoa2dVtUn+hEZMULUSS0RqcE9kPHBQCwRNSlDs6eUSy4Y45SO0
P5aqDLd7vMcDg41YPDbXp6JhvKov2Q7pAVbwhrLzn+M6O7XS+7i8J9PzgjBTKMhC
rLkGBYbyW04STIbgHmQ0G98y6deyXnkqg/d0OzNaB4XgOiRbuxw1IaPX2loTS5aV
hnuo/5tdcyiNMAjio/P1GrkE1OPSUwbdxROjmZW5peFkD4sogW/XH0oMYpMKwyWZ
cHiuj5E4IxeazqaJqzjbXIj7+hTywE2kXZDVK1o02JbkDRhig5NkXv38DyNu8R8W
dvh3GBczZS7lIn+2fjr3soILMOJ/NwIDAQABo28wbTAJBgNVHRMEAjAAMAsGA1Ud
DwQEAwIF4DATBgNVHSUEDDAKBggrBgEFBQcDAjAdBgNVHQ4EFgQUubkj5sTevwdf
SMd2J5WyKkrqtfIwHwYDVR0jBBgwFoAUyeZ0ko4R6lescj+K8zqZWomABfwwDQYJ
KoZIhvcNAQELBQADggEBAJmjtzv5aMkNKw8+EwDrdOHJsw6czOtPeVLTmIy02+Pv
4rvn+4VDCzogM7oBbFzFFGwUmBXqfdmP4wteqtfdCwHboiCzZySPw0O+OMbhQmEF
mCE+k+sCUEWrb3tiraVWh1aipoqOqE0WNcyZ1ZwY1OCMaVYsfFXw3lcND/7VXjp6
13WSO46avn3WvesTS/GhLg8yTJiQ8iPXMEEKhf7BTAn461ZsGR3hnz+DPtWTTOaI
9fCdjvvYsL4+k3+Y10LWUSsmB6kjyzCmx7/I4NeUEGmMAD4PD5dkkksw+TZBobsb
APf44t+dQGYc0dhfym7b+qeW8MTvmx40ZYL52HG7XCU=
-----END CERTIFICATE-----
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCxabpct6hrZ1W1
Sf6ERkxQtRJLRGpwT2Q8cFALBE1KUOzp5RLLhjjlI7Q/lqoMt3u8xwODjVg8Nten
omG8qi/ZDukBVvCGsvOf4zo7tdL7uLwn0/OCMFMoyEKsuQYFhvJbThJMhuAeZDQb
3zLp17JeeSqD93Q7M1oHheA6JFu7HDUho9faWhNLlpWGe6j/m11zKI0wCOKj8/Ua
uQTU49JTBt3FE6OZlbml4WQPiyiBb9cfSgxikwrDJZlweK6PkTgjF5rOpomrONtc
iPv6FPLATaRdkNUrWjTYluQNGGKDk2Re/fwPI27xHxZ2+HcYFzNlLuUif7Z+Ovey
ggsw4n83AgMBAAECggEAMLZZg7yvwzG/0EOtXQ9aQ+y7xavW19iMqqWh7Kx1NlsK
+du6ceR8Obo4cx9AuLYmhPpV5iiImhvq0a3dzSojciNMaeA/sZRwHS4MXrm5YQFj
tEHXgh8XrkJyQC+bTigz4ksI7jc4UU/tGNwLhDaD1LnLKSnoIZsjdJ5XJ0+1WiXa
pyTy5KBtKyhhLzy+toFeheNMbHV2yf2dFEFYM+76DKgXyMwNF1NzDUNhmxJrc/8H
0qb4P/gFgWe1H3ZveY/iOyLzqmqBQw02blug+YHxLfC9Gc7Wz6aY86YxGg1bKjvi
AG1GxtCKhUzBZMH7gGZSQJ+6Beq5cNReEgbSJu2N1QKBgQDnlz6cy22SMORCqUc9
CO+NwzZeywruY8wjhZYx0kKqeC/g5Ama1+2THL7DVR+dgTJOuRvBgBtps/jfQKdz
BpVeIfAH2n6x+62tjnHW274BwQy8SEf7nc4hvEY/PKUSqZ4JAeNISghHgfCMtcoW
Lv7Ehbx+uA1AJPsGwIgCmlxBlQKBgQDEHKoZ2jeLlouYFsJlgEpqcLRQA+z8QsR7
DSNjBZmuC4kKkQuoWhRoyvvgZIxT5xLkKG0eUh7kKsOdJ7Fv448rr6I9A03z9dDw
bGrDl+vKlHSyo+9rfw8HXPG8G1b2X0K9LI8t6wBKHSPt8Bv5CXL9exJVQ33CndMW
iIfpns0imwKBgANqyOK5YbGBhSyyoLl200oNMlUtu8iOsmlnxDKR/qfTRCmWU8n0
G65LA0mQjPne+SYONymgwUbLAAYTRyU8WKHd8FO9Vpc7tnFUI7ve3CvcdFqm2mEN
EAiRZZvzQiBHXmyVmYvsg7jCYxFAcW3oXZv6uTBJePCUWxvbZWZcbrYNAoGAcgWY
gN93XBlzoEHbVNh6a9iLfdpKd4D6a/D/mhsvdxoN267pcECvjR43xAex7zZyrWUz
zGVCwLZ8dWsWp09Pdr7vPTomoKlTifX/PSmfVnFqSFM4aO++9TD8+7mJnkVUsFiw
BqqTyIOY2Ea6fNkZmndr+Vb8T6Mjj/5hx1slOfECgYEAttRU86Duvm8gypIux5xY
CZeYiNCbZ/4+mR5yvfhVpMk2BJyOvtmoe6PnM+VLm+pNjZdK6mkPevXC6ownbyTl
WOOmoxnl0lbZiKBmreNrdSKuAgezAATLQdipzuV8R4Udsko0lF03ZT1uMTBqI0Fs
Kid3fvAzqQtoCLPyRsfKAr0=
-----END PRIVATE KEY-----
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+8VU37LjhtI2p
/O8QCBdhFzzYv/+3VipAySD7TCCO6coHEs8PyV6z+uQ868PRmkyqBJgbW0/WdSt4
RCTyCraTNMDIWEuoxbFHSLObT6fiMU9vlYcNlZkCMFIEqgd4r5657tQi1ROZ8gOD
Jx3zpW9M5Yl5+jSDzLP7oAJWgbf3rTK/ePk4AU7SWAJGQXcD/C8RLsryyWE0Lps/
X/B24GTXEj+u4Gp761KilDX8M3wLeLvYBb9DZ3rDwCXPJ8ukVc7ui5VZgGTOykVz
u8YUnc0jJI7ptaOMv4oDniJ6aqfGaV8ghwo1xq3Rpbo0jOOeFgjOgM8JyCtbK/4r
sRHiep3rAgMBAAECggEAH3x+V/2CMz3pymk6JsOez1TcpMVsbpgX2Z0RAj94cvic
ZvQ0Dt9e7YDm2CDspoiyMasWRhSVosCpjWh3Sy53Euk1DRR6TXdkF2Qmseq9vW/y
MG1Q2u2bUKAVNk2vc7hKDVETzDakx9L/v0XZC49xPhXvyJx4wm8kEs8883TqmD2/
T5d7Xs7Rxkwo3iduqwHs3jWgJWwi44Il+ATfySAbymTZcPCXxOtWjvStAjgjtMEm
KQYvvb0ZJIpqiPDH0Inq4D8U1AE0i16RlRteN6UB7avEP1v0SHFg1P2hTzWrwjZD
lpgQ5JU6WO8tdtddMuR3u4hO5g6MJ2k5wkdLOjLTuQKBgQDm0ijy2/mCiqvKxaVp
4hdAaTssHxT/+hDtWlcpqqYCgmNX7KRIzfTWLDg3qhENLcrxdBNt8bnhas2/E0/I
IA8NyB9tkQlEXv5DYfUHG7ZFUndBgIftFRLM0Ibfx4A58PjQWwe9jtqSpQJdrEL6
WRXsSBuveAqB4BTMtimUfxRH1wKBgQDTxYt1tij+x+ApVE4k//Vf+loKWOXDO/Bm
R+O1e0mYEViEjpHd2QCEyy6JTYkTktO9yLt2A5rpZiDIA2wqnl0VMUXTbUOvsLNH
UXOpy2rebWgEEZkTq/aFkhH4juLfimT6lJzZ18navPuFIj5Nj1emFU5NHQSOZ/EA
6OPo5eXIDQKBgEDudd57yyDR6anNF89Fbs0LzT2IMNwheImMlGCARNsH2vJs+3oP
lgR5xAbErK9MZn6t7JlNGsEyzlYmFJdzjUiPN2gXGMhHALfr4oXxYcD2hd3DTnl/
KB69unNRJ90k0JmsQe0tNodyK8w2HVFXpjclwcQGvM30P2WnCONhLE9ZAoGAHcKz
OJWi6Ts5m1VHrhdyakyKfs3DbE5uGFGeBJEQ5Jf7cpV+lki6s+7B2XXV/7QwoYkm
Hw2epZI+pR0mBE9BEYtdHrtKOdSBPVKLCJ+Xoy6I4Zl/g6409Mx0ThP2eie+zSA5
crvKmDzas/j9/HRagvKXkGq1izW8Pr572O0F/7kCgYANIGZ2YyGbuRdDxtNd1B/F
MhK9Njbwee8FN5Emxyq/nJJe13gyNDRCmDqUlTDbCXVCyT3fWg6dLVZu0igf3Zf2
+Z8lHBOD1VVBRdsYtRyZ/OvYksjOtBnZ5l4rMMt7MGxhA1Dm/oO/3ub0/dhrXnb+
MD6TRIZ3GhAZ1SPeuhEF5w==
-----END PRIVATE KEY-----
@@ -0,0 +1,20 @@
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = SG
ST = SG
L = SG
O = ESP32
CN = ESP32 HTTPS Server
[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = esp32-server
DNS.2 = localhost
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDhTCCAm2gAwIBAgIUeWALux8MJqS983GSSUHotYp9OxcwDQYJKoZIhvcNAQEL
BQAwJTEjMCEGA1UEAwwaRVNQMzIgSFRUUFMgc2VydmVyIGV4YW1wbGUwHhcNMjUx
MDEwMDIzOTAwWhcNMzUxMDA4MDIzOTAwWjBUMQswCQYDVQQGEwJTRzELMAkGA1UE
CAwCU0cxCzAJBgNVBAcMAlNHMQ4wDAYDVQQKDAVFU1AzMjEbMBkGA1UEAwwSRVNQ
MzIgSFRUUFMgU2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
vvFVN+y44bSNqfzvEAgXYRc82L//t1YqQMkg+0wgjunKBxLPD8les/rkPOvD0ZpM
qgSYG1tP1nUreEQk8gq2kzTAyFhLqMWxR0izm0+n4jFPb5WHDZWZAjBSBKoHeK+e
ue7UItUTmfIDgycd86VvTOWJefo0g8yz+6ACVoG3960yv3j5OAFO0lgCRkF3A/wv
ES7K8slhNC6bP1/wduBk1xI/ruBqe+tSopQ1/DN8C3i72AW/Q2d6w8AlzyfLpFXO
7ouVWYBkzspFc7vGFJ3NIySO6bWjjL+KA54iemqnxmlfIIcKNcat0aW6NIzjnhYI
zoDPCcgrWyv+K7ER4nqd6wIDAQABo34wfDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF
4DAiBgNVHREEGzAZggxlc3AzMi1zZXJ2ZXKCCWxvY2FsaG9zdDAdBgNVHQ4EFgQU
U2FQtf+ar/qQtk5hBObVuW/VAjMwHwYDVR0jBBgwFoAUyeZ0ko4R6lescj+K8zqZ
WomABfwwDQYJKoZIhvcNAQELBQADggEBAHS3Nr8OTEWV6s5srMDxnvjry4XmBOU2
gvNxLe7xci6DShCpFK+S+W/Vqmv0I17TEW5cV8Z/P5HKtiYAvNI7Ptc6BTK20Q83
jKC6kSYMlK54zW4ZNbnvI/zwtMNh4YLiLVjSQxMe11qaTu7eOqI49qEmgNP82VPu
JmFvO4W05McdUJ3xxVJVJk3l8ZTjgOTPfL/bbqibYSvewsyJlo2ihIHezP4Au/4Z
2Wpzj1scBDSucDTsWBkXMGdV4tUpUuDYLJF2XqKwIm39IkoxdPnHANC62OtcLawh
FOjfM34YqanizzWwfjNl6OD8vWP4ztIf3J4jONiDnnpVIo6skAGYTyQ=
-----END CERTIFICATE-----
@@ -0,0 +1,7 @@
dependencies:
protocol_examples_common:
path: ${IDF_PATH}/examples/common_components/protocol_examples_common
esp_stubs:
path: ${IDF_PATH}/examples/protocols/linux_stubs/esp_stubs
rules:
- if: "target in [linux]"
@@ -0,0 +1,324 @@
/* Simple HTTP + SSL Server Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <unistd.h>
#include <esp_event.h>
#include <esp_log.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "esp_netif.h"
#include "protocol_examples_common.h"
#if !CONFIG_IDF_TARGET_LINUX
#include <esp_wifi.h>
#include <esp_system.h>
#include "esp_eth.h"
#endif // !CONFIG_IDF_TARGET_LINUX
#include <esp_https_server.h>
#include "esp_tls.h"
#include "esp_key_config.h"
#include "sdkconfig.h"
#if CONFIG_EXAMPLE_ENABLE_HTTPS_SERVER_CUSTOM_CIPHERSUITES
#include "mbedtls/ssl_ciphersuites.h"
#endif // CONFIG_EXAMPLE_ENABLE_HTTPS_SERVER_CUSTOM_CIPHERSUITES
/* A simple example that demonstrates how to create GET and POST
* handlers and start an HTTPS server.
*/
static const char *TAG = "example";
#ifdef CONFIG_ESP_HTTPS_SERVER_EVENTS
/* Event handler for catching system events */
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
if (event_base == ESP_HTTPS_SERVER_EVENT) {
if (event_id == HTTPS_SERVER_EVENT_ERROR) {
esp_https_server_last_error_t *last_error = (esp_tls_last_error_t *) event_data;
ESP_LOGE(TAG, "Error event triggered: last_error = %s, last_tls_err = %d, tls_flag = %d", esp_err_to_name(last_error->last_error), last_error->esp_tls_error_code, last_error->esp_tls_flags);
}
}
}
#endif // CONFIG_ESP_HTTPS_SERVER_EVENTS
/* An HTTP GET handler */
static esp_err_t root_get_handler(httpd_req_t *req)
{
httpd_resp_set_type(req, "text/html");
httpd_resp_send(req, "<h1>Hello Secure World!</h1>", HTTPD_RESP_USE_STRLEN);
return ESP_OK;
}
#if CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
static void print_peer_cert_info(const mbedtls_ssl_context *ssl)
{
const mbedtls_x509_crt *cert;
const size_t buf_size = 1024;
char *buf = calloc(buf_size, sizeof(char));
if (buf == NULL) {
ESP_LOGE(TAG, "Out of memory - Callback execution failed!");
return;
}
// Logging the peer certificate info
cert = mbedtls_ssl_get_peer_cert(ssl);
if (cert != NULL) {
mbedtls_x509_crt_info((char *) buf, buf_size - 1, " ", cert);
ESP_LOGI(TAG, "Peer certificate info:\n%s", buf);
} else {
ESP_LOGW(TAG, "Could not obtain the peer certificate!");
}
free(buf);
}
#endif
/**
* Example callback function to get the certificate of connected clients,
* whenever a new SSL connection is created and closed
*
* Can also be used to other information like Socket FD, Connection state, etc.
*
* NOTE: This callback will not be able to obtain the client certificate if the
* following config `Set minimum Certificate Verification mode to Optional` is
* not enabled (enabled by default in this example).
*
* The config option is found here - Component config → ESP-TLS
*
*/
static void https_server_user_callback(esp_https_server_user_cb_arg_t *user_cb)
{
ESP_LOGI(TAG, "User callback invoked!");
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
mbedtls_ssl_context *ssl_ctx = NULL;
#endif
switch(user_cb->user_cb_state) {
case HTTPD_SSL_USER_CB_SESS_CREATE:
ESP_LOGD(TAG, "At session creation");
// Logging the socket FD
int sockfd = -1;
esp_err_t esp_ret;
esp_ret = esp_tls_get_conn_sockfd(user_cb->tls, &sockfd);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Error in obtaining the sockfd from tls context");
break;
}
ESP_LOGI(TAG, "Socket FD: %d", sockfd);
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
ssl_ctx = (mbedtls_ssl_context *) esp_tls_get_ssl_context(user_cb->tls);
if (ssl_ctx == NULL) {
ESP_LOGE(TAG, "Error in obtaining ssl context");
break;
}
// Logging the current ciphersuite
ESP_LOGI(TAG, "Current Ciphersuite: %s", mbedtls_ssl_get_ciphersuite(ssl_ctx));
#endif
break;
case HTTPD_SSL_USER_CB_SESS_CLOSE:
ESP_LOGD(TAG, "At session close");
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
// Logging the peer certificate
ssl_ctx = (mbedtls_ssl_context *) esp_tls_get_ssl_context(user_cb->tls);
if (ssl_ctx == NULL) {
ESP_LOGE(TAG, "Error in obtaining ssl context");
break;
}
print_peer_cert_info(ssl_ctx);
#endif
break;
case HTTPD_SSL_USER_CB_SESS_ERROR:
ESP_LOGD(TAG, "At session error (handshake failed)");
// Get socket FD to log failing client IP address
sockfd = -1;
esp_ret = esp_tls_get_conn_sockfd(user_cb->tls, &sockfd);
if (esp_ret == ESP_OK && sockfd >= 0) {
struct sockaddr_storage addr;
socklen_t len = sizeof(addr);
if (getpeername(sockfd, (struct sockaddr*)&addr, &len) == 0) {
char ip_str[INET6_ADDRSTRLEN];
if (addr.ss_family == AF_INET) {
inet_ntop(AF_INET, &((struct sockaddr_in*)&addr)->sin_addr, ip_str, sizeof(ip_str));
} else if (addr.ss_family == AF_INET6) {
inet_ntop(AF_INET6, &((struct sockaddr_in6*)&addr)->sin6_addr, ip_str, sizeof(ip_str));
} else {
strcpy(ip_str, "unknown");
}
ESP_LOGW(TAG, "SSL handshake failed from client IP: %s", ip_str);
}
}
break;
default:
ESP_LOGE(TAG, "Illegal state!");
return;
}
}
#endif
static const httpd_uri_t root = {
.uri = "/",
.method = HTTP_GET,
.handler = root_get_handler
};
static httpd_handle_t start_webserver(void)
{
httpd_handle_t server = NULL;
// Start the httpd server
ESP_LOGI(TAG, "Starting server");
httpd_ssl_config_t conf = HTTPD_SSL_CONFIG_DEFAULT();
#if CONFIG_IDF_TARGET_LINUX
/* Use non-privileged port on Linux since port 443 requires root */
conf.port_secure = 8443;
#endif
extern const unsigned char servercert_start[] asm("_binary_servercert_pem_start");
extern const unsigned char servercert_end[] asm("_binary_servercert_pem_end");
extern const unsigned char cacert_start[] asm("_binary_cacert_pem_start");
extern const unsigned char cacert_end[] asm("_binary_cacert_pem_end");
conf.servercert = servercert_start;
conf.servercert_len = servercert_end - servercert_start;
#if CONFIG_EXAMPLE_ENABLE_SKIP_CLIENT_CERT
conf.client_cert_authmode_optional = true;
#endif // EXAMPLE_ENABLE_SKIP_CLIENT_CERT
conf.cacert_pem = cacert_start;
conf.cacert_len = cacert_end - cacert_start;
extern const unsigned char prvtkey_pem_start[] asm("_binary_prvtkey_pem_start");
extern const unsigned char prvtkey_pem_end[] asm("_binary_prvtkey_pem_end");
static esp_key_config_t server_key = {
.source = ESP_KEY_SOURCE_BUFFER,
.buffer = {
.data = prvtkey_pem_start,
}
};
server_key.buffer.len = prvtkey_pem_end - prvtkey_pem_start;
conf.server_key = &server_key;
#if CONFIG_EXAMPLE_ENABLE_HTTPS_SERVER_CUSTOM_CIPHERSUITES
static const int ciphersuites_to_use[] = {
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
0,
};
conf.ciphersuites_list = ciphersuites_to_use;
#else
conf.ciphersuites_list = NULL;
#endif // CONFIG_EXAMPLE_ENABLE_HTTPS_SERVER_CUSTOM_CIPHERSUITES
#if CONFIG_EXAMPLE_ENABLE_HTTPS_SERVER_TLS_1_3_ONLY
conf.tls_version = ESP_TLS_VER_TLS_1_3;
#elif CONFIG_EXAMPLE_ENABLE_HTTPS_SERVER_TLS_1_2_ONLY
conf.tls_version = ESP_TLS_VER_TLS_1_2;
#else
conf.tls_version = ESP_TLS_VER_ANY;
#endif // CONFIG_EXAMPLE_ENABLE_HTTPS_SERVER_TLS_1_3_ONLY
#if CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
conf.user_cb = https_server_user_callback;
#endif
esp_err_t ret = httpd_ssl_start(&server, &conf);
if (ESP_OK != ret) {
ESP_LOGI(TAG, "Error starting server!");
return NULL;
}
// Set URI handlers
ESP_LOGI(TAG, "Registering URI handlers");
httpd_register_uri_handler(server, &root);
return server;
}
#if !CONFIG_IDF_TARGET_LINUX
static esp_err_t stop_webserver(httpd_handle_t server)
{
// Stop the httpd server
return httpd_ssl_stop(server);
}
static void disconnect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server) {
if (stop_webserver(*server) == ESP_OK) {
*server = NULL;
} else {
ESP_LOGE(TAG, "Failed to stop https server");
}
}
}
static void connect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server == NULL) {
*server = start_webserver();
}
}
#endif // !CONFIG_IDF_TARGET_LINUX
void app_main(void)
{
static httpd_handle_t server = NULL;
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* Register event handlers to start server when Wi-Fi or Ethernet is connected,
* and stop server when disconnection happens.
*/
#if !CONFIG_IDF_TARGET_LINUX
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
#endif // !CONFIG_IDF_TARGET_LINUX
#ifdef CONFIG_ESP_HTTPS_SERVER_EVENTS
ESP_ERROR_CHECK(esp_event_handler_register(ESP_HTTPS_SERVER_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
#endif // CONFIG_ESP_HTTPS_SERVER_EVENTS
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());
#if CONFIG_IDF_TARGET_LINUX
/* On Linux, start the server directly since there are no WiFi/Ethernet events */
server = start_webserver();
while (server) {
sleep(5);
}
#endif // CONFIG_IDF_TARGET_LINUX
}