f9a3c33586
Cierra el ultimo pendiente del plan de red P2P. Hasta ahora, rotar la keypair libp2p de un nodo cambiaba su peer_id, lo que invalidaba todas las allowlists/denylists remotas que lo referenciaban. Imposible rotar sin coordinar con todos los pares. Solucion: separar identity master (Ed25519 persistente forever, identifica al nodo como entidad logica) de session libp2p (Ed25519 efimera, rotable). El master firma certs de session con expiracion. La politica de admision se evalua contra el master_peer_id del cert — el session peer_id puede cambiar libremente sin tocar allowlists. API nueva en brahman_handshake::identity: - Identity::from_keypair / master_peer_id / issue_session_cert. - SessionCert::verify devuelve (master_peer_id, session_peer_id). - SessionCert::verify_against_session(expected_session_pk) verify + exige que el cert vincule esa session pubkey (previene reuso de certs ajenos). - CertError tipado: UnknownVersion, DecodeMaster, DecodeSession, InvalidSignature, Expired, SessionMismatch, Sign. - DEFAULT_SESSION_TTL = 24h. SESSION_CERT_VERSION = 1 documenta esquema; bump al cambiar canonicalizacion. Wire: - Hello.identity_cert: Option<SessionCert> agregado (default None, back-compat). - Client::connect_with_stream_signed_with_cert variante que adjunta cert. - network::connect_libp2p_with_cert paralelo a connect_libp2p. Server (do_handshake): nuevo paso ANTES del policy gate. Si el Hello trae cert, verify_against_session(&hello.signature.public_key) y el logical_peer = master_peer_id derivado. Sin cert (path Fase 3), logical_peer = expected_peer (compat). Cert invalido -> Unauthorized antes de evaluar policy. Migracion gradual: clientes sin cert siguen funcionando contra servers con policy basada en session peer_ids. Tests: 8 unit en identity::tests (issue+verify, mismatch, expired, tampered sig/expires_at, unknown version, rotated_session_with_same_ master_yields_same_master_peer_id — la propiedad fundamental). E2E definitivo identity_cert_allows_session_rotation_without_policy_ change: A allowlist[master_peer]; B conecta con session1+cert -> admitido; B rota a session2!=session1 con cert nuevo del MISMO master -> admitido SIN tocar la allowlist; sanity: session sin cert es rechazada. 40 tests verdes en brahman-handshake + brahman-net. Wire en Arje queda como follow-up: ente-zero es server-only y no necesita identity (su keypair libp2p ya es estable). La API esta lista para cuando algun modulo haga conexiones salientes con cert.
34 lines
1.2 KiB
Rust
34 lines
1.2 KiB
Rust
//! `brahman-handshake` — protocolo runtime Init↔módulo sobre Unix socket.
|
|
//!
|
|
//! Implementa la versión concreta de `shared_wit/protocol.wit` (handshake +
|
|
//! lifecycle): un servidor que vive en el Init (o un Admin proxy) y clientes
|
|
//! que son los módulos Brahman. Cada conexión arranca con un `Hello` que
|
|
//! lleva una [`brahman_card::Card`]; el servidor valida la Card, deriva el
|
|
//! [`TrustLevel`], emite un `HelloAck` con `session-id` ULID, y a partir de
|
|
//! ahí acepta `Ping`/`Farewell`.
|
|
//!
|
|
//! Wire format: frames length-prefixed (4 bytes LE) con cuerpo
|
|
//! [`postcard`]-codificado. Compacto, rápido y reversible.
|
|
//!
|
|
//! Esto NO es la implementación WIT/WASM (que generaría wit-bindgen). Es la
|
|
//! implementación nativa Rust↔Rust que cubre el caso común antes de que los
|
|
//! módulos WASM consuman el mismo contrato vía ABI generada.
|
|
|
|
#![forbid(unsafe_code)]
|
|
#![warn(rust_2018_idioms)]
|
|
|
|
pub mod codec;
|
|
pub mod identity;
|
|
pub mod messages;
|
|
pub mod server;
|
|
pub mod client;
|
|
pub mod network;
|
|
pub mod peer_policy;
|
|
pub mod signature;
|
|
pub mod transport;
|
|
|
|
pub use brahman_card::PROTOCOL_VERSION;
|
|
|
|
/// Versión del crate de handshake (independiente de `PROTOCOL_VERSION`).
|
|
pub const HANDSHAKE_VERSION: &str = env!("CARGO_PKG_VERSION");
|