use dosh::auth::{ build_bootstrap, decode_bootstrap, encode_bootstrap, load_or_create_server_secret, open_attach_ticket, verify_attach_ticket, verify_bootstrap, }; use dosh::config::ServerConfig; use dosh::crypto; use dosh::protocol::{self, CLIENT_TO_SERVER, PacketKind, ReplayWindow}; #[test] fn bootstrap_round_trips_and_verifies() { let dir = tempfile::tempdir().unwrap(); let config = ServerConfig { secret_path: dir.path().join("secret").display().to_string(), ..ServerConfig::default() }; let secret = load_or_create_server_secret(&config).unwrap(); let nonce = crypto::random_12(); let resp = build_bootstrap( &config, &secret, "user".to_string(), "default".to_string(), "read-write".to_string(), (80, 24), nonce, "127.0.0.1".to_string(), ) .unwrap(); assert!(verify_bootstrap(&resp, &secret).unwrap()); let encoded = encode_bootstrap(&resp).unwrap(); let decoded = decode_bootstrap(&encoded).unwrap(); assert_eq!(decoded.session, "default"); assert_eq!(decoded.session_key, resp.session_key); } #[test] fn encrypted_packet_round_trips() { let key = crypto::random_32(); let conn_id = crypto::random_16(); let packet = protocol::encode_encrypted( PacketKind::Input, conn_id, 7, 0, &key, CLIENT_TO_SERVER, b"hello", ) .unwrap(); let decoded = protocol::decode(&packet).unwrap(); assert_eq!(decoded.header.kind, PacketKind::Input); assert_eq!(decoded.header.conn_id, conn_id); let plain = protocol::decrypt_body(&decoded, &key, CLIENT_TO_SERVER).unwrap(); assert_eq!(plain, b"hello"); } #[test] fn attach_ticket_is_sealed_and_verifies_scope() { let dir = tempfile::tempdir().unwrap(); let config = ServerConfig { secret_path: dir.path().join("secret").display().to_string(), ..ServerConfig::default() }; let secret = load_or_create_server_secret(&config).unwrap(); let resp = build_bootstrap( &config, &secret, "user".to_string(), "work".to_string(), "view-only".to_string(), (100, 30), crypto::random_12(), "127.0.0.1".to_string(), ) .unwrap(); let opened = open_attach_ticket(&secret, &resp.attach_ticket).unwrap(); assert_eq!(opened.session, "work"); assert_eq!(opened.mode, "view-only"); assert_eq!(opened.psk, resp.attach_ticket_psk); assert!( verify_attach_ticket( &secret, &resp.attach_ticket, &resp.attach_ticket_psk, "work", "view-only", ) .unwrap() .is_some() ); assert!( verify_attach_ticket( &secret, &resp.attach_ticket, &resp.attach_ticket_psk, "default", "view-only", ) .unwrap() .is_none() ); } #[test] fn replay_window_rejects_duplicates_but_allows_bounded_out_of_order() { let mut replay = ReplayWindow::new(8); assert!(replay.accept(10)); assert!(!replay.accept(10)); assert!(replay.accept(12)); assert!(replay.accept(11)); assert!(!replay.accept(11)); assert!(replay.accept(18)); assert!(!replay.accept(9)); assert!(!replay.accept(0)); }