use std::path::PathBuf; use std::process::Command; use versevdi_core::input::{ decode_feedback, decode_input, encode_feedback, encode_input, FecStatus, FeedbackEvent, }; use versevdi_core::media::{MediaFragment, Reassembler}; use versevdi_core::wire::{ CapabilityProfile, ClientSessionAuthority, ConnectionManifest, NativeTunnelCredential, TunnelAdmissionRequest, }; fn fixture(name: &str) -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("tests/fixtures") .join(name) } #[test] fn copied_protocol_rc5_fixtures_have_immutable_hashes() { let cases = [ ( "tunnel-v1.tsv", "31a884800031c17844b9a8789702cf0d3639838ccfeb819c2bc3f0a5462ac5df", ), ( "datagram-v2.tsv", "65b9f6f018af624033562a78aae0b685df331c5e857d5f3d5d415aefa9d5b97b", ), ( "gateway-input-feedback-v1.tsv", "91b4dc1eb756476637ea7deebcb297256cb56d8e9c3d635088511af6b8914bda", ), ( "manifest.json", "76c33b33864d85f7d4a3761798eab52ffadbbe5fc313cf4e6e03369cfdc8df9a", ), ]; for (name, expected) in cases { let output = Command::new("shasum") .args(["-a", "256"]) .arg(fixture(name)) .output() .expect("shasum must be installed for fixture verification"); assert!(output.status.success(), "shasum failed for {name}"); let actual = String::from_utf8(output.stdout).expect("shasum output is UTF-8"); assert_eq!(&actual[..64], expected, "fixture drifted: {name}"); } } fn valid_manifest() -> &'static [u8] { br#"{ "version":"1","purpose":"launch","session_id":"session","reconnect_sequence":0, "gateway":{"id":"gateway","addresses":["gateway.test:443"],"public_identity":"gateway.test"}, "tunnel":{"versions":["verse-gateway-v1/1"],"features":["control.v1","input.absolute.v1","input.scroll.v1"]}, "profile":{"id":"standard","bounds":{"minimum_kbps":1000,"target_kbps":5000,"maximum_kbps":10000},"display_mode":{"resolution_width":1920,"resolution_height":1080,"fps":60}}, "grant":{"opaque_value":"ggggggggggggggggggggggggggggggggggggggggggg","expires_at":"2099-01-01T00:00:00Z","audience":"audience"}, "correlation_id":"correlation" }"# } fn capabilities() -> CapabilityProfile { CapabilityProfile::new( "quic-tls13", "datagram-v2", "encoded", "encoded", "server", vec!["h264-opus".to_owned(), "hevc-opus".to_owned()], ) .expect("literal capability profile is valid") } const VALID_CERTIFICATE_PEM: &str = "-----BEGIN CERTIFICATE-----\nAQID\n-----END CERTIFICATE-----"; fn credential_json(certificate_chain_pem: &str, trust_bundle_pem: &str) -> Vec { serde_json::to_vec(&serde_json::json!({ "client_device_id": "device", "device_key_id": "key", "certificate_chain_pem": certificate_chain_pem, "trust_bundle_pem": trust_bundle_pem, "expires_at": "2099-01-01T00:00:00Z", })) .expect("literal credential is JSON-encodable") } #[test] fn strict_rc5_dtos_reject_duplicate_trailing_unknown_and_provider_fields() { assert!(ConnectionManifest::decode(valid_manifest()).is_ok()); assert!( ConnectionManifest::decode(br#"{"version":"1","version":"1","purpose":"launch"}"#).is_err() ); let trailing = [valid_manifest(), b" {}"].concat(); assert!(ConnectionManifest::decode(&trailing).is_err()); let unknown = String::from_utf8(valid_manifest().to_vec()) .expect("fixture is UTF-8") .replacen( "\"correlation_id\"", "\"unknown\":true,\"correlation_id\"", 1, ); assert!(ConnectionManifest::decode(unknown.as_bytes()).is_err()); let provider = String::from_utf8(valid_manifest().to_vec()) .expect("fixture is UTF-8") .replacen( "\"addresses\"", "\"providerIdentity\":\"hidden\",\"addresses\"", 1, ); assert!(ConnectionManifest::decode(provider.as_bytes()).is_err()); let authority = br#"{"version":"1","session_id":"session","gateway_id":"gateway","audience":"audience","reconnect_sequence":0,"expires_at":"2098-01-01T00:00:00Z","capabilities":{"transport":"quic-tls13","framing":"datagram-v2","media":"encoded","audio":"encoded","source_rate_control":"server","client_decode":["h264-opus"]}}"#; let authority_trailing = [authority.as_slice(), b" {}"].concat(); assert!(ClientSessionAuthority::decode(&authority_trailing).is_err()); let authority_duplicate = String::from_utf8(authority.to_vec()) .expect("fixture is UTF-8") .replacen( "\"session_id\":", "\"session_id\":\"duplicate\",\"session_id\":", 1, ); assert!(ClientSessionAuthority::decode(authority_duplicate.as_bytes()).is_err()); let admission_provider = format!( r#"{{"version":"1","session_id":"session","gateway_id":"gateway","audience":"audience","grant":"{}","reconnect_sequence":0,"client_nonce":"{}","device_signature":"{}","provider_identity":"forbidden","capabilities":{{"transport":"quic-tls13","framing":"datagram-v2","media":"encoded","audio":"encoded","source_rate_control":"server","client_decode":["h264-opus"]}}}}"#, "g".repeat(43), "n".repeat(16), "A".repeat(86), ); assert!(TunnelAdmissionRequest::decode(admission_provider.as_bytes()).is_err()); } #[test] fn manifest_public_identity_requires_dns_sni_not_ip_or_uuid() { for invalid_identity in ["127.0.0.1", "::1", "550e8400-e29b-41d4-a716-446655440000"] { let manifest = String::from_utf8(valid_manifest().to_vec()) .expect("fixture is UTF-8") .replace("gateway.test\"}", &format!("{invalid_identity}\"}}")); assert!( ConnectionManifest::decode(manifest.as_bytes()).is_err(), "non-DNS SNI accepted: {invalid_identity}" ); } let identity_equals_dns_shaped_gateway_id = String::from_utf8(valid_manifest().to_vec()) .expect("fixture is UTF-8") .replace("\"id\":\"gateway\"", "\"id\":\"gateway.test\""); assert!( ConnectionManifest::decode(identity_equals_dns_shaped_gateway_id.as_bytes()).is_err(), "public SNI identity matched the logical gateway id" ); } #[test] fn rc5_manifest_credential_and_authority_enforce_bounds_and_bindings() { let manifest = ConnectionManifest::decode(valid_manifest()).expect("valid manifest"); manifest .validate_at("2026-08-12T00:00:00Z") .expect("unexpired manifest"); let credential = NativeTunnelCredential::decode(&credential_json( VALID_CERTIFICATE_PEM, VALID_CERTIFICATE_PEM, )) .expect("valid credential"); credential .validate_at("2026-08-12T00:00:00Z") .expect("unexpired credential"); assert!(NativeTunnelCredential::decode( br#"{"client_device_id":"device","device_key_id":"key","certificate_chain_pem":"-----BEGIN CERTIFICATE-----\nAQID\n-----END CERTIFICATE-----","trust_bundle_pem":"-----BEGIN CERTIFICATE-----\nAQID\n-----END CERTIFICATE-----","client_private_key_pem":"forbidden","expires_at":"2099-01-01T00:00:00Z"}"#, ) .is_err()); let authority = ClientSessionAuthority::decode( br#"{"version":"1","session_id":"session","gateway_id":"gateway","audience":"audience","reconnect_sequence":0,"expires_at":"2098-01-01T00:00:00Z","capabilities":{"transport":"quic-tls13","framing":"datagram-v2","media":"encoded","audio":"encoded","source_rate_control":"server","client_decode":["h264-opus"]}}"#, ) .expect("valid client-safe authority"); authority .validate_binding(&manifest, &capabilities(), "2026-08-12T00:00:00Z") .expect("authority is bound and is a capability subset"); let provider_authority = br#"{"version":"1","session_id":"session","gateway_id":"gateway","audience":"audience","reconnect_sequence":0,"expires_at":"2098-01-01T00:00:00Z","capabilities":{"transport":"quic-tls13","framing":"datagram-v2","media":"encoded","audio":"encoded","source_rate_control":"server","client_decode":["h264-opus"]},"provider_profile":"apollo"}"#; assert!(ClientSessionAuthority::decode(provider_authority).is_err()); let provider_route = br#"{"version":"1","session_id":"session","gateway_id":"gateway","audience":"audience","reconnect_sequence":0,"expires_at":"2098-01-01T00:00:00Z","capabilities":{"transport":"quic-tls13","framing":"datagram-v2","media":"encoded","audio":"encoded","source_rate_control":"server","client_decode":["h264-opus"]},"stream_host":"provider.invalid"}"#; assert!(ClientSessionAuthority::decode(provider_route).is_err()); } #[test] fn client_authority_directly_rejects_every_manifest_binding_mismatch() { let manifest = ConnectionManifest::decode(valid_manifest()).expect("valid manifest"); let offered = CapabilityProfile::new( "quic-tls13", "datagram-v2", "encoded", "encoded", "server", vec!["h264-opus".to_owned()], ) .expect("offered capabilities"); let valid = serde_json::json!({ "version": "1", "session_id": "session", "gateway_id": "gateway", "audience": "audience", "reconnect_sequence": 0, "expires_at": "2098-01-01T00:00:00Z", "capabilities": { "transport": "quic-tls13", "framing": "datagram-v2", "media": "encoded", "audio": "encoded", "source_rate_control": "server", "client_decode": ["h264-opus"], }, }); for case in [ "session", "gateway", "audience", "reconnect", "expired", "beyond-grant", "capability", ] { let mut value = valid.clone(); match case { "session" => value["session_id"] = "other".into(), "gateway" => value["gateway_id"] = "other".into(), "audience" => value["audience"] = "other".into(), "reconnect" => value["reconnect_sequence"] = 1.into(), "expired" => value["expires_at"] = "2026-08-12T00:00:00Z".into(), "beyond-grant" => value["expires_at"] = "2100-01-01T00:00:00Z".into(), "capability" => { value["capabilities"]["client_decode"] = serde_json::json!(["h264-opus", "hevc-opus"]); } _ => unreachable!(), } let authority = ClientSessionAuthority::decode(&serde_json::to_vec(&value).expect("encode authority")) .expect("structurally valid authority"); assert_eq!( authority.validate_binding(&manifest, &offered, "2026-08-12T00:00:00Z"), Err(versevdi_core::error::CoreError::AuthorityRejected), "binding mismatch accepted: {case}" ); } } #[test] fn native_tunnel_credential_rejects_private_key_pem_in_certificate_fields() { for field in ["certificate_chain_pem", "trust_bundle_pem"] { let private_key = "-----BEGIN PRIVATE KEY-----\nAQID\n-----END PRIVATE KEY-----"; let credential = if field == "certificate_chain_pem" { credential_json(private_key, VALID_CERTIFICATE_PEM) } else { credential_json(VALID_CERTIFICATE_PEM, private_key) }; assert!( NativeTunnelCredential::decode(&credential).is_err(), "private key armor accepted in {field}" ); } } #[test] fn native_tunnel_credential_accepts_one_or_more_certificate_blocks() { let two_certificates = format!("{VALID_CERTIFICATE_PEM}\n\n{VALID_CERTIFICATE_PEM}\n"); assert!(NativeTunnelCredential::decode(&credential_json( &two_certificates, VALID_CERTIFICATE_PEM, )) .is_ok()); } fn assert_credential_pem_rejected(invalid_values: &[&str]) { for invalid in invalid_values { assert!( NativeTunnelCredential::decode(&credential_json(invalid, VALID_CERTIFICATE_PEM)) .is_err(), "invalid certificate chain accepted" ); assert!( NativeTunnelCredential::decode(&credential_json(VALID_CERTIFICATE_PEM, invalid)) .is_err(), "invalid trust bundle accepted" ); } } #[test] fn native_tunnel_credential_rejects_bare_certificate_text() { assert_credential_pem_rejected(&["certificate"]); } #[test] fn native_tunnel_credential_rejects_non_certificate_pem_labels() { assert_credential_pem_rejected(&["-----BEGIN PUBLIC KEY-----\nAQID\n-----END PUBLIC KEY-----"]); } #[test] fn native_tunnel_credential_rejects_malformed_or_incomplete_certificate_armor() { assert_credential_pem_rejected(&[ "-----BEGIN CERTIFICATE-----\nAQID", "-----BEGIN CERTIFICATE-----\n!!!!\n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----\nAQI\n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----\nAQJ=\n-----END CERTIFICATE-----", ]); } #[test] fn native_tunnel_credential_rejects_junk_between_or_after_certificate_blocks() { let between = format!("{VALID_CERTIFICATE_PEM}\njunk\n{VALID_CERTIFICATE_PEM}"); let after = format!("{VALID_CERTIFICATE_PEM}\njunk"); assert_credential_pem_rejected(&[&between, &after]); } #[test] fn native_tunnel_credential_rejects_empty_certificate_blocks() { assert_credential_pem_rejected(&["-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"]); } #[test] fn expiry_mismatch_and_capability_escalation_are_rejected() { let manifest = ConnectionManifest::decode(valid_manifest()).expect("valid manifest"); assert!(manifest.validate_at("2100-01-01T00:00:00Z").is_err()); let credential = NativeTunnelCredential::decode(&credential_json( VALID_CERTIFICATE_PEM, VALID_CERTIFICATE_PEM, )) .expect("valid credential"); assert!(credential.validate_at("2099-01-01T00:00:00Z").is_err()); let mismatched = ClientSessionAuthority::decode( br#"{"version":"1","session_id":"other","gateway_id":"gateway","audience":"audience","reconnect_sequence":0,"expires_at":"2098-01-01T00:00:00Z","capabilities":{"transport":"quic-tls13","framing":"datagram-v2","media":"encoded","audio":"encoded","source_rate_control":"server","client_decode":["h264-opus"]}}"#, ) .expect("shape is valid"); assert!(mismatched .validate_binding(&manifest, &capabilities(), "2026-08-12T00:00:00Z") .is_err()); let escalated = ClientSessionAuthority::decode( br#"{"version":"1","session_id":"session","gateway_id":"gateway","audience":"audience","reconnect_sequence":0,"expires_at":"2098-01-01T00:00:00Z","capabilities":{"transport":"quic-tls13","framing":"datagram-v2","media":"encoded","audio":"encoded","source_rate_control":"server","client_decode":["h264-opus","hevc-opus"]}}"#, ) .expect("shape is valid"); let h264_only = CapabilityProfile::new( "quic-tls13", "datagram-v2", "encoded", "encoded", "server", vec!["h264-opus".to_owned()], ) .expect("literal capability profile"); assert!(escalated .validate_binding(&manifest, &h264_only, "2026-08-12T00:00:00Z") .is_err()); } #[test] fn admission_transcript_matches_rc5_literal() { let request = TunnelAdmissionRequest::decode( format!( r#"{{"version":"1","session_id":"session","gateway_id":"gateway","audience":"audience","grant":"{}","reconnect_sequence":0,"client_nonce":"{}","device_signature":"{}","capabilities":{{"transport":"quic-tls13","framing":"datagram-v1","media":"encoded","audio":"encoded","source_rate_control":"server","client_decode":["h264-opus"]}}}}"#, "g".repeat(43), "n".repeat(16), "A".repeat(86), ) .as_bytes(), ) .expect("valid admission request"); assert_eq!( request.admission_transcript(), format!( "versevdi/tunnel-admission/v17:session7:gateway8:audience43:{}1:016:{}10:quic-tls1311:datagram-v17:encoded7:encoded6:server1:19:h264-opus", "g".repeat(43), "n".repeat(16), ) .into_bytes() ); } #[test] fn admission_rejects_non_raw_base64url_nonce_and_signature() { for (nonce, signature) in [ ("!".repeat(16), "A".repeat(86)), ("A".repeat(17), "A".repeat(86)), ("A".repeat(16), "!".repeat(86)), ("A".repeat(16), format!("{}B", "A".repeat(85))), ] { let request = format!( r#"{{"version":"1","session_id":"session","gateway_id":"gateway","audience":"audience","grant":"{}","reconnect_sequence":0,"client_nonce":"{}","device_signature":"{}","capabilities":{{"transport":"quic-tls13","framing":"datagram-v2","media":"encoded","audio":"encoded","source_rate_control":"server","client_decode":["h264-opus"]}}}}"#, "g".repeat(43), nonce, signature, ); assert!(TunnelAdmissionRequest::decode(request.as_bytes()).is_err()); } } fn decode_hex(value: &str) -> Vec { value .as_bytes() .chunks_exact(2) .map(|pair| { let text = std::str::from_utf8(pair).expect("fixture hex is ASCII"); u8::from_str_radix(text, 16).expect("fixture hex is valid") }) .collect() } fn fixture_rows(name: &str) -> impl Iterator> { let data = match name { "datagram-v2.tsv" => include_str!("fixtures/datagram-v2.tsv"), "gateway-input-feedback-v1.tsv" => { include_str!("fixtures/gateway-input-feedback-v1.tsv") } _ => unreachable!("known fixture"), }; data.lines() .skip(1) .map(|line| line.split('\t').collect::>()) } #[test] fn datagram_v2_codec_matches_all_rc5_conformance_rows() { for row in fixture_rows("datagram-v2.tsv") { let bytes = decode_hex(row[3].strip_prefix("hex=").expect("hex fixture")); match row[4] { "valid" => { let fragment = MediaFragment::decode(&bytes).expect(row[0]); assert_eq!(fragment.encode().expect(row[0]), bytes, "{}", row[0]); } error => assert_eq!( MediaFragment::decode(&bytes).expect_err(row[0]).code(), error.strip_prefix("invalid:").expect("invalid fixture"), "{}", row[0] ), } } } #[test] fn vgi1_and_vgf1_codecs_match_all_rc5_conformance_rows() { let features = ["input.absolute.v1", "input.scroll.v1"]; for row in fixture_rows("gateway-input-feedback-v1.tsv") { let bytes = decode_hex(row[3].strip_prefix("hex=").expect("hex fixture")); let result = match row[2] { "gateway_input" => { decode_input(&bytes, &features).and_then(|event| encode_input(&event, &features)) } "gateway_feedback" => decode_feedback(&bytes).and_then(|event| encode_feedback(&event)), _ => unreachable!("known fixture kind"), }; match row[4] { "valid" => assert_eq!(result.expect(row[0]), bytes, "{}", row[0]), error => assert_eq!( result.expect_err(row[0]).code(), error.strip_prefix("invalid:").expect("invalid fixture"), "{}", row[0] ), } } } #[test] fn datagram_v2_reassembly_is_bounded_reordered_and_duplicate_safe() { let first = MediaFragment::new_video(7, 42, 0, 2, b"hello".to_vec()).expect("fragment"); let second = MediaFragment::new_video(7, 42, 1, 2, b" world".to_vec()).expect("fragment"); let mut reassembler = Reassembler::new(); assert!(reassembler .push(second.clone(), 10) .expect("second") .is_none()); assert!(reassembler.push(second, 11).expect("duplicate").is_none()); let unit = reassembler .push(first, 12) .expect("first") .expect("complete unit"); assert_eq!(unit.payload, b"hello world"); assert_eq!(reassembler.incomplete_units(), 0); for sequence in 0..5 { let fragment = MediaFragment::new_video(sequence, 1, 0, 2, vec![0]).expect("fragment"); assert!(reassembler.push(fragment, 20 + u64::from(sequence)).is_ok()); } assert_eq!(reassembler.incomplete_units(), 4); assert_eq!(reassembler.evicted_units(), 1); } #[test] fn datagram_v2_boundary_loop_covers_payload_fragment_count_and_audio() { for payload_length in [0, 1, 1_177] { let fragment = MediaFragment::new_audio( u32::try_from(payload_length).expect("small"), 1, 0, 1, vec![0; payload_length], ) .expect("boundary is valid"); assert_eq!( MediaFragment::decode(&fragment.encode().expect("encode")).expect("decode"), fragment ); } assert!(MediaFragment::new_audio(1, 1, 0, 1, vec![0; 1_178]).is_err()); assert!(MediaFragment::new_audio(1, 1, 0, 0, Vec::new()).is_err()); assert!(MediaFragment::new_audio(1, 1, 0, 892, Vec::new()).is_err()); } #[test] fn reassembly_discards_conflicts_and_expires_after_250_ms() { let mut reassembler = Reassembler::new(); let first = MediaFragment::new_video(1, 1, 0, 2, vec![1]).expect("fragment"); reassembler.push(first, 0).expect("first"); let conflict = MediaFragment::new_video(1, 1, 0, 2, vec![2]).expect("fragment"); assert!(reassembler.push(conflict, 1).is_err()); assert_eq!(reassembler.incomplete_units(), 0); let expiring = MediaFragment::new_video(2, 1, 0, 2, vec![1]).expect("fragment"); reassembler.push(expiring, 10).expect("first"); let next = MediaFragment::new_video(3, 1, 0, 2, vec![1]).expect("fragment"); reassembler.push(next, 261).expect("expiry sweep"); assert_eq!(reassembler.expired_units(), 1); } #[test] fn reassembly_expires_at_exactly_250_ms() { let mut reassembler = Reassembler::new(); let expiring = MediaFragment::new_video(2, 1, 0, 2, vec![1]).expect("fragment"); reassembler.push(expiring, 10).expect("first"); let next = MediaFragment::new_video(3, 1, 0, 2, vec![1]).expect("fragment"); reassembler.push(next, 260).expect("expiry sweep"); assert_eq!(reassembler.expired_units(), 1); } #[test] fn reassembly_rejects_a_complete_unit_above_one_mebibyte() { let mut reassembler = Reassembler::new(); for index in 0..891_u16 { let fragment = MediaFragment::new_video(9, 1, index, 891, vec![0; 1_177]) .expect("individual fragment is bounded"); let result = reassembler.push(fragment, 0); if index < 890 { assert!(result.expect("within aggregate bound").is_none()); } else { assert!(result.is_err()); } } assert_eq!(reassembler.incomplete_units(), 0); } #[test] fn input_features_and_feedback_booleans_fail_closed() { assert_eq!( decode_input(&decode_hex("56474931060804d202370a0005a0"), &[]) .expect_err("absolute feature is required") .code(), "unsupported_feature" ); assert_eq!( decode_feedback(&decode_hex("564746310112000102")) .expect_err("HDR is boolean") .code(), "length" ); } #[test] fn disconnected_gateway_feedback_is_provider_free_control() { assert_eq!( decode_feedback(&decode_hex("5647463101130000")).expect("disconnected feedback"), FeedbackEvent::Disconnected ); } #[test] fn fec_feedback_enforces_rc5_go_field_invariants_on_decode_and_encode() { for invalid in [ "56474631000200150000002a0005000300020000000200080002140001", "56474631000200150000002a000500030002000a0002000b0002140001", "56474631000200150000002a000500030002000a000200080003140001", "56474631000200150000002a000500030002000a000200080002650001", "56474631000200150000002a000500030002000a000200080002140000", "56474631000200150000002a000500030002000a000200080002140101", ] { assert_eq!( decode_feedback(&decode_hex(invalid)) .expect_err("invalid FEC status") .code(), "field" ); } let valid = FecStatus { frame_index: 42, highest_received_sequence: 5, next_contiguous_sequence: 3, missing_before_highest: 2, total_data_packets: 10, total_parity_packets: 2, received_data_packets: 8, received_parity_packets: 2, fec_percentage: 20, multi_fec_block_index: 0, multi_fec_block_count: 1, }; let invalid = [ FecStatus { total_data_packets: 0, ..valid.clone() }, FecStatus { received_data_packets: 11, ..valid.clone() }, FecStatus { received_parity_packets: 3, ..valid.clone() }, FecStatus { fec_percentage: 101, ..valid.clone() }, FecStatus { multi_fec_block_count: 0, ..valid.clone() }, FecStatus { multi_fec_block_index: 1, ..valid }, ]; for status in invalid { assert_eq!( encode_feedback(&FeedbackEvent::Fec(status)) .expect_err("invalid FEC status") .code(), "field" ); } }