Generate valid structure for MakeCredential params

* Add crate arbitrary as ctap's optional dependency, when feature "fuzz"
  is activated.

* Derive Arbitrary for all the necessary types in order to generate the
  concrete types from random bytes.

* Add a fuzz target that transforms the input to valid format for
  MakeCredential.
This commit is contained in:
Howard Yang
2022-03-14 16:16:50 +08:00
parent 12c5a419b4
commit 17ecd46b04
9 changed files with 79 additions and 4 deletions

View File

@@ -48,6 +48,12 @@ path = "fuzz_targets/fuzz_target_process_ctap2_make_credential.rs"
test = false
doc = false
[[bin]]
name = "fuzz_target_process_ctap2_make_credential_structured"
path = "fuzz_targets/fuzz_target_process_ctap2_make_credential_structured.rs"
test = false
doc = false
[[bin]]
name = "fuzz_target_split_assemble"
path = "fuzz_targets/fuzz_target_split_assemble.rs"

View File

@@ -11,5 +11,6 @@ embedded-time = "0.12.1"
libtock_drivers = { path = "../../third_party/libtock-drivers" }
crypto = { path = "../../libraries/crypto", features = ['std'] }
sk-cbor = { path = "../../libraries/cbor" }
ctap2 = { path = "../..", features = ['std'] }
ctap2 = { path = "../..", features = ["fuzz"] }
lang_items = { path = "../../third_party/lang-items", features = ['std'] }
arbitrary = { version = "0.4.7", features = ["derive"] }

View File

@@ -16,17 +16,18 @@
// `libtock_alloc_init` symbol.
extern crate lang_items;
use arbitrary::{Arbitrary, Unstructured};
use arrayref::array_ref;
use core::convert::TryFrom;
use ctap2::clock::CtapInstant;
use ctap2::ctap::cbor_read;
use ctap2::ctap::command::{
AuthenticatorClientPinParameters, AuthenticatorGetAssertionParameters,
AuthenticatorMakeCredentialParameters,
AuthenticatorMakeCredentialParameters, Command,
};
use ctap2::ctap::hid::{
ChannelID, CtapHidCommand, HidPacket, HidPacketIterator, Message, MessageAssembler,
};
use ctap2::ctap::{cbor_read, Channel, CtapState};
use ctap2::env::test::TestEnv;
use ctap2::{Ctap, Transport};
@@ -166,6 +167,39 @@ pub fn process_ctap_specific_type(data: &[u8], input_type: InputType) {
process_message(&command, &mut ctap);
}
pub fn process_ctap_structured(data: &[u8], input_type: InputType) -> arbitrary::Result<()> {
let unstructured = &mut Unstructured::new(data);
let mut env = TestEnv::new();
let mut state = CtapState::new(&mut env, CtapInstant::new(0));
let command = match input_type {
InputType::CborMakeCredentialParameter => Command::AuthenticatorMakeCredential(
AuthenticatorMakeCredentialParameters::arbitrary(unstructured)?,
),
InputType::CborGetAssertionParameter => {
unimplemented!()
}
InputType::CborClientPinParameter => {
unimplemented!()
}
InputType::Ctap1 => {
unimplemented!()
}
};
state
.process_parsed_command(
&mut env,
command,
Channel::MainHid(ChannelID::arbitrary(unstructured)?),
CtapInstant::new(0),
)
.ok();
Ok(())
}
// Splits the given data as HID packets and reassembles it, verifying that the original input message is reconstructed.
pub fn split_assemble_hid_packets(data: &[u8]) {
let message = raw_to_message(data);

View File

@@ -0,0 +1,10 @@
#![no_main]
use fuzz_helper::{process_ctap_structured, InputType};
use libfuzzer_sys::fuzz_target;
// Fuzz inputs as CTAP2 make credential command parameters.
// The inputs will used to construct arbitrary make credential parameters.
fuzz_target!(|data: &[u8]| {
process_ctap_structured(data, InputType::CborMakeCredentialParameter).ok();
});