Add ctap2-proto crate

The ctap2-proto crate defines the Ctap2_2Authenticator trait, which
implements the latest CTAP spec.
dev
Nick Zana 1 year ago
parent 1ea1e3b740
commit 4082fbb437
No known key found for this signature in database
GPG Key ID: 936524EE913D6538

@ -0,0 +1,2 @@
/target
/Cargo.lock

@ -0,0 +1,17 @@
[package]
name = "ctap2-proto"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
fido-common = { path = "../fido-common" }
bounded-integer = { version = "0.5.3", features = ["types", "std"] }
bounded-vec = "0.7.1"
coset = "0.3.3"
indexmap = "1.9.2"
serde = { version = "1.0", features = ["derive"], optional = true }
[features]
serde = ["dep:serde", "bounded-vec/serde", "fido-common/serde"]

@ -0,0 +1,4 @@
In *Client to Authenticator Protocol* terminology, this library is intended for
use between the [*client
platform*](https://www.w3.org/TR/webauthn-2/#client-platform) and
[*authenticator*](https://www.w3.org/TR/webauthn-2/#authenticator).

@ -0,0 +1,38 @@
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,84 @@
use crate::authenticator::{client_pin::AuthProtocolVersion, Sha256Hash};
use bounded_vec::BoundedVec;
use fido_common::credential::public_key;
use std::{collections::HashMap, usize};
pub enum Error {
OperationDenied,
PinNotSet,
PinInvalid,
InvalidParameter,
MissingParameter,
InvalidOption,
UnsupportedOption,
PinUvAuthTokenRequired,
PinAuthInvalid,
UserActionTimeout,
PinBlocked,
NoCredentials,
}
/// > The following option keys are defined for use in
/// > [`assertion::get::Request`]'s `options` parameter.
pub enum OptionKey {
/// > user presence: Instructs the authenticator to require user consent
/// > to complete the operation.
UserPrecense,
/// > user verification: If true, instructs the authenticator to require
/// > a user-verifying gesture in order to complete the request.
/// > Examples of such gestures are fingerprint scan or a PIN.
UserVerification,
}
/// Request parameters for [`Ctap2Device::get_assertion`] operation.
#[derive(Clone, Copy)]
pub struct Request<'a> {
/// > relying party identifier
pub relying_party_id: &'a str,
/// > Hash of the serialized client data collected by the host.
pub client_data_hash: &'a Sha256Hash,
/// > An array of [`public_key::Descriptor`] structures, each denoting a
/// > credential, as specified in `WebAuthn`. A platform MUST NOT send
/// > an empty `allowList`—if it would be empty it MUST be omitted. If
/// > this parameter is present the authenticator MUST only generate an
/// > assertion using one of the denoted credentials.
// TODO: Is there an equivalent of Vec1 but for a slice?
pub allow_list: Option<&'a BoundedVec<public_key::Descriptor, 1, { usize::MAX }>>,
/// > Parameters to influence authenticator operation. These parameters
/// > might be authenticator specific.
pub extensions: Option<&'a HashMap<fido_common::extension::Identifier, Vec<u8>>>,
/// > Parameters to influence authenticator operation.
pub options: Option<&'a HashMap<OptionKey, bool>>,
pub pin_uv_auth_param: Option<&'a [u8]>,
/// > PIN/UV protocol version selected by platform.
pub pin_uv_auth_protocol_version: Option<AuthProtocolVersion>,
}
/// Response structure for [`Ctap2Device::get_assertion`] operation.
pub struct Response {
/// > PublicKeyCredentialDescriptor structure containing the credential
/// > identifier whose private key was used to generate the assertion.
pub credential: public_key::Descriptor,
/// > The signed-over contextual bindings made by the authenticator, as
/// > specified in [WebAuthn].
pub auth_data: Vec<u8>,
/// > The assertion signature produced by the authenticator, as
/// > specified in [WebAuthn].
pub signature: Vec<u8>,
/// > [`public_key::UserEntity`] structure containing the user account
/// > information
pub user: Option<public_key::UserEntity>,
/// > Total number of account credentials for the RP. Optional; defaults
/// > to one. This member is required when more than one credential is
/// > found for an RP, and the authenticator does not have a display or
/// > the UV & UP flags are false.
pub number_of_credentials: Option<usize>,
/// > Indicates that a credential was selected by the user via
/// > interaction directly with the authenticator, and thus the platform
/// > does not need to confirm the credential.
pub user_selected: Option<bool>,
/// > The contents of the associated `largeBlobKey` if present for the
/// > asserted credential, and if `largeBlobKey` was true in the
/// > extensions input.
pub large_blob_key: Option<Vec<u8>>,
}

@ -0,0 +1,3 @@
pub enum Request {}
pub enum Response {}

@ -0,0 +1,157 @@
use std::collections::HashSet;
use bounded_integer::BoundedUsize;
#[derive(Clone, Copy)]
pub enum AuthProtocolVersion {
One,
Two,
}
pub enum Subcommand {
GetPinRetries,
GetKeyAgreement,
SetPin,
ChangePin,
GetPinToken,
GetPinUvAuthTokenUsingUvWithPermissions,
GetUvRetries,
GetPinUvAuthTokenUsingPinWithPermissions,
}
#[derive(Clone, Copy)]
pub enum Request<'a> {
GetPinRetries,
GetKeyAgreement {
version: AuthProtocolVersion,
},
SetPin {
key_agreement: &'a KeyAgreement,
new_pin_encrypted: &'a [u8],
pin_uv_auth_param: &'a [u8],
},
ChangePin {
version: AuthProtocolVersion,
pin_hash_encrypted: &'a [u8],
new_pin_encrypted: &'a [u8],
pin_uv_auth_param: &'a [u8],
},
GetPinToken {
version: AuthProtocolVersion,
key_agreement: &'a KeyAgreement,
pin_hash_encrypted: &'a [u8],
},
GetPinUvAuthTokenUsingUvWithPermissions {
version: AuthProtocolVersion,
key_agreement: &'a KeyAgreement,
permissions: &'a HashSet<Permission>, // TODO: Enforce non-empty hashset? HashSet1?
relying_party_id: Option<usize>,
},
GetUvRetries,
GetPinUvAuthTokenUsingPinWithPermissions {
version: AuthProtocolVersion,
key_agreement: &'a KeyAgreement,
pin_hash_encrypted: usize,
permissions: &'a HashSet<Permission>, // TODO: Enforce non-empty hashset? HashSet1?
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 {
Short([u8; 16]),
Long([u8; 32]),
}
pub enum Response {
GetPinRetries {
pin_retries: usize,
power_cycle_state: Option<usize>,
},
GetKeyAgreement {
key_agreement: KeyAgreement,
},
SetPin {
key_agreement: KeyAgreement,
new_pin_encrypted: [u8; 64],
pin_uv_auth_param: (),
},
ChangePin,
GetPinToken,
GetPinUvAuthTokenUsingUvWithPermissions {
/// > The pinUvAuthToken, encrypted by calling encrypt with the shared
/// > secret as the key.
pin_uv_auth_token: PinUvAuthToken,
},
GetUvRetries {
/// > Number of uv attempts remaining before lockout.
///
/// > The `uv_retries` counter represents the number of user
/// > verification attempts left before built-in user verification is
/// > disabled.
uv_retries: BoundedUsize<1, 25>,
},
GetPinUvAuthTokenUsingPinWithPermissions {
/// > The pinUvAuthToken, encrypted by calling encrypt with the shared
/// > secret as the key.
pin_uv_auth_token: PinUvAuthToken,
},
}
pub enum Error {
MissingParameter,
InvalidParameter,
PinAuthInvalid,
PinPolicyViolation,
PinBlocked,
PinAuthBlocked,
PinInvalid,
OperationDenied,
UnauthorizedPermission,
NotAllowed,
UserVerificationBlocked,
UserActionTimeout,
UserVerificationInvalid,
}
/// > When obtaining a `pinUvAuthToken`, the platform requests permissions
/// > appropriate for the operations it intends to perform. Consequently, the
/// > `pinUvAuthToken` can only be used for those operations.
#[derive(Clone, Copy)]
pub enum Permission {
/// > This allows the `pinUvAuthToken` to be used for
/// > `authenticatorMakeCredential` operations with the provided `rpId`
/// > parameter.
MakeCredential,
/// > This allows the `pinUvAuthToken` to be used for
/// > `authenticatorGetAssertion` operations with the provided `rpId`
/// > parameter.
GetAssertion,
/// > This allows the `pinUvAuthToken` to be used with the
/// > `authenticatorCredentialManagement` command. The `rpId` parameter is
/// > optional, if it is present, the `pinUvAuthToken` can only be used for
/// > Credential Management operations on Credentials associated with that
/// > RP ID.
CredentialManagement,
/// > This allows the `pinUvAuthToken` to be used with the
/// > `authenticatorBioEnrollment` command.
BiometricEnrollment,
/// > This allows the `pinUvAuthToken` to be used with the
/// > `authenticatorLargeBlobs` command.
LargeBlobWrite,
/// > This allows the `pinUvAuthToken` to be used with the
/// > `authenticatorConfig` command.
AuthenticatorConfiguration,
}

@ -0,0 +1,52 @@
use std::collections::HashMap;
use super::client_pin::AuthProtocolVersion;
#[derive(Clone, Copy)]
pub enum Request<'a> {
/// > This `enableEnterpriseAttestation` subcommand is only implemented if
/// > the enterprise attestation feature is supported.
EnableEnterpriseAttestation {
pin_uv_auth_protocol: AuthProtocolVersion,
pin_uv_auth_param: &'a [u8], // TODO: Is using a more specific type possible?
},
/// > This `toggleAlwaysUv` subcommand is only implemented if the Always
/// > Require User Verification feature is supported.
ToggleAlwaysUserVerification {
pin_uv_auth_protocol: AuthProtocolVersion,
pin_uv_auth_param: &'a [u8], // TODO: Is using a more specific type possible?
},
/// > This `setMinPINLength` subcommand is only implemented if the
/// > `setMinPINLength` option ID is present.
/// >
/// > This command sets the minimum PIN length in Unicode code points to be
/// > enforced by the authenticator while changing/setting up a ClientPIN.
SetMinPinLength {
pin_uv_auth_protocol: AuthProtocolVersion,
pin_uv_auth_param: &'a [u8], // TODO: Is using a more specific type possible?
},
/// > This subCommand allows vendors to test authenticator configuration
/// > features.
/// >
/// > This `vendorPrototype` subcommand is only implemented if the
/// > `vendorPrototypeConfigCommands` member in the `authenticatorGetInfo`
/// > response is present.
/// >
/// > Note: The `vendorPrototype` subCommand is reserved for vendor-specific
/// > authenticator configuration and experimentation. Platforms are not
/// > expected to generally utilize this subCommand.
VendorPrototype {
vendor_command_id: usize,
params: &'a HashMap<Vec<u8>, Vec<u8>>, /* TODO: Is the character space of keys
* restricted to UTF-8? */
pin_uv_auth_protocol: AuthProtocolVersion,
pin_uv_auth_param: &'a [u8], // TODO: Is using a more specific type possible?
},
}
pub enum Error {
MissingParameter,
InvalidParameter,
PinUvAuthTokenRequired,
PinAuthInvalid,
}

@ -0,0 +1,97 @@
use crate::{
attestation,
authenticator::{self, client_pin, Sha256Hash},
};
use fido_common::credential::public_key;
use indexmap::IndexSet;
use std::collections::HashMap;
pub enum Error {
OperationDenied,
PinNotSet,
PinInvalid,
InvalidParameter,
MissingParameter,
UnsupportedAlgorithm,
InvalidOption,
UnsupportedOption,
PinUvAuthTokenRequired,
PinAuthInvalid,
UserActionTimeout,
PinBlocked,
CredentialExcluded,
KeyStoreFull,
}
/// > The following option keys are defined for use in
/// > `authenticatorMakeCredential`'s `options` parameter.
pub enum OptionKey {
/// > Specifies whether this credential is to be discoverable or
/// > not.
Discoverable,
/// > user presence: Instructs the authenticator to require user
/// > consent
/// > to complete the operation.
UserPresence,
/// > user verification: If true, instructs the authenticator to require a
/// > user-verifying gesture in order to complete the request. Examples of
/// > such gestures are fingerprint scan or a PIN.
UserVerification,
}
/// Input parameters for [`Ctap2Device::make_credential`] operation.
#[derive(Clone, Copy)]
pub struct Request<'a> {
/// > Hash of the ClientData contextual binding specified by host.
pub client_data_hash: &'a Sha256Hash,
/// > This PublicKeyCredentialRpEntity data structure describes a
/// > Relying Party with which the new public key credential will be
/// > associated.
pub relying_party: &'a public_key::RelyingPartyEntity,
/// > ... describes the user account to which the new public key
/// > credential will be associated at the RP.
pub user: &'a public_key::UserEntity,
/// > [Set] of supported algorithms for credential generation, as
/// > specified in [WebAuthn]. The array is ordered from most preferred
/// > to least preferred...
pub public_key_credential_params: &'a IndexSet<public_key::Parameters>,
/// > An array of PublicKeyCredentialDescriptor structures, as specified
/// > in [WebAuthn]. The authenticator returns an error if the
/// > authenticator already contains one of the credentials enumerated
/// > in this array. This allows RPs to limit the creation of multiple
/// > credentials for the same account on a single authenticator.
pub exclude_list: Option<&'a [&'a public_key::Descriptor]>,
/// > Parameters to influence authenticator operation, as specified in
/// > [WebAuthn]. These parameters might be authenticator specific.
pub extensions: Option<&'a HashMap<fido_common::extension::Identifier, Vec<u8>>>,
pub options: Option<&'a HashMap<OptionKey, bool>>,
pub pin_uv_auth_param: &'a [u8],
/// > PIN/UV protocol version selected by platform.
pub pin_uv_auth_protocol_version: Option<client_pin::AuthProtocolVersion>,
/// > An authenticator supporting this enterprise attestation feature is
/// > enterprise attestation capable and signals its support via the `ep`
/// > Option ID in the `authenticatorGetInfo` command response.
/// >
/// > If the `enterpriseAttestation` parameter is absent, attestations
/// > privacy characteristics are unaffected, regardless of whether the
/// > enterprise attestation feature is presently enabled.
/// >
/// > If present with a valid value, the usual privacy concerns around
/// > attestation batching may not apply to the results of this operation
/// > and the platform is requesting an enterprise attestation that includes
/// > uniquely identifying information.
pub enterprise_attestation: Option<attestation::enterprise::Kind>,
}
pub struct Response {
pub format: fido_common::attestation::FormatIdentifier,
pub authenticator_data: authenticator::Data,
/// > Indicates whether an enterprise attestation was returned for this
/// > credential. If `epAtt` is absent or present and set to false, then an
/// > enterprise attestation was not returned. If `epAtt` is present and set
/// > to true, then an enterprise attestation was returned.
pub enterprise_attestation: Option<bool>,
/// > Contains the `largeBlobKey` for the credential, if requested with the
/// > `largeBlobKey` extension.
pub large_blob_key: Option<Vec<u8>>,
}

