Move several types from ctap2-proto to fido-common

dev
Nick Zana 2 years ago
parent 186d017d07
commit 0fb2487154
No known key found for this signature in database
GPG Key ID: 936524EE913D6538

@ -1,38 +0,0 @@
pub mod enterprise {
#[repr(usize)]
#[derive(Clone, Copy)]
pub enum Kind {
/// > In this case, an enterprise attestation capable authenticator, on
/// > which enterprise attestation is enabled, upon receiving the
/// > enterpriseAttestation parameter with a value of 1 (or 2, see Note
/// > below) on a authenticatorMakeCredential command, will provide
/// > enterprise attestation to a non-updateable pre-configured RP ID
/// > list, as identified by the enterprise and provided to the
/// > authenticator vendor, which is "burned into" the authenticator by
/// > the vendor.
/// > If enterprise attestation is requested for any RP ID other than
/// > the pre-configured RP ID(s), the attestation returned along with
/// > the new credential is a regular privacy-preserving attestation,
/// > i.e., NOT an enterprise attestation.
VendorFacilitated = 1,
/// > In this case, an enterprise attestation capable authenticator on
/// > which enterprise attestation is enabled, upon receiving the
/// > enterpriseAttestation parameter with a value of 2 on a
/// > authenticatorMakeCredential command, will return an enterprise
/// > attestation. The platform is enterprise-managed and has already
/// > performed the necessary vetting of the RP ID.
PlatformManaged = 2,
}
}
/// > Attested credential data is a variable-length byte array added to the
/// > authenticator data when generating an attestation object for a given
/// > credential.
pub struct CredentialData {
/// > The AAGUID of the authenticator.
pub aaguid: [u8; 16],
/// The ID of the credential.
pub id: Vec<u8>,
/// The public key of the credential.
pub public_key: coset::CoseKey,
}

