mirror of
https://github.com/trussed-dev/ctap-types.git
synced 2026-06-20 04:16:17 -07:00
ctap2.2: add wire types for FIDO_2_2 and hmac-secret-mc
This commit is contained in:
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Add `AuthenticatorConfig` command.
|
||||
- Add `credBlob` extension and split `make_credential::Extensions` into `ExtensionsInput` and `ExtensionsOutput`.
|
||||
- Add `minPinLength` extension.
|
||||
- Add support for missing CTAP 2.2 features:
|
||||
- Add `hmac-secret-mc` extension.
|
||||
|
||||
## [0.5.0] 2026-03-23
|
||||
|
||||
|
||||
@@ -308,6 +308,7 @@ impl<'a> Arbitrary<'a> for ctap2::make_credential::ExtensionsInput<'a> {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let hmac_secret_mc = u.arbitrary()?;
|
||||
Ok(Self {
|
||||
cred_protect,
|
||||
hmac_secret,
|
||||
@@ -315,6 +316,7 @@ impl<'a> Arbitrary<'a> for ctap2::make_credential::ExtensionsInput<'a> {
|
||||
#[cfg(feature = "third-party-payment")]
|
||||
third_party_payment,
|
||||
cred_blob,
|
||||
hmac_secret_mc,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ pub struct Response {
|
||||
|
||||
// 0x02
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub extensions: Option<Vec<Extension, 6>>,
|
||||
pub extensions: Option<Vec<Extension, 7>>,
|
||||
|
||||
// 0x03
|
||||
pub aaguid: Bytes<16>,
|
||||
@@ -252,6 +252,7 @@ pub enum Extension {
|
||||
CredProtect,
|
||||
CredBlob,
|
||||
HmacSecret,
|
||||
HmacSecretMc,
|
||||
LargeBlobKey,
|
||||
MinPinLength,
|
||||
ThirdPartyPayment,
|
||||
@@ -261,6 +262,7 @@ impl Extension {
|
||||
const CRED_PROTECT: &'static str = "credProtect";
|
||||
const CRED_BLOB: &'static str = "credBlob";
|
||||
const HMAC_SECRET: &'static str = "hmac-secret";
|
||||
const HMAC_SECRET_MC: &'static str = "hmac-secret-mc";
|
||||
const LARGE_BLOB_KEY: &'static str = "largeBlobKey";
|
||||
const MIN_PIN_LENGTH: &'static str = "minPinLength";
|
||||
const THIRD_PARTY_PAYMENT: &'static str = "thirdPartyPayment";
|
||||
@@ -272,6 +274,7 @@ impl From<Extension> for &str {
|
||||
Extension::CredProtect => Extension::CRED_PROTECT,
|
||||
Extension::CredBlob => Extension::CRED_BLOB,
|
||||
Extension::HmacSecret => Extension::HMAC_SECRET,
|
||||
Extension::HmacSecretMc => Extension::HMAC_SECRET_MC,
|
||||
Extension::LargeBlobKey => Extension::LARGE_BLOB_KEY,
|
||||
Extension::MinPinLength => Extension::MIN_PIN_LENGTH,
|
||||
Extension::ThirdPartyPayment => Extension::THIRD_PARTY_PAYMENT,
|
||||
@@ -287,6 +290,7 @@ impl TryFrom<&str> for Extension {
|
||||
Self::CRED_PROTECT => Ok(Self::CredProtect),
|
||||
Self::CRED_BLOB => Ok(Self::CredBlob),
|
||||
Self::HMAC_SECRET => Ok(Self::HmacSecret),
|
||||
Self::HMAC_SECRET_MC => Ok(Self::HmacSecretMc),
|
||||
Self::LARGE_BLOB_KEY => Ok(Self::LargeBlobKey),
|
||||
Self::MIN_PIN_LENGTH => Ok(Self::MinPinLength),
|
||||
Self::THIRD_PARTY_PAYMENT => Ok(Self::ThirdPartyPayment),
|
||||
@@ -475,6 +479,7 @@ mod tests {
|
||||
(Extension::CredProtect, "credProtect"),
|
||||
(Extension::CredBlob, "credBlob"),
|
||||
(Extension::HmacSecret, "hmac-secret"),
|
||||
(Extension::HmacSecretMc, "hmac-secret-mc"),
|
||||
(Extension::LargeBlobKey, "largeBlobKey"),
|
||||
(Extension::MinPinLength, "minPinLength"),
|
||||
(Extension::ThirdPartyPayment, "thirdPartyPayment"),
|
||||
|
||||
@@ -51,6 +51,13 @@ pub struct ExtensionsInput<'a> {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub large_blob_key: Option<bool>,
|
||||
|
||||
/// `hmac-secret-mc` (CTAP 2.2 §11.4.5 / WebAuthn L3): platform-supplied
|
||||
/// hmac-secret request evaluated at MakeCredential time, returning
|
||||
/// hmac-secret outputs alongside the freshly-minted credential.
|
||||
#[serde(rename = "hmac-secret-mc")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub hmac_secret_mc: Option<super::get_assertion::HmacSecretInput>,
|
||||
|
||||
#[cfg(feature = "third-party-payment")]
|
||||
#[serde(rename = "thirdPartyPayment")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@@ -77,6 +84,13 @@ pub struct ExtensionsOutput {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub hmac_secret: Option<bool>,
|
||||
|
||||
/// `hmac-secret-mc` (CTAP 2.2): encrypted hmac-secret outputs produced at
|
||||
/// MakeCredential time. Wire format mirrors GetAssertion's `hmac-secret`
|
||||
/// output — `enc(output1)` or `enc(output1 || output2)`, up to 80 bytes.
|
||||
#[serde(rename = "hmac-secret-mc")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub hmac_secret_mc: Option<crate::Bytes<80>>,
|
||||
|
||||
#[cfg(feature = "third-party-payment")]
|
||||
#[serde(rename = "thirdPartyPayment")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@@ -190,6 +204,8 @@ pub struct UnsignedExtensionOutputs {}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ctap2::get_assertion::HmacSecretInput;
|
||||
use cosey::EcdhEsHkdf256PublicKey;
|
||||
use serde_test::{assert_ser_tokens, Token};
|
||||
|
||||
#[test]
|
||||
@@ -223,6 +239,15 @@ mod tests {
|
||||
#[cfg(feature = "third-party-payment")]
|
||||
third_party_payment: Some(true),
|
||||
cred_blob: Some(serde_bytes::Bytes::new(b"1234")),
|
||||
hmac_secret_mc: Some(HmacSecretInput {
|
||||
key_agreement: EcdhEsHkdf256PublicKey {
|
||||
x: [0xff; 32].try_into().unwrap(),
|
||||
y: [0xff; 32].try_into().unwrap(),
|
||||
},
|
||||
salt_enc: [0xff; 80].try_into().unwrap(),
|
||||
salt_auth: [0xff; 32].try_into().unwrap(),
|
||||
pin_protocol: Some(1),
|
||||
}),
|
||||
};
|
||||
crate::test::assert_canonical_cbor(&extensions);
|
||||
}
|
||||
@@ -235,6 +260,7 @@ mod tests {
|
||||
#[cfg(feature = "third-party-payment")]
|
||||
third_party_payment: Some(true),
|
||||
cred_blob: Some(true),
|
||||
hmac_secret_mc: Some([0xff; 80].try_into().unwrap()),
|
||||
};
|
||||
crate::test::assert_canonical_cbor(&extensions);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user