Skip to main content

dig_tls/
lib.rs

1//! # dig-tls — the canonical mTLS certificate every DIG peer connection uses
2//!
3//! dig-tls is the single source of truth for DIG peer transport identity. It mirrors the
4//! `chia-blockchain` / `chia-tls` TLS model 1:1, swapping in a **DigNetwork** trust domain and
5//! layering the #1204 BLS-G1 cert binding. Every DIG peer (dig-node, dig-relay, dig-gossip, dig-nat,
6//! dig-peer) presents the SAME canonical cert shape, so any two DIG peers speak mutual TLS with a
7//! byte-identical `peer_id` derivation and binding.
8//!
9//! ## The model (Chia precedent — the CA is PUBLIC)
10//!
11//! - **A shipped, PUBLIC DigNetwork CA** ([`ca`]) — the CA certificate AND private key are both
12//!   compiled into this crate, exactly as `chia-blockchain` ships `chia_ca.crt` + `chia_ca.key`. The
13//!   CA key is intentionally NOT a secret: it is a shared trust-domain marker, so there is no user
14//!   step and no custody gate. Real authentication comes from the app layer (peer_id pin + BLS
15//!   binding), never from CA-key secrecy.
16//! - **A per-peer node cert** ([`node_cert::NodeCert`]) generated locally at first run, signed by the
17//!   DigNetwork CA, carrying the BLS binding. Persisted so a peer keeps a stable identity.
18//! - **`peer_id = SHA-256(TLS SPKI DER)`** ([`identity`]) — the transport identity (same as Chia's
19//!   node id).
20//! - **The #1204 BLS-G1 binding** ([`binding`]) — the cert self-attests the peer's BLS G1 identity
21//!   key over its SPKI, cryptographically binding `peer_id ↔ bls_pub` (the anti-substitution root of
22//!   the recipient-seal family).
23//! - **Ready rustls mutual-auth configs** ([`config`]) — [`config::server_config`] /
24//!   [`config::client_config`] wire the DigNetwork-CA chain check, peer_id pinning, and BLS-binding
25//!   verification, and hand back the handles that capture WHO connected.
26//!
27//! ## Quick start
28//!
29//! ```no_run
30//! use dig_tls::{binding::BindingPolicy, config, node_cert::NodeCert};
31//! # fn demo(bls_sk: &dig_tls::bls::SecretKey) -> dig_tls::Result<()> {
32//! // At first run: mint (or load) this peer's cert, signed by the shipped DigNetwork CA.
33//! let node = NodeCert::load_or_generate("/var/lib/dig/tls", bls_sk)?;
34//!
35//! // Accept inbound peers (mutual TLS, verify-if-present binding):
36//! let server = config::server_config(&node, BindingPolicy::Opportunistic)?;
37//!
38//! // Dial a specific peer, pinning its peer_id:
39//! let expected = node.peer_id(); // in practice: the peer you resolved
40//! let client = config::client_config(&node, Some(expected), BindingPolicy::Opportunistic)?;
41//! # let _ = (server.config, client.config); Ok(())
42//! # }
43//! ```
44//!
45//! Hierarchy: **L00 (00-foundation)** — zero DIG-crate dependencies (BLS via `chia-bls`/`blst` on raw
46//! bytes). See `SPEC.md` for the normative contract.
47
48pub mod binding;
49pub mod bls;
50pub mod ca;
51pub mod config;
52pub mod error;
53pub mod identity;
54pub mod node_cert;
55pub mod verify;
56
57// --- The curated public facade: the handful of names most consumers reach for, re-exported at the
58// crate root so a caller need not know the internal module split (§6.2 LLM-lookup surface). ---
59
60pub use binding::BindingPolicy;
61pub use config::{client_config, server_config, ClientTls, ServerTls};
62pub use error::{DigTlsError, Result};
63pub use identity::{peer_id_from_leaf_cert_der, peer_id_from_tls_spki_der, PeerId};
64pub use node_cert::{load_previous, retire_previous, NodeCert, RotatedNodeCert};