ctap_types/ctap2/
get_assertion.rs1use crate::{Bytes, Vec};
2use cosey::EcdhEsHkdf256PublicKey;
3use serde::{Deserialize, Serialize};
4use serde_bytes::ByteArray;
5use serde_indexed::{DeserializeIndexed, SerializeIndexed};
6
7use super::{AttestationFormatsPreference, AttestationStatement, AuthenticatorOptions, Result};
8use crate::sizes::*;
9use crate::webauthn::*;
10
11#[derive(Clone, Debug, Eq, PartialEq, SerializeIndexed, DeserializeIndexed)]
12#[non_exhaustive]
13#[serde_indexed(offset = 1)]
14pub struct HmacSecretInput {
15 pub key_agreement: EcdhEsHkdf256PublicKey,
16 pub salt_enc: Bytes<80>,
18 pub salt_auth: Bytes<32>,
19 #[serde(skip_serializing_if = "Option::is_none")]
20 pub pin_protocol: Option<u32>,
21}
22
23#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
24#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
25#[non_exhaustive]
26pub struct ExtensionsInput {
27 #[serde(rename = "hmac-secret")]
28 #[serde(skip_serializing_if = "Option::is_none")]
29 pub hmac_secret: Option<HmacSecretInput>,
30
31 #[serde(rename = "largeBlobKey")]
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub large_blob_key: Option<bool>,
35
36 #[cfg(feature = "third-party-payment")]
37 #[serde(rename = "thirdPartyPayment")]
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub third_party_payment: Option<bool>,
40}
41
42#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
43#[non_exhaustive]
44pub struct ExtensionsOutput {
45 #[serde(rename = "hmac-secret")]
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub hmac_secret: Option<Bytes<80>>,
49
50 #[cfg(feature = "third-party-payment")]
51 #[serde(rename = "thirdPartyPayment")]
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub third_party_payment: Option<bool>,
54}
55
56impl ExtensionsOutput {
57 #[inline]
58 pub fn is_set(&self) -> bool {
59 let Self {
60 hmac_secret,
61 #[cfg(feature = "third-party-payment")]
62 third_party_payment,
63 } = self;
64 if hmac_secret.is_some() {
65 return true;
66 }
67 #[cfg(feature = "third-party-payment")]
68 if third_party_payment.is_some() {
69 return true;
70 }
71 false
72 }
73}
74
75pub struct NoAttestedCredentialData;
76
77impl super::SerializeAttestedCredentialData for NoAttestedCredentialData {
78 fn serialize(&self, _buffer: &mut super::SerializedAuthenticatorData) -> Result<()> {
79 Ok(())
80 }
81}
82
83pub type AuthenticatorData<'a> =
84 super::AuthenticatorData<'a, NoAttestedCredentialData, ExtensionsOutput>;
85
86pub type AllowList<'a> = Vec<PublicKeyCredentialDescriptorRef<'a>, MAX_CREDENTIAL_COUNT_IN_LIST>;
87
88#[derive(Clone, Debug, Eq, PartialEq, DeserializeIndexed)]
89#[non_exhaustive]
90#[serde_indexed(offset = 1)]
91pub struct Request<'a> {
92 pub rp_id: &'a str,
93 pub client_data_hash: &'a serde_bytes::Bytes,
94 #[serde(skip_serializing_if = "Option::is_none")]
95 pub allow_list: Option<AllowList<'a>>,
96 #[serde(skip_serializing_if = "Option::is_none")]
97 pub extensions: Option<ExtensionsInput>,
98 #[serde(skip_serializing_if = "Option::is_none")]
99 pub options: Option<AuthenticatorOptions>,
100 #[serde(skip_serializing_if = "Option::is_none")]
101 pub pin_auth: Option<&'a serde_bytes::Bytes>,
102 #[serde(skip_serializing_if = "Option::is_none")]
103 pub pin_protocol: Option<u32>,
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub enterprise_attestation: Option<u32>,
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub attestation_formats_preference: Option<AttestationFormatsPreference>,
108}
109
110#[derive(Clone, Debug, Eq, PartialEq, SerializeIndexed)]
114#[non_exhaustive]
115#[serde_indexed(offset = 1)]
116pub struct Response {
117 pub credential: PublicKeyCredentialDescriptor,
118 pub auth_data: Bytes<AUTHENTICATOR_DATA_LENGTH>,
119 pub signature: Bytes<ASN1_SIGNATURE_LENGTH>,
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub user: Option<PublicKeyCredentialUserEntity>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub number_of_credentials: Option<u32>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub user_selected: Option<bool>,
126 #[serde(skip_serializing_if = "Option::is_none")]
129 pub large_blob_key: Option<ByteArray<32>>,
130 #[serde(skip_serializing_if = "Option::is_none")]
131 pub unsigned_extension_outputs: Option<UnsignedExtensionOutputs>,
132 #[serde(skip_serializing_if = "Option::is_none")]
133 pub ep_att: Option<bool>,
134 #[serde(skip_serializing_if = "Option::is_none")]
135 pub att_stmt: Option<AttestationStatement>,
136}
137
138#[derive(Debug)]
139pub struct ResponseBuilder {
140 pub credential: PublicKeyCredentialDescriptor,
141 pub auth_data: Bytes<AUTHENTICATOR_DATA_LENGTH>,
142 pub signature: Bytes<ASN1_SIGNATURE_LENGTH>,
143}
144
145impl ResponseBuilder {
146 #[inline(always)]
147 pub fn build(self) -> Response {
148 Response {
149 credential: self.credential,
150 auth_data: self.auth_data,
151 signature: self.signature,
152 user: None,
153 number_of_credentials: None,
154 user_selected: None,
155 large_blob_key: None,
156 unsigned_extension_outputs: None,
157 ep_att: None,
158 att_stmt: None,
159 }
160 }
161}
162
163#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
164#[non_exhaustive]
165pub struct UnsignedExtensionOutputs {}