mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(esp_http_client_mutual_auth): add mutual TLS example
Closes https://github.com/espressif/esp-idf/issues/18393
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
set(requires esp-tls nvs_flash esp_event esp_netif esp_http_client)
|
||||
|
||||
set(embed_txt certs/ca_cert.pem)
|
||||
|
||||
if(CONFIG_EXAMPLE_MUTUAL_AUTH_USE_HW_RSA_DS)
|
||||
list(APPEND requires esp_secure_cert_mgr)
|
||||
else()
|
||||
list(APPEND embed_txt certs/client_cert.pem certs/client_key.pem)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "mutual_auth_example.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES ${requires}
|
||||
EMBED_TXTFILES ${embed_txt})
|
||||
@@ -0,0 +1,12 @@
|
||||
menu "Example Configuration"
|
||||
config EXAMPLE_MUTUAL_AUTH_USE_HW_RSA_DS
|
||||
bool "Use DS peripheral for client authentication" if SOC_DIG_SIGN_SUPPORTED
|
||||
default n
|
||||
help
|
||||
When enabled, the client private key is held by the DS (Digital Signature)
|
||||
peripheral. The client certificate and DS context are loaded from the
|
||||
esp_secure_cert partition at runtime. Requires provisioning; see the README.
|
||||
|
||||
When disabled (default), the client certificate and private key are embedded
|
||||
in the firmware as PEM files from main/certs/.
|
||||
endmenu
|
||||
@@ -0,0 +1,41 @@
|
||||
# Certificate Generation for Mutual TLS Example
|
||||
|
||||
All certificates are pre-generated with a 10-year lifetime. To regenerate, run
|
||||
the following OpenSSL commands from this directory (`main/certs/`).
|
||||
|
||||
## Generate CA (signs both client and server certs)
|
||||
|
||||
openssl req -newkey rsa:2048 -nodes -keyout ca_key.pem -x509 -days 3650 \
|
||||
-out ca_cert.pem -subj "/CN=Mutual Auth Test CA"
|
||||
|
||||
## Generate client certificate (embedded in firmware)
|
||||
|
||||
openssl genrsa -out client_key.pem 2048
|
||||
openssl req -out client.csr -key client_key.pem -new -subj "/CN=esp_mutual_auth_client"
|
||||
openssl x509 -req -days 3650 -in client.csr -CA ca_cert.pem -CAkey ca_key.pem \
|
||||
-sha256 -CAcreateserial -out client_cert.pem
|
||||
rm client.csr ca_cert.srl
|
||||
|
||||
## Generate server certificate (used by pytest mTLS server)
|
||||
|
||||
openssl genrsa -out server_key.pem 2048
|
||||
openssl req -out server.csr -key server_key.pem -new -subj "/CN=esp_mutual_auth_server"
|
||||
openssl x509 -req -days 3650 -in server.csr -CA ca_cert.pem -CAkey ca_key.pem \
|
||||
-sha256 -CAcreateserial -out server_cert.pem
|
||||
rm server.csr ca_cert.srl
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose | Embedded in firmware? |
|
||||
|------|---------|----------------------|
|
||||
| `ca_cert.pem` | CA certificate (verifies server identity) | Yes |
|
||||
| `ca_key.pem` | CA private key (signs certs; keep private) | No |
|
||||
| `client_cert.pem` | Client certificate (sent to server) | Yes (software mode) |
|
||||
| `client_key.pem` | Client private key | Yes (software mode) |
|
||||
| `server_cert.pem` | Server certificate (pytest mTLS server) | No |
|
||||
| `server_key.pem` | Server private key (pytest mTLS server) | No |
|
||||
|
||||
## DS peripheral mode
|
||||
|
||||
For DS peripheral mode, see `esp_secure_cert_data/` and the DS provisioning
|
||||
section in the top-level README.
|
||||
@@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDBTCCAe2gAwIBAgIUHrbEhg+kRb2wd66oi57asPHvrBYwDQYJKoZIhvcNAQEL
|
||||
BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAeFw0yNjAyMDQwNzMwMDRaFw0zNjAyMDIw
|
||||
NzMwMDRaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
||||
DwAwggEKAoIBAQCpug883pCJKGj0cZ/zdJLnjBa9M6lPWscgDFh1wPO1wyOzu25Q
|
||||
kUykgUE8GE3W7RC4zw4LCUkU06EeVnp6UkXsKktC94OvAeYczsq6Z95WwyF8ktXP
|
||||
AzW/Lpz202MFpA4edcoczLJEf1GPmoI1RM//V19Op+6nLBNLLTj35yO3CUMjxeh6
|
||||
ptlxi3PbiFliOVff6DfPcNzp7rh1k+SWoNP5adTN8aHjpoO53wFHhBfiP4zqnLJG
|
||||
uHFHApGcwyf1SAbERJ4F2tV+xMRVnp2i/Bx9pIY7qVRKdqOswQK6YGSlznfY8RCM
|
||||
he9B0mZpSa9NFsPdm+Lpt2wxDvuSC/WtMLHBAgMBAAGjUzBRMB0GA1UdDgQWBBRG
|
||||
ECXpPzDsNPv55ZHXAsKgCIYF6zAfBgNVHSMEGDAWgBRGECXpPzDsNPv55ZHXAsKg
|
||||
CIYF6zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAFiLooiqC/
|
||||
LQBoN7J6FyQhsKvly+yX4Vh8ituhQQnt4kRD28ci+GmceqgNlX86e/MMTzTXOCMJ
|
||||
EIhR4xHd1xg5lnPLPS1o+LXsbyOlU8QTCoYgVkjDVHi4fGnbMIoWaZBt8o3MYgAy
|
||||
Fc+7A6ZoK9PIbbcRUYPSPGe1loop490tgyNrvyc29lLdg4ljO+Xg3Wpu95bTxe/F
|
||||
bjWFWZgF6aqAfrT7QZXk9OIfOkDpcb5EsxBySQIZNC06FEtNkwanVWFSMdDm3Axh
|
||||
Xjuv1HdGyHnS/jcFTZ4EfB76oU0+NuoYtDYF7Fns3Upvg8QZhhs+6Ob5mRKJefRD
|
||||
HlIA+c6CBmsY
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCpug883pCJKGj0
|
||||
cZ/zdJLnjBa9M6lPWscgDFh1wPO1wyOzu25QkUykgUE8GE3W7RC4zw4LCUkU06Ee
|
||||
Vnp6UkXsKktC94OvAeYczsq6Z95WwyF8ktXPAzW/Lpz202MFpA4edcoczLJEf1GP
|
||||
moI1RM//V19Op+6nLBNLLTj35yO3CUMjxeh6ptlxi3PbiFliOVff6DfPcNzp7rh1
|
||||
k+SWoNP5adTN8aHjpoO53wFHhBfiP4zqnLJGuHFHApGcwyf1SAbERJ4F2tV+xMRV
|
||||
np2i/Bx9pIY7qVRKdqOswQK6YGSlznfY8RCMhe9B0mZpSa9NFsPdm+Lpt2wxDvuS
|
||||
C/WtMLHBAgMBAAECggEAAt0DUwvvrQqwG5ibodIwhMS/oPVBSNgPli4zI1hsHB/E
|
||||
x0xVD/mljPxrvvFrhcHV14JRurSvRZFM7Wu40P24lYOApcpyb6ZE7S09bQ/hx72u
|
||||
v9Dj18RWeKlXB1B5Yg/al5+1107KPp7Vv8oT4oVsy2JcVqG9ZFdZY3optP/yoay4
|
||||
oRJprOV4jc8aaLB0+zze/7RJZ4DtpeOWhyNws/cGwwFvaDlncnylAoaDs20MBfsg
|
||||
VV+glo69rqvn3SCfSXIG5/vyfHS52xPN04kPrpXpu7kvTeJHqCfq4w5LSS0GgBdM
|
||||
5CbBSpW25AnX9Jqczxhu7Y2rt8kIx+4gnW05z0YB2QKBgQDn9yeQzsXK98R7R6hz
|
||||
ogKyOYQuNVNjjR7guSD0285QTU+XB8jC2nqiTVPy8Xy1w6udh9SjvqS47yQyySzC
|
||||
ZCFvT3rwwdWP5pUj89FG7XoX33hQrV4+jbBCcjajeyMxAmMM83ISL9NahsVLWx7K
|
||||
gdPdxhBiCB8dueF+kVcBf1Bb2QKBgQC7UAjwl45oOIDoXBqN3TDGVodwQM6gn1rY
|
||||
heYjEUeQmjL6j4e8PiUFl5rHCNavIUr0gkBhnN5hcq2mvfECBEVVm8dlrvHHa4Ti
|
||||
ujhC6DGgrOUIPok+rXJoELvmrYa72H04uHwkOkESkuHO+gHuRJ7nIxH/BktGKsol
|
||||
Unp+CNBcKQKBgQCtn+NvkjWeTII2vFYr5xIZkM+NPsDh/Nkl36v5WyU8GgH+zAbL
|
||||
QnkUTskNSQ/NhV5JFUhmH+Zvvh/cG5RzFDuqc1VUK+HMSg1L0c3NRydiAxStXnby
|
||||
X1+U/KRFDYAzyNOW+Alj74RFeCbo1pVfgnmwv/W3StjviRhtgiAbsM3XUQKBgQCg
|
||||
E94P/vWtC9zetxfadVXhqsFEpZ3wlz9EG+p5vaKzaZR3nYIa1eE9zjpwLpWKRaGR
|
||||
JF9xDGbgUOkmvtzhJFU8vEzEEaZ/DtwaB5tdUqJW9msliIwyDHjhhquOkG28y174
|
||||
wnEVZNOH1A82m2JbBjnmvon6sJ5T8O2gx8P3QgEPQQKBgQCcpSf/rJxMfEeZf4Kl
|
||||
EeqSjPwFRKsC/8gBs63VJrmYh2XigL5tI2MnTdgts+4W1xC8avPiRoeaZ8YN6258
|
||||
n2tVyhJrm3F1cw/tFmLE0kuNkS0jOA/hzFeOkLJTZXR9npBzwNduQQ5i0HqQM9Qi
|
||||
aIIVlhLZ0Jlqu6SLnJ74n34VnA==
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDBDCCAeygAwIBAgIUa91CxumwjyUKK9AHnJ9upekrqlgwDQYJKoZIhvcNAQEL
|
||||
BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAeFw0yNjA1MjkwMzI5MTlaFw0zNjA1MjYw
|
||||
MzI5MTlaMCIxIDAeBgNVBAMMF2VzcF9odHRwX2NsaWVudF9kc190ZXN0MIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsztCh5DaIh+KDzk6L5CEps8AJ6cw
|
||||
xJffL/wjZc3yTOCjwDOX7UdDilizLobkzCBMm8lccafts2+jEAVaMrR1pQVO0c8J
|
||||
5sDk1IHlNJVlq1UxnIl7JvbDjtAWp+cHYMRQSBXmHrkqJl45LPTdjC0FvdsB2oyj
|
||||
HFmDHp3A3B/BwzdwyBzucG+Xa3OILZI0wsri0oDMyTw6Xg6SoXmLTQhbqCD38Ijt
|
||||
d9AalLMElM+2j+IH5zVlnG+JpCrvzYy7pY7gIUmjLFBewSpEiPjxWjrFJ0teXyTj
|
||||
smhd/IK5rVQw2v1wjKT1Wc5lgRDifZTVNRxDIepr+m4Ck3clRfyesSslhQIDAQAB
|
||||
o0IwQDAdBgNVHQ4EFgQU7jBC4N9rFhRFkzBq0KcXGRsNatcwHwYDVR0jBBgwFoAU
|
||||
RhAl6T8w7DT7+eWR1wLCoAiGBeswDQYJKoZIhvcNAQELBQADggEBAHWHKGJ0Z4+b
|
||||
rw25oZ9ZK2pZkQcvAG1HBQxHoNBRmYruitvALnQhq7UuHlAoMFxBmkJ61FRjgA1x
|
||||
zGAZsfTCy/Agv2lfVf6LiRd+Rl134rzHLlCoTg0tZC5uFcS/6W5mbfXIviYaPRaf
|
||||
RMgpM1ZPYMF5VsX0B6CJH6I+UHoZVLTb1nz5gu01WiKKULTygW70xyk5B0osiK9C
|
||||
UDCOQ7jcYrjYNZulwY2qv+Kg3PH6aFR9xT+RUp1fDb0HJk0/M0YDOdh4QUzm29UL
|
||||
KCCM+E25tan4Nvgg1jQIw3dppWc6dCSE0IgCCVY+O3aZqnfRugHl7NCxJ5pHCyPr
|
||||
zV9BSaFx8Uk=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCzO0KHkNoiH4oP
|
||||
OTovkISmzwAnpzDEl98v/CNlzfJM4KPAM5ftR0OKWLMuhuTMIEybyVxxp+2zb6MQ
|
||||
BVoytHWlBU7RzwnmwOTUgeU0lWWrVTGciXsm9sOO0Ban5wdgxFBIFeYeuSomXjks
|
||||
9N2MLQW92wHajKMcWYMencDcH8HDN3DIHO5wb5drc4gtkjTCyuLSgMzJPDpeDpKh
|
||||
eYtNCFuoIPfwiO130BqUswSUz7aP4gfnNWWcb4mkKu/NjLuljuAhSaMsUF7BKkSI
|
||||
+PFaOsUnS15fJOOyaF38grmtVDDa/XCMpPVZzmWBEOJ9lNU1HEMh6mv6bgKTdyVF
|
||||
/J6xKyWFAgMBAAECggEABhTu3dUbTx4dMVq37+Y/rL4IcNAFC8llgDuA41L43lqf
|
||||
DoYRqTJfsdbvBEH9Nd9WCiaWivVvpO+XAROqwF626+nBXMWMPfbHV7NYA4/wOmny
|
||||
fC/UFySMypCivCwkPXMxOt5Mso0w8iAEtlL8Hjtm3vmKrLpUoevNqGEiVWCEfYBv
|
||||
h7Yc7uKcB90WyZ3LtgmghV46kDFvaSMMdPTqVU6jgCTpq6yBCntpeYz1VqcnDhZt
|
||||
nU6i/vinJz8BMDXIDbVonie0lZ9tCWnYwHaWCkIPy9Cb5eqlldJfiN1CYz9MFGGs
|
||||
oymeTF+lrtPphRTakpziDkxBM/AwnIkx5HQTsxF4jwKBgQD882SmrGvbshJLYMVl
|
||||
4UznqDoP59M7G5kwQ/j579VKkhbrKrV0JvOEYQuJx18d7drDyY7eLRF6KYRLYOhG
|
||||
FWznMpNhRYQMcWcAqNLHb5W4FSsGGRt8Q1qmmKQmO192FZVveG0czz2FAPY4uSBX
|
||||
4va+mJszMrnfEApqW8TdOrEwYwKBgQC1ZF5qTQR9wZPj+65mGwfYei1EP1OEE5xc
|
||||
DWo9fsdDVxv4ykHTpURF+EftMkOF+b/GTgJHyEceZfgm/9dx15EeQuHqpNDjffUD
|
||||
y/b8GVT7NB2nR2m3ztXYBHsRK7uYGbgVtB+7w1gFpcZRx92SvITy+EjQRTs9z4n/
|
||||
Ru2y8P+S9wKBgF0bTfIXxz+/xQIf5akBjCg9ANo378Vy/CkK7As7n1vqeCsptk7B
|
||||
w6L3gaK+UyGWGo80krTvC97Wh06jpfueCU70i9EjIF7gIxTYD3W/efGfQQ3mkfpk
|
||||
ZGqsBsfX1OSHP1Efl7IiCjf5yafJZMFU1pQDYiUvR8F2iw7pJoZ0AyKXAoGBAKKv
|
||||
RCaesLqBFTzSC5Y0BBNZcKPXD/ZTCFdfCLviqqBwzfuSmvtRLCx9AzVvcTQFzMP0
|
||||
TwNGUtKmrat8piPKLLMxVSF3dImz/D3NftSXe6pZEYdn+x8JeK1nR2EdEgDWgE2m
|
||||
4RcrmhRmm7nZQZZLUgoAOH3iucE0FBZJ7QIiN3X9AoGBAJmGvBoa6ZQpbRXZbVfv
|
||||
qvz+gzwN2fO3t7iWGaHVCGygnSaplCGl/MfVtb/ak3AG5NcjwDqjld8X7RE9dSk2
|
||||
l12Y3AtsyaDozLg5KXdwt+F1Pdhju9WB3pd5O25Ocn5JU1jUqL+huW+d7WhUDPO7
|
||||
PHTgtfI15eDu5LinkNPD73hE
|
||||
-----END PRIVATE KEY-----
|
||||
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
�¾Bÿ›Ä”<|S¾ßpt3®Nk”sc†dø�à
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDAzCCAeugAwIBAgIUcDdlf0FDC5KPEcTnJG58JcXKGtAwDQYJKoZIhvcNAQEL
|
||||
BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAeFw0yNjA0MDgwMzAzMzdaFw0zNjA0MDUw
|
||||
MzAzMzdaMCExHzAdBgNVBAMMFmVzcF9tdXR1YWxfYXV0aF9zZXJ2ZXIwggEiMA0G
|
||||
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4AfXPbz06C1kwJHSkMWgzVHgz85Pb
|
||||
bF7aRzImfHR9nfz2hNJ2Yg8Apdxt/xWM1n2uDDlVWjg0vK50X3DK4oz1Lk32//IE
|
||||
iYajZuiFsO6ZBNHgy1rehJUlk92Z4fklhpEgpVT67Ph6o8yhPDjNgPM03eJsl6yC
|
||||
lawxETSXU+dOhjzfuiT0IA74UOhTVIfVe8E0AlXGqjrN5QkKP5Xb74w1ovIZPOzy
|
||||
vWNjnzuwg2MKWHTFOolPpKft4GUqPvMD41qNfymUL46JxtONcKwx//Q5hO0bSAnB
|
||||
GJ1Brqca366ObF6Xh+dAXALnxVkbpauoJ7ZqdyiJg6YANovawe/oZZXpAgMBAAGj
|
||||
QjBAMB0GA1UdDgQWBBTOXVwKpLmhvv/2Nqe9E4Hx8VYsrzAfBgNVHSMEGDAWgBRG
|
||||
ECXpPzDsNPv55ZHXAsKgCIYF6zANBgkqhkiG9w0BAQsFAAOCAQEAdgeCBgBgu8N7
|
||||
r9ycEytvs1AKxf2P3c6VFOlXF8rRNq/+8a8CoyGm4cF8u7AyvQQJZya6Luv+xg+/
|
||||
tguXIbw5goNenNkEuUOHRlo39vZ/pHe/HGCAxHatWG8qgoahXCZh3OSEmHfDwEDc
|
||||
RbYTJXGb98VynFzuxQ4RSDXb+WxhslwGCV2NXrF6gLS1FgZDKpJChmhkvw/ubdxY
|
||||
QS3fSToWlvs7PSyZi2Ei5XuGfthQPT+PZpyHZufXX9evLDdGOB/5SOz+p0SSBXcZ
|
||||
he21O0jovx0RDSnnq6kdG+qHfUrwOt5TGJ8tIJQZuKi9VUIMEONC7RMV4u1T00j9
|
||||
8VtZEG2gfg==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4AfXPbz06C1kw
|
||||
JHSkMWgzVHgz85PbbF7aRzImfHR9nfz2hNJ2Yg8Apdxt/xWM1n2uDDlVWjg0vK50
|
||||
X3DK4oz1Lk32//IEiYajZuiFsO6ZBNHgy1rehJUlk92Z4fklhpEgpVT67Ph6o8yh
|
||||
PDjNgPM03eJsl6yClawxETSXU+dOhjzfuiT0IA74UOhTVIfVe8E0AlXGqjrN5QkK
|
||||
P5Xb74w1ovIZPOzyvWNjnzuwg2MKWHTFOolPpKft4GUqPvMD41qNfymUL46JxtON
|
||||
cKwx//Q5hO0bSAnBGJ1Brqca366ObF6Xh+dAXALnxVkbpauoJ7ZqdyiJg6YANova
|
||||
we/oZZXpAgMBAAECggEAHNtEgaUP9K6w7EmF9/Xo7HEpGfnvTHBAqSSUgHqbXiki
|
||||
RvAU0rdADmRJyapA5pcAm1npZ9w/3O1gwnlGhrAOq6ijq2z/Yadw85ErkpkTt0WN
|
||||
Ox6eVS/KSrFXWvmYM+1YNxwWfp9zvEU8eGX/ASNhgKnyB1ZQmc3/ygDJFEOhOQFe
|
||||
rAMntZvoEiQkkQIL45iKLceFfnTQ4iJNLRDvkOxt98OYgjOkVfLZvYXgTTH0r1mn
|
||||
x2M3ITVVcU4OGs5AFQgbV/9fB5raPCAnroQkRIG69XD+uOJmRX04WvW8Hk9BQXk0
|
||||
aAkPSa5yPdZbpjsV5aYaQYoQodblN2XKuVxoqmj6bQKBgQD+Bo5lDmhxNGC7x64B
|
||||
6pTLAmSM2oT/mHRGRUyR+YB/Mf3mw5MhoBwZS5CuB1UaOaFBUx0b8SpfXfXMAhcF
|
||||
483FcyYKK3B/ZV9u3EfvxCBiiLzwYqLQYaBp7efeQkAJzb+sIj0+ZE70Lh2IjspL
|
||||
zhFh7WaMaxeU1IAfqvfRaATjewKBgQC5cBY19erRuztFkP2SeNYHlIj0Y1uF6QRX
|
||||
8ds2QLQsnj7J4WU/5VgTKWTywx7gn82/hWcJAs2k1PEUspRfMLwpChtOxvYHEosM
|
||||
4a9fCBKlA+KPc4NpSGaC2M9VoJIJrgo7JjzJMFS6qSJ3zbmWUQh1XCLliNWNey2s
|
||||
LkiNrA0M6wKBgQCG5wxv9nrYw6wrjRuHwQBL33VuqA3Bf0EgoGTNkOcApZflGS/l
|
||||
x5WkiVDIWvSC/N/6RR1MXYLXKpsCQInhgt0gYsps1CzmOvu3cBxz5IAeU+ei8X7t
|
||||
kysRllpw2lYP3shPrc9AdxzG6Eae4tXj9AefLegr4iOf0kpIhw8cklUmSQKBgQC1
|
||||
5qRy9DMO3unqeKq0poHU17hsepZJymSvXBjbpCbZabVP1SC7x95YlY9nr003rKpo
|
||||
B5UlurE80oFV+0MeCTFZ1IcrBHJMR71MuomL3+BiLGhurTIn8ZRVIBZp+WOnyShS
|
||||
E1UnSZijrcuY154IPJ7eeK3mmQ5ahY0szA3xoub+VwKBgQDUqNuMGgDmZo5O2Jsz
|
||||
0J43BbRfqWXyQ9Q/nQQftHoxPEWkEQSoa3y58zWlYJKN4JoUU/UNR7dqdP5rnbhZ
|
||||
f/pPXWdmhWQQlImgAfqJNEAZscA2NgsW/BOcot7zl/ZMgMOyDNXHoDSHenKPksKb
|
||||
9POv9y/PnUWSUfG/WFwMEH65iQ==
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,7 @@
|
||||
dependencies:
|
||||
protocol_examples_common:
|
||||
path: ${IDF_PATH}/examples/common_components/protocol_examples_common
|
||||
esp_secure_cert_mgr:
|
||||
version: ">=2.0.0"
|
||||
rules:
|
||||
- if: "idf_version >=5.0"
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
/* ESP HTTP Client Mutual Authentication 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 <string.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_netif.h"
|
||||
#include "protocol_examples_common.h"
|
||||
#include "esp_http_client.h"
|
||||
|
||||
#if CONFIG_EXAMPLE_MUTUAL_AUTH_USE_HW_RSA_DS
|
||||
#include "esp_secure_cert_read.h"
|
||||
#if CONFIG_MBEDTLS_VER_4_X_SUPPORT
|
||||
#include "psa_crypto_driver_esp_rsa_ds_contexts.h"
|
||||
#else
|
||||
#include "esp_rsa_sign_alt.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
static const char *TAG = "MUTUAL_AUTH";
|
||||
|
||||
#define URL_BUF_SIZE 256
|
||||
|
||||
/* CA cert for server verification (embedded in both modes) */
|
||||
extern const char ca_cert_pem_start[] asm("_binary_ca_cert_pem_start");
|
||||
extern const char ca_cert_pem_end[] asm("_binary_ca_cert_pem_end");
|
||||
|
||||
#if !CONFIG_EXAMPLE_MUTUAL_AUTH_USE_HW_RSA_DS
|
||||
/* Software mode: client cert and key embedded as PEM */
|
||||
extern const char client_cert_pem_start[] asm("_binary_client_cert_pem_start");
|
||||
extern const char client_cert_pem_end[] asm("_binary_client_cert_pem_end");
|
||||
extern const char client_key_pem_start[] asm("_binary_client_key_pem_start");
|
||||
extern const char client_key_pem_end[] asm("_binary_client_key_pem_end");
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Read the server URL from stdin. Used by pytest to inject the mTLS server address.
|
||||
* Returns ESP_OK on success, ESP_FAIL on error or empty input.
|
||||
*/
|
||||
static esp_err_t read_url_from_stdin(char *url_buf, size_t buf_size)
|
||||
{
|
||||
example_configure_stdin_stdout();
|
||||
ESP_LOGI(TAG, "Enter mutual auth server URL:");
|
||||
|
||||
if (fgets(url_buf, (int)buf_size, stdin) == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to read URL from stdin");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
/* Strip trailing newline */
|
||||
size_t len = strlen(url_buf);
|
||||
if (len > 0 && url_buf[len - 1] == '\n') {
|
||||
url_buf[--len] = '\0';
|
||||
}
|
||||
if (len == 0) {
|
||||
ESP_LOGE(TAG, "Empty URL");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_EXAMPLE_MUTUAL_AUTH_USE_HW_RSA_DS
|
||||
/**
|
||||
* DS peripheral mode: load client cert and DS context from esp_secure_cert partition.
|
||||
*/
|
||||
static void mutual_auth_with_ds(const char *url)
|
||||
{
|
||||
char *dev_cert_buf = NULL;
|
||||
uint32_t dev_cert_len = 0;
|
||||
esp_ds_data_ctx_t *ds_ctx = NULL;
|
||||
|
||||
esp_err_t ret = esp_secure_cert_get_device_cert(&dev_cert_buf, &dev_cert_len);
|
||||
if (ret != ESP_OK || dev_cert_buf == NULL || dev_cert_len == 0) {
|
||||
ESP_LOGE(TAG, "Failed to get device cert: %s", esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
ds_ctx = esp_secure_cert_get_ds_ctx();
|
||||
if (ds_ctx == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to get DS context");
|
||||
esp_secure_cert_free_device_cert(dev_cert_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t ca_cert_len = ca_cert_pem_end - ca_cert_pem_start;
|
||||
esp_http_client_config_t config = {
|
||||
.url = url,
|
||||
.cert_pem = ca_cert_pem_start,
|
||||
.cert_len = ca_cert_len,
|
||||
.client_cert_pem = dev_cert_buf,
|
||||
.client_cert_len = dev_cert_len,
|
||||
.ds_data = ds_ctx,
|
||||
.skip_cert_common_name_check = true,
|
||||
.timeout_ms = 10000,
|
||||
};
|
||||
|
||||
esp_http_client_handle_t client = esp_http_client_init(&config);
|
||||
if (client == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to init HTTP client");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_http_client_perform(client);
|
||||
int status = esp_http_client_get_status_code(client);
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGI(TAG, "HTTPS Mutual Auth Status = %d, content_length = %" PRId64,
|
||||
status, esp_http_client_get_content_length(client));
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Request failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
|
||||
esp_http_client_cleanup(client);
|
||||
|
||||
cleanup:
|
||||
esp_secure_cert_free_ds_ctx(ds_ctx);
|
||||
esp_secure_cert_free_device_cert(dev_cert_buf);
|
||||
}
|
||||
|
||||
#else /* Software key mode */
|
||||
|
||||
/**
|
||||
* Software key mode: use embedded PEM client cert and key.
|
||||
*/
|
||||
static void mutual_auth_with_software_keys(const char *url)
|
||||
{
|
||||
size_t ca_cert_len = ca_cert_pem_end - ca_cert_pem_start;
|
||||
size_t client_cert_len = client_cert_pem_end - client_cert_pem_start;
|
||||
size_t client_key_len = client_key_pem_end - client_key_pem_start;
|
||||
|
||||
esp_http_client_config_t config = {
|
||||
.url = url,
|
||||
.cert_pem = ca_cert_pem_start,
|
||||
.cert_len = ca_cert_len,
|
||||
.client_cert_pem = client_cert_pem_start,
|
||||
.client_cert_len = client_cert_len,
|
||||
.client_key_pem = client_key_pem_start,
|
||||
.client_key_len = client_key_len,
|
||||
.skip_cert_common_name_check = true,
|
||||
.timeout_ms = 10000,
|
||||
};
|
||||
|
||||
esp_http_client_handle_t client = esp_http_client_init(&config);
|
||||
if (client == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to init HTTP client");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_http_client_perform(client);
|
||||
int status = esp_http_client_get_status_code(client);
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGI(TAG, "HTTPS Mutual Auth Status = %d, content_length = %" PRId64,
|
||||
status, esp_http_client_get_content_length(client));
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Request failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
|
||||
esp_http_client_cleanup(client);
|
||||
}
|
||||
#endif /* CONFIG_EXAMPLE_MUTUAL_AUTH_USE_HW_RSA_DS */
|
||||
|
||||
static void mutual_auth_task(void *pvParameters)
|
||||
{
|
||||
char url_buf[URL_BUF_SIZE];
|
||||
if (read_url_from_stdin(url_buf, sizeof(url_buf)) != ESP_OK) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if CONFIG_EXAMPLE_MUTUAL_AUTH_USE_HW_RSA_DS
|
||||
mutual_auth_with_ds(url_buf);
|
||||
#else
|
||||
mutual_auth_with_software_keys(url_buf);
|
||||
#endif
|
||||
|
||||
done:
|
||||
ESP_LOGI(TAG, "Finish mutual auth example");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
ESP_LOGI(TAG, "Connected, starting mutual auth example");
|
||||
xTaskCreate(mutual_auth_task, "mutual_auth", 8192, NULL, 5, NULL);
|
||||
}
|
||||
Reference in New Issue
Block a user