//! CLI-level end-to-end loopback (no TUN): mint certs via [`aura_pki::AuraCa`], build proto //! Client/Server configs, [`AuraServer::bind`] on `127.0.0.1:0`, [`AuraClient::connect`], and //! exchange packets via the [`PacketConnection`] API, asserting integrity. //! //! This is the full CLI integration path short of the privileged TUN device: it proves the crate's //! wiring of aura-pki + aura-proto + aura-transport works end to end without root or external //! network. use std::sync::Arc; use aura_pki::AuraCa; use aura_proto::{ClientConfig, PacketConnection, ServerConfig}; use aura_transport::{AuraClient, AuraServer}; const SERVER_NAME: &str = "localhost"; const CAMOUFLAGE_SNI: &str = "cdn.example.com"; #[tokio::test] async fn cli_loopback_packet_exchange() { // PKI: CA + server cert (SAN localhost) + client cert. let ca = AuraCa::generate("Aura CLI Test CA").expect("generate CA"); let server_cert = ca.issue_server_cert(SERVER_NAME).expect("server cert"); let client_cert = ca.issue_client_cert("cli-client").expect("client cert"); let ca_pem = ca.ca_cert_pem(); let server_cfg = ServerConfig { ca_cert_pem: ca_pem.clone(), server_cert_pem: server_cert.cert_pem.clone(), server_key_pem: server_cert.key_pem.clone(), }; let client_cfg = ClientConfig { ca_cert_pem: ca_pem.clone(), client_cert_pem: client_cert.cert_pem.clone(), client_key_pem: client_cert.key_pem.clone(), server_name: SERVER_NAME.to_string(), }; // Bind on an OS-assigned loopback port. let server = AuraServer::bind( "127.0.0.1:0".parse().unwrap(), &server_cert.cert_pem, &server_cert.key_pem, server_cfg, ) .expect("bind server"); let server_addr = server.local_addr().expect("local_addr"); // Accept + connect concurrently. let accept = tokio::spawn(async move { server.accept().await }); let connect = tokio::spawn( async move { AuraClient::connect(server_addr, CAMOUFLAGE_SNI, client_cfg).await }, ); let server_conn = accept.await.expect("accept join").expect("accept"); let client_conn = connect.await.expect("connect join").expect("connect"); // Mutual auth established the client's verified CN on the server side. assert_eq!(server_conn.peer_id(), Some("cli-client")); let server_conn: Arc = Arc::new(server_conn); let client_conn: Arc = Arc::new(client_conn); // Client -> server. for pkt in [ b"ping".to_vec(), vec![0u8; 1400], (0..=255u8).collect::>(), ] { client_conn.send_packet(&pkt).await.expect("client send"); let got = server_conn.recv_packet().await.expect("server recv"); assert_eq!(got, pkt); } // Server -> client. for pkt in [b"pong".to_vec(), vec![0x5Au8; 999]] { server_conn.send_packet(&pkt).await.expect("server send"); let got = client_conn.recv_packet().await.expect("client recv"); assert_eq!(got, pkt); } }