1use server::{CheckedConn, CheckedPermissions, MessageAllowed};
5
6#[cfg(feature = "test-app")]
7use crate::messages::ResetState;
8use crate::messages::{
9 CreateSecurityKey, CtapProcessCbor, EditSecurityKey, GetSelectedSecurityKey, ListSecurityKeys,
10 SelectSecurityKey, SetArchived, Transport, U2fApduCommand, U2fProcessApdu,
11};
12use crate::SecurityKeyView;
13
14#[macro_export]
15macro_rules! use_api {
16 () => {
17 mod fido_permissions {
18 use fido::messages::*;
19 #[derive(Debug, Clone, Default, server::Permissions)]
20 #[server_name = "os/fido"]
21 pub struct FidoPermissions;
22 }
23 type FidoApi = fido::api::FidoApi<fido_permissions::FidoPermissions>;
24 };
25}
26
27#[derive(Debug, Default)]
28pub struct FidoApi<P: CheckedPermissions>(CheckedConn<P>);
29
30#[derive(Debug, Default)]
33pub struct FidoApiStub;
34
35impl FidoApiStub {
36 pub fn u2f_process_apdu(&self, _command: U2fApduCommand, _transport: Transport) -> Vec<u8> { Vec::new() }
37
38 pub fn ctap_process_cbor(&self, _cmd: u8, _raw: Vec<u8>) -> Vec<u8> { Vec::new() }
39}
40
41impl<P: CheckedPermissions> FidoApi<P> {
42 pub fn create_security_key(
50 &self,
51 label: String,
52 color: u8,
53 icon: String,
54 ) -> Result<usize, crate::error::FidoError>
55 where
56 P: MessageAllowed<CreateSecurityKey>,
57 {
58 self.0.send_blocking_archive(CreateSecurityKey { label, color, icon })
59 }
60
61 pub fn edit_security_key(
65 &self,
66 index: usize,
67 label: String,
68 color: u8,
69 icon: String,
70 date: u64,
71 ) -> Result<(), crate::error::FidoError>
72 where
73 P: MessageAllowed<EditSecurityKey>,
74 {
75 self.0.send_blocking_archive(EditSecurityKey { index, label, color, icon, date })
76 }
77
78 pub fn set_archived(&self, index: usize, archived: bool) -> Result<(), crate::error::FidoError>
82 where
83 P: MessageAllowed<SetArchived>,
84 {
85 self.0.try_send_blocking_scalar(SetArchived { index, archived })?
86 }
87
88 pub fn list_security_keys(&self) -> Vec<SecurityKeyView>
91 where
92 P: MessageAllowed<ListSecurityKeys>,
93 {
94 self.0.send_blocking_archive(ListSecurityKeys)
95 }
96
97 pub fn selected_security_key_index(&self) -> Result<Option<usize>, crate::error::FidoError>
99 where
100 P: MessageAllowed<GetSelectedSecurityKey>,
101 {
102 Ok(self.0.try_send_blocking_scalar(GetSelectedSecurityKey)?)
103 }
104
105 pub fn select_security_key(&self, index: Option<usize>)
107 where
108 P: MessageAllowed<SelectSecurityKey>,
109 {
110 self.0.try_send_scalar(SelectSecurityKey(index)).ok();
111 }
112
113 pub fn u2f_process_apdu(&self, command: U2fApduCommand, transport: Transport) -> Vec<u8>
116 where
117 P: MessageAllowed<U2fProcessApdu>,
118 {
119 self.0.send_blocking_archive(U2fProcessApdu { command, transport })
120 }
121
122 pub fn ctap_process_cbor(&self, cmd: u8, raw: Vec<u8>) -> Vec<u8>
123 where
124 P: MessageAllowed<CtapProcessCbor>,
125 {
126 self.0.send_blocking_archive(CtapProcessCbor { cmd, raw })
127 }
128
129 #[cfg(feature = "test-app")]
132 pub fn reset_state(&mut self) -> Result<(), crate::error::FidoError>
133 where
134 P: MessageAllowed<ResetState>,
135 {
136 self.0.try_send_blocking_scalar(ResetState)?
137 }
138}