mod any;
pub mod iso7816;
pub use crate::transport::any::{AnyToken, AnyTransport};
use base64urlsafedata::Base64UrlSafeData;
use std::fmt;
use webauthn_rs_proto::{PubKeyCredParams, RelyingParty, User};
use crate::cbor::*;
use crate::error::WebauthnCError;
#[allow(non_camel_case_types)]
pub enum Selected<T>
where
T: Token,
{
FIDO_2_1_PRE(Ctap2_1_pre<T>),
}
#[allow(non_camel_case_types)]
pub struct Ctap2_1_pre<T>
where
T: Token,
{
tokinfo: GetInfoResponse,
token: T,
}
pub trait Transport: Sized + Default + fmt::Debug {
type Token: Token;
fn tokens(&mut self) -> Result<Vec<Self::Token>, WebauthnCError>;
}
pub trait Token: Sized + fmt::Debug {
fn transmit<C, R>(&self, cmd: C) -> Result<R, WebauthnCError>
where
C: CBORCommand<Response = R>,
R: CBORResponse;
fn init(&mut self) -> Result<(), WebauthnCError>;
fn select_any(self) -> Result<Selected<Self>, WebauthnCError> {
let tokinfo = self.transmit(GetInfoRequest {})?;
debug!(?tokinfo);
if tokinfo.versions.contains("FIDO_2_1_PRE") {
Ok(Selected::FIDO_2_1_PRE(Ctap2_1_pre {
tokinfo,
token: self,
}))
} else {
error!(?tokinfo.versions);
Err(WebauthnCError::NotSupported)
}
}
fn close(&self) -> Result<(), WebauthnCError>;
}
impl<T: Token> fmt::Debug for Ctap2_1_pre<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Ctap2_1_pre")
.field("token_info", &self.tokinfo)
.finish()
}
}
impl<T: Token> Ctap2_1_pre<T> {
pub fn hack_make_cred(&mut self) -> Result<NoResponse, WebauthnCError> {
let mc = MakeCredentialRequest {
client_data_hash: vec![
104, 113, 52, 150, 130, 34, 236, 23, 32, 46, 66, 80, 95, 142, 210, 177, 106, 226,
47, 22, 187, 5, 184, 140, 37, 219, 158, 96, 38, 69, 241, 65,
],
rp: RelyingParty {
name: "test".to_string(),
id: "test".to_string(),
},
user: User {
id: Base64UrlSafeData("test".as_bytes().into()),
name: "test".to_string(),
display_name: "test".to_string(),
},
pub_key_cred_params: vec![PubKeyCredParams {
type_: "public-key".to_string(),
alg: -7,
}],
options: None,
pin_uv_auth_param: None,
pin_uv_auth_proto: None,
enterprise_attest: None,
};
self.token.transmit(mc)
}
pub fn deselect_applet(&self) -> Result<(), WebauthnCError> {
self.token.close()
}
}