1use crate::error::DfnsError;
4use async_trait::async_trait;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub enum CredentialTransport {
10 Ble,
11
12 Internal,
13
14 Nfc,
15
16 Usb,
17}
18
19#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
20pub struct AllowCredential {
21 pub id: String,
22
23 #[serde(rename = "type")]
24 pub allow_credential_type: Type,
25}
26
27#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
28#[serde(rename_all = "kebab-case")]
29pub enum Type {
30 #[serde(rename = "public-key")]
31 PublicKey,
32}
33
34#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
35#[serde(rename_all = "camelCase")]
36pub struct SupportedCredential {
37 pub factor: CredentialFactor,
38
39 pub kind: CredentialKind,
40
41 pub requires_second_factor: bool,
42}
43
44#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
45#[serde(rename_all = "snake_case")]
46pub enum CredentialFactor {
47 Either,
48
49 First,
50
51 Second,
52}
53
54#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
55pub enum CredentialKind {
56 Fido2,
57
58 Key,
59
60 Password,
61
62 #[serde(rename = "PasswordProtectedKey")]
63 PasswordProtectedKey,
64
65 #[serde(rename = "RecoveryKey")]
66 RecoveryKey,
67
68 Totp,
69}
70
71#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
72#[serde(rename_all = "camelCase")]
73pub struct UserActionChallenge {
74 pub allow_credentials: AllowCredentials,
75
76 pub challenge: String,
77
78 pub challenge_identifier: String,
79
80 pub external_authentication_url: String,
81
82 pub rp: Option<Rp>,
83
84 pub supported_credential_kinds: Vec<SupportedCredentialKind>,
85
86 pub user_verification: UserVerificationRequirement,
87}
88
89#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
90pub struct AllowCredentials {
91 pub key: Vec<Key>,
92
93 pub webauthn: Vec<Webauthn>,
94}
95
96#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
97pub struct Key {
98 pub id: String,
99
100 #[serde(rename = "type")]
101 pub key_type: Type,
102}
103
104#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
105pub struct Webauthn {
106 pub id: String,
107
108 #[serde(rename = "type")]
109 pub webauthn_type: Type,
110}
111
112#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
113pub struct Rp {
114 pub id: String,
115
116 pub name: String,
117}
118
119#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
120#[serde(rename_all = "camelCase")]
121pub struct SupportedCredentialKind {
122 pub factor: CredentialFactor,
123
124 pub kind: CredentialKind,
125
126 pub requires_second_factor: bool,
127}
128
129#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
130#[serde(rename_all = "snake_case")]
131pub enum UserVerificationRequirement {
132 Discouraged,
133
134 Preferred,
135
136 Required,
137}
138
139#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
140#[serde(rename_all = "camelCase")]
141pub struct KeyAssertion {
142 pub credential_assertion: KeyAssertionCredentialAssertion,
143
144 pub kind: KeyAssertionKind,
145}
146
147#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
148#[serde(rename_all = "camelCase")]
149pub struct KeyAssertionCredentialAssertion {
150 pub algorithm: Option<String>,
151
152 pub client_data: String,
153
154 pub cred_id: String,
155
156 pub signature: String,
157}
158
159#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
160pub enum KeyAssertionKind {
161 Key,
162}
163
164#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
165#[serde(rename_all = "camelCase")]
166pub struct Fido2Assertion {
167 pub credential_assertion: Fido2AssertionCredentialAssertion,
168
169 pub kind: Fido2AssertionKind,
170}
171
172#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
173#[serde(rename_all = "camelCase")]
174pub struct Fido2AssertionCredentialAssertion {
175 pub authenticator_data: String,
176
177 pub client_data: String,
178
179 pub cred_id: String,
180
181 pub signature: String,
182
183 pub user_handle: Option<String>,
184}
185
186#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
187pub enum Fido2AssertionKind {
188 Fido2,
189}
190
191#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
192pub struct PasswordAssertion {
193 pub kind: PasswordAssertionKind,
194
195 pub password: String,
196}
197
198#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
199pub enum PasswordAssertionKind {
200 Password,
201}
202
203#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
204#[serde(rename_all = "camelCase")]
205pub struct TotpAssertion {
206 pub kind: TotpAssertionKind,
207
208 pub otp_code: String,
209}
210
211#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
212pub enum TotpAssertionKind {
213 Totp,
214}
215
216#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
217#[serde(rename_all = "camelCase")]
218pub struct RecoveryKeyAssertion {
219 pub credential_assertion: RecoveryKeyAssertionCredentialAssertion,
220
221 pub kind: RecoveryKeyAssertionKind,
222}
223
224#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
225#[serde(rename_all = "camelCase")]
226pub struct RecoveryKeyAssertionCredentialAssertion {
227 pub algorithm: Option<String>,
228
229 pub client_data: String,
230
231 pub cred_id: String,
232
233 pub signature: String,
234}
235
236#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
237pub enum RecoveryKeyAssertionKind {
238 #[serde(rename = "RecoveryKey")]
239 RecoveryKey,
240}
241
242#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
243#[serde(rename_all = "camelCase")]
244pub struct FirstFactorAssertion {
245 pub credential_assertion: Option<FirstFactorAssertionCredentialAssertion>,
246
247 pub kind: FirstFactorAssertionKind,
248
249 pub password: Option<String>,
250}
251
252#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
253#[serde(rename_all = "camelCase")]
254pub struct FirstFactorAssertionCredentialAssertion {
255 pub algorithm: Option<String>,
256
257 pub client_data: String,
258
259 pub cred_id: String,
260
261 pub signature: String,
262
263 pub authenticator_data: Option<String>,
264
265 pub user_handle: Option<String>,
266}
267
268#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
269pub enum FirstFactorAssertionKind {
270 Fido2,
271
272 Key,
273
274 Password,
275}
276
277#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
278#[serde(rename_all = "camelCase")]
279pub struct SecondFactorAssertion {
280 pub credential_assertion: Option<SecondFactorAssertionCredentialAssertion>,
281
282 pub kind: SecondFactorAssertionKind,
283
284 pub otp_code: Option<String>,
285}
286
287#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
288#[serde(rename_all = "camelCase")]
289pub struct SecondFactorAssertionCredentialAssertion {
290 pub algorithm: Option<String>,
291
292 pub client_data: String,
293
294 pub cred_id: String,
295
296 pub signature: String,
297
298 pub authenticator_data: Option<String>,
299
300 pub user_handle: Option<String>,
301}
302
303#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
304pub enum SecondFactorAssertionKind {
305 Fido2,
306
307 Key,
308
309 Totp,
310}
311
312#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
313#[serde(rename_all = "camelCase")]
314pub struct CredentialAssertion {
315 pub credential_assertion: Option<CredentialAssertionCredentialAssertion>,
316
317 pub kind: CredentialAssertionKind,
318
319 pub password: Option<String>,
320
321 pub otp_code: Option<String>,
322}
323
324#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
325#[serde(rename_all = "camelCase")]
326pub struct CredentialAssertionCredentialAssertion {
327 pub algorithm: Option<String>,
328
329 pub client_data: String,
330
331 pub cred_id: String,
332
333 pub signature: String,
334
335 pub authenticator_data: Option<String>,
336
337 pub user_handle: Option<String>,
338}
339
340#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
341pub enum CredentialAssertionKind {
342 Fido2,
343
344 Key,
345
346 Password,
347
348 Totp,
349}
350
351#[async_trait]
352pub trait CredentialSigner: Send + Sync {
353 async fn sign(&self, challenge: UserActionChallenge)
354 -> Result<FirstFactorAssertion, DfnsError>;
355}