Resolved PR comments and added more fuzz targets.
This commit is contained in:
@@ -16,12 +16,30 @@ fuzz_helper = { path = "fuzz_helper" }
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = ["."]
|
members = ["."]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "fuzz_target_process_ctap_command"
|
||||||
|
path = "fuzz_targets/fuzz_target_process_ctap_command.rs"
|
||||||
|
test = false
|
||||||
|
doc = false
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "fuzz_target_process_ctap1"
|
name = "fuzz_target_process_ctap1"
|
||||||
path = "fuzz_targets/fuzz_target_process_ctap1.rs"
|
path = "fuzz_targets/fuzz_target_process_ctap1.rs"
|
||||||
test = false
|
test = false
|
||||||
doc = false
|
doc = false
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "fuzz_target_process_ctap2_client_pin"
|
||||||
|
path = "fuzz_targets/fuzz_target_process_ctap2_client_pin.rs"
|
||||||
|
test = false
|
||||||
|
doc = false
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "fuzz_target_process_ctap2_get_assertion"
|
||||||
|
path = "fuzz_targets/fuzz_target_process_ctap2_get_assertion.rs"
|
||||||
|
test = false
|
||||||
|
doc = false
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "fuzz_target_process_ctap2_make_credential"
|
name = "fuzz_target_process_ctap2_make_credential"
|
||||||
path = "fuzz_targets/fuzz_target_process_ctap2_make_credential.rs"
|
path = "fuzz_targets/fuzz_target_process_ctap2_make_credential.rs"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2019 Google LLC
|
// Copyright 2020 Google LLC
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@@ -38,7 +38,7 @@ const CLOCK_FREQUENCY_HZ: usize = 32768;
|
|||||||
const DUMMY_TIMESTAMP: Timestamp<isize> = Timestamp::from_ms(0);
|
const DUMMY_TIMESTAMP: Timestamp<isize> = Timestamp::from_ms(0);
|
||||||
const DUMMY_CLOCK_VALUE: ClockValue = ClockValue::new(0, CLOCK_FREQUENCY_HZ);
|
const DUMMY_CLOCK_VALUE: ClockValue = ClockValue::new(0, CLOCK_FREQUENCY_HZ);
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum InputType {
|
pub enum InputType {
|
||||||
CborMakeCredentialParameter,
|
CborMakeCredentialParameter,
|
||||||
CborGetAssertionParameter,
|
CborGetAssertionParameter,
|
||||||
@@ -78,11 +78,11 @@ where
|
|||||||
let message = Message {
|
let message = Message {
|
||||||
cid: CHANNEL_BROADCAST,
|
cid: CHANNEL_BROADCAST,
|
||||||
cmd: COMMAND_INIT,
|
cmd: COMMAND_INIT,
|
||||||
payload: nonce.clone(),
|
payload: nonce,
|
||||||
};
|
};
|
||||||
let mut assembler_reply = MessageAssembler::new();
|
let mut assembler_reply = MessageAssembler::new();
|
||||||
let mut result_cid: ChannelID = Default::default();
|
let mut result_cid: ChannelID = Default::default();
|
||||||
for pkt_request in HidPacketIterator::new(message.clone()).unwrap() {
|
for pkt_request in HidPacketIterator::new(message).unwrap() {
|
||||||
for pkt_reply in ctap_hid.process_hid_packet(&pkt_request, DUMMY_CLOCK_VALUE, ctap_state) {
|
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) {
|
if let Ok(Some(result)) = assembler_reply.parse_packet(&pkt_reply, DUMMY_TIMESTAMP) {
|
||||||
result_cid.copy_from_slice(&result.payload[8..12]);
|
result_cid.copy_from_slice(&result.payload[8..12]);
|
||||||
@@ -94,7 +94,7 @@ where
|
|||||||
|
|
||||||
// Checks whether the given data can be interpreted as the given type.
|
// Checks whether the given data can be interpreted as the given type.
|
||||||
fn is_type(data: &[u8], input_type: InputType) -> bool {
|
fn is_type(data: &[u8], input_type: InputType) -> bool {
|
||||||
if input_type.clone() == InputType::Ctap1 {
|
if input_type == InputType::Ctap1 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
match cbor::read(data) {
|
match cbor::read(data) {
|
||||||
@@ -114,10 +114,50 @@ fn is_type(data: &[u8], input_type: InputType) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interprets the raw data as a complete message (with channel id, command type and payload) and
|
||||||
|
// invokes message splitting, packet processing at CTAP HID level and response assembling.
|
||||||
|
fn process_message<CheckUserPresence>(
|
||||||
|
data: &[u8],
|
||||||
|
ctap_state: &mut CtapState<ThreadRng256, CheckUserPresence>,
|
||||||
|
ctap_hid: &mut CtapHid,
|
||||||
|
) where
|
||||||
|
CheckUserPresence: Fn(ChannelID) -> Result<(), Ctap2StatusCode>,
|
||||||
|
{
|
||||||
|
let message = raw_to_message(data);
|
||||||
|
if let Some(hid_packet_iterator) = HidPacketIterator::new(message) {
|
||||||
|
let mut assembler_reply = MessageAssembler::new();
|
||||||
|
for pkt_request in hid_packet_iterator {
|
||||||
|
for pkt_reply in
|
||||||
|
ctap_hid.process_hid_packet(&pkt_request, DUMMY_CLOCK_VALUE, ctap_state)
|
||||||
|
{
|
||||||
|
// Only checks for assembling crashes, not for semantics.
|
||||||
|
let _ = assembler_reply.parse_packet(&pkt_reply, DUMMY_TIMESTAMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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]) {
|
||||||
|
// Initialize ctap state and hid and get the allocated cid.
|
||||||
|
let mut rng = ThreadRng256 {};
|
||||||
|
let user_immediately_present = |_| Ok(());
|
||||||
|
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present);
|
||||||
|
let mut ctap_hid = CtapHid::new();
|
||||||
|
let cid = initialize(&mut ctap_state, &mut ctap_hid);
|
||||||
|
// Wrap input as message with the allocated cid.
|
||||||
|
let mut command = cid.to_vec();
|
||||||
|
command.extend(data);
|
||||||
|
process_message(&command, &mut ctap_state, &mut ctap_hid);
|
||||||
|
}
|
||||||
|
|
||||||
// Interprets the raw data as of the given input type and
|
// Interprets the raw data as of the given input type and
|
||||||
// invokes message splitting, assembling and packet processing at CTAP HID level.
|
// invokes message splitting, packet processing at CTAP HID level and response assembling
|
||||||
pub fn process_input(data: &[u8], input_type: InputType) {
|
// using an initialized and allocated channel.
|
||||||
if !is_type(data, input_type.clone()) {
|
pub fn process_ctap_specific_type(data: &[u8], input_type: InputType) {
|
||||||
|
if !is_type(data, input_type) {
|
||||||
return ();
|
return ();
|
||||||
}
|
}
|
||||||
// Initialize ctap state and hid and get the allocated cid.
|
// Initialize ctap state and hid and get the allocated cid.
|
||||||
@@ -143,23 +183,11 @@ pub fn process_input(data: &[u8], input_type: InputType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
command.extend(data);
|
command.extend(data);
|
||||||
// Process message at HID level.
|
process_message(&command, &mut ctap_state, &mut ctap_hid);
|
||||||
let message = raw_to_message(&command);
|
|
||||||
if let Some(hid_packet_iterator) = HidPacketIterator::new(message) {
|
|
||||||
let mut assembler_reply = MessageAssembler::new();
|
|
||||||
for pkt_request in hid_packet_iterator {
|
|
||||||
for pkt_reply in
|
|
||||||
ctap_hid.process_hid_packet(&pkt_request, DUMMY_CLOCK_VALUE, &mut ctap_state)
|
|
||||||
{
|
|
||||||
// Only checks for assembling crashes, not for semantics.
|
|
||||||
let _ = assembler_reply.parse_packet(&pkt_reply, DUMMY_TIMESTAMP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Splits and reassembles the given data as HID packets.
|
// Splits and reassembles the given data as HID packets.
|
||||||
pub fn split_assemble(data: &[u8]) {
|
pub fn split_assemble_hid_packets(data: &[u8]) {
|
||||||
let mut message = raw_to_message(data);
|
let mut message = raw_to_message(data);
|
||||||
if let Some(hid_packet_iterator) = HidPacketIterator::new(message.clone()) {
|
if let Some(hid_packet_iterator) = HidPacketIterator::new(message.clone()) {
|
||||||
let mut assembler = MessageAssembler::new();
|
let mut assembler = MessageAssembler::new();
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use fuzz_helper::{process_input, InputType};
|
use fuzz_helper::{process_ctap_specific_type, InputType};
|
||||||
use libfuzzer_sys::fuzz_target;
|
use libfuzzer_sys::fuzz_target;
|
||||||
|
|
||||||
// Fuzz inputs as CTAP1 U2F raw message.
|
// Fuzz inputs as CTAP1 U2F raw messages.
|
||||||
|
// For a more generic fuzz target including all CTAP commands, you can use
|
||||||
|
// fuzz_target_process_ctap_command.
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
process_input(data, InputType::Ctap1);
|
process_ctap_specific_type(data, InputType::Ctap1);
|
||||||
});
|
});
|
||||||
|
|||||||
11
fuzz/fuzz_targets/fuzz_target_process_ctap2_client_pin.rs
Normal file
11
fuzz/fuzz_targets/fuzz_target_process_ctap2_client_pin.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use fuzz_helper::{process_ctap_specific_type, InputType};
|
||||||
|
use libfuzzer_sys::fuzz_target;
|
||||||
|
|
||||||
|
// Fuzz inputs as CTAP2 client pin command parameters encoded in cbor.
|
||||||
|
// For a more generic fuzz target including all CTAP commands, you can use
|
||||||
|
// fuzz_target_process_ctap_command.
|
||||||
|
fuzz_target!(|data: &[u8]| {
|
||||||
|
process_ctap_specific_type(data, InputType::CborClientPinParameter);
|
||||||
|
});
|
||||||
11
fuzz/fuzz_targets/fuzz_target_process_ctap2_get_assertion.rs
Normal file
11
fuzz/fuzz_targets/fuzz_target_process_ctap2_get_assertion.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use fuzz_helper::{process_ctap_specific_type, InputType};
|
||||||
|
use libfuzzer_sys::fuzz_target;
|
||||||
|
|
||||||
|
// Fuzz inputs as CTAP2 get assertion command parameters encoded in cbor.
|
||||||
|
// For a more generic fuzz target including all CTAP commands, you can use
|
||||||
|
// fuzz_target_process_ctap_command.
|
||||||
|
fuzz_target!(|data: &[u8]| {
|
||||||
|
process_ctap_specific_type(data, InputType::CborGetAssertionParameter);
|
||||||
|
});
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use fuzz_helper::{process_input, InputType};
|
use fuzz_helper::{process_ctap_specific_type, InputType};
|
||||||
use libfuzzer_sys::fuzz_target;
|
use libfuzzer_sys::fuzz_target;
|
||||||
|
|
||||||
// Fuzz inputs as CTAP2 make credential command parameters encoded in cbor.
|
// Fuzz inputs as CTAP2 make credential command parameters encoded in cbor.
|
||||||
|
// For a more generic fuzz target including all CTAP commands, you can use
|
||||||
|
// fuzz_target_process_ctap_command.
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
process_input(data, InputType::CborMakeCredentialParameter);
|
process_ctap_specific_type(data, InputType::CborMakeCredentialParameter);
|
||||||
});
|
});
|
||||||
|
|||||||
9
fuzz/fuzz_targets/fuzz_target_process_ctap_command.rs
Normal file
9
fuzz/fuzz_targets/fuzz_target_process_ctap_command.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use fuzz_helper::process_ctap_any_type;
|
||||||
|
use libfuzzer_sys::fuzz_target;
|
||||||
|
|
||||||
|
// Generically fuzz inputs as CTAP commands.
|
||||||
|
fuzz_target!(|data: &[u8]| {
|
||||||
|
process_ctap_any_type(data);
|
||||||
|
});
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use fuzz_helper::split_assemble;
|
use fuzz_helper::split_assemble_hid_packets;
|
||||||
use libfuzzer_sys::fuzz_target;
|
use libfuzzer_sys::fuzz_target;
|
||||||
|
|
||||||
// Fuzzing HID packets splitting and assembling functions.
|
// Fuzzing HID packets splitting and assembling functions.
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
split_assemble(data);
|
split_assemble_hid_packets(data);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user