esp_https_server component with mTLS client auth
Posted: Tue Apr 16, 2024 4:17 pm
My project requires a secure and trusted connectivity for controls in the local WiFi network between the ESP32 device and other parties (currently testing with python script on PC). I am going to use a standard X509 certificate routines and mTLS within my custom PKI and 'esp_https_server' component.
I got a working sample, but have some worries/potential misunderstanding is everything configured right for this.
What I have:
- custom RootCA self-signed certificate (exist on PC and only for singing).
esp:
- issued Intermediate deviceCA cert that is set as ‘cacert_pem‘ property in ‘httpd_ssl_config_t’
- issued Server cert (by Intermediate deviceCA) that is set as ‘servercert‘ property in ‘httpd_ssl_config_t’
- Server private key that is set as ‘prvtkey_pem‘ property in ‘httpd_ssl_config_t’
python script:
- same Intermediate deviceCA when requesting (and checking Server cert)
- Client cert issued by that Intermediate deviceCA, exist and used in the script
- Client private key in the script
Connection is going normal, handshake is performed fine and both my parties can talk freely and Client cert is accepted and parsed fine in ESP https server context.
Then I try to simulate an emergency like ‘attacker’ is trying to ‘hack’ my Client private key. So I try to manually change symbols in client private key and try connect with the same python script (expecting error in connection). BUT in some circumstances this is still being accepted by ESP https server handshake as a valid connection!
I can change up to about entire ~1-2 lines in ‘--begin….--end' of the key to any random symbols (mainly in the end of it) and it is still accepted by ESP server as normal and a verified TLS connection opens with no error (isn’t it strange and not ok?). However, if I change any !one! symbol in first lines of THAT private key, the connection is not accepted by the server which is the intended behavior.
As of my understanding RSA 2048 private key is a unique secret and any symbol in it is crucial and meaningful to provide trusted asymmetric handshake in TLS connection. I expect client private key to be a secure proof of owning and providing trusted certificate on peer side. Does some simplified partial verification is used inside component (or mbedTLS itself) and seems no any way to intrude in that process? What am I missing in general mTLS approach?
Note: on successful connect, the esp_server reply selected ciphersuite: TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384, which seems pretty solid and ok.
I got a working sample, but have some worries/potential misunderstanding is everything configured right for this.
What I have:
- custom RootCA self-signed certificate (exist on PC and only for singing).
esp:
- issued Intermediate deviceCA cert that is set as ‘cacert_pem‘ property in ‘httpd_ssl_config_t’
- issued Server cert (by Intermediate deviceCA) that is set as ‘servercert‘ property in ‘httpd_ssl_config_t’
- Server private key that is set as ‘prvtkey_pem‘ property in ‘httpd_ssl_config_t’
python script:
- same Intermediate deviceCA when requesting (and checking Server cert)
- Client cert issued by that Intermediate deviceCA, exist and used in the script
- Client private key in the script
Connection is going normal, handshake is performed fine and both my parties can talk freely and Client cert is accepted and parsed fine in ESP https server context.
Then I try to simulate an emergency like ‘attacker’ is trying to ‘hack’ my Client private key. So I try to manually change symbols in client private key and try connect with the same python script (expecting error in connection). BUT in some circumstances this is still being accepted by ESP https server handshake as a valid connection!
I can change up to about entire ~1-2 lines in ‘--begin….--end' of the key to any random symbols (mainly in the end of it) and it is still accepted by ESP server as normal and a verified TLS connection opens with no error (isn’t it strange and not ok?). However, if I change any !one! symbol in first lines of THAT private key, the connection is not accepted by the server which is the intended behavior.
As of my understanding RSA 2048 private key is a unique secret and any symbol in it is crucial and meaningful to provide trusted asymmetric handshake in TLS connection. I expect client private key to be a secure proof of owning and providing trusted certificate on peer side. Does some simplified partial verification is used inside component (or mbedTLS itself) and seems no any way to intrude in that process? What am I missing in general mTLS approach?
Note: on successful connect, the esp_server reply selected ciphersuite: TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384, which seems pretty solid and ok.