Repository: google/OpenSK
File: fuzz/fuzz_helper/src/lib.rs (Rust)

Code before:

    let data = unstructured.take_rest();
    // Initialize ctap state and hid and get the allocated cid.
    let mut ctap = Ctap::new(env, CtapInstant::new(0));
    let cid = initialize(&mut ctap);
    // Wrap input as message with the allocated cid.
    let mut command = cid.to_vec();
    command.extend(data);
    process_message(&command, &mut ctap);
    Ok(())
}

fn setup_env(
    unstructured: &mut Unstructured,
    state: &mut CtapState,
    env: &mut TestEnv,
) -> arbitrary::Result<()> {
    if bool::arbitrary(unstructured)? {
        test_helpers::env::setup_enterprise_attestation(state, env).ok();
    }
    Ok(())
}

fn setup_customization(
    unstructured: &mut Unstructured,
    env: &mut TestEnv,
) -> arbitrary::Result<()> {
    test_helpers::customization::setup_enterprise_attestation(
        env.customization_mut(),
        Option::<EnterpriseAttestationMode>::arbitrary(unstructured)?,
        // TODO: Generate arbitrary rp_id_list (but with some dummies because content doesn't
        // matter), and use the rp ids in commands.
        None,
    );
    Ok(())
}

// Interprets the raw data as of the given input type and
// invokes message splitting, packet processing at CTAP HID level and response assembling
// using an initialized and allocated channel.
pub fn process_ctap_specific_type(data: &[u8], input_type: InputType) -> arbitrary::Result<()> {
    let mut unstructured = Unstructured::new(data);

    let mut env = TestEnv::new();
    env.rng().seed_from_u64(u64::arbitrary(&mut unstructured)?);

    let data = unstructured.take_rest();
    if !is_type(data, input_type) {
        return Ok(());
    }
    // Initialize ctap state and hid and get the allocated cid.

Review comment (suggestion):
nit: If this function is really about customization, why not take `env.customization_mut()` directly instead of `env`? We might need to change that in the future if some weird case happens, but then we would know why.

Code after:
                // Only checks for assembling crashes, not for semantics.
                let _ = assembler_reply.parse_packet(ctap.env(), &pkt_reply, CtapInstant::new(0));
            }
        }
    }
}

// Interprets the raw data as any ctap command (including the command byte) and
// invokes message splitting, packet processing at CTAP HID level and response assembling
// using an initialized and allocated channel.
pub fn process_ctap_any_type(data: &[u8]) -> arbitrary::Result<()> {
    let mut unstructured = Unstructured::new(data);

    let mut env = TestEnv::new();
    env.rng().seed_from_u64(u64::arbitrary(&mut unstructured)?);

    let data = unstructured.take_rest();
    // Initialize ctap state and hid and get the allocated cid.
    let mut ctap = Ctap::new(env, CtapInstant::new(0));
    let cid = initialize(&mut ctap);
    // Wrap input as message with the allocated cid.
    let mut command = cid.to_vec();
    command.extend(data);
    process_message(&command, &mut ctap);
    Ok(())
}

fn setup_customization(
    unstructured: &mut Unstructured,
    customization: &mut TestCustomization,
) -> FuzzResult<()> {
    customization.setup_enterprise_attestation(
        Option::<EnterpriseAttestationMode>::arbitrary(unstructured)?,
        // TODO: Generate arbitrary rp_id_list (but with some dummies because content doesn't
        // matter), and use the rp ids in commands.
        None,
    );
    if !is_valid(customization) {
        return Err(FuzzError::InvalidCustomization);
    }
    Ok(())
}

fn setup_state(
    unstructured: &mut Unstructured,
    state: &mut CtapState,
    env: &mut TestEnv,
) -> FuzzResult<()> {
    if bool::arbitrary(unstructured)? {
        test_helpers::enable_enterprise_attestation(state, env).ok();
    }