@ -1,7 +1,8 @@
use crate::authenticator::{client_pin::AuthProtocolVersion, Sha256Hash}; use crate::{authenticator::client_pin::AuthProtocolVersion, extensions};
use crate::Sha256Hash;
use bounded_vec::BoundedVec; use bounded_vec::BoundedVec;
use fido_common::credential::public_key; use fido_common::credential::public_key;
use std::{collections::{BTreeMap}, usize}; use std::{collections::BTreeMap, usize};
pub enum Error { pub enum Error {
OperationDenied, OperationDenied,
@ -44,7 +45,7 @@ pub struct Request<'a> {
pub allow_list: Option<&'a BoundedVec<&'a public_key::Descriptor, 1, { usize::MAX }>>, pub allow_list: Option<&'a BoundedVec<&'a public_key::Descriptor, 1, { usize::MAX }>>,
/// > Parameters to influence authenticator operation. These parameters /// > Parameters to influence authenticator operation. These parameters
/// > might be authenticator specific. /// > might be authenticator specific.
pub extensions: Option<&'a BTreeMap<fido_common::extension::Identifier, &'a [u8]>>, pub extensions: Option<&'a BTreeMap<extensions::Identifier, &'a [u8]>>,
/// > Parameters to influence authenticator operation. /// > Parameters to influence authenticator operation.
pub options: Option<&'a BTreeMap<OptionKey, bool>>, pub options: Option<&'a BTreeMap<OptionKey, bool>>,
pub pin_uv_auth_param: Option<&'a [u8]>, pub pin_uv_auth_param: Option<&'a [u8]>,

@ -1,4 +1,4 @@
use std::collections::{BTreeSet}; use std::collections::BTreeSet;
use bounded_integer::BoundedUsize; use bounded_integer::BoundedUsize;
@ -26,7 +26,7 @@ pub enum Request<'a> {
version: AuthProtocolVersion, version: AuthProtocolVersion,
}, },
SetPin { SetPin {
key_agreement: &'a KeyAgreement, key_agreement: &'a coset::CoseKey,
new_pin_encrypted: &'a [u8], new_pin_encrypted: &'a [u8],
pin_uv_auth_param: &'a [u8], pin_uv_auth_param: &'a [u8],
}, },
@ -38,38 +38,25 @@ pub enum Request<'a> {
}, },
GetPinToken { GetPinToken {
version: AuthProtocolVersion, version: AuthProtocolVersion,
key_agreement: &'a KeyAgreement, key_agreement: &'a coset::CoseKey,
pin_hash_encrypted: &'a [u8], pin_hash_encrypted: &'a [u8],
}, },
GetPinUvAuthTokenUsingUvWithPermissions { GetPinUvAuthTokenUsingUvWithPermissions {
version: AuthProtocolVersion, version: AuthProtocolVersion,
key_agreement: &'a KeyAgreement, key_agreement: &'a coset::CoseKey,
permissions: &'a BTreeSet<Permission>, // TODO: Enforce non-empty set? permissions: &'a BTreeSet<Permission>, // TODO: Enforce non-empty set?
relying_party_id: Option<usize>, relying_party_id: Option<usize>,
}, },
GetUvRetries, GetUvRetries,
GetPinUvAuthTokenUsingPinWithPermissions { GetPinUvAuthTokenUsingPinWithPermissions {
version: AuthProtocolVersion, version: AuthProtocolVersion,
key_agreement: &'a KeyAgreement, key_agreement: &'a coset::CoseKey,
pin_hash_encrypted: usize, pin_hash_encrypted: usize,
permissions: &'a BTreeSet<Permission>, // TODO: Enforce non-empty set? permissions: &'a BTreeSet<Permission>, // TODO: Enforce non-empty set?
relying_party_id: Option<usize>, relying_party_id: Option<usize>,
}, },
} }
/// The [`Ctap2Device::client_pin`] command enforces several restrictions on the
/// COSE key used in a request and response. The restrictions are as follows:
///
/// > This COSE_Key-encoded public key MUST contain the optional "`alg`"
/// > parameter and MUST NOT contain any other optional parameters. The "`alg`"
/// > parameter MUST contain a `COSEAlgorithmIdentifier` value.
// This seems like it should be an enum where each `KeyType` variant has its own
// parameters? `coset` uses a CBOR map directly
pub struct KeyAgreement {
pub kty: coset::KeyType,
pub alg: Option<coset::Algorithm>,
}
pub enum PinUvAuthToken { pub enum PinUvAuthToken {
Short([u8; 16]), Short([u8; 16]),
Long([u8; 32]), Long([u8; 32]),
@ -81,10 +68,10 @@ pub enum Response {
power_cycle_state: Option<usize>, power_cycle_state: Option<usize>,
}, },
GetKeyAgreement { GetKeyAgreement {
key_agreement: KeyAgreement, key_agreement: coset::CoseKey,
}, },
SetPin { SetPin {
key_agreement: KeyAgreement, key_agreement: coset::CoseKey,
new_pin_encrypted: [u8; 64], new_pin_encrypted: [u8; 64],
pin_uv_auth_param: (), pin_uv_auth_param: (),
}, },

@ -1,6 +1,9 @@
use crate::authenticator::{self, client_pin, Sha256Hash}; use crate::{
use fido_common::{credential::public_key, extension}; authenticator::{self, client_pin},
use std::collections::{HashMap, BTreeMap}; extensions, Sha256Hash,
};
use fido_common::{attestation, credential::public_key};
use std::collections::{BTreeMap, HashMap};
pub enum Error { pub enum Error {
OperationDenied, OperationDenied,
@ -61,7 +64,7 @@ pub struct Request<'a> {
pub exclude_list: Option<&'a [&'a public_key::Descriptor]>, pub exclude_list: Option<&'a [&'a public_key::Descriptor]>,
/// > Parameters to influence authenticator operation, as specified in /// > Parameters to influence authenticator operation, as specified in
/// > [WebAuthn]. These parameters might be authenticator specific. /// > [WebAuthn]. These parameters might be authenticator specific.
pub extensions: Option<&'a HashMap<extension::Identifier, Vec<u8>>>, pub extensions: Option<&'a HashMap<extensions::Identifier, Vec<u8>>>,
pub options: Option<&'a BTreeMap<OptionKey, bool>>, pub options: Option<&'a BTreeMap<OptionKey, bool>>,
pub pin_uv_auth_param: &'a [u8], pub pin_uv_auth_param: &'a [u8],
/// > PIN/UV protocol version selected by platform. /// > PIN/UV protocol version selected by platform.
@ -78,7 +81,7 @@ pub struct Request<'a> {
/// > attestation batching may not apply to the results of this operation /// > attestation batching may not apply to the results of this operation
/// > and the platform is requesting an enterprise attestation that includes /// > and the platform is requesting an enterprise attestation that includes
/// > uniquely identifying information. /// > uniquely identifying information.
pub enterprise_attestation: Option<crate::attestation::enterprise::Kind>, pub enterprise_attestation: Option<attestation::enterprise::Kind>,
} }
pub struct Response { pub struct Response {
@ -94,5 +97,5 @@ pub struct Response {
pub large_blob_key: Option<Vec<u8>>, pub large_blob_key: Option<Vec<u8>>,
/// > A map, keyed by extension identifiers, to unsigned outputs of /// > A map, keyed by extension identifiers, to unsigned outputs of
/// > extensions, if any. /// > extensions, if any.
pub unsigned_extension_outputs: Option<BTreeMap<extension::Identifier, Vec<u8>>>, pub unsigned_extension_outputs: Option<BTreeMap<extensions::Identifier, Vec<u8>>>,
} }

@ -1,7 +1,4 @@
use crate::{ use crate::{authenticator::client_pin, extensions::cred_protect, Sha256Hash};
authenticator::{client_pin, Sha256Hash},
extensions::cred_protect,
};
use fido_common::credential::public_key; use fido_common::credential::public_key;
pub type PinUvAuthParam = [u8; 16]; pub type PinUvAuthParam = [u8; 16];
@ -93,7 +90,7 @@ pub struct Credential {
/// A description of the public key associated with the credential. /// A description of the public key associated with the credential.
pub credential_id: public_key::Descriptor, pub credential_id: public_key::Descriptor,
/// The public key associated with the credential. /// The public key associated with the credential.
pub public_key: coset::CoseKey, // TODO: Is this the right set of parameters for cosekey? pub public_key: Vec<u8>, // TODO: Replace arbitrary bytes with parsed key type
/// Indicates the level of user verification the authenticator requires for /// Indicates the level of user verification the authenticator requires for
/// this credential. /// this credential.
pub credential_protection_policy: cred_protect::Policy, pub credential_protection_policy: cred_protect::Policy,

@ -1,12 +1,12 @@
use crate::authenticator::client_pin::AuthProtocolVersion; use crate::authenticator::client_pin::AuthProtocolVersion;
use crate::authenticator::Transport;
use crate::extensions;
use bounded_vec::BoundedVec; use bounded_vec::BoundedVec;
use fido_common::credential::public_key; use fido_common::credential::public_key;
use fido_common::{registry, Transport}; use fido_common::registry;
use std::collections::{BTreeSet, BTreeMap}; use std::collections::{BTreeMap, BTreeSet};
use std::num::NonZeroUsize;
use std::usize; use std::usize;
use std::{
num::NonZeroUsize,
};
/// A usize with a minimum value of N /// A usize with a minimum value of N
#[derive(PartialEq, Eq)] #[derive(PartialEq, Eq)]
@ -15,13 +15,7 @@ pub struct UsizeN<const N: usize>(bounded_integer::BoundedUsize<N, { usize::MAX
/// > data type byte string and identifying the authenticator model, i.e. /// > data type byte string and identifying the authenticator model, i.e.
/// > identical values mean that they refer to the same authenticator model and /// > identical values mean that they refer to the same authenticator model and
/// > different values mean they refer to different authenticator models. /// > different values mean they refer to different authenticator models.
pub struct Aaguid([u8; 16]); pub type Aaguid = [u8; 16];
impl Aaguid {
pub const fn from(bytes: [u8; 16]) -> Self {
Self(bytes)
}
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, PartialOrd, Ord)] #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, PartialOrd, Ord)]
pub enum Version { pub enum Version {
@ -192,7 +186,7 @@ pub struct Info {
/// > List of supported CTAP versions. /// > List of supported CTAP versions.
pub versions: BTreeSet<Version>, pub versions: BTreeSet<Version>,
/// > List of supported extensions. /// > List of supported extensions.
pub extensions: Option<BTreeSet<fido_common::extension::Identifier>>, pub extensions: Option<BTreeSet<extensions::Identifier>>,
/// > The claimed AAGUID. /// > The claimed AAGUID.
pub aaguid: Aaguid, pub aaguid: Aaguid,
/// > List of supported options. /// > List of supported options.

@ -1,6 +1,4 @@
use crate::attestation; pub use fido_common::authenticator::*;
use fido_common::extension;
use std::collections::{BTreeMap};
pub mod assertion; pub mod assertion;
pub mod bio_enrollment; pub mod bio_enrollment;
@ -11,25 +9,3 @@ pub mod device;
pub mod reset; pub mod reset;
pub mod selection; pub mod selection;
/// SHA 256 hash values are 32 bytes long.
pub struct Sha256Hash(pub [u8; 32]);
/// > The authenticator data structure encodes contextual bindings made by the
/// > authenticator. These bindings are controlled by the authenticator itself,
/// > and derive their trust from the `WebAuthn` Relying Party's assessment of
/// > the security properties of the authenticator. In one extreme case, the
/// > authenticator may be embedded in the client, and its bindings may be no
/// > more trustworthy than the client data. At the other extreme, the
/// > authenticator may be a discrete entity with high-security hardware and
/// > software, connected to the client over a secure channel. In both cases,
/// > the Relying Party receives the authenticator data in the same format, and
/// > uses its knowledge of the authenticator to make trust decisions.
pub struct Data {
/// > SHA-256 hash of the RP ID the credential is scoped to.
pub relying_party_id_hash: Sha256Hash,
pub user_is_present: bool,
pub user_is_verified: bool,
pub signature_counter: u32,
pub attested_credential_data: Option<attestation::CredentialData>,
pub extensions: Option<BTreeMap<extension::Identifier, Vec<u8>>>,
}

@ -1,3 +1,5 @@
pub use fido_common::extensions::*;
pub mod cred_protect; pub mod cred_protect;
/// The extension input parameters passed to the authenticator during a call to /// The extension input parameters passed to the authenticator during a call to

@ -8,9 +8,9 @@ pub mod prelude {
}, },
Ctap2_2Authenticator, Ctap2_2Authenticator,
}; };
pub use fido_common::Sha256Hash;
} }
pub mod attestation;
pub mod authenticator; pub mod authenticator;
pub mod extensions; pub mod extensions;
@ -49,26 +49,27 @@ pub trait Ctap2_2Authenticator {
/// > factory default state. /// > factory default state.
fn reset() -> Result<(), reset::Error>; fn reset() -> Result<(), reset::Error>;
fn bio_enrollment( // fn bio_enrollment(
request: bio_enrollment::Request, // request: bio_enrollment::Request,
) -> Result<bio_enrollment::Response, bio_enrollment::Error>; // ) -> Result<bio_enrollment::Response, bio_enrollment::Error>;
#[allow(clippy::missing_errors_doc)] // #[allow(clippy::missing_errors_doc)]
/// > This command is used by the platform to manage discoverable // > This command is used by the platform to manage discoverable
/// > credentials on the authenticator. // > credentials on the authenticator.
fn credential_management( // fn credential_management(
request: management::Request, // request: management::Request,
) -> Result<management::Response, management::Error>; // ) -> Result<management::Response, management::Error>;
#[allow(clippy::missing_errors_doc)] #[allow(clippy::missing_errors_doc)]
/// > This command allows the platform to let a user select a certain /// > This command allows the platform to let a user select a certain
/// > authenticator by asking for user presence. /// > authenticator by asking for user presence.
fn selection() -> Result<(), authenticator::selection::Error>; fn selection() -> Result<(), authenticator::selection::Error>;
fn large_blobs() -> Result<(), ()>; // fn large_blobs() -> Result<(), ()>;
#[allow(clippy::missing_errors_doc)] // #[allow(clippy::missing_errors_doc)]
/// > This command is used to configure various authenticator features // > This command is used to configure various authenticator features
/// > through the use of its subcommands. // > through the use of its subcommands.
fn authenticator_config(request: config::Request) -> Result<(), config::Error>; // fn authenticator_config(request: config::Request) -> Result<(),
// config::Error>;
} }

@ -7,6 +7,7 @@ edition = "2021"
[dependencies] [dependencies]
bounded-vec = { version = "0.7.1", features = ["serde"] } bounded-vec = { version = "0.7.1", features = ["serde"] }
coset = { version = "0.3.4", default-features = false }
serde = { version = "1", features = ["derive"], optional = true } serde = { version = "1", features = ["derive"], optional = true }
[features] [features]

@ -69,3 +69,42 @@ pub enum FormatIdentifier {
#[cfg_attr(feature = "serde", serde(rename = "none"))] #[cfg_attr(feature = "serde", serde(rename = "none"))]
None, None,
} }
pub mod enterprise {
#[repr(usize)]
#[derive(Clone, Copy)]
pub enum Kind {
/// > In this case, an enterprise attestation capable authenticator, on
/// > which enterprise attestation is enabled, upon receiving the
/// > enterpriseAttestation parameter with a value of 1 (or 2, see Note
/// > below) on a authenticatorMakeCredential command, will provide
/// > enterprise attestation to a non-updateable pre-configured RP ID
/// > list, as identified by the enterprise and provided to the
/// > authenticator vendor, which is "burned into" the authenticator by
/// > the vendor.
/// > If enterprise attestation is requested for any RP ID other than
/// > the pre-configured RP ID(s), the attestation returned along with
/// > the new credential is a regular privacy-preserving attestation,
/// > i.e., NOT an enterprise attestation.
VendorFacilitated = 1,
/// > In this case, an enterprise attestation capable authenticator on
/// > which enterprise attestation is enabled, upon receiving the
/// > enterpriseAttestation parameter with a value of 2 on a
/// > authenticatorMakeCredential command, will return an enterprise
/// > attestation. The platform is enterprise-managed and has already
/// > performed the necessary vetting of the RP ID.
PlatformManaged = 2,
}
}
/// > Attested credential data is a variable-length byte array added to the
/// > authenticator data when generating an attestation object for a given
/// > credential.
pub struct CredentialData {
/// > The AAGUID of the authenticator.
pub aaguid: [u8; 16],
/// The ID of the credential.
pub id: Vec<u8>,
/// The public key of the credential.
pub public_key: coset::CoseKey,
}

@ -0,0 +1,82 @@
use crate::{attestation, extensions, Sha256Hash};
use std::collections::BTreeMap;
pub enum Flags {}
/// > The authenticator data structure encodes contextual bindings made by the
/// > authenticator. These bindings are controlled by the authenticator itself,
/// > and derive their trust from the `WebAuthn` Relying Party's assessment of
/// > the security properties of the authenticator. In one extreme case, the
/// > authenticator may be embedded in the client, and its bindings may be no
/// > more trustworthy than the client data. At the other extreme, the
/// > authenticator may be a discrete entity with high-security hardware and
/// > software, connected to the client over a secure channel. In both cases,
/// > the Relying Party receives the authenticator data in the same format, and
/// > uses its knowledge of the authenticator to make trust decisions.
pub struct Data {
/// > SHA-256 hash of the RP ID the credential is scoped to.
pub relying_party_id_hash: Sha256Hash,
pub user_is_present: bool,
pub user_is_verified: bool,
pub signature_counter: u32,
pub attested_credential_data: Option<attestation::CredentialData>,
pub extensions: Option<BTreeMap<extensions::Identifier, Vec<u8>>>,
}
impl Data {
fn try_from(value: &[u8]) -> Option<Self> {
// 32 bytes: RP id hash
let rp_id = value.get(0..32)?.as_ref();
//
let flags = value.get(32)?;
None
}
}
impl TryFrom<&[u8]> for Data {
type Error = ();
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Self::try_from(value).ok_or(())
}
}
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
/// > Authenticators may implement various transports for communicating with
/// > clients. This enumeration defines hints as to how clients might
/// > communicate with a particular authenticator in order to obtain an
/// > assertion for a specific credential. Note that these hints represent the
/// > `WebAuthn` Relying Party's best belief as to how an authenticator may be
/// > reached. A Relying Party will typically learn of the supported transports
/// > for a public key credential via getTransports().
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(untagged))]
pub enum Transport {
/// > Indicates the respective authenticator can be contacted over removable
/// > USB.
#[cfg_attr(feature = "serde", serde(rename = "usb"))]
Usb,
/// > Indicates the respective authenticator can be contacted over Near
/// > Field Communication (NFC).
#[cfg_attr(feature = "serde", serde(rename = "nfc"))]
Nfc,
/// > Indicates the respective authenticator can be contacted over Bluetooth
/// > Smart (Bluetooth Low Energy / BLE).
#[cfg_attr(feature = "serde", serde(rename = "ble"))]
Ble,
/// > Indicates the respective authenticator can be contacted using a
/// > combination of (often separate) data-transport and proximity
/// > mechanisms. This supports, for example, authentication on a desktop
/// > computer using a smartphone.
#[cfg_attr(feature = "serde", serde(rename = "hybrid"))]
Hybrid,
/// > Indicates the respective authenticator is contacted using a client
/// > device-specific transport, i.e., it is a platform authenticator. These
/// > authenticators are not removable from the client device.
#[cfg_attr(feature = "serde", serde(rename = "internal"))]
Internal,
Unknown(String),
}

@ -1,7 +1,7 @@
use crate::registry::algorithms; use crate::registry::algorithms;
use crate::{credential, Transport}; use crate::{authenticator::Transport, credential};
use bounded_vec::BoundedVec; use bounded_vec::BoundedVec;
use std::collections::{BTreeSet}; use std::collections::BTreeSet;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

@ -1,43 +1,7 @@
pub mod authenticator;
pub mod attestation; pub mod attestation;
pub mod credential; pub mod credential;
pub mod extension; pub mod extensions;
pub mod registry; pub mod registry;
#[cfg(feature = "serde")] pub type Sha256Hash = [u8; 32];
use serde::{Deserialize, Serialize};
/// > Authenticators may implement various transports for communicating with
/// > clients. This enumeration defines hints as to how clients might
/// > communicate with a particular authenticator in order to obtain an
/// > assertion for a specific credential. Note that these hints represent the
/// > `WebAuthn` Relying Party's best belief as to how an authenticator may be
/// > reached. A Relying Party will typically learn of the supported transports
/// > for a public key credential via getTransports().
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(untagged))]
pub enum Transport {
/// > Indicates the respective authenticator can be contacted over removable
/// > USB.
#[cfg_attr(feature = "serde", serde(rename = "usb"))]
Usb,
/// > Indicates the respective authenticator can be contacted over Near
/// > Field Communication (NFC).
#[cfg_attr(feature = "serde", serde(rename = "nfc"))]
Nfc,
/// > Indicates the respective authenticator can be contacted over Bluetooth
/// > Smart (Bluetooth Low Energy / BLE).
#[cfg_attr(feature = "serde", serde(rename = "ble"))]
Ble,
/// > Indicates the respective authenticator can be contacted using a
/// > combination of (often separate) data-transport and proximity
/// > mechanisms. This supports, for example, authentication on a desktop
/// > computer using a smartphone.
#[cfg_attr(feature = "serde", serde(rename = "hybrid"))]
Hybrid,
/// > Indicates the respective authenticator is contacted using a client
/// > device-specific transport, i.e., it is a platform authenticator. These
/// > authenticators are not removable from the client device.
#[cfg_attr(feature = "serde", serde(rename = "internal"))]
Internal,
Unknown(String),
}

@ -1,5 +1,4 @@
use fido_common::{attestation::FormatIdentifier, credential::public_key}; use fido_common::{attestation::FormatIdentifier, credential::public_key};
use crate::{attestation, UserVerificationRequirement}; use crate::{attestation, UserVerificationRequirement};
/// > [This struct] supplies `get()` with the data it needs to generate an /// > [This struct] supplies `get()` with the data it needs to generate an

Loading…
Cancel
Save