fido-common: Add attestation::Statement data type

Attestation statements are returned as part of the CBOR maps returned by
authenticators in response to authenticatorMakeCredential and
authenticatorGetAssertion commands.

The attestation statements defined by WebAuthn come in various formats.
However, the format identifier is not part of the attestation statement
field in the CBOR map (0x03 attStmt), but rather as a distinct format
field (fmt 0x01).

Normally, this could be worked around with an externally tagged enum,
but using integer tags is not currently supported by serde. By marking
the enum instead as untagged, this should ideally mean that serde can
differentiate between the enum variants by the fields of the attestation
statement, which is itself a CBOR map.

Otherwise, we could always revert to just raw byte sequences for the
attestation statements during (de)serialization and push validating
these statements onto another part of the code.
main
Nick Zana 2 years ago
parent a0bd1c9e01
commit 6ef8cee4de

@ -1,5 +1,10 @@
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use crate::credential::public_key::algorithm;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[cfg(feature = "serde")]
use serde_with::{serde_as, Bytes};
pub mod enterprise; pub mod enterprise;
/// > Attestation statement formats are identified by a string, called an /// > Attestation statement formats are identified by a string, called an
@ -71,6 +76,31 @@ pub enum FormatIdentifier {
None, None,
} }
#[cfg_eval]
#[derive(Debug)]
#[cfg_attr(
feature = "serde",
serde_as,
derive(Serialize, Deserialize),
// TODO: Workaround until serde can use integer keys as tag, since "fmt" is CBOR key 0x01.
serde(untagged)
)]
pub enum Statement {
#[cfg_attr(feature = "serde", serde(rename = "packed"))]
Packed {
#[cfg_attr(feature = "serde", serde(rename = "alg", with = "algorithm"))]
algorithm: coset::iana::Algorithm,
#[cfg_attr(feature = "serde", serde_as(as = "Bytes"), serde(rename = "sig"))]
signature: Vec<u8>,
#[cfg_attr(feature = "serde", serde_as(as = "Vec<Bytes>"), serde(rename = "x5c"))]
attestation_certificate_chain: Vec<Vec<u8>>, // TODO: Parse X.509 certs
},
Unregistered {
identifier: String,
data: Vec<u8>,
},
}
/// > Attested credential data is a variable-length byte array added to the /// > Attested credential data is a variable-length byte array added to the
/// > authenticator data when generating an attestation object for a given /// > authenticator data when generating an attestation object for a given
/// > credential. /// > credential.

Loading…
Cancel
Save