#![no_main] //! Fuzz the native handshake structs and their structural verifiers. //! //! Beyond plain deserialization (covered by the `from_body` target), this drives //! the verifier state machine: if the input happens to decode into the handshake //! structs, run `verify_server_hello`, `user_auth_transcript`, and //! `verify_native_user_auth` on them. These run on attacker-controlled material //! during the handshake and must reject (Err) without panicking. use libfuzzer_sys::fuzz_target; use dosh::native::{ NativeClientHello, NativeServerHello, NativeUserAuth, user_auth_transcript, verify_native_user_auth, verify_server_hello, }; use dosh::protocol; fuzz_target!(|data: &[u8]| { // Split the input into three slices and try to decode each into a handshake // struct. Use a length prefix scheme that is robust to short inputs. if data.len() < 3 { return; } let n = data.len(); let a = n / 3; let b = 2 * n / 3; let (chunk_client, chunk_server, chunk_auth) = (&data[..a], &data[a..b], &data[b..]); let client: Option = protocol::from_body(chunk_client).ok(); let server: Option = protocol::from_body(chunk_server).ok(); let auth: Option = protocol::from_body(chunk_auth).ok(); if let (Some(client), Some(server)) = (&client, &server) { // Host signature verification over the transcript must not panic. let _ = verify_server_hello(client, server); if let Some(auth) = &auth { // Transcript construction and full user-auth verification (signature // check + authorized-key matching) must not panic on garbage. let _ = user_auth_transcript(client, server, auth); let _ = verify_native_user_auth(client, server, auth, &[], None); } } });