From e099284e2819be0134231ac1485c202824675f2b Mon Sep 17 00:00:00 2001 From: Alfie Fresta Date: Sun, 23 Feb 2025 21:46:15 +0000 Subject: [PATCH] Move to cosey crate --- .gitmodules | 6 +- Cargo.lock | 139 ++++++++++++++---- cosey | 1 + ctap-types | 1 - libwebauthn/Cargo.toml | 5 +- libwebauthn/src/fido.rs | 2 +- libwebauthn/src/ops/u2f.rs | 2 +- libwebauthn/src/pin.rs | 2 +- .../proto/ctap2/model/authenticator_config.rs | 6 - .../src/proto/ctap2/model/bio_enrollment.rs | 27 +--- .../src/proto/ctap2/model/client_pin.rs | 7 +- .../ctap2/model/credential_management.rs | 28 +--- .../src/proto/ctap2/model/get_assertion.rs | 17 ++- libwebauthn/src/proto/ctap2/model/get_info.rs | 27 ---- .../src/transport/cable/qr_code_device.rs | 3 - libwebauthn/src/webauthn.rs | 2 +- 16 files changed, 148 insertions(+), 127 deletions(-) create mode 160000 cosey delete mode 160000 ctap-types diff --git a/.gitmodules b/.gitmodules index 78feb2a..c5fe319 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "solo/src/ext"] path = solo/src/ext url = https://github.com/AlfioEmanueleFresta/solo.git -[submodule "ctap-types"] - path = ctap-types - url = https://github.com/AlfioEmanueleFresta/ctap-types.git +[submodule "cosey"] + path = cosey + url = https://github.com/AlfioEmanueleFresta/cosey.git diff --git a/Cargo.lock b/Cargo.lock index eb244d0..e4f83f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -267,6 +267,18 @@ dependencies = [ "serde", ] +[[package]] +name = "cbor-smol" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087b31faa4ad4ba21c9bd0209204eef424dae6424195aafc7242006b69fc8d" +dependencies = [ + "delog", + "heapless", + "heapless-bytes", + "serde", +] + [[package]] name = "cc" version = "1.2.7" @@ -318,6 +330,33 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919" +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half 2.4.1", +] + [[package]] name = "cipher" version = "0.4.4" @@ -357,6 +396,20 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cosey" +version = "0.3.1" +dependencies = [ + "cbor-smol 0.4.1", + "ciborium", + "heapless-bytes", + "hex 0.4.3", + "itertools 0.12.1", + "quickcheck", + "serde", + "serde_repr", +] + [[package]] name = "cosey" version = "0.3.1" @@ -394,6 +447,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -418,21 +477,21 @@ dependencies = [ [[package]] name = "ctap-types" -version = "0.1.3" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1beeb5a05e42c7cbfb788ce3e9fd6ce7d0aa214893b5ca6cd38d09ac9afe722" dependencies = [ "bitflags 1.3.2", - "cbor-smol", - "cosey", + "cbor-smol 0.5.0", + "cosey 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "delog", "heapless", "heapless-bytes", - "interchange", "iso7816", "serde", "serde-indexed", - "serde_derive", + "serde_bytes", "serde_repr", - "serde_test", ] [[package]] @@ -631,6 +690,16 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "log", + "regex", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -833,6 +902,16 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if 1.0.0", + "crunchy", +] + [[package]] name = "hash32" version = "0.2.1" @@ -1124,12 +1203,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "interchange" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310d743c23f798f10d5ba2f77fdd3eff06aaf2d8f8b9d78beba7fb1167f4ccbf" - [[package]] name = "iso7816" version = "0.1.3" @@ -1149,6 +1222,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.14" @@ -1573,7 +1655,7 @@ checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "float-cmp", - "itertools", + "itertools 0.10.5", "normalize-line-endings", "predicates-core", "regex", @@ -1639,6 +1721,17 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quickcheck" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" +dependencies = [ + "env_logger 0.8.4", + "log", + "rand", +] + [[package]] name = "quote" version = "1.0.38" @@ -1903,13 +1996,13 @@ dependencies = [ [[package]] name = "serde-indexed" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "431fb604dab775c7bdabdab23b491ec773de085afd92b5dac26b8f3db5965f42" +checksum = "fca2da10b1f1623f47130256065e05e94fd7a98dbd26a780a4c5de831b21e5c2" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.95", ] [[package]] @@ -1927,7 +2020,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ - "half", + "half 1.8.3", "serde", ] @@ -1953,15 +2046,6 @@ dependencies = [ "syn 2.0.95", ] -[[package]] -name = "serde_test" -version = "1.0.177" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f901ee573cab6b3060453d2d5f0bae4e6d628c23c0a962ff9b5f1d7c8d4f1ed" -dependencies = [ - "serde", -] - [[package]] name = "serdect" version = "0.2.0" @@ -2076,7 +2160,7 @@ dependencies = [ name = "solo" version = "0.1.0" dependencies = [ - "env_logger", + "env_logger 0.7.1", "log", "tokio", ] @@ -2734,6 +2818,7 @@ dependencies = [ "blurz", "byteorder", "cbc", + "cosey 0.3.1", "ctap-types", "curve25519-dalek", "dbus 0.9.7", diff --git a/cosey b/cosey new file mode 160000 index 0000000..3d30a03 --- /dev/null +++ b/cosey @@ -0,0 +1 @@ +Subproject commit 3d30a03abc7c7a4f501f46727fbe2396233fc94a diff --git a/ctap-types b/ctap-types deleted file mode 160000 index 295dca4..0000000 --- a/ctap-types +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 295dca4fad0e3beba8d185ae5d55931a1096ac9d diff --git a/libwebauthn/Cargo.toml b/libwebauthn/Cargo.toml index 5727ef8..26b1a8d 100644 --- a/libwebauthn/Cargo.toml +++ b/libwebauthn/Cargo.toml @@ -27,7 +27,7 @@ futures = "0.3.5" tokio = { version = "1.1.1", features = ["full"] } serde = "1.0.110" serde_cbor = "0.11.1" -serde-indexed = "=0.1.0" +serde-indexed = "0.1.1" serde_derive = "1.0.123" serde_repr = "0.1.6" serde_bytes = "0.11.5" @@ -53,7 +53,6 @@ aes = "0.8.2" hmac = "0.12.1" cbc = { version = "0.1", features = ["alloc"] } hkdf = "0.12" -ctap-types = { path = "../ctap-types", features = ["alloc"] } solo = { path = "../solo", optional = true } text_io = "0.1" tungstenite = { version = "0.20.1" } @@ -62,6 +61,8 @@ tokio-tungstenite = { version = "0.20.1", features = [ ] } tokio-stream = "0.1.4" snow = { version = "0.10.0-alpha.1", features = ["use-p256"] } +cosey = { path = "../cosey" } +ctap-types = { version = "0.3.2" } [dev-dependencies] tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } diff --git a/libwebauthn/src/fido.rs b/libwebauthn/src/fido.rs index f27c84d..b870a10 100644 --- a/libwebauthn/src/fido.rs +++ b/libwebauthn/src/fido.rs @@ -1,5 +1,5 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; -use ctap_types::cose::PublicKey; +use cosey::PublicKey; use serde::{ de::{DeserializeOwned, Error as DesError, Visitor}, ser::Error as SerError, diff --git a/libwebauthn/src/ops/u2f.rs b/libwebauthn/src/ops/u2f.rs index c006a60..8ff5f53 100644 --- a/libwebauthn/src/ops/u2f.rs +++ b/libwebauthn/src/ops/u2f.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use ctap_types::cose; +use cosey as cose; use serde_bytes::ByteBuf; use serde_cbor::to_vec; use sha2::{Digest, Sha256}; diff --git a/libwebauthn/src/pin.rs b/libwebauthn/src/pin.rs index 2fd13c6..1fdc10f 100644 --- a/libwebauthn/src/pin.rs +++ b/libwebauthn/src/pin.rs @@ -5,7 +5,7 @@ use super::transport::error::Error; use aes::cipher::{block_padding::NoPadding, BlockDecryptMut}; use async_trait::async_trait; use cbc::cipher::{BlockEncryptMut, KeyIvInit}; -use ctap_types::cose; +use cosey as cose; use hkdf::Hkdf; use hmac::Mac; use p256::{ diff --git a/libwebauthn/src/proto/ctap2/model/authenticator_config.rs b/libwebauthn/src/proto/ctap2/model/authenticator_config.rs index c290553..260ff39 100644 --- a/libwebauthn/src/proto/ctap2/model/authenticator_config.rs +++ b/libwebauthn/src/proto/ctap2/model/authenticator_config.rs @@ -12,17 +12,14 @@ pub struct Ctap2AuthenticatorConfigRequest { pub subcommand: Ctap2AuthenticatorConfigCommand, // subCommandParams (0x02) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub subcommand_params: Option, ///pinUvAuthProtocol (0x03) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub protocol: Option, /// pinUvAuthParam (0x04): - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub uv_auth_param: Option, } @@ -112,17 +109,14 @@ pub enum Ctap2AuthenticatorConfigParams { #[serde_indexed(offset = 1)] pub struct Ctap2SetMinPINLengthParams { // newMinPINLength (0x01) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub new_min_pin_length: Option, // minPinLengthRPIDs (0x02) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub min_pin_length_rpids: Option>, // forceChangePin (0x03) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub force_change_pin: Option, } diff --git a/libwebauthn/src/proto/ctap2/model/bio_enrollment.rs b/libwebauthn/src/proto/ctap2/model/bio_enrollment.rs index 12b2fb6..f6088a4 100644 --- a/libwebauthn/src/proto/ctap2/model/bio_enrollment.rs +++ b/libwebauthn/src/proto/ctap2/model/bio_enrollment.rs @@ -8,36 +8,30 @@ use std::time::Duration; #[serde_indexed(offset = 1)] pub struct Ctap2BioEnrollmentRequest { // modality (0x01) Unsigned Integer Optional The user verification modality being requested - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub modality: Option, // subCommand (0x02) Unsigned Integer Optional The authenticator user verification sub command currently being requested - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub subcommand: Option, // subCommandParams (0x03) CBOR Map Optional Map of subCommands parameters. This parameter MAY be omitted when the subCommand does not take any arguments. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub subcommand_params: Option, // pinUvAuthProtocol (0x04) Unsigned Integer Optional PIN/UV protocol version chosen by the platform. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub protocol: Option, // pinUvAuthParam (0x05) Byte String Optional First 16 bytes of HMAC-SHA-256 of contents using pinUvAuthToken. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub uv_auth_param: Option, // getModality (0x06) Boolean Optional Get the user verification type modality. This MUST be set to true. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub get_modality: Option, - #[serde(skip)] + #[serde(skip_serializing_if = "always_skip_bool")] pub use_legacy_preview: bool, } @@ -56,15 +50,12 @@ pub enum Ctap2BioEnrollmentSubcommand { #[derive(Debug, Clone, SerializeIndexed)] #[serde_indexed(offset = 1)] pub struct Ctap2BioEnrollmentParams { - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] template_id: Option, - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] template_friendly_name: Option, - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] timeout_milliseconds: Option, } @@ -73,42 +64,34 @@ pub struct Ctap2BioEnrollmentParams { #[serde_indexed(offset = 1)] pub struct Ctap2BioEnrollmentResponse { // modality (0x01) Unsigned Integer Optional The user verification modality. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub modality: Option, // fingerprintKind (0x02) Unsigned Integer Optional Indicates the type of fingerprint sensor. For touch type sensor, its value is 1. For swipe type sensor its value is 2. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub fingerprint_kind: Option, // maxCaptureSamplesRequiredForEnroll (0x03) Unsigned Integer Optional Indicates the maximum good samples required for enrollment. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub max_capture_samples_required_for_enroll: Option, // templateId (0x04) Byte String Optional Template Identifier. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub template_id: Option, // lastEnrollSampleStatus (0x05) Unsigned Integer Optional Last enrollment sample status. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub last_enroll_sample_status: Option, // remainingSamples (0x06) Unsigned Integer Optional Number of more sample required for enrollment to complete - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub remaining_samples: Option, // templateInfos (0x07) CBOR ARRAY Optional Array of templateInfo’s - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub template_infos: Option>, // maxTemplateFriendlyName (0x08) Unsigned Integer Optional Indicates the maximum number of bytes the authenticator will accept as a templateFriendlyName. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub max_template_friendly_name: Option, } @@ -117,12 +100,10 @@ pub struct Ctap2BioEnrollmentResponse { #[serde_indexed(offset = 1)] pub struct Ctap2BioEnrollmentTemplateId { // templateId (0x01) Byte String Required Template Identifier. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub template_id: Option, // templateFriendlyName (0x02) String Optional Template Friendly Name. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub template_friendly_name: Option, } @@ -281,3 +262,9 @@ impl Ctap2BioEnrollmentRequest { } } } + +// Required by serde_indexed, as serde(skip) isn't supported yet: +// https://github.com/trussed-dev/serde-indexed/pull/14 +fn always_skip_bool(_v: &bool) -> bool { + true +} diff --git a/libwebauthn/src/proto/ctap2/model/client_pin.rs b/libwebauthn/src/proto/ctap2/model/client_pin.rs index 0a284f8..18fa0b5 100644 --- a/libwebauthn/src/proto/ctap2/model/client_pin.rs +++ b/libwebauthn/src/proto/ctap2/model/client_pin.rs @@ -1,4 +1,4 @@ -use ctap_types::cose::PublicKey; +use cosey::PublicKey; use serde_bytes::ByteBuf; use serde_indexed::{DeserializeIndexed, SerializeIndexed}; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -213,27 +213,22 @@ pub enum Ctap2PinUvAuthProtocolCommand { #[serde_indexed(offset = 1)] pub struct Ctap2ClientPinResponse { /// keyAgreement (0x01) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub key_agreement: Option, /// pinUvAuthToken (0x02) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub pin_uv_auth_token: Option, /// pinRetries (0x03) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub pin_retries: Option, /// powerCycleState (0x04) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub power_cycle_state: Option, /// uvRetries (0x05) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub uv_retries: Option, } diff --git a/libwebauthn/src/proto/ctap2/model/credential_management.rs b/libwebauthn/src/proto/ctap2/model/credential_management.rs index 315624e..45db858 100644 --- a/libwebauthn/src/proto/ctap2/model/credential_management.rs +++ b/libwebauthn/src/proto/ctap2/model/credential_management.rs @@ -2,7 +2,7 @@ use super::{ Ctap2PinUvAuthProtocol, Ctap2PublicKeyCredentialDescriptor, Ctap2PublicKeyCredentialRpEntity, Ctap2PublicKeyCredentialUserEntity, }; -use ctap_types::cose::PublicKey; +use cosey::PublicKey; use serde_bytes::ByteBuf; use serde_indexed::{DeserializeIndexed, SerializeIndexed}; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -11,26 +11,22 @@ use serde_repr::{Deserialize_repr, Serialize_repr}; #[serde_indexed(offset = 1)] pub struct Ctap2CredentialManagementRequest { //subCommand (0x01) Unsigned Integer subCommand currently being requested - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub subcommand: Option, //subCommandParams (0x02) CBOR Map Map of subCommands parameters. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub subcommand_params: Option, //pinUvAuthProtocol (0x03) Unsigned Integer PIN/UV protocol version chosen by the platform. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub protocol: Option, //pinUvAuthParam (0x04) Byte String First 16 bytes of HMAC-SHA-256 of contents using pinUvAuthToken. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub uv_auth_param: Option, - #[serde(skip)] + #[serde(skip_serializing_if = "always_skip_bool")] pub use_legacy_preview: bool, } @@ -50,17 +46,14 @@ pub enum Ctap2CredentialManagementSubcommand { #[serde_indexed(offset = 1)] pub struct Ctap2CredentialManagementParams { // rpIDHash (0x01) Byte String RP ID SHA-256 hash - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] rpid_hash: Option, // credentialID (0x02) PublicKeyCredentialDescriptor Credential Identifier - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] credential_id: Option, // user (0x03) PublicKeyCredentialUserEntity User Entity - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] user: Option, } @@ -69,57 +62,46 @@ pub struct Ctap2CredentialManagementParams { #[serde_indexed(offset = 1)] pub struct Ctap2CredentialManagementResponse { // existingResidentCredentialsCount (0x01) Unsigned Integer Number of existing discoverable credentials present on the authenticator. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub existing_resident_credentials_count: Option, // maxPossibleRemainingResidentCredentialsCount (0x02) Unsigned Integer Number of maximum possible remaining discoverable credentials which can be created on the authenticator. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub max_possible_remaining_resident_credentials_count: Option, // rp (0x03) PublicKeyCredentialRpEntity RP Information - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub rp: Option, // rpIDHash (0x04) Byte String RP ID SHA-256 hash - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub rp_id_hash: Option, // totalRPs (0x05) Unsigned Integer total number of RPs present on the authenticator - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub total_rps: Option, // user (0x06) PublicKeyCredentialUserEntity User Information - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub user: Option, // credentialID (0x07) PublicKeyCredentialDescriptor PublicKeyCredentialDescriptor - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub credential_id: Option, // publicKey (0x08) COSE_Key Public key of the credential. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub public_key: Option, // totalCredentials (0x09) Unsigned Integer Total number of credentials present on the authenticator for the RP in question - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub total_credentials: Option, // credProtect (0x0A) Unsigned Integer Credential protection policy. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub cred_protect: Option, // largeBlobKey (0x0B) Byte string Large blob encryption key. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub large_blob_key: Option, } @@ -270,3 +252,9 @@ impl Ctap2RPData { Self { rp, rp_id_hash } } } + +// Required by serde_indexed, as serde(skip) isn't supported yet: +// https://github.com/trussed-dev/serde-indexed/pull/14 +fn always_skip_bool(_v: &bool) -> bool { + true +} diff --git a/libwebauthn/src/proto/ctap2/model/get_assertion.rs b/libwebauthn/src/proto/ctap2/model/get_assertion.rs index 29ace17..847df68 100644 --- a/libwebauthn/src/proto/ctap2/model/get_assertion.rs +++ b/libwebauthn/src/proto/ctap2/model/get_assertion.rs @@ -154,30 +154,31 @@ impl From<&GetAssertionRequest> for Ctap2GetAssertionRequest { #[derive(Debug, Clone, DeserializeIndexed)] #[serde_indexed(offset = 1)] pub struct Ctap2GetAssertionResponse { - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub credential_id: Option, + pub authenticator_data: AuthenticatorData, + pub signature: ByteBuf, - #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] pub user: Option, - #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] pub credentials_count: Option, - #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] pub user_selected: Option, - #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] pub large_blob_key: Option, - #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] pub unsigned_extension_outputs: Option>, - #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] pub enterprise_attestation: Option, - #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] pub attestation_statement: Option, } diff --git a/libwebauthn/src/proto/ctap2/model/get_info.rs b/libwebauthn/src/proto/ctap2/model/get_info.rs index 51ebc0b..f4d6c79 100644 --- a/libwebauthn/src/proto/ctap2/model/get_info.rs +++ b/libwebauthn/src/proto/ctap2/model/get_info.rs @@ -13,7 +13,6 @@ pub struct Ctap2GetInfoResponse { pub versions: Vec, /// extensions (0x02) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub extensions: Option>, @@ -21,132 +20,106 @@ pub struct Ctap2GetInfoResponse { pub aaguid: ByteBuf, /// options (0x04) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub options: Option>, /// maxMsgSize (0x05) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub max_msg_size: Option, /// pinUvAuthProtocols (0x06) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub pin_auth_protos: Option>, /// maxCredentialCountInList (0x07) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub max_credential_count: Option, /// maxCredentialIdLength (0x08) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub max_credential_id_length: Option, /// transports (0x09) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub transports: Option>, /// algorithms (0x0A) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub algorithms: Option>, /// maxSerializedLargeBlobArray (0x0B) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub max_blob_array: Option, /// forcePINChange (0x0C) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub force_pin_change: Option, /// minPINLength (0x0D) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub min_pin_length: Option, /// firmwareVersion (0x0E) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub firmware_version: Option, /// maxCredBlobLength (0x0F) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub max_cred_blob_length: Option, /// maxRPIDsForSetMinPINLength (0x10) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub max_rpids_for_setminpinlength: Option, /// preferredPlatformUvAttempts (0x11) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub preferred_platform_uv_attempts: Option, /// uvModality (0x12) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub uv_modality: Option, /// certifications (0x13) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub certifications: Option>, /// remainingDiscoverableCredentials (0x14) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub remaining_discoverable_creds: Option, /// vendorPrototypeConfigCommands (0x15) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub vendor_proto_config_cmds: Option>, /// attestationFormats (0x16) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub attestation_formats: Option>, /// uvCountSinceLastPinEntry (0x17) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub uv_count_since_last_pin_entry: Option, /// longTouchForReset (0x18) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub long_touch_for_reset: Option, /// encIdentifier (0x19) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub enc_identifier: Option, /// transportsForReset (0x1A) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub transports_for_reset: Option>, /// pinComplexityPolicy (0x1B) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub pin_complexity_policy: Option, /// pinComplexityPolicyURL (0x1C) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub pin_complexity_policy_url: Option, /// maxPINLength (0x1D) - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub max_pin_length: Option, } diff --git a/libwebauthn/src/transport/cable/qr_code_device.rs b/libwebauthn/src/transport/cable/qr_code_device.rs index 93ccd12..3b45a07 100644 --- a/libwebauthn/src/transport/cable/qr_code_device.rs +++ b/libwebauthn/src/transport/cable/qr_code_device.rs @@ -55,12 +55,10 @@ pub struct CableQrCode { /// Key 2: the number of assigned tunnel server domains known to this implementation. pub known_tunnel_domains_count: u8, /// Key 3: (optional) the current time in epoch seconds. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub current_time: Option, /// Key 4: (optional) a boolean that is true if the device displaying the QR code can perform state- /// assisted transactions. - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub state_assisted: Option, /// Key 5: either the string “ga” to hint that a getAssertion will follow, or “mc” to hint that a @@ -69,7 +67,6 @@ pub struct CableQrCode { /// prior to the authenticator receiving any CTAP message. While this hint SHOULD be as accurate as /// possible, it does not constrain the subsequent CTAP messages that the platform may send. pub operation_hint: QrCodeOperationHint, - #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub supports_non_discoverable_mc: Option, } diff --git a/libwebauthn/src/webauthn.rs b/libwebauthn/src/webauthn.rs index 0cab4a5..8549194 100644 --- a/libwebauthn/src/webauthn.rs +++ b/libwebauthn/src/webauthn.rs @@ -3,7 +3,7 @@ use std::time::Duration; use async_trait::async_trait; use tracing::{debug, error, info, instrument, trace, warn}; -use ctap_types::cose::PublicKey; +use cosey::PublicKey; use crate::fido::FidoProtocol; use crate::ops::u2f::{RegisterRequest, SignRequest, UpgradableResponse};