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

Code before:
        let mut credentials: Vec<(usize, PublicKeyCredentialSource)> = iter
            .filter(|(_, credential)| credential.credential_id == credential_id)
            .collect();
        iter_result?;
        if credentials.len() > 1 {
            return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
        }
        credentials
            .pop()
            .ok_or(Ctap2StatusCode::CTAP2_ERR_NO_CREDENTIALS)
    }

    /// Returns the first matching credential.
    ///
    /// Returns `None` if no credentials are matched or if `check_cred_protect` is set and the first
    /// matched credential requires user verification.
    pub fn find_credential(
        &self,
        rp_id: &str,
        credential_id: &[u8],
        check_cred_protect: bool,
    ) -> Result<Option<PublicKeyCredentialSource>, Ctap2StatusCode> {
        let credential = match self.find_credential_item(credential_id) {
            Err(Ctap2StatusCode::CTAP2_ERR_NO_CREDENTIALS) => return Ok(None),
            Err(e) => return Err(e),
            Ok(credential) => credential.1,
        };
        let is_protected = credential.cred_protect_policy
            == Some(CredentialProtectionPolicy::UserVerificationRequired);
        if credential.rp_id != rp_id || (check_cred_protect && is_protected) {
            return Ok(None);
        }
        Ok(Some(credential))
    }

    /// Stores or updates a credential.
    ///
    /// If a credential with the same RP id and user handle already exists, it is replaced.
    pub fn store_credential(
        &mut self,
        new_credential: PublicKeyCredentialSource,
    ) -> Result<(), Ctap2StatusCode> {
        // Holds the key of the existing credential if this is an update.
        let mut old_key = None;
        let min_key = key::CREDENTIALS.start;
        // Holds whether a key is used (indices are shifted by min_key).
        let mut keys = vec![false; MAX_SUPPORTED_RESIDENTIAL_KEYS];
        let mut iter_result = Ok(());
        let iter = self.iter_credentials(&mut iter_result)?;
        for (key, credential) in iter {
            if key < min_key

Review comment (security):
I think it's more readable to have:

```rust
Ok((_, credential)) => credential,
// or
Ok((_key, credential)) => credential,
```

Code after:
        let mut credentials: Vec<(usize, PublicKeyCredentialSource)> = iter
            .filter(|(_, credential)| credential.credential_id == credential_id)
            .collect();
        iter_result?;
        if credentials.len() > 1 {
            return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
        }
        credentials
            .pop()
            .ok_or(Ctap2StatusCode::CTAP2_ERR_NO_CREDENTIALS)
    }

    /// Returns the first matching credential.
    ///
    /// Returns `None` if no credentials are matched or if `check_cred_protect` is set and the first
    /// matched credential requires user verification.
    pub fn find_credential(
        &self,
        rp_id: &str,
        credential_id: &[u8],
        check_cred_protect: bool,
    ) -> Result<Option<PublicKeyCredentialSource>, Ctap2StatusCode> {
        let credential = match self.find_credential_item(credential_id) {
            Err(Ctap2StatusCode::CTAP2_ERR_NO_CREDENTIALS) => return Ok(None),
            Err(e) => return Err(e),
            Ok((_key, credential)) => credential,
        };
        let is_protected = credential.cred_protect_policy
            == Some(CredentialProtectionPolicy::UserVerificationRequired);
        if credential.rp_id != rp_id || (check_cred_protect && is_protected) {
            return Ok(None);
        }
        Ok(Some(credential))
    }

    /// Stores or updates a credential.
    ///
    /// If a credential with the same RP id and user handle already exists, it is replaced.
    pub fn store_credential(
        &mut self,
        new_credential: PublicKeyCredentialSource,
    ) -> Result<(), Ctap2StatusCode> {
        // Holds the key of the existing credential if this is an update.
        let mut old_key = None;
        let min_key = key::CREDENTIALS.start;
        // Holds whether a key is used (indices are shifted by min_key).
        let mut keys = vec![false; MAX_SUPPORTED_RESIDENTIAL_KEYS];
        let mut iter_result = Ok(());
        let iter = self.iter_credentials(&mut iter_result)?;
        for (key, credential) in iter {
            if key < min_key