Skip to content

Commit

Permalink
feat: add support for new Origin type
Browse files Browse the repository at this point in the history
  • Loading branch information
coroiu committed Sep 13, 2024
1 parent 5eb836d commit c38bec7
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 19 deletions.
23 changes: 9 additions & 14 deletions crates/bitwarden-fido/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
use passkey::client::WebauthnError;
use reqwest::Url;
use thiserror::Error;

use crate::types::InvalidOriginError;

use super::{
authenticator::GetSelectedCredentialError,
get_string_name_from_enum,
types::{
AuthenticatorAssertionResponse, AuthenticatorAttestationResponse, ClientData,
ClientExtensionResults, CredPropsResult,
ClientExtensionResults, CredPropsResult, Origin,
},
Fido2Authenticator, PublicKeyCredentialAuthenticatorAssertionResponse,
PublicKeyCredentialAuthenticatorAttestationResponse,
};

#[derive(Debug, Error)]
#[error("Invalid origin: {0}")]
pub struct InvalidOriginError(String);

#[derive(Debug, Error)]
pub enum Fido2ClientError {
#[error(transparent)]
Expand All @@ -43,12 +40,11 @@ pub struct Fido2Client<'a> {
impl<'a> Fido2Client<'a> {
pub async fn register(
&mut self,
origin: String,
origin: Origin,

Check warning on line 43 in crates/bitwarden-fido/src/client.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/client.rs#L43

Added line #L43 was not covered by tests
request: String,
client_data: ClientData,
) -> Result<PublicKeyCredentialAuthenticatorAttestationResponse, Fido2ClientError> {
let origin = Url::parse(&origin).map_err(|e| InvalidOriginError(format!("{}", e)))?;

let origin: passkey::client::Origin = origin.try_into()?;

Check warning on line 47 in crates/bitwarden-fido/src/client.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/client.rs#L47

Added line #L47 was not covered by tests
let request: passkey::types::webauthn::CredentialCreationOptions =
serde_json::from_str(&request)?;

Expand All @@ -67,7 +63,7 @@ impl<'a> Fido2Client<'a> {
let rp_id = request.public_key.rp.id.clone();

let mut client = passkey::client::Client::new(self.authenticator.get_authenticator(true));
let result = client.register(&origin, request, client_data).await?;
let result = client.register(origin, request, client_data).await?;

Check warning on line 66 in crates/bitwarden-fido/src/client.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/client.rs#L66

Added line #L66 was not covered by tests

Ok(PublicKeyCredentialAuthenticatorAttestationResponse {
id: result.id,
Expand Down Expand Up @@ -98,12 +94,11 @@ impl<'a> Fido2Client<'a> {

pub async fn authenticate(
&mut self,
origin: String,
origin: Origin,

Check warning on line 97 in crates/bitwarden-fido/src/client.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/client.rs#L97

Added line #L97 was not covered by tests
request: String,
client_data: ClientData,
) -> Result<PublicKeyCredentialAuthenticatorAssertionResponse, Fido2ClientError> {
let origin = Url::parse(&origin).map_err(|e| InvalidOriginError(format!("{}", e)))?;

let origin: passkey::client::Origin = origin.try_into()?;

Check warning on line 101 in crates/bitwarden-fido/src/client.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/client.rs#L101

Added line #L101 was not covered by tests
let request: passkey::types::webauthn::CredentialRequestOptions =
serde_json::from_str(&request)?;

Expand All @@ -116,7 +111,7 @@ impl<'a> Fido2Client<'a> {
.replace(uv);

let mut client = passkey::client::Client::new(self.authenticator.get_authenticator(false));
let result = client.authenticate(&origin, request, client_data).await?;
let result = client.authenticate(origin, request, client_data).await?;

Check warning on line 114 in crates/bitwarden-fido/src/client.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/client.rs#L114

Added line #L114 was not covered by tests

Ok(PublicKeyCredentialAuthenticatorAssertionResponse {
id: result.id,
Expand Down
4 changes: 2 additions & 2 deletions crates/bitwarden-fido/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ pub use traits::{
pub use types::{
AuthenticatorAssertionResponse, AuthenticatorAttestationResponse, ClientData,
Fido2CredentialAutofillView, Fido2CredentialAutofillViewError, GetAssertionRequest,
GetAssertionResult, MakeCredentialRequest, MakeCredentialResult, Options,
GetAssertionResult, MakeCredentialRequest, MakeCredentialResult, Options, Origin,
PublicKeyCredentialAuthenticatorAssertionResponse,
PublicKeyCredentialAuthenticatorAttestationResponse, PublicKeyCredentialRpEntity,
PublicKeyCredentialUserEntity,
PublicKeyCredentialUserEntity, UnverifiedAssetLink,
};

use self::crypto::{cose_key_to_pkcs8, pkcs8_to_cose_key};
Expand Down
64 changes: 64 additions & 0 deletions crates/bitwarden-fido/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::borrow::Cow;

use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use bitwarden_crypto::KeyContainer;
use bitwarden_vault::{CipherError, CipherView};
use passkey::types::webauthn::UserVerificationRequirement;
use reqwest::Url;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use thiserror::Error;
Expand Down Expand Up @@ -359,6 +362,67 @@ pub struct AuthenticatorAssertionResponse {
pub user_handle: Vec<u8>,
}

#[derive(Debug, Error)]

Check warning on line 365 in crates/bitwarden-fido/src/types.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/types.rs#L365

Added line #L365 was not covered by tests
#[error("Invalid origin: {0}")]
pub struct InvalidOriginError(String);

#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
/// An Unverified asset link.
pub struct UnverifiedAssetLink {
/// Application package name.
package_name: String,
/// Fingerprint to compare.
sha256_cert_fingerprint: String,
/// Host to lookup the well known asset link.
host: String,
/// When sourced from the application statement list or parsed from host for passkeys.
/// Will be generated from `host` if not provided.
asset_link_url: Option<String>,
}

#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
/// The origin of a WebAuthn request.
pub enum Origin {
/// A Url, meant for a request in the web browser.
Web(String),
/// An android digital asset fingerprint.
/// Meant for a request coming from an android application.
Android(UnverifiedAssetLink),
}

impl<'a> TryFrom<Origin> for passkey::client::Origin<'a> {
type Error = InvalidOriginError;

fn try_from(value: Origin) -> Result<Self, Self::Error> {
Ok(match value {
Origin::Web(url) => {
let url = Url::parse(&url).map_err(|e| InvalidOriginError(format!("{}", e)))?;
passkey::client::Origin::Web(Cow::Owned(url))

Check warning on line 400 in crates/bitwarden-fido/src/types.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/types.rs#L396-L400

Added lines #L396 - L400 were not covered by tests
}
Origin::Android(link) => passkey::client::Origin::Android(link.try_into()?),

Check warning on line 402 in crates/bitwarden-fido/src/types.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/types.rs#L402

Added line #L402 was not covered by tests
})
}

Check warning on line 404 in crates/bitwarden-fido/src/types.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/types.rs#L404

Added line #L404 was not covered by tests
}

impl<'a> TryFrom<UnverifiedAssetLink> for passkey::client::UnverifiedAssetLink<'a> {
type Error = InvalidOriginError;

fn try_from(value: UnverifiedAssetLink) -> Result<Self, Self::Error> {
let asset_link_url = match value.asset_link_url {
Some(url) => Some(Url::parse(&url).map_err(|e| InvalidOriginError(format!("{}", e)))?),
None => None,

Check warning on line 413 in crates/bitwarden-fido/src/types.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/types.rs#L410-L413

Added lines #L410 - L413 were not covered by tests
};

passkey::client::UnverifiedAssetLink::new(
Cow::from(value.package_name),
value.sha256_cert_fingerprint.as_str(),
Cow::from(value.host),
asset_link_url,
)
.map_err(|e| InvalidOriginError(format!("{:?}", e)))
}

Check warning on line 423 in crates/bitwarden-fido/src/types.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-fido/src/types.rs#L416-L423

Added lines #L416 - L423 were not covered by tests
}

#[cfg(test)]
mod tests {
use serde::{Deserialize, Serialize};
Expand Down
6 changes: 3 additions & 3 deletions crates/bitwarden-uniffi/src/platform/fido2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use bitwarden::{
},
vault::{Cipher, CipherView, Fido2CredentialNewView},
};
use bitwarden_fido::Fido2CredentialAutofillView;
use bitwarden_fido::{Fido2CredentialAutofillView, Origin};

use crate::{error::Result, Client};

Expand Down Expand Up @@ -135,7 +135,7 @@ pub struct ClientFido2Client(pub(crate) ClientFido2Authenticator);
impl ClientFido2Client {
pub async fn register(
&self,
origin: String,
origin: Origin,

Check warning on line 138 in crates/bitwarden-uniffi/src/platform/fido2.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-uniffi/src/platform/fido2.rs#L138

Added line #L138 was not covered by tests
request: String,
client_data: ClientData,
) -> Result<PublicKeyCredentialAuthenticatorAttestationResponse> {
Expand All @@ -153,7 +153,7 @@ impl ClientFido2Client {

pub async fn authenticate(
&self,
origin: String,
origin: Origin,

Check warning on line 156 in crates/bitwarden-uniffi/src/platform/fido2.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden-uniffi/src/platform/fido2.rs#L156

Added line #L156 was not covered by tests
request: String,
client_data: ClientData,
) -> Result<PublicKeyCredentialAuthenticatorAssertionResponse> {
Expand Down

0 comments on commit c38bec7

Please sign in to comment.