Add ctap2-proto crate
The ctap2-proto crate defines the Ctap2_2Authenticator trait, which implements the latest CTAP spec.dev
parent
1ea1e3b740
commit
4082fbb437
@ -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 @@
|
|||||||
|
pub mod get;
|
@ -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,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,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…
Reference in New Issue