Skip to main content

passkey_authenticator/
ctap2.rs

1//! Ctap 2.0 Authenticator API
2//!
3//! This module defines the [`Ctap2Api`] trait which is sealed to the [`Authenticator`] type and a
4//! future `RemoteAuthenticator` type wich will implement the different transports.
5//!
6//! <https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#authenticator-api>
7
8use passkey_crypto::CryptoBackend;
9use passkey_types::ctap2::{StatusCode, get_assertion, get_info, make_credential};
10
11use crate::{Authenticator, CredentialStore, UserValidationMethod};
12
13mod sealed {
14    use super::{Authenticator, CredentialStore, CryptoBackend, UserValidationMethod};
15
16    pub trait Sealed {}
17
18    #[cfg(all(feature = "linux", target_os = "linux"))]
19    impl Sealed for crate::linux::LinuxAuthenticator {}
20    impl<S: CredentialStore, U: UserValidationMethod, C: CryptoBackend> Sealed
21        for Authenticator<S, U, C>
22    {
23    }
24}
25
26/// Methods defined as being required for a [CTAP 2.0] compliant authenticator to implement.
27///
28/// This trait is sealed to prevent missuse and to prevent incorrect implementations in the wild.
29/// If you need to define an authenticator please use the [`Authenticator`] struct which provides
30/// the necessary generics to customize storage and UI interactions.
31///
32/// These methods are provided as traits in order to have a remotely connected authenticators through
33/// the different transports defined in [CTAP 2.0].
34///
35/// [CTAP 2.0]: https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html
36#[async_trait::async_trait]
37pub trait Ctap2Api: sealed::Sealed {
38    /// Request to get the information of the authenticator and see what it supports.
39    async fn get_info(&self) -> Box<get_info::Response>;
40
41    /// Request to create and save a new credential in the authenticator.
42    async fn make_credential(
43        &mut self,
44        request: make_credential::Request,
45    ) -> Result<make_credential::Response, StatusCode>;
46
47    /// Request to assert a user's existing credential that might exist in the authenticator.
48    async fn get_assertion(
49        &mut self,
50        request: get_assertion::Request,
51    ) -> Result<get_assertion::Response, StatusCode>;
52}
53
54#[async_trait::async_trait]
55impl<S, U, C> Ctap2Api for Authenticator<S, U, C>
56where
57    S: CredentialStore + Sync + Send,
58    U: UserValidationMethod<PasskeyItem = <S as CredentialStore>::PasskeyItem> + Sync + Send,
59    C: CryptoBackend<SecretKey: Sync + Send> + Sync + Send,
60{
61    async fn get_info(&self) -> Box<get_info::Response> {
62        Authenticator::get_info(self).await
63    }
64
65    async fn make_credential(
66        &mut self,
67        request: make_credential::Request,
68    ) -> Result<make_credential::Response, StatusCode> {
69        Authenticator::make_credential(self, request).await
70    }
71
72    async fn get_assertion(
73        &mut self,
74        request: get_assertion::Request,
75    ) -> Result<get_assertion::Response, StatusCode> {
76        Authenticator::get_assertion(self, request).await
77    }
78}