Skip to content

feat: optional TLS for P2P connections (#1420)#3907

Open
iho wants to merge 2 commits into
mimblewimble:stagingfrom
iho:feat/p2p-tls
Open

feat: optional TLS for P2P connections (#1420)#3907
iho wants to merge 2 commits into
mimblewimble:stagingfrom
iho:feat/p2p-tls

Conversation

@iho

@iho iho commented Jul 10, 2026

Copy link
Copy Markdown

Summary

Implements optional TLS for peer-to-peer connections (#1420).

  • Encrypts P2P traffic with rustls (same stack as the HTTP API) for privacy against passive packet inspection
  • Opt-in via p2p_config.tls_enabled (default false) so the existing plaintext network stays compatible
  • Self-signed certificates are auto-generated under {data_dir}/p2p_tls/ when paths are not configured
  • Clients intentionally do not verify peer certificates — goal is privacy encryption, not PKI authentication
  • Optional PEM paths: tls_certificate_file / tls_certificate_key
  • Config comments updated in grin-server.toml template

Peer discovery: Capabilities::TLS + tls_required

  • New capability bit Capabilities::TLS (0b1_0000_0000), advertised when tls_enabled = true
  • Not part of default capabilities (TLS remains opt-in for network compatibility)
  • p2p_config.tls_required (default false): when set with tls_enabled, only attempt outbound connections to peers known to advertise TLS, and request PEER_LIST | TLS in peer-list queries
  • Seeds, preferred, and allow-listed addresses are still tried for bootstrap (capabilities unknown until first successful handshake)
  • Unknown peers (no stored capabilities) are skipped when tls_required is on

Design notes

  • New Stream abstraction wraps plain TcpStream or a mutex-shared rustls session (needed because reader/writer threads cannot try_clone a TLS session the way they do TCP)
  • Both peers must enable TLS to connect; mixed TLS/plaintext will fail the handshake
  • Not consensus-breaking; pure transport layer change

How to enable

[server.p2p_config]
tls_enabled = true
# Optional: only connect to peers known to support TLS
# tls_required = true
# optional PEM paths:
# tls_certificate_file = "/path/to/p2p.crt"
# tls_certificate_key = "/path/to/p2p.key"

Testing

  • cargo test -p grin_p2p (includes peer_handshake_tls, capability / tls_required helpers)
  • cargo check -p grin_config -p grin_servers
  • Manual: two nodes with tls_enabled = true connecting on testnet/local

Consensus / compatibility

  • Not consensus breaking
  • Default remains plaintext; operators must opt in
  • Nodes with TLS enabled will not successfully complete Grin handshake with plaintext-only peers
  • With tls_required = true, automatic outbound selection prefers the TLS peer mesh once capabilities are known

Closes #1420

Ihor Horobets and others added 2 commits July 10, 2026 23:17
Encrypt peer traffic with rustls for privacy against passive observers.
TLS is opt-in via p2p_config.tls_enabled (default false) so the existing
plaintext network remains compatible. When enabled, peers use self-signed
certificates (auto-generated under the node data dir if paths are not set)
and clients intentionally skip certificate authentication — encryption for
privacy only, matching the issue intent.

Wire a plain/TLS Stream abstraction through handshake, codec, and conn
I/O, and add an integration test for TLS peer handshake + ping/pong.
Advertise Capabilities::TLS when tls_enabled so peers can discover
encrypted endpoints. Add tls_required to filter outbound attempts and
peer-list requests to TLS-capable peers (seeds/preferred/allow still
used for bootstrap).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant