From 85fe9cd29d62bacd5a062be7634b95f99dd493ab Mon Sep 17 00:00:00 2001 From: hcyang <100930165+hcyang-google@users.noreply.github.com> Date: Fri, 27 May 2022 10:34:38 +0800 Subject: [PATCH] Add sturctured get assertion and client pin fuzzers (#482) --- fuzz/Cargo.toml | 12 ++++++++++++ fuzz/fuzz_helper/src/lib.rs | 12 ++++++------ ...uzz_target_process_ctap2_client_pin_structured.rs | 10 ++++++++++ ..._target_process_ctap2_get_assertion_structured.rs | 10 ++++++++++ src/ctap/command.rs | 2 ++ src/ctap/data_formats.rs | 5 +++++ 6 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 fuzz/fuzz_targets/fuzz_target_process_ctap2_client_pin_structured.rs create mode 100644 fuzz/fuzz_targets/fuzz_target_process_ctap2_get_assertion_structured.rs diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index e6c8308..0e88562 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -36,12 +36,24 @@ path = "fuzz_targets/fuzz_target_process_ctap2_client_pin.rs" test = false doc = false +[[bin]] +name = "fuzz_target_process_ctap2_client_pin_structured" +path = "fuzz_targets/fuzz_target_process_ctap2_client_pin_structured.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]] +name = "fuzz_target_process_ctap2_get_assertion_structured" +path = "fuzz_targets/fuzz_target_process_ctap2_get_assertion_structured.rs" +test = false +doc = false + [[bin]] name = "fuzz_target_process_ctap2_make_credential" path = "fuzz_targets/fuzz_target_process_ctap2_make_credential.rs" diff --git a/fuzz/fuzz_helper/src/lib.rs b/fuzz/fuzz_helper/src/lib.rs index 9acf7ec..2d389f1 100644 --- a/fuzz/fuzz_helper/src/lib.rs +++ b/fuzz/fuzz_helper/src/lib.rs @@ -239,12 +239,12 @@ pub fn process_ctap_structured(data: &[u8], input_type: InputType) -> FuzzResult InputType::CborMakeCredentialParameter => Command::AuthenticatorMakeCredential( AuthenticatorMakeCredentialParameters::arbitrary(unstructured)?, ), - InputType::CborGetAssertionParameter => { - unimplemented!() - } - InputType::CborClientPinParameter => { - unimplemented!() - } + InputType::CborGetAssertionParameter => Command::AuthenticatorGetAssertion( + AuthenticatorGetAssertionParameters::arbitrary(unstructured)?, + ), + InputType::CborClientPinParameter => Command::AuthenticatorClientPin( + AuthenticatorClientPinParameters::arbitrary(unstructured)?, + ), InputType::Ctap1 => { unimplemented!() } diff --git a/fuzz/fuzz_targets/fuzz_target_process_ctap2_client_pin_structured.rs b/fuzz/fuzz_targets/fuzz_target_process_ctap2_client_pin_structured.rs new file mode 100644 index 0000000..bdd34d0 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_target_process_ctap2_client_pin_structured.rs @@ -0,0 +1,10 @@ +#![no_main] + +use fuzz_helper::{process_ctap_structured, InputType}; +use libfuzzer_sys::fuzz_target; + +// Fuzz inputs as CTAP2 client pin command parameters. +// The inputs will used to construct arbitrary client pin parameters. +fuzz_target!(|data: &[u8]| { + process_ctap_structured(data, InputType::CborClientPinParameter).ok(); +}); diff --git a/fuzz/fuzz_targets/fuzz_target_process_ctap2_get_assertion_structured.rs b/fuzz/fuzz_targets/fuzz_target_process_ctap2_get_assertion_structured.rs new file mode 100644 index 0000000..bdfa28b --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_target_process_ctap2_get_assertion_structured.rs @@ -0,0 +1,10 @@ +#![no_main] + +use fuzz_helper::{process_ctap_structured, InputType}; +use libfuzzer_sys::fuzz_target; + +// Fuzz inputs as CTAP2 get assertion command parameters. +// The inputs will used to construct arbitrary get assertion parameters. +fuzz_target!(|data: &[u8]| { + process_ctap_structured(data, InputType::CborGetAssertionParameter).ok(); +}); diff --git a/src/ctap/command.rs b/src/ctap/command.rs index 0255dd0..7f88cb6 100644 --- a/src/ctap/command.rs +++ b/src/ctap/command.rs @@ -246,6 +246,7 @@ impl TryFrom for AuthenticatorMakeCredentialParameters { } #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "fuzz", derive(Arbitrary))] pub struct AuthenticatorGetAssertionParameters { pub rp_id: String, pub client_data_hash: Vec, @@ -317,6 +318,7 @@ impl TryFrom for AuthenticatorGetAssertionParameters { } #[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "fuzz", derive(Arbitrary))] pub struct AuthenticatorClientPinParameters { pub pin_uv_auth_protocol: PinUvAuthProtocol, pub sub_command: ClientPinSubCommand, diff --git a/src/ctap/data_formats.rs b/src/ctap/data_formats.rs index 6de8c17..b73f58e 100644 --- a/src/ctap/data_formats.rs +++ b/src/ctap/data_formats.rs @@ -327,6 +327,7 @@ impl TryFrom for MakeCredentialExtensions { } #[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "fuzz", derive(Arbitrary))] pub struct GetAssertionExtensions { pub hmac_secret: Option, pub cred_blob: bool, @@ -364,6 +365,7 @@ impl TryFrom for GetAssertionExtensions { } #[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "fuzz", derive(Arbitrary))] pub struct GetAssertionHmacSecretInput { pub key_agreement: CoseKey, pub salt_enc: Vec, @@ -437,6 +439,7 @@ impl TryFrom for MakeCredentialOptions { } #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "fuzz", derive(Arbitrary))] pub struct GetAssertionOptions { pub up: bool, pub uv: bool, @@ -723,6 +726,7 @@ impl PublicKeyCredentialSource { // The COSE key is used for both ECDH and ECDSA public keys for transmission. #[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "fuzz", derive(Arbitrary))] pub struct CoseKey { x_bytes: [u8; ecdh::NBYTES], y_bytes: [u8; ecdh::NBYTES], @@ -976,6 +980,7 @@ impl TryFrom for PinUvAuthProtocol { #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(test, derive(IntoEnumIterator))] +#[cfg_attr(feature = "fuzz", derive(Arbitrary))] pub enum ClientPinSubCommand { GetPinRetries = 0x01, GetKeyAgreement = 0x02,