Repository: google/OpenSK
File: src/ctap/mod.rs (Rust)

Code before:
        }
    }

    fn pin_uv_auth_precheck(
        &mut self,
        env: &mut impl Env,
        pin_uv_auth_param: &Option<Vec<u8>>,
        pin_uv_auth_protocol: Option<PinUvAuthProtocol>,
        channel: Channel,
    ) -> Result<(), Ctap2StatusCode> {
        if let Some(auth_param) = &pin_uv_auth_param {
            // This case was added in FIDO 2.1.
            if auth_param.is_empty() {
                check_user_presence(env, channel)?;
                if storage::pin_hash(env)?.is_none() {
                    return Err(Ctap2StatusCode::CTAP2_ERR_PIN_NOT_SET);
                } else {
                    return Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID);
                }
            }
            pin_uv_auth_protocol.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?;
        }
        Ok(())
    }

    fn check_cred_protect(
        &mut self,
        credential: &Option<PublicKeyCredentialSource>,
        has_uv: bool,
    ) -> bool {
        if let Some(credential) = credential {
            has_uv
                || !matches!(
                    credential.cred_protect_policy,
                    Some(CredentialProtectionPolicy::UserVerificationRequired),
                )
        } else {
            false
        }
    }

    fn process_make_credential(
        &mut self,
        env: &mut impl Env,
        make_credential_params: AuthenticatorMakeCredentialParameters,
        channel: Channel,
    ) -> Result<ResponseData, Ctap2StatusCode> {
        let AuthenticatorMakeCredentialParameters {
            client_data_hash,
            rp,
            user,

Review comment (security):
Maybe we can rename this function, to make its purpose clear. This policy check is only correct if performed for a credential coming from an allow list or exclude list. There is also the `is_discoverable` function that does the equivalent check for non-allow-listed credentials (rk=true) during GetAssertion. `check_listed_...` or something similar?

Code after:
        }
    }

    fn pin_uv_auth_precheck(
        &mut self,
        env: &mut impl Env,
        pin_uv_auth_param: &Option<Vec<u8>>,
        pin_uv_auth_protocol: Option<PinUvAuthProtocol>,
        channel: Channel,
    ) -> Result<(), Ctap2StatusCode> {
        if let Some(auth_param) = &pin_uv_auth_param {
            // This case was added in FIDO 2.1.
            if auth_param.is_empty() {
                check_user_presence(env, channel)?;
                if storage::pin_hash(env)?.is_none() {
                    return Err(Ctap2StatusCode::CTAP2_ERR_PIN_NOT_SET);
                } else {
                    return Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID);
                }
            }
            pin_uv_auth_protocol.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?;
        }
        Ok(())
    }

    fn check_cred_protect_for_listed_credential(
        &mut self,
        credential: &Option<PublicKeyCredentialSource>,
        has_uv: bool,
    ) -> bool {
        if let Some(credential) = credential {
            has_uv
                || !matches!(
                    credential.cred_protect_policy,
                    Some(CredentialProtectionPolicy::UserVerificationRequired),
                )
        } else {
            false
        }
    }

    fn process_make_credential(
        &mut self,
        env: &mut impl Env,
        make_credential_params: AuthenticatorMakeCredentialParameters,
        channel: Channel,
    ) -> Result<ResponseData, Ctap2StatusCode> {
        let AuthenticatorMakeCredentialParameters {
            client_data_hash,
            rp,
            user,