Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion libwebauthn/src/proto/ctap2/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ impl Ctap2PublicKeyCredentialUserEntity {
pub enum Ctap2PublicKeyCredentialType {
#[serde(rename = "public-key")]
PublicKey,

#[serde(other)]
Unknown,
}

#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -154,9 +157,11 @@ pub enum Ctap2COSEAlgorithmIdentifier {
ES256 = -7,
EDDSA = -8,
TOPT = -9,
#[serde(other)]
Unknown = -999,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub struct Ctap2CredentialType {
#[serde(rename = "alg")]
pub algorithm: Ctap2COSEAlgorithmIdentifier,
Expand Down Expand Up @@ -184,6 +189,11 @@ impl Ctap2CredentialType {
algorithm,
}
}

pub fn is_known(&self) -> bool {
self.algorithm != Ctap2COSEAlgorithmIdentifier::Unknown
&& self.public_key_type != Ctap2PublicKeyCredentialType::Unknown
}
}

pub trait Ctap2UserVerifiableRequest {
Expand Down Expand Up @@ -243,4 +253,44 @@ mod tests {
let expected = hex::decode("a2626964414264747970656a7075626c69632d6b6579").unwrap();
assert_eq!(serialized, expected);
}

#[test]
pub fn deserialize_known_credential_type() {
// python $ cbor2.dumps({"alg":-7,"type":"public-key"}).hex()
let serialized: Vec<u8> =
hex::decode("a263616c672664747970656a7075626c69632d6b6579").unwrap();
let credential_type: Ctap2CredentialType = serde_cbor::from_slice(&serialized).unwrap();
assert_eq!(
credential_type,
Ctap2CredentialType {
algorithm: Ctap2COSEAlgorithmIdentifier::ES256,
public_key_type: Ctap2PublicKeyCredentialType::PublicKey,
}
);
assert!(credential_type.is_known());
}

#[test]
pub fn deserialize_unknown_credential_type_algorithm() {
// python $ cbor2.dumps({"alg":-42,"type":"public-key"}).hex()
let serialized: Vec<u8> =
hex::decode("a263616c67382964747970656a7075626c69632d6b6579").unwrap();
let credential_type: Ctap2CredentialType = serde_cbor::from_slice(&serialized).unwrap();
assert_eq!(
credential_type,
Ctap2CredentialType {
algorithm: Ctap2COSEAlgorithmIdentifier::Unknown,
public_key_type: Ctap2PublicKeyCredentialType::PublicKey,
}
);
assert!(!credential_type.is_known());
}

#[test]
pub fn deserialize_unknown_credential_type() {
// python $ cbor2.dumps({"alg":-7,"type":"unknown"}).hex()
let serialized: Vec<u8> = hex::decode("a263616c6726647479706567756e6b6e6f776e").unwrap();
let credential_type: Ctap2CredentialType = serde_cbor::from_slice(&serialized).unwrap();
assert!(!credential_type.is_known());
}
}
Loading