passkey_authenticator/
passkey.rs

1use std::{borrow::Cow, ops::Deref};
2
3use coset::CoseKey;
4use passkey_types::{
5    CredentialExtensions,
6    webauthn::{AuthenticatorTransport, PublicKeyCredentialDescriptor, PublicKeyCredentialType},
7};
8
9#[cfg(doc)]
10use passkey_types::Passkey;
11
12/// A trait to model the different aspects of a passkey, this allows the abstraction of a passkey
13/// on custom items.
14pub trait PasskeyAccessor {
15    /// The private key
16    ///
17    /// This is a Cow in case the type does not save the private key in Cose format.
18    fn key(&self) -> Cow<'_, CoseKey>;
19    /// The passkey's credential Id.
20    fn credential_id(&self) -> &[u8];
21    /// The Relying Party ID to which the passkey is bound to.
22    fn rp_id(&self) -> &str;
23    /// The user handle for which this passkey is bound to.
24    fn user_handle(&self) -> Option<&[u8]>;
25    /// The username that this passkey is created for.
26    fn username(&self) -> Option<&str>;
27    /// The user's display name.
28    fn user_display_name(&self) -> Option<&str>;
29    /// The counter of times this passkey has been used.
30    ///
31    /// See Counter considerations on [`Passkey::counter`]
32    fn counter(&self) -> Option<u32>;
33    /// Set a new value for the [`PasskeyAccessor::set_counter`]
34    fn set_counter(&mut self, counter: u32);
35    /// Get the extensions that that this passkey provides
36    ///
37    /// This is a Cow in case the type does not save the extension data in the format defined by
38    /// `passkey-types`.
39    fn extensions(&self) -> Cow<'_, CredentialExtensions>;
40}
41
42pub(crate) trait AsCredentialDescriptor: PasskeyAccessor {
43    fn as_credential_descriptor(
44        &self,
45        transports: Option<Vec<AuthenticatorTransport>>,
46    ) -> PublicKeyCredentialDescriptor;
47}
48
49impl<P> AsCredentialDescriptor for P
50where
51    P: PasskeyAccessor,
52{
53    fn as_credential_descriptor(
54        &self,
55        transports: Option<Vec<AuthenticatorTransport>>,
56    ) -> PublicKeyCredentialDescriptor {
57        PublicKeyCredentialDescriptor {
58            ty: PublicKeyCredentialType::PublicKey,
59            id: self.credential_id().into(),
60            transports,
61        }
62    }
63}
64
65impl PasskeyAccessor for passkey_types::Passkey {
66    fn key(&self) -> Cow<'_, CoseKey> {
67        Cow::Borrowed(&self.key)
68    }
69
70    fn credential_id(&self) -> &[u8] {
71        &self.credential_id
72    }
73
74    fn rp_id(&self) -> &str {
75        &self.rp_id
76    }
77
78    fn user_handle(&self) -> Option<&[u8]> {
79        self.user_handle.as_ref().map(|b| b.deref().deref())
80    }
81
82    fn username(&self) -> Option<&str> {
83        self.username.as_deref()
84    }
85
86    fn user_display_name(&self) -> Option<&str> {
87        self.user_display_name.as_deref()
88    }
89
90    fn counter(&self) -> Option<u32> {
91        self.counter
92    }
93
94    fn set_counter(&mut self, counter: u32) {
95        self.counter = Some(counter);
96    }
97
98    fn extensions(&self) -> Cow<'_, CredentialExtensions> {
99        Cow::Borrowed(&self.extensions)
100    }
101}