use crate::{Bytes, Vec};
use cosey::EcdhEsHkdf256PublicKey;
use serde::{Deserialize, Serialize};
use serde_bytes::ByteArray;
use serde_indexed::{DeserializeIndexed, SerializeIndexed};
use super::{AttestationFormatsPreference, AttestationStatement, AuthenticatorOptions, Result};
use crate::sizes::*;
use crate::webauthn::*;
#[derive(Clone, Debug, Eq, PartialEq, SerializeIndexed, DeserializeIndexed)]
#[non_exhaustive]
#[serde_indexed(offset = 1)]
pub struct HmacSecretInput {
pub key_agreement: EcdhEsHkdf256PublicKey,
pub salt_enc: Bytes<80>,
pub salt_auth: Bytes<32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pin_protocol: Option<u32>,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[non_exhaustive]
pub struct ExtensionsInput {
#[serde(rename = "hmac-secret")]
#[serde(skip_serializing_if = "Option::is_none")]
pub hmac_secret: Option<HmacSecretInput>,
#[serde(rename = "largeBlobKey")]
#[serde(skip_serializing_if = "Option::is_none")]
pub large_blob_key: Option<bool>,
#[cfg(feature = "third-party-payment")]
#[serde(rename = "thirdPartyPayment")]
#[serde(skip_serializing_if = "Option::is_none")]
pub third_party_payment: Option<bool>,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct ExtensionsOutput {
#[serde(rename = "hmac-secret")]
#[serde(skip_serializing_if = "Option::is_none")]
pub hmac_secret: Option<Bytes<80>>,
#[cfg(feature = "third-party-payment")]
#[serde(rename = "thirdPartyPayment")]
#[serde(skip_serializing_if = "Option::is_none")]
pub third_party_payment: Option<bool>,
}
impl ExtensionsOutput {
#[inline]
pub fn is_set(&self) -> bool {
let Self {
hmac_secret,
#[cfg(feature = "third-party-payment")]
third_party_payment,
} = self;
if hmac_secret.is_some() {
return true;
}
#[cfg(feature = "third-party-payment")]
if third_party_payment.is_some() {
return true;
}
false
}
}
pub struct NoAttestedCredentialData;
impl super::SerializeAttestedCredentialData for NoAttestedCredentialData {
fn serialize(&self, _buffer: &mut super::SerializedAuthenticatorData) -> Result<()> {
Ok(())
}
}
pub type AuthenticatorData<'a> =
super::AuthenticatorData<'a, NoAttestedCredentialData, ExtensionsOutput>;
pub type AllowList<'a> = Vec<PublicKeyCredentialDescriptorRef<'a>, MAX_CREDENTIAL_COUNT_IN_LIST>;
#[derive(Clone, Debug, Eq, PartialEq, DeserializeIndexed)]
#[non_exhaustive]
#[serde_indexed(offset = 1)]
pub struct Request<'a> {
pub rp_id: &'a str,
pub client_data_hash: &'a serde_bytes::Bytes,
#[serde(skip_serializing_if = "Option::is_none")]
pub allow_list: Option<AllowList<'a>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub extensions: Option<ExtensionsInput>,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<AuthenticatorOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pin_auth: Option<&'a serde_bytes::Bytes>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pin_protocol: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub enterprise_attestation: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attestation_formats_preference: Option<AttestationFormatsPreference>,
}
#[derive(Clone, Debug, Eq, PartialEq, SerializeIndexed)]
#[non_exhaustive]
#[serde_indexed(offset = 1)]
pub struct Response {
pub credential: PublicKeyCredentialDescriptor,
pub auth_data: Bytes<AUTHENTICATOR_DATA_LENGTH>,
pub signature: Bytes<ASN1_SIGNATURE_LENGTH>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user: Option<PublicKeyCredentialUserEntity>,
#[serde(skip_serializing_if = "Option::is_none")]
pub number_of_credentials: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_selected: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub large_blob_key: Option<ByteArray<32>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unsigned_extension_outputs: Option<UnsignedExtensionOutputs>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ep_att: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub att_stmt: Option<AttestationStatement>,
}
#[derive(Debug)]
pub struct ResponseBuilder {
pub credential: PublicKeyCredentialDescriptor,
pub auth_data: Bytes<AUTHENTICATOR_DATA_LENGTH>,
pub signature: Bytes<ASN1_SIGNATURE_LENGTH>,
}
impl ResponseBuilder {
#[inline(always)]
pub fn build(self) -> Response {
Response {
credential: self.credential,
auth_data: self.auth_data,
signature: self.signature,
user: None,
number_of_credentials: None,
user_selected: None,
large_blob_key: None,
unsigned_extension_outputs: None,
ep_att: None,
att_stmt: None,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
#[non_exhaustive]
pub struct UnsignedExtensionOutputs {}