@ -0,0 +1,111 @@
use crate::{
authenticator::{client_pin, Sha256Hash},
extensions::cred_protect,
};
use fido_common::credential::public_key;
pub type PinUvAuthParam = [u8; 16];
#[derive(Clone, Copy)]
pub enum Request<'a> {
GetCredentialsMetadata {
/// > PIN/UV protocol version chosen by the platform.
pin_uv_auth_protocol: client_pin::AuthProtocolVersion,
/// > First 16 bytes of HMAC-SHA-256 of contents using `pinUvAuthToken`.
pin_uv_auth_param: &'a PinUvAuthParam,
},
EnumerateRPsBegin {
/// > PIN/UV protocol version chosen by the platform.
pin_uv_auth_protocol: client_pin::AuthProtocolVersion,
/// > First 16 bytes of HMAC-SHA-256 of contents using `pinUvAuthToken`.
pin_uv_auth_param: &'a PinUvAuthParam,
},
EnumerateRPsGetNextRP,
EnumerateCredentialsBegin {
/// The ID of the relying party to enumerate credentials for.
relying_party_id_hash: &'a Sha256Hash,
/// > PIN/UV protocol version chosen by the platform.
pin_uv_auth_protocol: client_pin::AuthProtocolVersion,
/// > First 16 bytes of HMAC-SHA-256 of contents using `pinUvAuthToken`.
pin_uv_auth_param: &'a PinUvAuthParam,
},
EnumerateCredentialsGetNextCredential,
DeleteCredential {
/// The ID of the credential to delete.
credential_id: &'a public_key::Descriptor,
/// > PIN/UV protocol version chosen by the platform.
pin_uv_auth_protocol: client_pin::AuthProtocolVersion,
/// > First 16 bytes of HMAC-SHA-256 of contents using `pinUvAuthToken`.
pin_uv_auth_param: &'a PinUvAuthParam,
},
UpdateUserInformation {
/// The ID of the credential to update.
credential_id: &'a public_key::Descriptor,
/// The updated user information.
user: &'a public_key::UserEntity,
/// > PIN/UV protocol version chosen by the platform.
pin_uv_auth_protocol: client_pin::AuthProtocolVersion,
/// > First 16 bytes of HMAC-SHA-256 of contents using `pinUvAuthToken`.
pin_uv_auth_param: &'a PinUvAuthParam,
},
}
pub enum Response {
GetCredentialsMetadata {
/// > Number of existing discoverable credentials present on the
/// > authenticator.
existing_resident_credentials_count: usize,
/// > Number of maximum possible remaining discoverable credentials
/// > which can be created on the authenticator.
max_possible_remaining_resident_credentials_count: usize,
},
EnumerateRPsBegin {
relying_party: RelyingParty,
/// > total number of RPs present on the authenticator
total_relying_parties: usize,
},
EnumerateRPsGetNextRP {
relying_party: RelyingParty,
},
EnumerateCredentialsBegin {
credential: Credential,
/// > Total number of credentials present on the authenticator for the
/// > RP in question
total_credentials: usize,
},
EnumerateCredentialsGetNextCredential {
credential: Credential,
},
DeleteCredential,
UpdateUserInformation,
}
pub struct RelyingParty {
/// The description of the relying party.
pub relying_party: public_key::RelyingPartyEntity,
/// The hash of the relying party ID.
pub relying_party_id_hash: Sha256Hash,
}
pub struct Credential {
/// The description of the user account associated with the credential.
pub user: public_key::UserEntity,
/// A description of the public key associated with the credential.
pub credential_id: public_key::Descriptor,
/// The public key associated with the credential.
pub public_key: coset::CoseKey, // TODO: Is this the right set of parameters for cosekey?
/// Indicates the level of user verification the authenticator requires for
/// this credential.
pub credential_protection_policy: cred_protect::Policy,
/// > Large blob encryption key.
pub large_blob_key: Vec<u8>,
}
pub enum Error {
PinUvAuthTokenRequired,
MissingParameter,
InvalidParameter,
PinAuthInvalid,
NoCredentials,
KeyStoreFull,
}

@ -0,0 +1,2 @@
pub mod make;
pub mod management;

@ -0,0 +1,277 @@
use crate::authenticator::client_pin::AuthProtocolVersion;
use bounded_vec::BoundedVec;
use fido_common::credential::public_key;
use fido_common::{registry, Transport};
use std::usize;
use std::{
collections::{HashMap, HashSet},
num::NonZeroUsize,
};
/// A usize with a minimum value of N
#[derive(PartialEq, Eq)]
pub struct UsizeN<const N: usize>(bounded_integer::BoundedUsize<N, { usize::MAX }>);
/// > data type byte string and identifying the authenticator model, i.e.
/// > identical values mean that they refer to the same authenticator model and
/// > different values mean they refer to different authenticator models.
pub struct Aaguid([u8; 16]);
#[derive(Hash)]
pub enum Version {
Fido2_1,
Fido2_0,
Fido2_1Preview,
U2fV2,
}
/// > The certifications member provides a hint to the platform with additional
/// > information about certifications that the authenticator has received.
/// > Certification programs may revoke certification of specific devices at any
/// > time. Relying partys are responsible for validating attestations and
/// > `AAGUID` via appropriate methods. Platforms may alter their behaviour
/// > based on these hints such as selecting a PIN protocol or `credProtect`
/// > level.
pub enum Certification {
/// > The [FIPS140-2] Cryptographic-Module-Validation-Program overall
/// > certification level.
FipsCryptoValidation2(FipsCryptoValidation2Level),
FipsCryptoValidation3(FipsCryptoValidation3Level),
FipsPhysicalCryptoValidation2(FipsPhysicalCryptoValidation2Level),
FipsPhysicalCryptoValidation3(FipsPhysicalCryptoValidation3Level),
CommonCriteria(CommonCriterialLevel),
Fido(FidoLevel),
}
#[repr(usize)]
pub enum FipsCryptoValidation2Level {
Level1 = 1,
Level2 = 2,
Level3 = 3,
Level4 = 4,
}
#[repr(usize)]
pub enum FipsCryptoValidation3Level {
Level1 = 1,
Level2 = 2,
Level3 = 3,
Level4 = 4,
}
#[repr(usize)]
pub enum FipsPhysicalCryptoValidation2Level {
Level1 = 1,
Level2 = 2,
Level3 = 3,
Level4 = 4,
}
#[repr(usize)]
pub enum FipsPhysicalCryptoValidation3Level {
Level1 = 1,
Level2 = 2,
Level3 = 3,
Level4 = 4,
}
/// > Common Criteria Evaluation Assurance Level [CC1V3-1R5]. This is a integer
/// > from 1 to 7. The intermediate-plus levels are not represented.
#[repr(usize)]
pub enum CommonCriterialLevel {
EAL1 = 1,
EAL2 = 2,
EAL3 = 3,
EAL4 = 4,
EAL5 = 5,
EAL6 = 6,
EAL7 = 7,
}
/// > FIDO Alliance certification level. This is an integer from 1 to 6. The
/// > numbered levels are mapped to the odd numbers, with the plus levels mapped
/// > to the even numbers e.g., level 3+ is mapped to 6.
#[repr(usize)]
pub enum FidoLevel {
L1 = 1,
L1Plus = 2,
L2 = 3,
L2Plus = 4,
L3 = 5,
L3Plus = 6,
}
/// These options describe properties of a CTAP device.
pub enum OptionId {
/// > Indicates that the device is attached to the client and therefore
/// > cant be removed and used on another client.
PlatformDevice,
/// > Specifies whether this authenticator can create discoverable
/// > credentials, and therefore can satisfy `authenticatorGetAssertion`
/// > requests with the `allowList` parameter omitted.
DiscoverableCredentials,
/// > ClientPIN feature support:
/// > If present and set to true, it indicates that the device is capable of
/// > accepting a PIN from the client and PIN has been set.
/// >
/// > If present and set to false, it indicates that the device is capable
/// > of accepting a PIN from the client and PIN has not been set yet.
/// >
/// > If absent, it indicates that the device is not capable of accepting a
/// > PIN from the client.
ClientPin,
/// > Indicates that the device is capable of testing user presence.
UserPresence,
/// > Indicates that the authenticator supports a built-in user verification
/// > method. For example, devices with UI, biometrics fall into this
/// > category.
/// >
/// > If present and set to true, it indicates that the device is capable of
/// > built-in user verification and its user verification feature is
/// > presently configured.
/// >
/// > If present and set to false, it indicates that the authenticator is
/// > capable of built-in user verification and its user verification
/// > feature is not presently configured. For example, an authenticator
/// > featuring a built-in biometric user verification feature that is not
/// > presently configured will return this "uv" option id set to false.
/// >
/// > If absent, it indicates that the authenticator does not have a
/// > built-in user verification capability.
/// >
/// > A device that can only do Client PIN will not return the "uv" option
/// > id.
/// >
/// > If a device is capable of both built-in user verification and Client
/// > PIN, the authenticator will return both the "uv" and the "clientPin"
/// > option ids.
UserVerification,
PinUvAuthToken,
/// > If this noMcGaPermissionsWithClientPin is:
/// > - present and set to true: A `pinUvAuthToken` obtained via
/// > `getPinUvAuthTokenUsingPinWithPermissions` (or `getPinToken`) cannot
/// > be used for `authenticatorMakeCredential` or
/// > `authenticatorGetAssertion` commands, because it will lack the
/// > necessary `mc` and `ga` permissions. In this situation, platforms
/// > SHOULD NOT attempt to use `getPinUvAuthTokenUsingPinWithPermissions`
/// > if using `getPinUvAuthTokenUsingUvWithPermissions` fails.
/// >
/// > - present and set to false, or absent: A `pinUvAuthToken` obtained via
/// > `getPinUvAuthTokenUsingPinWithPermissions` (or `getPinToken`) can be
/// > used for `authenticatorMakeCredential` or `authenticatorGetAssertion`
/// > commands.
/// >
/// > Note: `noMcGaPermissionsWithClientPin` MUST only be present if the
/// > `clientPin` option ID is present.
NoMcGaPermissionsWithClientPin,
LargeBlobs,
EnterpriseAttestation,
BiometricEnroll,
UvManagementPreview,
UvBiometricEnroll,
AuthenticatorConfig,
UvAuthenticatorConfig,
CredentialManagement,
SetMinPinLength,
MakeCredentialUvNotRequired,
AlwaysRequireUv,
}
/// > Using this method, platforms can request that the authenticator report a
/// > list of its supported protocol versions and extensions, its AAGUID, and
/// > other aspects of its overall capabilities. Platforms should use this
/// > information to tailor their command parameters choices.
pub struct Info {
/// > List of supported CTAP versions.
pub versions: HashSet<Version>,
/// > List of supported extensions.
pub extensions: Option<HashSet<fido_common::extension::Identifier>>,
/// > The claimed AAGUID.
pub aaguid: Aaguid,
/// > List of supported options.
pub options: Option<HashMap<OptionId, bool>>,
/// > Maximum message size supported by the authenticator.
pub max_message_size: Option<usize>,
/// > List of supported PIN/UV auth protocols in order of decreasing
/// > authenticator preference. MUST NOT contain duplicate values nor be
/// > empty if present.
pub pin_uv_auth_protocols: Option<BoundedVec<AuthProtocolVersion, 1, { usize::MAX }>>,
/// > Maximum number of credentials supported in credentialID list at a time
/// > by the authenticator.
pub max_credential_count_in_list: Option<NonZeroUsize>,
/// > Maximum Credential ID Length supported by the authenticator.
pub max_credential_id_length: Option<NonZeroUsize>,
/// > List of supported transports.
pub transports: Option<HashSet<Transport>>,
/// > List of supported algorithms for credential generation... The array is
/// > ordered from most preferred to least preferred and MUST NOT include
/// > duplicate entries...
pub algorithms: Option<BoundedVec<public_key::Parameters, 1, { usize::MAX }>>,
/// > The maximum size, in bytes, of the serialized large-blob array that
/// > this authenticator can store. If the `authenticatorLargeBlobs` command
/// > is supported, this MUST be specified. Otherwise it MUST NOT be.
pub max_serialized_large_blob_array_size: Option<UsizeN<1024>>,
/// > If this member is:
/// > - present and set to true: `getPinToken` and
/// > `getPinUvAuthTokenUsingPinWithPermissions` will return errors until
/// > after a successful PIN Change.
/// > - present and set to false, or absent: no PIN Change is required.
pub force_pin_change: Option<bool>,
/// > This specifies the current minimum PIN length, in Unicode code points,
/// > the authenticator enforces for ClientPIN. This is applicable for
/// > ClientPIN only: the minPINLength member MUST be absent if the
/// > clientPin option ID is absent; it MUST be present if the authenticator
/// > supports authenticatorClientPIN.
pub min_pin_length: Option<usize>,
/// > Indicates the firmware version of the authenticator model identified
/// > by AAGUID.
pub firmware_version: Option<usize>,
/// > Maximum credBlob length in bytes supported by the authenticator. Must
/// > be present if, and only if, credBlob is included in the supported
/// > extensions list.
pub max_cred_blob_length: Option<UsizeN<32>>,
/// > This specifies the max number of RP IDs that authenticator can set via
/// > `setMinPINLength` subcommand. This is in addition to pre-configured
/// > list authenticator may have. If the authenticator does not support
/// > adding additional RP IDs, its value is 0. This MUST ONLY be present
/// > if, and only if, the authenticator supports the `setMinPINLength`
/// > subcommand.
pub max_rpids_for_set_min_pin_length: Option<usize>,
/// > This specifies the preferred number of invocations of the
/// > `getPinUvAuthTokenUsingUvWithPermissions` subCommand the platform may
/// > attempt before falling back to the
/// > `getPinUvAuthTokenUsingPinWithPermissions` subCommand or displaying an
/// > error.
pub preferred_platform_uv_attempts: Option<NonZeroUsize>,
/// > This specifies the user verification modality supported by the
/// > authenticator via `authenticatorClientPIN`'s
/// > `getPinUvAuthTokenUsingUvWithPermissions` subcommand. This is a hint
/// > to help the platform construct user dialogs. If `clientPin`
/// > is supported it MUST NOT be included in the bit-flags, as `clientPIN`
/// > is not a built-in user verification method.
pub uv_modality: Option<HashSet<registry::UserVerify>>,
/// > This specifies a list of authenticator certifications.
pub certifications: Option<HashSet<Certification>>,
/// > If this member is present it indicates the estimated number of
/// > additional discoverable credentials that can be stored. If this value
/// > is zero then platforms SHOULD create non-discoverable credentials if
/// > possible.
/// >
/// > This estimate SHOULD be based on the assumption that all future
/// > discoverable credentials will have maximally-sized fields and SHOULD
/// > be zero whenever an attempt to create a discoverable credential may
/// > fail due to lack of space, even if its possible that some specific
/// > request might succeed. For example, a specific request might include
/// > fields that are smaller than the maximum possible size and thus
/// > succeed, but this value should be zero if a request with maximum-sized
/// > fields would fail. Also, a specific request might have an rp.id and
/// > user.id that match an existing discoverable credential and thus
/// > overwrite it, but this value should be set assuming that will not
/// > happen.
pub remaining_discoverable_credentials: Option<usize>,
/// > If present the authenticator supports the `authenticatorConfig`
/// > `vendorPrototype` subcommand, and its value is a list of
/// > `authenticatorConfig` `vendorCommandId` values supported, which MAY be
/// > empty.
pub vendor_prototype_config_commands: Option<HashSet<usize>>,
}

