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

Code before:
pub enum InputType {
    CborMakeCredentialParameter,
    CborGetAssertionParameter,
    CborClientPinParameter,
    Ctap1,
}

// Converts a byte slice into Message
fn raw_to_message(data: &[u8]) -> Message {
    if data.len() <= 4 {
        let mut cid = [0; 4];
        cid[..data.len()].copy_from_slice(data);
        Message {
            cid,
            cmd: 0,
            payload: vec![],
        }
    } else {
        Message {
            cid: array_ref!(data, 0, 4).clone(),
            cmd: data[4],
            payload: data[5..].to_vec(),
        }
    }
}

// Returns an initialized ctap state, hid and the allocated cid
// after processing the init command.
fn initialize<CheckUserPresence>(
    ctap_state: &mut CtapState<ThreadRng256, CheckUserPresence>,
    ctap_hid: &mut CtapHid,
) -> ChannelID
where
    CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>,
{
    let nonce = vec![0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
    let message = Message {
        cid: CHANNEL_BROADCAST,
        cmd: COMMAND_INIT,
        payload: nonce.clone(),
    };
    let mut assembler_reply = MessageAssembler::new();
    let mut result_cid: ChannelID = Default::default();
    for pkt_request in HidPacketIterator::new(message.clone()).unwrap() {
        for pkt_reply in ctap_hid.process_hid_packet(&pkt_request, DUMMY_CLOCK_VALUE, ctap_state) {
            if let Ok(Some(result)) = assembler_reply.parse_packet(&pkt_reply, DUMMY_TIMESTAMP) {
                result_cid.copy_from_slice(&result.payload[8..12]);
            }
        }
    }
    result_cid

Review comment (suggestion):
FYI, the `arrayref` crate also has a macro to split into multiple slices. One can either use

```rust
let (cid, cmd, payload) = array_refs![data, 4, 1, data.len() - 5]
```

or maybe clearer:

```rust
let (header, payload) = data.split_at(5);
let (cid, cmd) = array_refs![header, 4, 1];
```

Code after:
pub enum InputType {
    CborMakeCredentialParameter,
    CborGetAssertionParameter,
    CborClientPinParameter,
    Ctap1,
}

fn user_immediately_present(_: ChannelID) -> Result<(), Ctap2StatusCode> {
    Ok(())
}

// Converts a byte slice into Message
fn raw_to_message(data: &[u8]) -> Message {
    if data.len() <= 4 {
        let mut cid = [0; 4];
        cid[..data.len()].copy_from_slice(data);
        Message {
            cid,
            cmd: 0,
            payload: vec![],
        }
    } else {
        Message {
            cid: array_ref!(data, 0, 4).clone(),
            cmd: data[4],
            payload: data[5..].to_vec(),
        }
    }
}

// Returns an initialized ctap state, hid and the allocated cid
// after processing the init command.
fn initialize<CheckUserPresence>(
    ctap_state: &mut CtapState<ThreadRng256, CheckUserPresence>,
    ctap_hid: &mut CtapHid,
) -> ChannelID
where
    CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>,
{
    let nonce = vec![0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
    let message = Message {
        cid: CHANNEL_BROADCAST,
        cmd: COMMAND_INIT,
        payload: nonce,
    };
    let mut assembler_reply = MessageAssembler::new();
    let mut result_cid: ChannelID = Default::default();
    for pkt_request in HidPacketIterator::new(message).unwrap() {
        for pkt_reply in ctap_hid.process_hid_packet(&pkt_request, DUMMY_CLOCK_VALUE, ctap_state) {
            if let Ok(Some(result)) = assembler_reply.parse_packet(&pkt_reply, DUMMY_TIMESTAMP) {
                result_cid.copy_from_slice(&result.payload[8..12]);