{"id":27775796,"url":"https://github.com/blark/sscte","last_synced_at":"2026-04-25T12:35:51.818Z","repository":{"id":290206189,"uuid":"973690242","full_name":"blark/SSCTE","owner":"blark","description":"Secure Super Cereal Tap ESP: A lightweight ESP32 firmware to bridge UART devices over TCP with TLS/mTLS support.","archived":false,"fork":false,"pushed_at":"2025-04-30T00:59:13.000Z","size":39,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-30T04:57:16.193Z","etag":null,"topics":["esp-idf","esp32","mtls","serial","serial-bridge","tls","uart","uart-bridge"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blark.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-27T14:34:25.000Z","updated_at":"2025-04-30T00:59:16.000Z","dependencies_parsed_at":"2025-04-27T15:43:56.278Z","dependency_job_id":null,"html_url":"https://github.com/blark/SSCTE","commit_stats":null,"previous_names":["blark/sscte"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blark%2FSSCTE","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blark%2FSSCTE/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blark%2FSSCTE/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blark%2FSSCTE/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blark","download_url":"https://codeload.github.com/blark/SSCTE/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251644826,"owners_count":21620630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["esp-idf","esp32","mtls","serial","serial-bridge","tls","uart","uart-bridge"],"created_at":"2025-04-30T04:57:15.485Z","updated_at":"2026-04-25T12:35:51.777Z","avatar_url":"https://github.com/blark.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Secure Super Cereal Tap ESP 💁‍♂️🔒🌉\n*Half serial interface, half encryption layer, half TCP bridge*\n\n```mermaid\nflowchart LR\n  Client[\"\u003cb\u003eClient\u003c/b\u003e\u003cbr/\u003e\u003ccode\u003esocat STDIO,raw,echo=0 TCP:{$ESP32_IP}:6969\u003c/code\u003e\"] \u003c--\u003e|TCP or TLS| ESP32[\"\u003cb\u003eSecure Super Cereal Tap ESP\u003c/b\u003e\u003cbr/\u003eTX=GPIO7\u003cbr/\u003eRX=GPIO6\"]\n  ESP32 \u003c--\u003e|UART TX/RX| UARTDevice[\"\u003cb\u003eTarget Device\u003c/b\u003e\u003cbr/\u003eESP RX \u003e DEV TX\u003cbr/\u003eESP TX \u003e DEV RX\"]\n```\n\nA lightweight ESP32 firmware to bridge UART devices over TCP with optional TLS/mTLS support.\n\nMotivation: Existing solutions lacked secure connectivity (or maybe I’m just bad at Google), and I was tired of physically disconnecting and relocating devices to debug or fix them. Also, it made a fun weekend project.\n\n## Features ✨\n\n- Bidirectional communication between TCP clients and UART devices\n- UART speeds up to 5 Mbps with configurable pins (hardware UART limit on ESP32)\n- Secure TLS mode with optional client certificate verification (mTLS)\n- Fully configurable via `menuconfig`\n\n## Requirements ✅\n\n- [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/) (v4.1.0 or later)\n- Compatible with ESP32, ESP32-S3, ESP32-C3, ESP32-C6\n\n## Setup 🛠️\n\n### 1. Clone this repository\n\n```bash\ngit clone https://github.com/yourusername/esp32-serial-tcp-bridge.git\ncd esp32-serial-tcp-bridge\n```\n\n### 2. Set your target board\n\n```bash\nidf.py set-target esp32c6  # or esp32, esp32s3, esp32c3\n```\n\n### 3. Configure the project\n\n```bash\nidf.py menuconfig\n```\n\n**Important settings:**\n\nThese should be automatically enabled by menuconfig when you enable TLS in Component configuration.\n\n- **Component configuration → ESP-TLS → Enable ESP-TLS Server**\n- **Partition Table → Custom partition table CSV (partitions.csv)**\n\n*Note:* For the ESP32-C6 board I tested, in **Serial flasher config** I had to configure my board's flash size and enabled **Detect flash size when flashing bootloader** or it wouldn't boot.\n\n**Bridge settings:**\n- **Component configuration → Serial TCP Bridge Configuration → WiFi Configuration:** SSID, password, reconnect behavior\n- **Component configuration → Serial TCP Bridge Configuration → UART Configuration:** Pins, port, baud rate\n- **Component configuration → Serial TCP Bridge Configuration → Network Configuration:** TCP port\n- **Component configuration → Serial TCP Bridge Configuration → Buffer and Timing Configuration:** Buffer sizes\n- **Component configuration → Serial TCP Bridge Configuration → TLS Configuration:** Enable TLS, client verification\n\n### 4. Configure the partition table\n\nTo use TLS, you must include a SPIFFS partition for storing certificates. You can either:\n\n- Use the **Factory app, SPIFFS** predefined partition table in menuconfig (if available), or\n- Create a custom partition table with a SPIFFS partition.\n\nDefault partition layout:\n\n```csv\n# Name,   Type, SubType, Offset,   Size,  Flags\nnvs,       data, nvs,     0x9000,   24K,\nphy_init,  data, phy,     0xF000,   4K,\nfactory,   app,  factory, 0x10000,  1M,\nspiffs,    data, spiffs,  0x110000, 512K,\n```\n\nVerify partition configuration:\n\n```bash\nidf.py partition-table\n```\n\nThe **spiffs** partition is critical for TLS certificates. Do not rename it.\n\n## TLS Configuration 🔐\n\nIf using TLS, configure it in menuconfig:\n\n```bash\nidf.py menuconfig\n```\n\nNavigate to: **Component configuration → Serial TCP Bridge Configuration → TLS Configuration**\n\nImportant TLS settings:\n\n- **Enable TLS security**: Enable TLS\n- **Server certificate path**: Path in SPIFFS (default `/spiffs/server.crt`)\n- **Server private key path**: Path in SPIFFS (default `/spiffs/server.key`)\n- **Verify client certificates**: Enable for mTLS\n- **CA certificate path**: Path in SPIFFS (default `/spiffs/ca.crt`)\n\nThese paths refer to the ESP32's SPIFFS filesystem after flashing.\n\n## Certificate Generation for TLS 🪪\n\nPlace certificates in `\u003crepo_root\u003e/certs`. The build system automatically creates a SPIFFS image from this directory.\n\nTo generate certificates:\n\n```bash\n# Generate CA key and certificate using EC\nopenssl ecparam -name prime256v1 -genkey -noout -out ca.key\nopenssl req -new -x509 -key ca.key -out ca.crt -days 365 -subj \"/CN=Test-CA\"\n\n# Generate server key and CSR using EC\nopenssl ecparam -name prime256v1 -genkey -noout -out server.key\nopenssl req -new -key server.key -out server.csr -subj \"/CN=ESP32-Server\"\n\n# Sign server certificate (same as before)\nopenssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365\n\n# Generate client key and CSR using EC (for mTLS)\nopenssl ecparam -name prime256v1 -genkey -noout -out client.key\nopenssl req -new -key client.key -out client.csr -subj \"/CN=Client\"\n\n# Sign client certificate (same as before)\nopenssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365\n```\nPlace the files in `\u003crepo_root\u003e/certs/`:\n\n- `certs/server.crt` - Server certificate\n- `certs/server.key` - Server private key\n- `certs/ca.crt` - CA certificate (only for mTLS)\n\n**Note:** Certificate paths in `menuconfig` are ESP32 SPIFFS partition paths (not local filesystem). Don't change them unless you know what you're doing.\n\n## Build, flash, monitor 🏗️💥🧐\n\n```bash\nidf.py build flash monitor\n```\n\n- `build`: Compiles firmware and creates SPIFFS image\n- `flash`: Uploads firmware and filesystem to ESP32\n- `monitor`: Opens serial console to ESP32\n\n## Default Configuration 💡\n\n- **WiFi**: Connects to configured SSID with auto-reconnect\n- **UART**:\n  - Port: UART1\n  - Pins: TX=7, RX=6\n  - Baud Rate: 1.5 Mbps\n  - Buffer Size: 4 KB\n- **TCP**: Port 6969 (plain TCP by default)\n- **Data Transfer**: 2 KB buffer for efficient communication\n\n## Connecting to the Bridge 🔌\n\nUse `socat` for terminal access. Raw mode (`raw,echo=0`) prevents local echo and ensures proper character handling.\n\n### With mutual authentication (secure, mTLS)\n\nWhen using mTLS, the server certificate must match the DNS name used by the client due to Server Name Indication (SNI) checks during the TLS handshake. Connecting by IP address will fail if the certificate was issued for a hostname.\n\n```bash\nsocat STDIO,raw,echo=0,escape=0x1d OPENSSL:[ESP32_DNS]:6969,cert=client.crt,key=client.key,cafile=ca.crt,verify=1\n```\n\n*If no DNS entry exists for your ESP32, add to hosts file: 192.168.1.x ESP32-Server*\n\n### TLS connection (encryped in transit, but still wide open to anyone on your network)\n\n```bash\nsocat STDIO,raw,echo=0,escape=0x1d OPENSSL:[ESP32_IP]:6969,verify=0\n```\n\n### Plain TCP (completely insecure, wide open)\n\n```bash\nsocat STDIO,raw,echo=0,escape=0x1d TCP:[ESP32_IP]:6969\n```\n\n## License\n\nThis project is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License.\nSee the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblark%2Fsscte","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblark%2Fsscte","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblark%2Fsscte/lists"}