diff --git a/CHANGELOG.md b/CHANGELOG.md index af899e5..329afc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -[Unreleased]: https://github.com/trussed-dev/ctap-types/compare/0.3.2...HEAD +[Unreleased]: https://github.com/trussed-dev/ctap-types/compare/0.4.0...HEAD - +## [0.4.0] 2025-05-09 + +[0.4.0]: https://github.com/trussed-dev/ctap-types/compare/0.3.2...0.4.0 + +- Make `pin_protocol` optional in `ctap2::client_pin::Request` for compliance with CTAP 2.1. + ## [0.3.2] 2024-10-24 [0.3.2]: https://github.com/trussed-dev/ctap-types/compare/0.3.1...0.3.2 diff --git a/Cargo.toml b/Cargo.toml index e3a43cf..359c857 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ctap-types" -version = "0.3.2" +version = "0.4.0" authors = ["Nicolas Stalder ", "The Trussed developers"] edition = "2021" license = "Apache-2.0 OR MIT" @@ -38,6 +38,7 @@ third-party-payment = [] log-all = [] log-none = [] +log-trace = [] log-info = [] log-debug = [] log-warn = [] diff --git a/src/ctap1.rs b/src/ctap1.rs index 0fc6153..805f023 100644 --- a/src/ctap1.rs +++ b/src/ctap1.rs @@ -156,7 +156,7 @@ impl Response { impl<'a, const S: usize> TryFrom<&'a iso7816::Command> for Request<'a> { type Error = Error; - fn try_from(apdu: &'a iso7816::Command) -> Result { + fn try_from(apdu: &'a iso7816::Command) -> Result> { apdu.as_view().try_into() } } @@ -164,7 +164,7 @@ impl<'a, const S: usize> TryFrom<&'a iso7816::Command> for Request<'a> { impl<'a> TryFrom> for Request<'a> { type Error = Error; #[inline(never)] - fn try_from(apdu: iso7816::command::CommandView<'a>) -> Result { + fn try_from(apdu: iso7816::command::CommandView<'a>) -> Result> { let cla = apdu.class().into_inner(); let ins = match apdu.instruction() { iso7816::Instruction::Unknown(ins) => ins, diff --git a/src/ctap2.rs b/src/ctap2.rs index 8136be2..354a5c1 100644 --- a/src/ctap2.rs +++ b/src/ctap2.rs @@ -219,7 +219,7 @@ pub type SerializedAuthenticatorData = Bytes; // The reason for this non-use of CBOR is for compatibility with // FIDO U2F authentication signatures. -impl<'a, A: SerializeAttestedCredentialData, E: serde::Serialize> AuthenticatorData<'a, A, E> { +impl AuthenticatorData<'_, A, E> { #[inline(never)] pub fn serialize(&self) -> Result { let mut bytes = SerializedAuthenticatorData::new(); @@ -544,7 +544,7 @@ pub trait Authenticator { } } -impl<'a, A: Authenticator> crate::Rpc, Response> for A { +impl crate::Rpc, Response> for A { /// Dispatches the enum of possible requests into the appropriate trait method. #[inline(never)] fn call(&mut self, request: &Request) -> Result { diff --git a/src/ctap2/client_pin.rs b/src/ctap2/client_pin.rs index 048f375..50b4dae 100644 --- a/src/ctap2/client_pin.rs +++ b/src/ctap2/client_pin.rs @@ -41,8 +41,8 @@ bitflags! { pub struct Request<'a> { // 0x01 // PIN protocol version chosen by the client. - // For this version of the spec, this SHALL be the number 1. - pub pin_protocol: u8, + #[serde(skip_serializing_if = "Option::is_none")] + pub pin_protocol: Option, // 0x02 // The authenticator Client PIN sub command currently being requested @@ -119,7 +119,7 @@ pub struct Response { mod tests { use super::*; use hex_literal::hex; - use serde_test::{assert_de_tokens, assert_ser_tokens, assert_tokens, Token}; + use serde_test::{assert_de_tokens, assert_ser_tokens, Token}; const KEY_AGREEMENT: &[u8] = &hex!("b174bc49c7ca254b70d2e5c207cee9cf174820ebd77ea3c65508c26da51b657c1cc6b952f8621697936482da0a6d3d3826a59095daf6cd7c03e2e60385d2f6d9"); const NEW_PIN_ENC: &[u8] = &[0xde; 64]; @@ -130,7 +130,7 @@ mod tests { #[test] fn test_de_request_get_retries() { let request = Request { - pin_protocol: 1, + pin_protocol: Some(1), sub_command: PinV1Subcommand::GetRetries, key_agreement: None, pin_auth: None, @@ -141,7 +141,7 @@ mod tests { permissions: None, rp_id: None, }; - assert_tokens( + assert_de_tokens( &request, &[ Token::Map { len: Some(2) }, @@ -159,7 +159,7 @@ mod tests { #[test] fn test_de_request_get_key_agreement() { let request = Request { - pin_protocol: 1, + pin_protocol: Some(1), sub_command: PinV1Subcommand::GetKeyAgreement, key_agreement: None, pin_auth: None, @@ -170,7 +170,7 @@ mod tests { permissions: None, rp_id: None, }; - assert_tokens( + assert_de_tokens( &request, &[ Token::Map { len: Some(2) }, @@ -192,7 +192,7 @@ mod tests { y: Bytes::from_slice(&KEY_AGREEMENT[32..]).unwrap(), }; let request = Request { - pin_protocol: 1, + pin_protocol: Some(1), sub_command: PinV1Subcommand::SetPin, key_agreement: Some(key_agreement), pin_auth: Some(serde_bytes::Bytes::new(PIN_AUTH)), @@ -250,7 +250,7 @@ mod tests { y: Bytes::from_slice(&KEY_AGREEMENT[32..]).unwrap(), }; let request = Request { - pin_protocol: 1, + pin_protocol: Some(1), sub_command: PinV1Subcommand::ChangePin, key_agreement: Some(key_agreement), pin_auth: Some(serde_bytes::Bytes::new(PIN_AUTH)), @@ -311,7 +311,7 @@ mod tests { y: Bytes::from_slice(&KEY_AGREEMENT[32..]).unwrap(), }; let request = Request { - pin_protocol: 1, + pin_protocol: Some(1), sub_command: PinV1Subcommand::GetPinToken, key_agreement: Some(key_agreement), pin_auth: None, @@ -366,7 +366,7 @@ mod tests { y: Bytes::from_slice(&KEY_AGREEMENT[32..]).unwrap(), }; let request = Request { - pin_protocol: 1, + pin_protocol: Some(1), sub_command: PinV1Subcommand::GetPinUvAuthTokenUsingPinWithPermissions, key_agreement: Some(key_agreement), pin_auth: None, diff --git a/src/ctap2/make_credential.rs b/src/ctap2/make_credential.rs index 0d6f992..9ebabaa 100644 --- a/src/ctap2/make_credential.rs +++ b/src/ctap2/make_credential.rs @@ -87,7 +87,7 @@ pub struct AttestedCredentialData<'a> { pub credential_public_key: &'a [u8], } -impl<'a> super::SerializeAttestedCredentialData for AttestedCredentialData<'a> { +impl super::SerializeAttestedCredentialData for AttestedCredentialData<'_> { fn serialize(&self, buffer: &mut super::SerializedAuthenticatorData) -> Result<(), Error> { // TODO: validate lengths of credential ID and credential public key // 16 bytes, the aaguid