@ -0,0 +1,38 @@
use crate::attestation;
pub mod assertion;
pub mod bio_enrollment;
pub mod client_pin;
pub mod config;
pub mod credential;
pub mod device;
pub mod reset;
pub mod selection;
/// SHA 256 hash values are 32 bytes long.
pub type Sha256Hash = [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.
/// >
/// > The authenticator data has a compact but extensible encoding. This is
/// > desired since authenticators can be devices with limited capabilities and
/// > low power requirements, with much simpler software stacks than the client
/// > platform.
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: attestation::CredentialData,
// TODO: extensions
}

@ -0,0 +1,17 @@
/// Possible errors for the [`Ctap2Device::reset`] command.
pub enum Error {
/// Returned if the `reset` operation is disabled for the transport used or
/// if user precense is explicitly denied.
OperationDenied,
/// Returned when a user action timeout occurs.
///
/// > This refers to a timeout that occurs when the authenticator is waiting
/// > for direct action from the user, like a touch. (I.e. not a command
/// > from the platform.) The duration of this timeout is chosen by the
/// > authenticator but MUST be at least 10 seconds. Thirty seconds is a
/// > reasonable value.
UserActionTimeout,
/// Returned when the `reset` request is received by the authenticator more
/// than ten seconds after powering up.
NotAllowed,
}

