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

Code before:
    type Error = Ctap2StatusCode;

    fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
        match extract_integer(cbor_value)? {
            ES256_ALGORITHM => Ok(SignatureAlgorithm::ES256),
            _ => Ok(SignatureAlgorithm::Unknown),
        }
    }
}

/// The level of protection granted by the credProtect extension.
///
/// This level applies to resident credentials. The levels have the following
/// implications:
///
/// UserVerificationOptional
/// The credential is always discoverable, as if it had no protection level.
///
/// UserVerificationOptionalWithCredentialIdList
/// The credential is discoverable with
/// - an allowList,
/// - an excludeList,
/// - user verification.
///
/// UserVerificationRequired
/// The credentials is discoverable with user verification only.
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(test, derive(IntoEnumIterator))]
pub enum CredentialProtectionPolicy {
    UserVerificationOptional = 0x01,
    UserVerificationOptionalWithCredentialIdList = 0x02,
    UserVerificationRequired = 0x03,
}

impl From<CredentialProtectionPolicy> for cbor::Value {
    fn from(policy: CredentialProtectionPolicy) -> Self {
        (policy as i64).into()
    }
}

impl TryFrom<cbor::Value> for CredentialProtectionPolicy {
    type Error = Ctap2StatusCode;

    fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
        match extract_integer(cbor_value)? {
            0x01 => Ok(CredentialProtectionPolicy::UserVerificationOptional),
            0x02 => Ok(CredentialProtectionPolicy::UserVerificationOptionalWithCredentialIdList),
            0x03 => Ok(CredentialProtectionPolicy::UserVerificationRequired),
            _ => Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE),
        }
    }

Review comment (suggestion):
Those documentation should be directly on the enum values.

```rust
/// Documentation of Foo
enum Foo {
    /// Documentation of Bar
    Bar,
    /// Documentation of Baz
    Baz,
}
```

Code after:
    type Error = Ctap2StatusCode;

    fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
        match extract_integer(cbor_value)? {
            ES256_ALGORITHM => Ok(SignatureAlgorithm::ES256),
            _ => Ok(SignatureAlgorithm::Unknown),
        }
    }
}

/// The credProtect extension's policies for resident credentials.
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(test, derive(IntoEnumIterator))]
pub enum CredentialProtectionPolicy {
    /// The credential is always discoverable, as if it had no protection level.
    UserVerificationOptional = 0x01,
    /// The credential is discoverable with
    /// - an allowList,
    /// - an excludeList,
    /// - user verification.
    UserVerificationOptionalWithCredentialIdList = 0x02,
    /// The credentials is discoverable with user verification only.
    UserVerificationRequired = 0x03,
}

impl From<CredentialProtectionPolicy> for cbor::Value {
    fn from(policy: CredentialProtectionPolicy) -> Self {
        (policy as i64).into()
    }
}

impl TryFrom<cbor::Value> for CredentialProtectionPolicy {
    type Error = Ctap2StatusCode;

    fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
        match extract_integer(cbor_value)? {
            0x01 => Ok(CredentialProtectionPolicy::UserVerificationOptional),
            0x02 => Ok(CredentialProtectionPolicy::UserVerificationOptionalWithCredentialIdList),
            0x03 => Ok(CredentialProtectionPolicy::UserVerificationRequired),
            _ => Err(Ctap2StatusCode::CTAP2_ERR_CBOR_UNEXPECTED_TYPE),
        }
    }
}

// https://www.w3.org/TR/webauthn/#public-key-credential-source
//
// Note that we only use the WebAuthn definition as an example. This data-structure is not specified
// by FIDO. In particular we may choose how we serialize and deserialize it.
#[derive(Clone, Debug, PartialEq)]
pub struct PublicKeyCredentialSource {
    // TODO function to convert to / from Vec<u8>