https://github.com/burumdev/esp32-padlock
Securely lock and unlock your ESP32-cX device over an encrypted web endpoint.
https://github.com/burumdev/esp32-padlock
embedded esp32 esp32-c3 esp32-c6 https rust security tls
Last synced: 3 months ago
JSON representation
Securely lock and unlock your ESP32-cX device over an encrypted web endpoint.
- Host: GitHub
- URL: https://github.com/burumdev/esp32-padlock
- Owner: burumdev
- License: mit
- Created: 2025-09-26T17:15:59.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2025-10-03T19:00:27.000Z (3 months ago)
- Last Synced: 2025-10-03T21:06:29.030Z (3 months ago)
- Topics: embedded, esp32, esp32-c3, esp32-c6, https, rust, security, tls
- Language: Rust
- Homepage:
- Size: 1.56 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 🔒 ESP32 Padlock 🔒
Securely lock and unlock your esp32-cX device over an encrypted web endpoint.
## Description
This app can be used as a template for building web-authorized embedded applications for esp32-cX series of IoT chips.
It serves web pages `locked.html` for a locked device and `unlocked.html` for unlocked.
The user can enter a password to a web form on these pages to lock or unlock the device.
Once unlocked, an `AtomicBool` flag named `DEVICE_LOCK` gets set to `false`.
Default value for this flag is `true`, which means device boots as locked, but this can be changed in `main.rs` file.
This flag can be used to enable or disable whatever further functionality on the device.
## Screenshots


## Memory hog
The app is a memory hog for c3 devices and barely survives the ordeal of serving https pages, locking unlocking etc.
It should work much better on a c6 or newer device with 512kb+ RAM.
## Susceptible to Denial of Service attacks
By default app uses one task to handle incoming requests because of memory issues.
This makes it very easy to maliciously hold this connection captive and deny others from reaching the endpoint. At least two asynchronous connections would be minimaly required to mitigate the most basic form of DoS attacks. One half-solution to this problem is to keep the static IP of the device a secret which should make it a tid-bit harder for malicious actors to find the endpoint. Another solution is to use a device with more RAM and run two tasks simultaneously along with hiding the static IP. Task size can be changed by increasing the value of `SERVER_SOCKETS` value in `main.rs`.
## Timeouts
In order to free-up resources as soon as possible and keep the server mostly reachable, we use an idle timeout of 7 seconds and overall request response timeout of 7 seconds.
If the user exceeds this timeout before they enter a password, the connection with server (keepalive) will be dropped and they'll have to resubmit the form or reload the page.
This is a trade-off that had to be made to keep the endpoint accessable.
## Encryption engine
Mbed-TLS C library is used for https. esp-mbedtls wrapper included uses FFI bindings to the library.
As esp-mbedtls is experimental and currently not published to crates.io, we have to use a cloned git version.
Something native like [embedded-tls](https://crates.io/crates/embedded-tls) can be used in the future if it saves some memory resources and works as fast.
## Setup
To setup the app with your device:
* Generate TLS certificates with the .pem format and put them into the `certs` directory in the project root.
The file names are: `cert.pem` for public key and `key.pem` for private key. I highly recommend using [mkcert](https://github.com/FiloSottile/mkcert)
for development purposes. This will install a certificate authority to the system that's accepted both by your system and web browsers.
Certificates generated by a known signing entity can later be used for production.
* Make a copy of `config.toml.example` file in `.cargo` directory as `config.toml`.
Edit this file with your Wifi credentials, static ip for the device from your network and a custom device password for locking-unlocking the device.
* Set build target from esp32c3 to your device configuration in `config.toml`.
* `riscv32imc-unknown-none-elf` for esp32-c3
* `riscv32imac-unknown-none-elf` for esp32-c6
* Edit the `locked.html` and `unlocked.html` with your style and wording, or keep them as they are for gigachad lazyness.
## Building
* You'll need Rust build target for RISC-V esp32 processors. It's
* `riscv32imc-unknown-none-elf` for esp32-c3
* `riscv32imac-unknown-none-elf` for esp32-c6
* and can be something different for other chips.
* esp-mbedtls shipped uses a prebuilt version of mbedtls C library, so you won't normally need C build targets.
* Build script `build.rs` will minify the html template files `locked.html` and `unlocked.html` as `*.min.html`. This uses [minify-html](https://crates.io/crates/minify-html) tool, minified files will be used while running the app and generated files are not part of version control.
* To build and run as production:
```bash
# Replace chip with esp32c3 or esp32c6 depending on the device
cargo run -r -F CHIP
```
## License
[MIT](https://choosealicense.com/licenses/mit/)
## Contributing
Pull requests are welcome. For major changes, please open an issue first
to discuss what you would like to change.