@ -0,0 +1,4 @@
pub enum Error {
OperationDenied,
UserActionTimeout,
}

@ -0,0 +1,5 @@
pub enum Policy {
UserVerificationOptional,
UserVerificationOptionalWithCredentialIdList,
UserVerificationRequired,
}

@ -0,0 +1,29 @@
pub mod cred_protect;
/// The extension input parameters passed to the authenticator during a call to
/// `make_credential` call. Defined by the extension author.
///
/// > An extension defines one or two request arguments. The client extension
/// > input, which is a value that can be encoded in JSON, is passed from the
/// > WebAuthn Relying Party to the client in the get() or create() call, while
/// > the CBOR authenticator extension input is passed from the client to the
/// > authenticator for authenticator extensions during the processing of these
/// > calls.
pub enum AuthenticatorExtensionInput {
AppId,
TransactionAuthSimple,
TransactionAuthGeneric,
AuthenticationSelection,
Extensions,
UserVerificationIndex,
Location,
UserVerificationMethod,
CredentialProtection,
CredentialBlob,
LargeBlobKey,
MinPinLength,
HmacSecret,
AppIdExclude,
CredentialProperties,
LargeBlob,
}

@ -0,0 +1,65 @@
use authenticator::{
assertion::get,
bio_enrollment, client_pin, config,
credential::{make, management},
reset,
};
pub mod attestation;
pub mod authenticator;
pub mod extensions;
/// Defines the raw CTAP operations
pub trait Ctap2_2Authenticator {
#[allow(clippy::missing_errors_doc)]
/// > This method is invoked by the host to request generation of a new
/// > credential in the authenticator.
fn make_credential(request: make::Request) -> Result<make::Response, make::Error>;
#[allow(clippy::missing_errors_doc)]
/// > This method is used by a host to request cryptographic proof of user
/// > authentication as well as user consent to a given transaction, using a
/// > previously generated credential that is bound to the authenticator and
/// > relying party identifier.
fn get_assertion(request: get::Request) -> Result<get::Response, get::Error>;
/// > Using this method, platforms can request that the authenticator report
/// > a list of its supported protocol versions and extensions, its AAGUID,
/// > and other aspects of its overall capabilities. Platforms should use
/// > this information to tailor their command parameters choices.
fn get_info() -> authenticator::device::Info;
#[allow(clippy::missing_errors_doc)]
/// > This command exists so that plaintext PINs are not sent to the
/// > authenticator. Instead, a PIN/UV auth protocol (aka
/// > `pinUvAuthProtocol`) ensures that PINs are encrypted when sent to an
/// > authenticator and are exchanged for a `pinUvAuthToken` that serves to
/// > authenticate subsequent commands.
fn client_pin(request: client_pin::Request) -> Result<client_pin::Response, client_pin::Error>;
#[allow(clippy::missing_errors_doc)]
/// > This method is used by the client to reset an authenticator back to a
/// > factory default state.
fn reset() -> Result<(), reset::Error>;
fn bio_enrollment(request: bio_enrollment::Request, response: bio_enrollment::Response);
#[allow(clippy::missing_errors_doc)]
/// > This command is used by the platform to manage discoverable
/// > credentials on the authenticator.
fn credential_management(
request: management::Request,
) -> Result<management::Response, management::Error>;
#[allow(clippy::missing_errors_doc)]
/// > This command allows the platform to let a user select a certain
/// > authenticator by asking for user presence.
fn selection() -> Result<(), authenticator::selection::Error>;
fn large_blobs() -> Result<(), ()>;
#[allow(clippy::missing_errors_doc)]
/// > This command is used to configure various authenticator features
/// > through the use of its subcommands.
fn authenticator_config(request: config::Request) -> Result<(), config::Error>;
}
Loading…
Cancel
Save