Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions credentialsd-common/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1 @@
use std::pin::Pin;

use futures_lite::Stream;

use crate::{
model::{Device, RequestId},
server::BackgroundEvent,
};

/// Used for communication from trusted UI to credential service
pub trait FlowController {
fn get_available_public_key_devices(
&self,
) -> impl Future<Output = Result<Vec<Device>, ()>> + Send;

fn start_discovery(&mut self) -> impl Future<Output = Result<(), ()>> + Send;
fn subscribe(
&mut self,
) -> impl Future<
Output = Result<Pin<Box<dyn Stream<Item = BackgroundEvent> + Send + 'static>>, ()>,
> + Send;
fn enter_client_pin(&mut self, pin: String) -> impl Future<Output = Result<(), ()>> + Send;
fn select_credential(
&self,
credential_id: String,
) -> impl Future<Output = Result<(), ()>> + Send;
fn cancel_request(&self, request_id: RequestId) -> impl Future<Output = Result<(), ()>> + Send;
}
223 changes: 0 additions & 223 deletions credentialsd-common/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,6 @@ pub struct Credential {
pub username: Option<String>,
}

/// Client Capabilities, as defined in
/// [WebAuthn](https://www.w3.org/TR/webauthn-3/#enumdef-clientcapability).
#[derive(SerializeDict, Type)]
#[zvariant(signature = "dict", rename_all = "camelCase")]
pub struct GetClientCapabilitiesResponse {
pub conditional_create: bool,
pub conditional_get: bool,
pub hybrid_transport: bool,
pub passkey_platform_authenticator: bool,
pub user_verifying_platform_authenticator: bool,
pub related_origins: bool,
pub signal_all_accepted_credentials: bool,
pub signal_current_user_details: bool,
pub signal_unknown_credential: bool,
}

#[derive(Debug, Serialize, Deserialize)]
pub enum CredentialType {
Passkey,
// Password,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Type)]
pub struct Device {
pub id: String,
Expand Down Expand Up @@ -115,153 +93,6 @@ impl Transport {
}
}

#[derive(Debug, Default, Clone, Serialize, Deserialize, Type)]
pub struct RequestingParty {
pub rp_id: String,
pub origin: String,
}

/// Identifier for a request to be used for cancellation.
pub type RequestId = u32;

// TODO: Move to credentialsd-ui
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ViewUpdate {
SetTitle {
title: String,
subtitle: String,
qr_prompt: String,
usb_prompt: String,
},
SetDevices(Vec<Device>),
// TODO: Fix this
SetCredentials(Vec<crate::server::Credential>),

WaitingForDevice(Device),
SelectingDevice,

NeedsPin {
attempts_left: Option<u32>,
},
NeedsUserVerification {
attempts_left: Option<u32>,
},
NeedsUserPresence,

HybridNeedsQrCode(String),
HybridConnecting,
HybridConnected,

Completed,
Cancelled,
Failed(String),
}

#[derive(Clone, Debug, Default)]
pub enum HybridState {
/// Default state, not listening for hybrid transport.
#[default]
Idle,

/// QR code flow is starting, awaiting QR code scan and BLE advert from phone.
Started(String),

/// BLE advert received, connecting to caBLE tunnel with shared secret.
Connecting,

/// Connected to device via caBLE tunnel.
Connected,

/// Credential received over tunnel.
Completed,

// This isn't actually sent from the server.
UserCancelled,

/// Failed to receive a credential
Failed,
}

/// Used to share public state between credential service and UI.
#[derive(Clone, Debug, Default)]
pub enum UsbState {
/// Not polling for FIDO USB device.
#[default]
Idle,

/// Awaiting FIDO USB device to be plugged in.
Waiting,

// When we encounter multiple devices, we let all of them blink and continue
// with the one that was tapped.
SelectingDevice,

/// USB device connected, prompt user to tap
Connected,

/// The device needs the PIN to be entered.
NeedsPin {
attempts_left: Option<u32>,
},

/// The device needs on-device user verification.
NeedsUserVerification {
attempts_left: Option<u32>,
},

/// The device needs evidence of user presence (e.g. touch) to release the credential.
NeedsUserPresence,
// TODO: implement cancellation
// This isn't actually sent from the server.
//UserCancelled,
/// Multiple credentials have been found and the user has to select which to use
SelectingCredential {
/// List of user-identities to decide which to use.
creds: Vec<Credential>,
},

/// USB tapped, received credential
Completed,

/// Interaction with the authenticator failed.
Failed(Error),
}

/// Used to share public state between credential service and UI.
#[derive(Clone, Debug, Default)]
pub enum NfcState {
/// Not polling for FIDO NFC device.
#[default]
Idle,

/// Awaiting FIDO NFC device to connect.
Waiting,

/// USB device connected, prompt user to tap
Connected,

/// The device needs the PIN to be entered.
NeedsPin { attempts_left: Option<u32> },

/// The device needs on-device user verification.
NeedsUserVerification { attempts_left: Option<u32> },

// TODO: implement cancellation
// This isn't actually sent from the server.
//UserCancelled,
/// Multiple credentials have been found and the user has to select which to use
SelectingCredential {
/// List of user-identities to decide which to use.
creds: Vec<Credential>,
},

/// NFC tapped, received credential
Completed,

/// Interaction with the authenticator failed.
Failed(Error),
}

pub enum UserInteractedEvent {
/// Start discovery
DiscoveryRequested,
Expand Down Expand Up @@ -328,57 +159,3 @@ impl Display for Error {
}
}
}

#[derive(Debug)]
pub enum WebAuthnError {
/// The ceremony was cancelled by an AbortController. See § 5.6 Abort
/// Operations with AbortSignal and § 1.3.4 Aborting Authentication
/// Operations.
AbortError,

/// Either `residentKey` was set to required and no available authenticator
/// supported resident keys, or `userVerification` was set to required and no
/// available authenticator could perform user verification.
ConstraintError,

/// The authenticator used in the ceremony recognized an entry in
/// `excludeCredentials` after the user consented to registering a credential.
InvalidStateError,

/// No entry in `pubKeyCredParams` had a type property of `public-key`, or the
/// authenticator did not support any of the signature algorithms specified
/// in `pubKeyCredParams`.
NotSupportedError,

/// The effective domain was not a valid domain, or `rp.id` was not equal to
/// or a registrable domain suffix of the effective domain. In the latter
/// case, the client does not support related origin requests or the related
/// origins validation procedure failed.
SecurityError,

/// A catch-all error covering a wide range of possible reasons, including
/// common ones like the user canceling out of the ceremony. Some of these
/// causes are documented throughout this spec, while others are
/// client-specific.
NotAllowedError,

/// The options argument was not a valid `CredentialCreationOptions` value, or
/// the value of `user.id` was empty or was longer than 64 bytes.
TypeError,
}

impl std::error::Error for WebAuthnError {}

impl Display for WebAuthnError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
WebAuthnError::AbortError => "Operation was aborted by client.",
WebAuthnError::ConstraintError => "Resident key or user verification requirement was not able to be met.",
WebAuthnError::InvalidStateError => "A user consented to create a new credential after trying to use an authenticator with a previously registered credential.",
WebAuthnError::NotSupportedError => "Operation parameters are not supported.",
WebAuthnError::SecurityError => "Validation of the client context for given RP ID failed.",
WebAuthnError::NotAllowedError => "An unspecified error occurred, and the operation is not allowed to continue.",
WebAuthnError::TypeError => "Invalid parameters specified.",
})
}
}
Loading
Loading