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

Code before:
                    CtapState::<R, CheckUserPresence>::PIN_PROTOCOL_VERSION,
                ]),
                max_credential_count_in_list: MAX_CREDENTIAL_COUNT_IN_LIST.map(|c| c as u64),
                // TODO(#106) update with version 2.1 of HMAC-secret
                max_credential_id_length: Some(CREDENTIAL_ID_SIZE as u64),
                transports: Some(vec![AuthenticatorTransport::Usb]),
                algorithms: Some(vec![ES256_CRED_PARAM]),
                default_cred_protect: DEFAULT_CRED_PROTECT,
                min_pin_length: self.persistent_store.min_pin_length()?,
                firmware_version: None,
                max_cred_blob_length: None,
                // TODO(kaczmarczyck) update when extension is implemented
                max_rp_ids_for_set_min_pin_length: None,
                remaining_discoverable_credentials: Some(
                    self.persistent_store.remaining_credentials()? as u64,
                ),
            },
        ))
    }

    fn process_client_pin(
        &mut self,
        client_pin_params: AuthenticatorClientPinParameters,
    ) -> Result<ResponseData, Ctap2StatusCode> {
        self.pin_protocol_v1.process_subcommand(
            self.rng,
            &mut self.persistent_store,
            client_pin_params,
        )
    }

    fn process_reset(
        &mut self,
        cid: ChannelID,
        now: ClockValue,
    ) -> Result<ResponseData, Ctap2StatusCode> {
        // Resets are only possible in the first 10 seconds after booting.
        // TODO(kaczmarczyck) 2.1 allows Reset after Reset and 15 seconds?
        self.check_command_permission(now)?;
        match &self.stateful_command_type {
            Some(StatefulCommand::Reset) => (),
            _ => return Err(Ctap2StatusCode::CTAP2_ERR_NOT_ALLOWED),
        }
        (self.check_user_presence)(cid)?;

        self.persistent_store.reset(self.rng)?;
        self.pin_protocol_v1.reset(self.rng);
        #[cfg(feature = "with_ctap1")]
        {
            self.u2f_up_state = U2fUserPresenceState::new(
                U2F_UP_PROMPT_TIMEOUT,

Review comment (security):
Just making sure this is alright with information leakage here. On one side we only expose some credentials according to some permissions and here we expose the count (including those that are not "visible") according to the same permissions?

Code after:
            AuthenticatorGetInfoResponse {
                versions: vec![
                    #[cfg(feature = "with_ctap1")]
                    String::from(U2F_VERSION_STRING),
                    String::from(FIDO2_VERSION_STRING),
                    String::from(FIDO2_1_VERSION_STRING),
                ],
                extensions: Some(vec![String::from("hmac-secret")]),
                aaguid: self.persistent_store.aaguid()?,
                options: Some(options_map),
                max_msg_size: Some(1024),
                pin_protocols: Some(vec![
                    CtapState::<R, CheckUserPresence>::PIN_PROTOCOL_VERSION,
                ]),
                max_credential_count_in_list: MAX_CREDENTIAL_COUNT_IN_LIST.map(|c| c as u64),
                // TODO(#106) update with version 2.1 of HMAC-secret
                max_credential_id_length: Some(CREDENTIAL_ID_SIZE as u64),
                transports: Some(vec![AuthenticatorTransport::Usb]),
                algorithms: Some(vec![ES256_CRED_PARAM]),
                default_cred_protect: DEFAULT_CRED_PROTECT,
                min_pin_length: self.persistent_store.min_pin_length()?,
                firmware_version: None,
                max_cred_blob_length: None,
                // TODO(kaczmarczyck) update when extension is implemented
                max_rp_ids_for_set_min_pin_length: None,
                remaining_discoverable_credentials: Some(
                    self.persistent_store.remaining_credentials()? as u64,
                ),
            },
        ))
    }

    fn process_client_pin(
        &mut self,
        client_pin_params: AuthenticatorClientPinParameters,
    ) -> Result<ResponseData, Ctap2StatusCode> {
        self.pin_protocol_v1.process_subcommand(
            self.rng,
            &mut self.persistent_store,
            client_pin_params,
        )
    }

    fn process_reset(
        &mut self,
        cid: ChannelID,
        now: ClockValue,
    ) -> Result<ResponseData, Ctap2StatusCode> {
        // Resets are only possible in the first 10 seconds after booting.
        // TODO(kaczmarczyck) 2.1 allows Reset after Reset and 15 seconds?
        self.check_command_permission(now)?;