diff --git a/Cargo.lock b/Cargo.lock index abfa879..92a44bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -362,6 +362,12 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.2" @@ -405,17 +411,6 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" -[[package]] -name = "fido2-rs" -version = "0.1.0" -dependencies = [ - "bitflags 1.3.2", - "foreign-types", - "libfido2-sys", - "openssl", - "thiserror", -] - [[package]] name = "fido_ssh_maker" version = "0.1.0" @@ -425,8 +420,8 @@ dependencies = [ "clap", "ctrlc", "dialoguer", - "fido2-rs", "gethostname", + "libfido2", "p256", "rand", "ssh-encoding", @@ -434,21 +429,6 @@ dependencies = [ "whoami", ] -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "generic-array" version = "0.14.7" @@ -492,6 +472,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.4.1" @@ -513,6 +499,16 @@ dependencies = [ "digest", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "inout" version = "0.1.3" @@ -557,6 +553,16 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +[[package]] +name = "libfido2" +version = "0.1.0" +dependencies = [ + "libfido2-sys", + "num_enum", + "paste", + "thiserror", +] + [[package]] name = "libfido2-sys" version = "0.2.0" @@ -585,6 +591,12 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "memchr" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76fc44e2588d5b436dbc3c6cf62aef290f90dab6235744a93dfe1cc18f451e2c" + [[package]] name = "nix" version = "0.26.2" @@ -646,48 +658,31 @@ dependencies = [ ] [[package]] -name = "once_cell" -version = "1.18.0" +name = "num_enum" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "openssl" -version = "0.10.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" +checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", + "num_enum_derive", ] [[package]] -name = "openssl-macros" -version = "0.1.1" +name = "num_enum_derive" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" dependencies = [ + "proc-macro-crate", "proc-macro2", "quote", "syn", ] [[package]] -name = "openssl-sys" -version = "0.9.91" +name = "once_cell" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "p256" @@ -713,6 +708,12 @@ dependencies = [ "sha2", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -770,6 +771,16 @@ dependencies = [ "elliptic-curve", ] +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.66" @@ -1036,24 +1047,41 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "typenum" version = "1.16.0" @@ -1302,6 +1330,15 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "winnow" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +dependencies = [ + "memchr", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index 6a83102..ec60bf5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,8 @@ bitflags = "2.4.0" clap = { version = "4.3.21", features = ["derive"] } ctrlc = "3.4.0" dialoguer = "0.10.4" -fido2-rs = { version = "0.1.0", path = "fido-rs/fido2-rs" } gethostname = "0.4.3" +libfido2 = { version = "0.1.0", path = "../libfido2" } p256 = "0.13.2" rand = "0.8.5" ssh-encoding = { version = "0.2.0" } diff --git a/fido-rs/.gitignore b/fido-rs/.gitignore deleted file mode 100644 index 2150fcb..0000000 --- a/fido-rs/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.idea -target/ -Cargo.lock \ No newline at end of file diff --git a/fido-rs/Cargo.toml b/fido-rs/Cargo.toml deleted file mode 100644 index 5dbaa60..0000000 --- a/fido-rs/Cargo.toml +++ /dev/null @@ -1,2 +0,0 @@ -[workspace] -members = ["libfido2-sys", "fido2-rs"] \ No newline at end of file diff --git a/fido-rs/README.MD b/fido-rs/README.MD deleted file mode 100644 index f31079f..0000000 --- a/fido-rs/README.MD +++ /dev/null @@ -1,36 +0,0 @@ -# fido-rs - -[libfido2](https://github.com/Yubico/libfido2) bindings for the Rust programming language. - -# Example - -1. Make a credential -```rust -use fido2_rs::device::Device; -use fido2_rs::credentials::Credential; -use fido2_rs::credentials::CoseType; -use anyhow::Result; -fn main() -> Result<()> { - let dev = Device::open("windows://hello").expect("unable open windows hello"); - - let mut cred = Credential::new(); - cred.set_client_data(&[1, 2, 3, 4, 5, 6])?; - cred.set_rp("fido_rs", "fido example")?; - cred.set_user(&[1, 2, 3, 4, 5, 6], "alice", Some("alice"), None)?; - cred.set_cose_type(CoseType::RS256)?; - - let _ = dev.make_credential(&mut cred, None)?; - dbg!(cred.id()); - - Ok(()) -} -``` - -# Support platform -* Windows (MSVC and MinGW) -* Linux - -# TODO - -* [ ] more doc -* [x] full bindings to `fido_cred_t` and `fido_assert_t` \ No newline at end of file diff --git a/fido-rs/fido2-rs/Cargo.toml b/fido-rs/fido2-rs/Cargo.toml deleted file mode 100644 index e9d0f32..0000000 --- a/fido-rs/fido2-rs/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "fido2-rs" -version = "0.1.0" -authors = ["tyan boot "] -license = "MIT" -description = "Rust bindings to Yubico fido2" -repository = "https://github.com/tyan-boot/fido-rs" -keywords = ["fido2", "webauthn"] -categories = ["authentication", "api-bindings", "hardware-support"] -edition = "2021" - -[dependencies] -thiserror = "1.0.37" -bitflags = "1.3.2" -libfido2-sys = { version = "0.2.0", path = "../libfido2-sys" } -openssl = "0.10.45" -foreign-types = "0.3" - -[dev-dependencies] -anyhow = "1.0.66" \ No newline at end of file diff --git a/fido-rs/fido2-rs/LICENSE b/fido-rs/fido2-rs/LICENSE deleted file mode 100644 index 4fa01fb..0000000 --- a/fido-rs/fido2-rs/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 tyan boot - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/fido-rs/fido2-rs/README.MD b/fido-rs/fido2-rs/README.MD deleted file mode 100644 index a061706..0000000 --- a/fido-rs/fido2-rs/README.MD +++ /dev/null @@ -1,30 +0,0 @@ -# fido2-rs - -[![crates.io](https://img.shields.io/crates/v/fido2-rs?style=flat-square)](https://crates.io/crates/fido2-rs) -[![MIT](https://img.shields.io/crates/l/libfido2-sys?style=flat-square)](./LICENSE) - -[libfido2](https://github.com/Yubico/libfido2) bindings for the Rust programming language. - -For more details, see [tyan-boot/fido-rs](https://github.com/tyan-boot/fido-rs) - -```rust -use fido2_rs::device::Device; -use fido2_rs::credentials::Credential; -use fido2_rs::credentials::CoseType; -use anyhow::Result; - -fn main() -> Result<()> { - let dev = Device::open("windows://hello").expect("unable open windows hello"); - - let mut cred = Credential::new(); - cred.set_client_data(&[1, 2, 3, 4, 5, 6])?; - cred.set_rp("fido_rs", "fido example")?; - cred.set_user(&[1, 2, 3, 4, 5, 6], "alice", Some("alice"), None)?; - cred.set_cose_type(CoseType::RS256)?; - - let _ = dev.make_credential(&mut cred, None)?; - dbg!(cred.id()); - - Ok(()) -} -``` \ No newline at end of file diff --git a/fido-rs/fido2-rs/src/assertion.rs b/fido-rs/fido2-rs/src/assertion.rs deleted file mode 100644 index 6a4336f..0000000 --- a/fido-rs/fido2-rs/src/assertion.rs +++ /dev/null @@ -1,465 +0,0 @@ -use crate::credentials::{CoseType, Opt}; -use crate::error::{FidoError, Result}; -use crate::key::{Eddsa, Rsa, ES256, ES384}; -use crate::utils::check; -use ffi::FIDO_ERR_INVALID_ARGUMENT; -use openssl::nid::Nid; -use openssl::pkey::{Id, PKey, Public}; -use std::ffi::CString; -use std::marker::PhantomData; -use std::ptr::NonNull; - -macro_rules! impl_assertion_set { - ($ty:ty, $($f:tt).*) => { - impl $ty { - /// Set the client data hash of assert by specifying the assertion's unhashed client data. - /// - /// This is required by Windows Hello, which calculates the client data hash internally. - /// - /// For compatibility with Windows Hello, applications should use [AssertRequestBuilder::client_data] - /// instead of [AssertRequestBuilder::client_data_hash]. - pub fn set_client_data(&mut self, data: impl AsRef<[u8]>) -> Result<()> { - let data = data.as_ref(); - unsafe { - check(ffi::fido_assert_set_clientdata( - self.$($f).*.as_ptr(), - data.as_ptr(), - data.len(), - ))?; - } - - Ok(()) - } - - /// See [AssertRequestBuilder::client_data] - pub fn set_client_data_hash(&mut self, data: impl AsRef<[u8]>) -> Result<()> { - let data = data.as_ref(); - unsafe { - check(ffi::fido_assert_set_clientdata_hash( - self.$($f).*.as_ptr(), - data.as_ptr(), - data.len(), - ))?; - } - - Ok(()) - } - - /// Set the relying party id of assert. - pub fn set_rp(&mut self, id: impl AsRef) -> Result<()> { - let id = CString::new(id.as_ref())?; - - unsafe { - check(ffi::fido_assert_set_rp(self.$($f).*.as_ptr(), id.as_ptr()))?; - } - - Ok(()) - } - - /// Set the up (user presence) attribute of assert. - /// - /// **Default to [Opt::Omit]** - pub fn set_up(&mut self, up: Opt) -> Result<()> { - unsafe { - check(ffi::fido_assert_set_up(self.$($f).*.as_ptr(), up as _))?; - } - - Ok(()) - } - - /// Set the uv (user verification) attribute of assert. - /// - /// **Default to [Opt::Omit]** - pub fn set_uv(&mut self, uv: Opt) -> Result<()> { - unsafe { - check(ffi::fido_assert_set_uv(self.$($f).*.as_ptr(), uv as _))?; - } - - Ok(()) - } - - /// Set the extensions of assert to the bitmask flags. - /// - /// At the moment, only the FIDO_EXT_CRED_BLOB, FIDO_EXT_HMAC_SECRET, and FIDO_EXT_LARGEBLOB_KEY extensions are supported. - pub fn set_extensions(&mut self, flags: crate::credentials::Extensions) -> Result<()> { - unsafe { - check(ffi::fido_assert_set_extensions( - self.$($f).*.as_ptr(), - flags.bits(), - ))?; - } - - Ok(()) - } - - /// Allow a credential in a FIDO2 assertion. - /// - /// Add id to the list of credentials allowed in assert. - /// - /// If fails, the existing list of allowed credentials is preserved. - pub fn set_allow_credential(&mut self, id: impl AsRef<[u8]>) -> Result<()> { - let id = id.as_ref(); - - unsafe { - check(ffi::fido_assert_allow_cred( - self.$($f).*.as_ptr(), - id.as_ptr(), - id.len(), - ))?; - } - - Ok(()) - } - } - }; -} - -/// FIDO assertions from device, contains one or more assertion. -pub struct Assertions { - pub(crate) ptr: NonNull, -} - -/// A single FIDO assertion. -pub struct Assertion<'a> { - ptr: NonNull, - idx: usize, - _p: PhantomData<&'a ()>, -} - -/// Request to get a assertion. -pub struct AssertRequest(pub(crate) Assertions); - -impl_assertion_set!(AssertRequest, 0.ptr); - -impl AssertRequest { - /// Return a [AssertRequest] - #[allow(clippy::new_without_default)] - pub fn new() -> AssertRequest { - unsafe { - let assert = ffi::fido_assert_new(); - - AssertRequest(Assertions { - ptr: NonNull::new_unchecked(assert), - }) - } - } -} - -/// helper for verify an exist single assertion -pub struct AssertVerifier(Assertions); - -impl_assertion_set!(AssertVerifier, 0.ptr); - -impl AssertVerifier { - /// Return a [AssertVerifier] for verify. - #[allow(clippy::new_without_default)] - pub fn new() -> AssertVerifier { - unsafe { - let assert = ffi::fido_assert_new(); - ffi::fido_assert_set_count(assert, 1); - - AssertVerifier(Assertions { - ptr: NonNull::new_unchecked(assert), - }) - } - } - - /// Set the authenticator data part of the statement. - /// - /// A copy of data is made, and no references to the passed data are kept. - /// - /// The authenticator data passed to [AssertVerifier::set_auth_data] must be a CBOR-encoded byte string, - /// as obtained from [Assertion::auth_data]. - /// - /// Alternatively, a raw binary blob may be passed to [AssertVerifier::set_auth_data_raw] - pub fn set_auth_data(&mut self, data: impl AsRef<[u8]>) -> Result<()> { - let data = data.as_ref(); - - unsafe { - check(ffi::fido_assert_set_authdata( - self.0.ptr.as_ptr(), - 0, - data.as_ptr(), - data.len(), - ))?; - } - - Ok(()) - } - - /// Set the raw binary authenticator data part of the statement. - pub fn set_auth_data_raw(&mut self, data: impl AsRef<[u8]>) -> Result<()> { - let data = data.as_ref(); - - unsafe { - check(ffi::fido_assert_set_authdata_raw( - self.0.ptr.as_ptr(), - 0, - data.as_ptr(), - data.len(), - ))?; - } - - Ok(()) - } - - /// Set the signature part of the statement. - pub fn set_signature(&mut self, signature: impl AsRef<[u8]>) -> Result<()> { - let signature = signature.as_ref(); - - unsafe { - check(ffi::fido_assert_set_sig( - self.0.ptr.as_ptr(), - 0, - signature.as_ptr(), - signature.len(), - ))?; - } - - Ok(()) - } - - /// Verify whether the signature contained in statement of assert matches the parameters of the assertion. - /// - /// And verify whether the client data hash, relying party ID, user presence and user verification - /// attributes of assert have been attested by the holder of the private counterpart of the public key. - /// - /// The `public_key` is a public key of type COSE_ES256, COSE_ES384, COSE_RS256, or COSE_EDDSA. - /// - /// # Return - /// On verify success, this method return Ok(()), otherwise return Err. - pub fn verify(&self, public_key: PKey) -> Result<()> { - match public_key.id() { - Id::ED25519 => { - let pk = Eddsa::try_from(public_key)?; - - unsafe { - check(ffi::fido_assert_verify( - self.0.ptr.as_ptr(), - 0, - CoseType::EDDSA as i32, - pk.as_ptr().cast(), - ))?; - } - } - Id::RSA => { - let pk = Rsa::try_from(public_key)?; - - unsafe { - check(ffi::fido_assert_verify( - self.0.ptr.as_ptr(), - 0, - CoseType::EDDSA as i32, - pk.as_ptr().cast(), - ))?; - } - } - Id::EC => { - let ec_key = public_key.ec_key()?; - let group = ec_key.group(); - let curve = group - .curve_name() - .ok_or(FidoError::new(FIDO_ERR_INVALID_ARGUMENT))?; - match curve { - Nid::X9_62_PRIME256V1 => { - let pk = ES256::try_from(ec_key)?; - - unsafe { - check(ffi::fido_assert_verify( - self.0.ptr.as_ptr(), - 0, - CoseType::ES256 as i32, - pk.as_ptr().cast(), - ))?; - } - } - Nid::SECP384R1 => { - let pk = ES384::try_from(ec_key)?; - - unsafe { - check(ffi::fido_assert_verify( - self.0.ptr.as_ptr(), - 0, - CoseType::ES384 as i32, - pk.as_ptr().cast(), - ))?; - } - } - _ => { - return Err(FidoError::new(FIDO_ERR_INVALID_ARGUMENT))?; - } - } - } - _ => { - return Err(FidoError::new(FIDO_ERR_INVALID_ARGUMENT))?; - } - } - - Ok(()) - } -} - -impl Drop for Assertions { - fn drop(&mut self) { - let mut ptr = self.ptr.as_ptr(); - - unsafe { - ffi::fido_assert_free(&mut ptr); - } - - let _ = std::mem::replace(&mut self.ptr, NonNull::dangling()); - } -} - -impl Assertion<'_> { - /// Return relying party ID of assert. - pub fn rp_id(&self) -> Option<&str> { - let rp_id = unsafe { ffi::fido_assert_rp_id(self.ptr.as_ptr()) }; - str_or_none!(rp_id) - } - - /// Return user display name of assert. - pub fn user_display_name(&self) -> Option<&str> { - let display_name = - unsafe { ffi::fido_assert_user_display_name(self.ptr.as_ptr(), self.idx) }; - - str_or_none!(display_name) - } - - /// Return user icon of assert. - pub fn user_icon(&self) -> Option<&str> { - let icon = unsafe { ffi::fido_assert_user_icon(self.ptr.as_ptr(), self.idx) }; - - str_or_none!(icon) - } - - /// Return user name of assert. - pub fn user_name(&self) -> Option<&str> { - let name = unsafe { ffi::fido_assert_user_name(self.ptr.as_ptr(), self.idx) }; - - str_or_none!(name) - } - - /// Return CBOR-encoded authenticator data - pub fn auth_data(&self) -> &[u8] { - let len = unsafe { ffi::fido_assert_authdata_len(self.ptr.as_ptr(), self.idx) }; - let ptr = unsafe { ffi::fido_assert_authdata_ptr(self.ptr.as_ptr(), self.idx) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return client data hash. - pub fn client_data_hash(&self) -> &[u8] { - let len = unsafe { ffi::fido_assert_clientdata_hash_len(self.ptr.as_ptr()) }; - let ptr = unsafe { ffi::fido_assert_clientdata_hash_ptr(self.ptr.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return the credBlob attribute. - pub fn blob(&self) -> &[u8] { - let len = unsafe { ffi::fido_assert_blob_len(self.ptr.as_ptr(), self.idx) }; - let ptr = unsafe { ffi::fido_assert_blob_ptr(self.ptr.as_ptr(), self.idx) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return the hmac-secret attribute. - /// - /// The HMAC Secret Extension (hmac-secret) is a CTAP 2.0 extension. - /// - /// Note that the resulting hmac-secret varies according to whether user verification was performed by the authenticator. - pub fn hmac_secret(&self) -> &[u8] { - let len = unsafe { ffi::fido_assert_hmac_secret_len(self.ptr.as_ptr(), self.idx) }; - let ptr = unsafe { ffi::fido_assert_hmac_secret_ptr(self.ptr.as_ptr(), self.idx) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return largeBlobKey attribute. - pub fn large_blob_key(&self) -> &[u8] { - let len = unsafe { ffi::fido_assert_largeblob_key_len(self.ptr.as_ptr(), self.idx) }; - let ptr = unsafe { ffi::fido_assert_largeblob_key_ptr(self.ptr.as_ptr(), self.idx) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return user ID. - pub fn user_id(&self) -> &[u8] { - let len = unsafe { ffi::fido_assert_user_id_len(self.ptr.as_ptr(), self.idx) }; - let ptr = unsafe { ffi::fido_assert_user_id_ptr(self.ptr.as_ptr(), self.idx) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return signature - pub fn signature(&self) -> &[u8] { - let len = unsafe { ffi::fido_assert_sig_len(self.ptr.as_ptr(), self.idx) }; - let ptr = unsafe { ffi::fido_assert_sig_ptr(self.ptr.as_ptr(), self.idx) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return credential ID - pub fn id(&self) -> &[u8] { - let len = unsafe { ffi::fido_assert_id_len(self.ptr.as_ptr(), self.idx) }; - let ptr = unsafe { ffi::fido_assert_id_ptr(self.ptr.as_ptr(), self.idx) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return signature count. - pub fn counter(&self) -> u32 { - unsafe { ffi::fido_assert_sigcount(self.ptr.as_ptr(), self.idx) } - } - - /// Return authenticator data flags. - pub fn flags(&self) -> u8 { - unsafe { ffi::fido_assert_flags(self.ptr.as_ptr(), self.idx) } - } -} - -impl Assertions { - /// Return the number of assertion. - pub fn count(&self) -> usize { - unsafe { ffi::fido_assert_count(self.ptr.as_ptr()) } - } - - /// Return a iterator of contained assertion - pub fn iter(&self) -> impl Iterator { - let count = self.count(); - - AssertionIter { - asserts: self, - idx: 0, - count, - } - } -} - -/// Iterator of assertion -pub struct AssertionIter<'a> { - asserts: &'a Assertions, - idx: usize, - count: usize, -} - -impl<'a> Iterator for AssertionIter<'a> { - type Item = Assertion<'a>; - - fn next(&mut self) -> Option { - if self.idx >= self.count { - None - } else { - let item = Assertion { - ptr: self.asserts.ptr, - idx: self.idx, - _p: PhantomData, - }; - - self.idx += 1; - - Some(item) - } - } -} diff --git a/fido-rs/fido2-rs/src/cbor.rs b/fido-rs/fido2-rs/src/cbor.rs deleted file mode 100644 index 3af0a78..0000000 --- a/fido-rs/fido2-rs/src/cbor.rs +++ /dev/null @@ -1,195 +0,0 @@ -use std::collections::HashMap; -use std::ffi::CStr; -use std::ptr::NonNull; - -pub struct CBORInfo { - pub(crate) ptr: NonNull, -} - -impl CBORInfo { - pub(crate) fn new() -> CBORInfo { - unsafe { - CBORInfo { - ptr: NonNull::new_unchecked(ffi::fido_cbor_info_new()), - } - } - } - - pub fn aaguid(&self) -> &[u8] { - unsafe { - let len = ffi::fido_cbor_info_aaguid_len(self.ptr.as_ptr()); - let ptr = ffi::fido_cbor_info_aaguid_ptr(self.ptr.as_ptr()); - - std::slice::from_raw_parts(ptr, len) - } - } - - pub fn extensions(&self) -> Vec<&str> { - unsafe { - let len = ffi::fido_cbor_info_extensions_len(self.ptr.as_ptr()); - let ptr = ffi::fido_cbor_info_extensions_ptr(self.ptr.as_ptr()); - - let exts = std::slice::from_raw_parts(ptr, len); - - exts.iter() - .map(|it| CStr::from_ptr(*it)) - .map(|it| it.to_str().expect("invalid utf8")) - .collect() - } - } - - pub fn protocols(&self) -> &[u8] { - unsafe { - let len = ffi::fido_cbor_info_protocols_len(self.ptr.as_ptr()); - let ptr = ffi::fido_cbor_info_protocols_ptr(self.ptr.as_ptr()); - - std::slice::from_raw_parts(ptr, len) - } - } - - pub fn transports(&self) -> Vec<&str> { - unsafe { - let len = ffi::fido_cbor_info_transports_len(self.ptr.as_ptr()); - let ptr = ffi::fido_cbor_info_transports_ptr(self.ptr.as_ptr()); - - let txs = std::slice::from_raw_parts(ptr, len); - - txs.iter() - .map(|it| CStr::from_ptr(*it)) - .map(|it| it.to_str().expect("invalid utf8")) - .collect() - } - } - - pub fn versions(&self) -> Vec<&str> { - unsafe { - let len = ffi::fido_cbor_info_versions_len(self.ptr.as_ptr()); - let ptr = ffi::fido_cbor_info_versions_ptr(self.ptr.as_ptr()); - - let versions = std::slice::from_raw_parts(ptr, len); - - versions - .iter() - .map(|it| CStr::from_ptr(*it)) - .map(|it| it.to_str().expect("invalid utf8")) - .collect() - } - } - - pub fn options(&self) -> HashMap<&str, bool> { - unsafe { - let len = ffi::fido_cbor_info_options_len(self.ptr.as_ptr()); - let names = ffi::fido_cbor_info_options_name_ptr(self.ptr.as_ptr()); - let values = ffi::fido_cbor_info_options_value_ptr(self.ptr.as_ptr()); - - let names = std::slice::from_raw_parts(names, len); - let values = std::slice::from_raw_parts(values, len); - - names - .iter() - .map(|it| CStr::from_ptr(*it)) - .map(|it| it.to_str().expect("invalid utf8")) - .zip(values) - .map(|(k, v)| (k, *v)) - .collect() - } - } - - pub fn algorithms(&self) -> Vec<(&str, i32)> { - unsafe { - let count = ffi::fido_cbor_info_algorithm_count(self.ptr.as_ptr()); - - let mut rets = Vec::with_capacity(count); - - for idx in 0..count { - let algo_type = ffi::fido_cbor_info_algorithm_type(self.ptr.as_ptr(), idx); - let algo_cose = ffi::fido_cbor_info_algorithm_cose(self.ptr.as_ptr(), idx); - - let algo_type = CStr::from_ptr(algo_type).to_str().expect("invalid utf8"); - - rets.push((algo_type, algo_cose)) - } - - rets - } - } - - pub fn certs(&self) -> HashMap<&str, u64> { - unsafe { - let len = ffi::fido_cbor_info_certs_len(self.ptr.as_ptr()); - - let names = ffi::fido_cbor_info_certs_name_ptr(self.ptr.as_ptr()); - let values = ffi::fido_cbor_info_certs_value_ptr(self.ptr.as_ptr()); - - let names = std::slice::from_raw_parts(names, len); - let values = std::slice::from_raw_parts(values, len); - - names - .iter() - .map(|it| CStr::from_ptr(*it)) - .map(|it| it.to_str().expect("invalid utf8")) - .zip(values) - .map(|(k, v)| (k, *v)) - .collect() - } - } - - pub fn max_msg_size(&self) -> u64 { - unsafe { ffi::fido_cbor_info_maxmsgsiz(self.ptr.as_ptr()) } - } - - pub fn max_cred_blob_len(&self) -> u64 { - unsafe { ffi::fido_cbor_info_maxcredbloblen(self.ptr.as_ptr()) } - } - - pub fn max_cred_count_list(&self) -> u64 { - unsafe { ffi::fido_cbor_info_maxcredcntlst(self.ptr.as_ptr()) } - } - - pub fn max_cred_id_len(&self) -> u64 { - unsafe { ffi::fido_cbor_info_maxcredidlen(self.ptr.as_ptr()) } - } - - pub fn max_large_blob(&self) -> u64 { - unsafe { ffi::fido_cbor_info_maxlargeblob(self.ptr.as_ptr()) } - } - - pub fn max_rp_id_minpinlen(&self) -> u64 { - unsafe { ffi::fido_cbor_info_maxrpid_minpinlen(self.ptr.as_ptr()) } - } - - pub fn min_pin_len(&self) -> u64 { - unsafe { ffi::fido_cbor_info_minpinlen(self.ptr.as_ptr()) } - } - - pub fn fw_version(&self) -> u64 { - unsafe { ffi::fido_cbor_info_fwversion(self.ptr.as_ptr()) } - } - - pub fn uv_attempts(&self) -> u64 { - unsafe { ffi::fido_cbor_info_uv_attempts(self.ptr.as_ptr()) } - } - - pub fn uv_modality(&self) -> u64 { - unsafe { ffi::fido_cbor_info_uv_modality(self.ptr.as_ptr()) } - } - - pub fn rk_remaining(&self) -> i64 { - unsafe { ffi::fido_cbor_info_rk_remaining(self.ptr.as_ptr()) } - } - - pub fn new_pin_required(&self) -> bool { - unsafe { ffi::fido_cbor_info_new_pin_required(self.ptr.as_ptr()) } - } -} - -impl Drop for CBORInfo { - fn drop(&mut self) { - unsafe { - let mut ptr = self.ptr.as_ptr(); - ffi::fido_cbor_info_free(&mut ptr); - - let _ = std::mem::replace(&mut self.ptr, NonNull::dangling()); - } - } -} diff --git a/fido-rs/fido2-rs/src/credentials.rs b/fido-rs/fido2-rs/src/credentials.rs deleted file mode 100644 index d0941bb..0000000 --- a/fido-rs/fido2-rs/src/credentials.rs +++ /dev/null @@ -1,578 +0,0 @@ -use crate::error::Result; -use crate::utils::check; -use bitflags::bitflags; -use std::ffi::{CStr, CString}; -use std::ptr::NonNull; - -/// FIDO credential -pub struct Credential(pub(crate) NonNull); - -impl Drop for Credential { - fn drop(&mut self) { - unsafe { - // `fido_cred_free` set this ptr to `NULL` - ffi::fido_cred_free(&mut self.0.as_ptr()); - } - } -} - -impl Credential { - /// Create a new credential - #[allow(clippy::new_without_default)] - pub fn new() -> Self { - unsafe { - let cred = ffi::fido_cred_new(); - - Credential(NonNull::new_unchecked(cred)) - } - } - /// If the CTAP 2.1 FIDO_EXT_MINPINLEN extension is enabled on cred, then this function returns - /// the minimum PIN length of cred. - /// - /// Otherwise, returns zero. - pub fn pin_min_len(&self) -> usize { - unsafe { ffi::fido_cred_pin_minlen(self.0.as_ptr()) } - } - - /// If the CTAP 2.1 FIDO_EXT_CRED_PROTECT extension is enabled on cred, then this function returns - /// the protection of cred. - /// - /// Otherwise, returns [None] - pub fn protection(&self) -> Option { - unsafe { - let prot = ffi::fido_cred_prot(self.0.as_ptr()); - - match prot { - ffi::FIDO_CRED_PROT_UV_OPTIONAL => Some(Protection::UvOptional), - ffi::FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID => Some(Protection::UvOptionalWithId), - ffi::FIDO_CRED_PROT_UV_REQUIRED => Some(Protection::UvRequired), - _ => None, - } - } - } - - /// Return the attestation statement format identifier of cred, or [None] if cred does not have a format set. - pub fn attestation_format(&self) -> Option { - let fmt = unsafe { ffi::fido_cred_fmt(self.0.as_ptr()) }; - - if fmt.is_null() { - None - } else { - let fmt = unsafe { CStr::from_ptr(fmt).to_str().expect("invalid utf8") }; - - match fmt { - "packed" => Some(AttestationFormat::Packed), - "fido-u2f" => Some(AttestationFormat::FidoU2f), - "tpm" => Some(AttestationFormat::Tpm), - "none" => Some(AttestationFormat::None), - _ => None, - } - } - } - - /// Return relying party ID, or [None] if is not set. - pub fn rp_id(&self) -> Option<&str> { - let rp_id = unsafe { ffi::fido_cred_rp_id(self.0.as_ptr()) }; - str_or_none!(rp_id) - } - - /// Return relying party name, or [None] if is not set. - pub fn rp_name(&self) -> Option<&str> { - let rp_name = unsafe { ffi::fido_cred_rp_name(self.0.as_ptr()) }; - str_or_none!(rp_name) - } - - /// Return user name, or [None] if is not set. - pub fn user_name(&self) -> Option<&str> { - let user_name = unsafe { ffi::fido_cred_rp_id(self.0.as_ptr()) }; - str_or_none!(user_name) - } - - /// Return user display name, or [None] if is not set. - pub fn display_name(&self) -> Option<&str> { - let display_name = unsafe { ffi::fido_cred_rp_id(self.0.as_ptr()) }; - str_or_none!(display_name) - } - - /// Return CBOR-encoded authenticator data. - /// - /// The slice len will be 0 if is not set. - pub fn auth_data(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_authdata_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_authdata_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return raw authenticator data. - /// - /// The slice len will be 0 if is not set. - pub fn auth_data_raw(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_authdata_raw_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_authdata_raw_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return client data hash - /// - /// The slice len will be 0 if is not set. - pub fn client_data_hash(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_clientdata_hash_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_clientdata_hash_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return credential ID - /// - /// The slice len will be 0 if is not set. - pub fn id(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_id_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_id_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return authenticator attestation GUID - /// - /// The slice len will be 0 if is not set. - pub fn attestation_guid(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_aaguid_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_aaguid_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return "largeBlobKey". - /// - /// The slice len will be 0 if is not set. - pub fn large_blob_key(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_largeblob_key_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_largeblob_key_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return public key. - /// - /// The slice len will be 0 if is not set. - pub fn public_key(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_pubkey_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_pubkey_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return signature. - /// - /// The slice len will be 0 if is not set. - pub fn signature(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_sig_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_sig_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return user ID. - /// - /// The slice len will be 0 if is not set. - pub fn user_id(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_user_id_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_user_id_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return X509 certificate. - /// - /// The slice len will be 0 if is not set. - pub fn certificate(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_x5c_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_x5c_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return attestation statement. - /// - /// The slice len will be 0 if is not set. - pub fn attestation(&self) -> &[u8] { - let len = unsafe { ffi::fido_cred_attstmt_len(self.0.as_ptr()) }; - let ptr = unsafe { ffi::fido_cred_attstmt_ptr(self.0.as_ptr()) }; - - unsafe { std::slice::from_raw_parts(ptr, len) } - } - - /// Return the COSE algorithm of cred. - pub fn cose_type(&self) -> CoseType { - unsafe { - let cred_type = ffi::fido_cred_type(self.0.as_ptr()); - - CoseType::try_from(cred_type).unwrap_or(CoseType::UNSPEC) - } - } - - /// Return the authenticator data flags of cred. - pub fn flags(&self) -> u8 { - unsafe { ffi::fido_cred_flags(self.0.as_ptr()) } - } - - /// Return the authenticator data signature counter of cred. - pub fn counter(&self) -> u32 { - unsafe { ffi::fido_cred_sigcount(self.0.as_ptr()) } - } - - /// Verifies whether the client data hash, relying party ID, credential ID, type, protection policy, - /// minimum PIN length, and resident/discoverable key and user verification attributes of cred - /// have been attested by the holder of the private counterpart of the public key contained in the credential's x509 certificate. - /// - /// Please note that the x509 certificate itself is not verified. - /// - /// The attestation statement formats supported by [Credential::verify] are packed, fido-u2f, and tpm. - /// - /// The attestation type implemented by [Credential::verify] is Basic Attestation. - pub fn verify(&self) -> Result<()> { - unsafe { - check(ffi::fido_cred_verify(self.0.as_ptr()))?; - } - - Ok(()) - } - - /// verifies whether the client data hash, relying party ID, credential ID, type, protection policy, - /// minimum PIN length, and resident/discoverable key and user verification attributes of cred - /// have been attested by the holder of the credential's private key. - /// - /// The attestation statement formats supported by [Credential::verify_self] are packed and fido-u2f. - /// - /// The attestation type implemented by [Credential::verify_self] is Self Attestation. - pub fn verify_self(&self) -> Result<()> { - unsafe { - check(ffi::fido_cred_verify_self(self.0.as_ptr()))?; - } - - Ok(()) - } - - /// Set CBOR-encoded authenticator data - pub fn set_auth_data(&mut self, data: impl AsRef<[u8]>) -> Result<()> { - dbg!(data.as_ref().len()); - let data = data.as_ref(); - unsafe { - check(ffi::fido_cred_set_authdata( - self.0.as_ptr(), - data.as_ptr(), - data.len(), - ))?; - } - - Ok(()) - } - - /// Set raw authenticator data - pub fn set_auth_data_raw(&mut self, data: impl AsRef<[u8]>) -> Result<()> { - let data = data.as_ref(); - unsafe { - check(ffi::fido_cred_set_authdata_raw( - self.0.as_ptr(), - data.as_ptr(), - data.len(), - ))?; - } - - Ok(()) - } - - /// Set X509 certificate - pub fn set_certificate(&mut self, cert: impl AsRef<[u8]>) -> Result<()> { - let cert = cert.as_ref(); - unsafe { - check(ffi::fido_cred_set_x509( - self.0.as_ptr(), - cert.as_ptr(), - cert.len(), - ))?; - } - - Ok(()) - } - - /// Set the client data hash of cred by specifying the credential's unhashed client data. - /// - /// This is required by Windows Hello, which calculates the client data hash internally. - /// - /// For compatibility with Windows Hello, applications should use [CredentialRequestBuilder::client_data] instead of [CredentialRequestBuilder::client_data_hash] - pub fn set_client_data(&mut self, data: impl AsRef<[u8]>) -> Result<()> { - let data = data.as_ref(); - unsafe { - check(ffi::fido_cred_set_clientdata( - self.0.as_ptr(), - data.as_ptr(), - data.len(), - ))?; - } - - Ok(()) - } - - /// See [CredentialRequestBuilder::client_data] - pub fn set_client_data_hash(&mut self, data: impl AsRef<[u8]>) -> Result<()> { - let data = data.as_ref(); - unsafe { - check(ffi::fido_cred_set_clientdata_hash( - self.0.as_ptr(), - data.as_ptr(), - data.len(), - ))?; - } - - Ok(()) - } - - /// Set credential ID - pub fn set_id(&mut self, id: impl AsRef<[u8]>) -> Result<()> { - let id = id.as_ref(); - unsafe { - check(ffi::fido_cred_set_id( - self.0.as_ptr(), - id.as_ptr(), - id.len(), - ))?; - } - - Ok(()) - } - - /// Set the relying party id and name parameters of cred - pub fn set_rp(&mut self, id: impl AsRef, name: impl AsRef) -> Result<()> { - let id = CString::new(id.as_ref())?; - let name = CString::new(name.as_ref())?; - - unsafe { - check(ffi::fido_cred_set_rp( - self.0.as_ptr(), - id.as_ptr(), - name.as_ptr(), - ))?; - } - - Ok(()) - } - - /// See [CredentialRequestBuilder::client_data] - pub fn set_signature(&mut self, sig: impl AsRef<[u8]>) -> Result<()> { - let sig = sig.as_ref(); - unsafe { - check(ffi::fido_cred_set_sig( - self.0.as_ptr(), - sig.as_ptr(), - sig.len(), - ))?; - } - - Ok(()) - } - - /// Sets the user attributes of cred. - /// - /// Previously set user attributes are flushed - pub fn set_user( - &mut self, - id: impl AsRef<[u8]>, - name: impl AsRef, - display_name: Option<&str>, - icon: Option<&str>, - ) -> Result<()> { - let id = id.as_ref(); - let name = CString::new(name.as_ref())?; - let display_name = display_name.map(CString::new).transpose()?; - let icon = icon.map(CString::new).transpose()?; - - let display_name_ptr = match &display_name { - Some(it) => it.as_ptr(), - None => std::ptr::null(), - }; - - let icon_ptr = match &icon { - Some(it) => it.as_ptr(), - None => std::ptr::null(), - }; - - unsafe { - check(ffi::fido_cred_set_user( - self.0.as_ptr(), - id.as_ptr(), - id.len(), - name.as_ptr(), - display_name_ptr, - icon_ptr, - ))?; - } - - Ok(()) - } - - /// Sets the extensions of cred to the bitmask flags. - /// - /// Only the FIDO_EXT_CRED_BLOB, FIDO_EXT_CRED_PROTECT, FIDO_EXT_HMAC_SECRET, - /// FIDO_EXT_MINPINLEN, and FIDO_EXT_LARGEBLOB_KEY extensions are supported. - /// - /// See [Extensions] - pub fn set_extension(&mut self, flags: Extensions) -> Result<()> { - unsafe { - check(ffi::fido_cred_set_extensions(self.0.as_ptr(), flags.bits))?; - } - - Ok(()) - } - - /// Sets the “credBlob” to be stored with cred. - pub fn set_blob(&mut self, data: impl AsRef<[u8]>) -> Result<()> { - let data = data.as_ref(); - unsafe { - check(ffi::fido_cred_set_blob( - self.0.as_ptr(), - data.as_ptr(), - data.len(), - ))?; - } - - Ok(()) - } - - /// Enable the CTAP 2.1 FIDO_EXT_MINPINLEN extension on cred and sets the expected minimum PIN length of cred to len. - /// - /// If len is zero, the FIDO_EXT_MINPINLEN extension is disabled on cred. - pub fn set_pin_min_len(&mut self, len: usize) -> Result<()> { - unsafe { - check(ffi::fido_cred_set_pin_minlen(self.0.as_ptr(), len))?; - } - - Ok(()) - } - - /// Enables the CTAP 2.1 FIDO_EXT_CRED_PROTECT extension on cred and sets the protection of cred to the scalar prot. - /// - /// At the moment, only the FIDO_CRED_PROT_UV_OPTIONAL, FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID, and FIDO_CRED_PROT_UV_REQUIRED protections are supported. - /// - /// See [Protection] - pub fn set_protection(&mut self, prot: Protection) -> Result<()> { - unsafe { - check(ffi::fido_cred_set_prot(self.0.as_ptr(), prot as i32))?; - } - - Ok(()) - } - - /// Set the rk (resident/discoverable key) attribute of cred. - pub fn set_rk(&mut self, rk: Opt) -> Result<()> { - unsafe { - check(ffi::fido_cred_set_rk(self.0.as_ptr(), rk as _))?; - } - - Ok(()) - } - - /// Set the uv (user verification) attribute of cred. - pub fn set_uv(&mut self, uv: Opt) -> Result<()> { - unsafe { - check(ffi::fido_cred_set_uv(self.0.as_ptr(), uv as _))?; - } - - Ok(()) - } - - /// Sets the attestation statement format identifier of cred. - /// - /// Note that not all authenticators support FIDO2 and therefore may only be able to generate fido-u2f attestation statements. - pub fn set_attestation_format(&mut self, fmt: AttestationFormat) -> Result<()> { - let fmt = match fmt { - AttestationFormat::Packed => CString::new("packed"), - AttestationFormat::FidoU2f => CString::new("fido-u2f"), - AttestationFormat::Tpm => CString::new("tpm"), - AttestationFormat::None => CString::new("none"), - }; - let fmt = fmt.unwrap(); - - unsafe { - check(ffi::fido_cred_set_fmt(self.0.as_ptr(), fmt.as_ptr()))?; - } - - Ok(()) - } - - /// Sets the type of cred. - /// - /// The `type` of a credential may only be set once. - /// - /// Note that not all authenticators support COSE_RS256, COSE_ES384, or COSE_EDDSA. - pub fn set_cose_type(&mut self, ty: CoseType) -> Result<()> { - unsafe { - check(ffi::fido_cred_set_type(self.0.as_ptr(), ty as i32))?; - } - - Ok(()) - } -} - -#[derive(Copy, Clone, Debug)] -#[repr(i32)] -pub enum Opt { - Omit = 0, - False = 1, - True = 2, -} - -#[derive(Copy, Clone, Debug)] -#[repr(i32)] -pub enum Protection { - UvOptional = ffi::FIDO_CRED_PROT_UV_OPTIONAL, - UvOptionalWithId = ffi::FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID, - UvRequired = ffi::FIDO_CRED_PROT_UV_REQUIRED, -} - -/// Attestation statement format -#[derive(Copy, Clone, Debug)] -pub enum AttestationFormat { - Packed, - FidoU2f, - Tpm, - None, -} - -/// COSE Algorithms type -#[repr(i32)] -pub enum CoseType { - ES256 = ffi::COSE_ES256, - ES384 = ffi::COSE_ES384, - RS256 = ffi::COSE_RS256, - EDDSA = ffi::COSE_EDDSA, - UNSPEC = ffi::COSE_UNSPEC, -} - -impl TryFrom for CoseType { - type Error = i32; - - fn try_from(value: i32) -> Result { - match value { - ffi::COSE_UNSPEC => Ok(CoseType::UNSPEC), - ffi::COSE_ES256 => Ok(CoseType::ES256), - ffi::COSE_ES384 => Ok(CoseType::ES384), - ffi::COSE_RS256 => Ok(CoseType::RS256), - ffi::COSE_EDDSA => Ok(CoseType::EDDSA), - _ => Err(value), - } - } -} - -bitflags! { - /// FIDO extensions - pub struct Extensions: i32 { - const CRED_BLOB = ffi::FIDO_EXT_CRED_BLOB; - const CRED_PROTECT = ffi::FIDO_EXT_CRED_PROTECT; - const HMAC_SECRET = ffi::FIDO_EXT_HMAC_SECRET; - const MIN_PINLEN = ffi::FIDO_EXT_MINPINLEN; - const LARGEBLOB_KEY = ffi::FIDO_EXT_LARGEBLOB_KEY; - } -} diff --git a/fido-rs/fido2-rs/src/device.rs b/fido-rs/fido2-rs/src/device.rs deleted file mode 100644 index 7a300d4..0000000 --- a/fido-rs/fido2-rs/src/device.rs +++ /dev/null @@ -1,390 +0,0 @@ -use crate::assertion::{AssertRequest, Assertions}; -use crate::cbor::CBORInfo; -use crate::credentials::Credential; -use crate::error::Result; -use crate::utils::check; -use bitflags::bitflags; -use ffi::fido_dev_t; -use std::ffi::{CStr, CString}; -use std::marker::PhantomData; -use std::ptr::NonNull; - -/// Device list. -/// -/// contain fido devices found by the underlying operating system. -/// -/// user can call [DeviceList::list_devices] to start enumerate fido devices. -pub struct DeviceList<'a> { - ptr: NonNull, - idx: usize, - found: usize, - _p: PhantomData<&'a ()>, -} - -impl<'a> DeviceList<'a> { - /// Enumerate up to `max` fido devices found by the underlying operating system. - /// - /// Currently only USB HID devices are supported - pub fn list_devices(max: usize) -> DeviceList<'a> { - unsafe { - let mut found = 0; - let ptr = ffi::fido_dev_info_new(max); - - ffi::fido_dev_info_manifest(ptr, max, &mut found); - - DeviceList { - ptr: NonNull::new_unchecked(ptr), - idx: 0, - found, - _p: PhantomData, - } - } - } -} - -impl<'a> Iterator for DeviceList<'a> { - type Item = DeviceInfo<'a>; - - fn next(&mut self) -> Option { - if self.idx >= self.found { - return None; - } - - unsafe { - let ptr = self.ptr.as_ptr(); - let info = ffi::fido_dev_info_ptr(ptr, self.idx); - - let path = ffi::fido_dev_info_path(info); - let path = CStr::from_ptr(path); - - let product_id = ffi::fido_dev_info_product(info); - let vendor_id = ffi::fido_dev_info_vendor(info); - - let manufacturer = ffi::fido_dev_info_manufacturer_string(info); - let manufacturer = CStr::from_ptr(manufacturer); - - let product = ffi::fido_dev_info_product_string(info); - let product = CStr::from_ptr(product); - self.idx += 1; - - Some(DeviceInfo { - path, - product_id, - vendor_id, - manufacturer, - product, - }) - } - } -} - -impl<'a> ExactSizeIterator for DeviceList<'a> { - fn len(&self) -> usize { - self.found - } -} - -impl<'a> Drop for DeviceList<'a> { - fn drop(&mut self) { - unsafe { - ffi::fido_dev_info_free(&mut self.ptr.as_ptr(), self.found); - } - } -} - -/// Device info obtained from [DeviceList] -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct DeviceInfo<'a> { - pub path: &'a CStr, - pub product_id: i16, - pub vendor_id: i16, - pub manufacturer: &'a CStr, - pub product: &'a CStr, -} - -impl<'a> DeviceInfo<'a> { - /// Open the device specified by this [DeviceInfo] - pub fn open(&self) -> Result { - unsafe { - let ptr = ffi::fido_dev_new(); - check(ffi::fido_dev_open(ptr, self.path.as_ptr()))?; - - let ptr = NonNull::new_unchecked(ptr); - - Ok(Device { ptr }) - } - } -} - -/// A cancel handle to device, used to cancel a pending requests. -/// -/// This handle can be copy/clone. -#[derive(Copy, Clone, Eq, PartialEq)] -pub struct DeviceCancel(NonNull); - -impl DeviceCancel { - /// Cancel any pending requests on device. - pub fn cancel(&self) { - unsafe { - ffi::fido_dev_cancel(self.0.as_ptr()); - } - } -} - -/// A fido device. -pub struct Device { - ptr: NonNull, -} - -impl Device { - /// Open the device pointed to by `path`. - /// - /// If dev claims to be FIDO2, libfido2 will attempt to speak FIDO2 to dev. - /// If that fails, libfido2 will fallback to U2F unless the FIDO_DISABLE_U2F_FALLBACK flag - /// was set in fido_init(3). - pub fn open(path: impl AsRef) -> Result { - let path = CString::new(path.as_ref())?; - unsafe { - let dev = ffi::fido_dev_new(); - assert!(!dev.is_null()); - - check(ffi::fido_dev_open(dev, path.as_ptr()))?; - - Ok(Device { - ptr: NonNull::new_unchecked(dev), - }) - } - } - - /// Get a handle of this device for cancel. - pub fn cancel_handle(&self) -> DeviceCancel { - DeviceCancel(self.ptr) - } - - /// can be used to force CTAP2 communication with dev - pub fn force_u2f(&self) { - unsafe { - ffi::fido_dev_force_u2f(self.ptr.as_ptr()); - } - } - - /// Can be used to force CTAP1 (U2F) communication with dev - pub fn force_fido2(&self) { - unsafe { - ffi::fido_dev_force_fido2(self.ptr.as_ptr()); - } - } - - /// Returns true if dev is a FIDO2 device. - pub fn is_fido2(&self) -> bool { - unsafe { ffi::fido_dev_is_fido2(self.ptr.as_ptr()) } - } - - /// Returns true if dev is a Windows Hello device. - pub fn is_winhello(&self) -> bool { - unsafe { ffi::fido_dev_is_winhello(self.ptr.as_ptr()) } - } - - /// Returns true if dev supports CTAP 2.1 Credential Management. - pub fn supports_credman(&self) -> bool { - unsafe { ffi::fido_dev_supports_credman(self.ptr.as_ptr()) } - } - - /// Returns true if dev supports CTAP 2.1 Credential Protection. - pub fn supports_cred_prot(&self) -> bool { - unsafe { ffi::fido_dev_supports_cred_prot(self.ptr.as_ptr()) } - } - - /// Returns true if dev supports CTAP 2.1 UV token permissions. - pub fn supports_permission(&self) -> bool { - unsafe { ffi::fido_dev_supports_permissions(self.ptr.as_ptr()) } - } - - /// Returns true if dev supports CTAP 2.0 Client PINs. - pub fn supports_pin(&self) -> bool { - unsafe { ffi::fido_dev_supports_pin(self.ptr.as_ptr()) } - } - - /// Returns true if dev supports a built-in user verification method. - pub fn supports_uv(&self) -> bool { - unsafe { ffi::fido_dev_supports_uv(self.ptr.as_ptr()) } - } - - /// Returns true if dev has a CTAP 2.0 Client PIN set. - pub fn has_pin(&self) -> bool { - unsafe { ffi::fido_dev_has_pin(self.ptr.as_ptr()) } - } - - /// Returns true if dev supports built-in user verification and its user verification feature is configured. - pub fn has_uv(&self) -> bool { - unsafe { ffi::fido_dev_has_uv(self.ptr.as_ptr()) } - } - - /// Return CTAPHID protocol info. - pub fn ctap_protocol(&self) -> CTAPHIDInfo { - unsafe { - let protocol = ffi::fido_dev_protocol(self.ptr.as_ptr()); - let build = ffi::fido_dev_build(self.ptr.as_ptr()); - let flags = ffi::fido_dev_flags(self.ptr.as_ptr()); - let flags = CTAPHIDFlags::from_bits_truncate(flags); - let major = ffi::fido_dev_major(self.ptr.as_ptr()); - let minor = ffi::fido_dev_minor(self.ptr.as_ptr()); - - CTAPHIDInfo { - protocol, - build, - flags, - major, - minor, - } - } - } - - /// Return device info. - pub fn info(&self) -> Result { - let info = CBORInfo::new(); - - unsafe { - check(ffi::fido_dev_get_cbor_info( - self.ptr.as_ptr(), - info.ptr.as_ptr(), - ))?; - } - - Ok(info) - } - - /// Generates a new credential on a FIDO2 device. - /// - /// Ask the FIDO2 device represented by dev to generate a new credential according to the following parameters defined in cred: - /// * type - /// * client data hash - /// * relying party - /// * user attributes - /// * list of excluded credential IDs - /// * resident/discoverable key and user verification attributes - /// - /// If a PIN is not needed to authenticate the request against dev, then pin may be [None]. - /// - /// **Please note that fido_dev_make_cred() is synchronous and will block if necessary.** - /// - /// # Example - /// ```rust,no_run - /// use fido2_rs::credentials::Credential; - /// use fido2_rs::device::Device; - /// use fido2_rs::credentials::CoseType; - /// - /// fn main() -> anyhow::Result<()> { - /// let dev = Device::open("windows://hello").expect("unable open device"); - /// let mut cred = Credential::new(); - /// cred.set_client_data(&[1, 2, 3, 4, 5, 6])?; - /// cred.set_rp("fido_rs", "fido example")?; - /// cred.set_user(&[1, 2, 3, 4, 5, 6], "alice", Some("alice"), None)?; - /// cred.set_cose_type(CoseType::RS256)?; - /// - /// let _ = dev.make_credential(&mut cred, None)?; // and not require pin.. - /// - /// dbg!(cred.id()); - /// Ok(()) - /// } - /// ``` - pub fn make_credential(&self, credential: &mut Credential, pin: Option<&str>) -> Result<()> { - let pin = pin.map(CString::new).transpose()?; - let pin_ptr = match &pin { - Some(pin) => pin.as_ptr(), - None => std::ptr::null(), - }; - - unsafe { - check(ffi::fido_dev_make_cred( - self.ptr.as_ptr(), - credential.0.as_ptr(), - pin_ptr, - ))?; - } - - Ok(()) - } - - /// Obtains an assertion from a FIDO2 device. - /// - /// Ask the FIDO2 device represented by dev for an assertion according to the following parameters defined in assert: - /// * relying party ID - /// * client data hash - /// * list of allowed credential IDs - /// * user presence and user verification attributes - /// - /// If a PIN is not needed to authenticate the request against dev, then pin may be NULL. - /// - /// **Please note that fido_dev_get_assert() is synchronous and will block if necessary.** - /// - /// # Example - /// ```rust,no_run - /// use fido2_rs::assertion::AssertRequest; - /// use fido2_rs::credentials::Opt; - /// use fido2_rs::device::Device; - /// - /// fn main() -> anyhow::Result<()> { - /// let dev = Device::open("windows://hello")?; - /// let mut request = AssertRequest::new(); /// - /// - /// request.set_rp("fido_rs")?; - /// request.set_client_data(&[1, 2, 3, 4, 5, 6])?; - /// request.set_uv(Opt::True)?; - /// - /// let _assertions = dev.get_assertion(request, None)?; - /// Ok(()) - /// } - /// ``` - pub fn get_assertion(&self, request: AssertRequest, pin: Option<&str>) -> Result { - let pin = pin.map(CString::new).transpose()?; - let pin_ptr = match &pin { - Some(pin) => pin.as_ptr(), - None => std::ptr::null(), - }; - - unsafe { - check(ffi::fido_dev_get_assert( - self.ptr.as_ptr(), - request.0.ptr.as_ptr(), - pin_ptr, - ))?; - } - - Ok(request.0) - } -} - -impl Drop for Device { - fn drop(&mut self) { - unsafe { - let _ = ffi::fido_dev_close(self.ptr.as_ptr()); - ffi::fido_dev_free(&mut self.ptr.as_ptr()); - } - } -} - -bitflags! { - /// CTAPHID capabilities - pub struct CTAPHIDFlags: u8 { - const WINK = ffi::FIDO_CAP_WINK as u8; - const CBOR = ffi::FIDO_CAP_CBOR as u8; - const NMSG = ffi::FIDO_CAP_NMSG as u8; - } -} - -/// For the format and meaning of the CTAPHID parameters, -/// please refer to the FIDO Client to Authenticator Protocol (CTAP) specification. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct CTAPHIDInfo { - /// CTAPHID protocol version identifier of dev - pub protocol: u8, - /// CTAPHID build version number of dev. - pub build: u8, - /// CTAPHID capabilities flags of dev. - pub flags: CTAPHIDFlags, - /// CTAPHID major version number of dev. - pub major: u8, - /// CTAPHID minor version number of dev. - pub minor: u8, -} diff --git a/fido-rs/fido2-rs/src/error.rs b/fido-rs/fido2-rs/src/error.rs deleted file mode 100644 index f29750a..0000000 --- a/fido-rs/fido2-rs/src/error.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::ffi::CStr; -use std::fmt::{Debug, Display, Formatter}; - -pub type Result = std::result::Result; - -/// Error type of fido2-rs -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error("libfido2: {0}")] - Fido(#[from] FidoError), - - #[error("{0}")] - NulError(#[from] std::ffi::NulError), - - #[error("openssl {0}")] - Openssl(#[from] openssl::error::ErrorStack), -} - -/// Error from libfido2 -pub struct FidoError { - /// the origin error code - pub code: i32, -} - -impl FidoError { - pub(crate) const fn new(code: i32) -> FidoError { - FidoError { code } - } -} - -impl Debug for FidoError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - ::fmt(self, f) - } -} - -impl Display for FidoError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let err = unsafe { - let err = ffi::fido_strerr(self.code); - CStr::from_ptr(err) - }; - - f.debug_struct("Error") - .field("code", &self.code) - .field("message", &err) - .finish() - } -} - -impl std::error::Error for FidoError {} diff --git a/fido-rs/fido2-rs/src/key.rs b/fido-rs/fido2-rs/src/key.rs deleted file mode 100644 index cf71856..0000000 --- a/fido-rs/fido2-rs/src/key.rs +++ /dev/null @@ -1,85 +0,0 @@ -use crate::error::FidoError; -use openssl::ec::EcKey; -use openssl::pkey::{PKey, Public}; -use std::ptr::NonNull; - -macro_rules! impl_key { - ( - type CType = $ctype:ty; - fn new = $new:expr; - $(fn from<$t:ty> = $from:expr;)* - fn drop = $drop:expr; - - pub struct $ty:ident; - ) => { - pub struct $ty(NonNull<$ctype>); - - $(impl TryFrom<$t> for $ty { - type Error = FidoError; - - fn try_from(value: $t) -> Result { - use foreign_types::ForeignType; - - unsafe { - let pk = $new(); - crate::utils::check($from(pk, value.as_ptr() as _))?; - - Ok($ty(NonNull::new_unchecked(pk))) - } - } - })* - - impl Drop for $ty { - fn drop(&mut self) { - let mut ptr = self.0.as_ptr(); - unsafe { - $drop(&mut ptr); - } - - let _ = std::mem::replace(&mut self.0, NonNull::dangling()); - } - } - - impl $ty { - pub(crate) fn as_ptr(&self) -> *const $ctype { - self.0.as_ptr() - } - } - }; -} - -impl_key! { - type CType = ffi::eddsa_pk_t; - fn new = ffi::eddsa_pk_new; - fn from> = ffi::eddsa_pk_from_EVP_PKEY; - fn drop = ffi::eddsa_pk_free; - - pub struct Eddsa; -} - -impl_key! { - type CType = ffi::rs256_pk_t; - fn new = ffi::rs256_pk_new; - fn from> = ffi::rs256_pk_from_EVP_PKEY; - fn drop = ffi::rs256_pk_free; - - pub struct Rsa; -} - -impl_key! { - type CType = ffi::es256_pk_t; - fn new = ffi::es256_pk_new; - fn from> = ffi::es256_pk_from_EC_KEY; - fn drop = ffi::es256_pk_free; - - pub struct ES256; -} - -impl_key! { - type CType = ffi::es384_pk_t; - fn new = ffi::es384_pk_new; - fn from> = ffi::es384_pk_from_EC_KEY; - fn drop = ffi::es384_pk_free; - - pub struct ES384; -} diff --git a/fido-rs/fido2-rs/src/lib.rs b/fido-rs/fido2-rs/src/lib.rs deleted file mode 100644 index 2310fb4..0000000 --- a/fido-rs/fido2-rs/src/lib.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! Bindings to Yubico libfido2 -//! -//! This crate provides a safe interface to the Yubico libfido2 library. -//! -//! # Building -//! -//! There are multiple options available to locate libfido2. -//! -//! ## Pre-build MSVC binary. -//! -//! If the rust toolchain is msvc, the `libfido2-sys` crate will download a pre-build binary dll from -//! Yubico release. -//! -//! ## Build from source. -//! -//! If the target is not msvc(mingw on windows or linux), this crate will build a static library from source. -//! -//! The build process requires a C compiler, cmake, libcbor, zlib, libcrypto. -//! -//! ## Automatic -//! -//! The `libfido2-sys` crate can automatically detect libfido2 installations via vcpkg on Windows and `pkg-config` on Linux. -//! -//! This method can be enabled by set environment variable `FIDO2_USE_PKG_CONFIG` to any non empty value. -//! -//! ## Manual -//! -//! A `FIDO2_LIB_DIR` environment variable can be used to help `libfido2-sys` to find a libfido2 installation. -//! -//! The directory should contains the libfido2 libraries. -//! -//! The other dependency like libcbor, libcrypto, zlib will use system version. Currently there is no way to -//! set these library directory, but you can put them together in `FIDO2_LIB_DIR`. -//! -//! # Example -//! -//! ## Enumerate fido devices on system -//! ```rust,no_run -//! use fido2_rs::device::DeviceList; -//! -//! let list = DeviceList::list_devices(4); -//! for dev in list { -//! println!("{:?}", dev.path); -//! } -//! -//! ``` -//! -//! ## Make a credential -//! ```rust,no_run -//! use fido2_rs::device::Device; -//! use fido2_rs::credentials::Credential; -//! use fido2_rs::credentials::CoseType; -//! use anyhow::Result; -//! fn main() -> Result<()> { -//! let dev = Device::open("windows://hello").expect("unable open windows hello"); -//! -//! let mut cred = Credential::new(); -//! cred.set_client_data(&[1, 2, 3, 4, 5, 6])?; -//! cred.set_rp("fido_rs", "fido example")?; -//! cred.set_user(&[1, 2, 3, 4, 5, 6], "alice", Some("alice"), None)?; -//! cred.set_cose_type(CoseType::RS256)?; -//! -//! let _ = dev.make_credential(&mut cred, None)?; -//! dbg!(cred.id()); -//! -//! Ok(()) -//! } -//! ``` -extern crate libfido2_sys as ffi; - -#[macro_use] -mod utils; - -pub mod assertion; -mod cbor; -pub mod credentials; -pub mod device; -pub mod error; -mod key; diff --git a/fido-rs/fido2-rs/src/utils.rs b/fido-rs/fido2-rs/src/utils.rs deleted file mode 100644 index f364107..0000000 --- a/fido-rs/fido2-rs/src/utils.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::error::FidoError; - -pub(crate) const fn check(code: i32) -> Result<(), FidoError> { - match code { - 0 => Ok(()), - _ => Err(FidoError::new(code)), - } -} - -macro_rules! str_or_none { - ($ptr:ident) => { - if $ptr.is_null() { - None - } else { - let $ptr = unsafe { - std::ffi::CStr::from_ptr($ptr) - .to_str() - .expect("invalid utf8") - }; - - Some($ptr) - } - }; -} diff --git a/fido-rs/libfido2-sys/Cargo.toml b/fido-rs/libfido2-sys/Cargo.toml deleted file mode 100644 index d1f8894..0000000 --- a/fido-rs/libfido2-sys/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "libfido2-sys" -version = "0.2.0" -authors = ["tyan boot "] -license = "MIT" -description = "FFI bindings to Yubico fido2" -repository = "https://github.com/tyan-boot/fido-rs" -keywords = ["fido2", "webauthn"] -categories = ["external-ffi-bindings"] -edition = "2021" -links = "fido2" - -build = "build.rs" - -[dependencies] - -[build-dependencies] -anyhow = "1.0.66" -cfg-if = "1.0.0" - -[target.'cfg(target_env = "msvc")'.build-dependencies] -vcpkg = "0.2.15" - -[target.'cfg(not(target_env = "msvc"))'.build-dependencies] -pkg-config = "0.3.26" diff --git a/fido-rs/libfido2-sys/LICENSE b/fido-rs/libfido2-sys/LICENSE deleted file mode 100644 index 4fa01fb..0000000 --- a/fido-rs/libfido2-sys/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 tyan boot - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/fido-rs/libfido2-sys/README.MD b/fido-rs/libfido2-sys/README.MD deleted file mode 100644 index 2b69a18..0000000 --- a/fido-rs/libfido2-sys/README.MD +++ /dev/null @@ -1,6 +0,0 @@ -# libfido2-sys - -[![crates.io](https://img.shields.io/crates/v/libfido2-sys?style=flat-square)](https://crates.io/crates/libfido2-sys) -[![MIT](https://img.shields.io/crates/l/libfido2-sys?style=flat-square)](./LICENSE) - -FFI bindings to Yubico [libfido2](https://github.com/Yubico/libfido2) \ No newline at end of file diff --git a/fido-rs/libfido2-sys/build.rs b/fido-rs/libfido2-sys/build.rs deleted file mode 100644 index 65f6207..0000000 --- a/fido-rs/libfido2-sys/build.rs +++ /dev/null @@ -1,57 +0,0 @@ -use anyhow::Result; -use cfg_if::cfg_if; -use std::env; - -fn main() -> Result<()> { - println!("cargo:rerun-if-env-changed=FIDO2_LIB_DIR"); - println!("cargo:rerun-if-env-changed=FIDO2_USE_PKG_CONFIG"); - - if let Ok(dir) = env::var("FIDO2_LIB_DIR") { - println!("cargo:rustc-link-search={}", dir); - println!("cargo:rustc-link-lib=static=fido2"); - - if cfg!(windows) { - println!("cargo:rustc-link-lib=hid"); - println!("cargo:rustc-link-lib=user32"); - println!("cargo:rustc-link-lib=setupapi"); - println!("cargo:rustc-link-lib=crypt32"); - } - - cfg_if! { - if #[cfg(all(windows, target_env = "msvc"))] { - // link to pre-build cbor,zlib,crypto - println!("cargo:rustc-link-lib=cbor"); - println!("cargo:rustc-link-lib=zlib1"); - println!("cargo:rustc-link-lib=crypto-49"); - } else { - println!("cargo:rustc-link-lib=cbor"); - println!("cargo:rustc-link-lib=z"); - println!("cargo:rustc-link-lib=crypto"); - } - } - - return Ok(()); - } - - find_pkg() - -} - -#[cfg(not(target_env = "msvc"))] -fn find_pkg() -> Result<()> { - let _lib = pkg_config::probe_library("libfido2")?; - - Ok(()) -} - -#[cfg(all(windows, target_env = "msvc"))] -fn find_pkg() -> Result<()> { - let _lib = vcpkg::find_package("libfido2")?; - - println!("cargo:rustc-link-lib=hid"); - println!("cargo:rustc-link-lib=user32"); - println!("cargo:rustc-link-lib=setupapi"); - println!("cargo:rustc-link-lib=crypt32"); - - Ok(()) -} diff --git a/fido-rs/libfido2-sys/fido2_wrapper.h b/fido-rs/libfido2-sys/fido2_wrapper.h deleted file mode 100644 index ef4c8f1..0000000 --- a/fido-rs/libfido2-sys/fido2_wrapper.h +++ /dev/null @@ -1,5 +0,0 @@ -#include -#include -#include -#include -#include diff --git a/fido-rs/libfido2-sys/help.txt b/fido-rs/libfido2-sys/help.txt deleted file mode 100644 index 7334de0..0000000 Binary files a/fido-rs/libfido2-sys/help.txt and /dev/null differ diff --git a/fido-rs/libfido2-sys/src/ffi.rs b/fido-rs/libfido2-sys/src/ffi.rs deleted file mode 100644 index 2225c90..0000000 --- a/fido-rs/libfido2-sys/src/ffi.rs +++ /dev/null @@ -1,856 +0,0 @@ -/* automatically generated by rust-bindgen 0.63.0 */ - -pub const FIDO_ERR_SUCCESS: i32 = 0; -pub const FIDO_ERR_INVALID_COMMAND: i32 = 1; -pub const FIDO_ERR_INVALID_PARAMETER: i32 = 2; -pub const FIDO_ERR_INVALID_LENGTH: i32 = 3; -pub const FIDO_ERR_INVALID_SEQ: i32 = 4; -pub const FIDO_ERR_TIMEOUT: i32 = 5; -pub const FIDO_ERR_CHANNEL_BUSY: i32 = 6; -pub const FIDO_ERR_LOCK_REQUIRED: i32 = 10; -pub const FIDO_ERR_INVALID_CHANNEL: i32 = 11; -pub const FIDO_ERR_CBOR_UNEXPECTED_TYPE: i32 = 17; -pub const FIDO_ERR_INVALID_CBOR: i32 = 18; -pub const FIDO_ERR_MISSING_PARAMETER: i32 = 20; -pub const FIDO_ERR_LIMIT_EXCEEDED: i32 = 21; -pub const FIDO_ERR_UNSUPPORTED_EXTENSION: i32 = 22; -pub const FIDO_ERR_FP_DATABASE_FULL: i32 = 23; -pub const FIDO_ERR_LARGEBLOB_STORAGE_FULL: i32 = 24; -pub const FIDO_ERR_CREDENTIAL_EXCLUDED: i32 = 25; -pub const FIDO_ERR_PROCESSING: i32 = 33; -pub const FIDO_ERR_INVALID_CREDENTIAL: i32 = 34; -pub const FIDO_ERR_USER_ACTION_PENDING: i32 = 35; -pub const FIDO_ERR_OPERATION_PENDING: i32 = 36; -pub const FIDO_ERR_NO_OPERATIONS: i32 = 37; -pub const FIDO_ERR_UNSUPPORTED_ALGORITHM: i32 = 38; -pub const FIDO_ERR_OPERATION_DENIED: i32 = 39; -pub const FIDO_ERR_KEY_STORE_FULL: i32 = 40; -pub const FIDO_ERR_NOT_BUSY: i32 = 41; -pub const FIDO_ERR_NO_OPERATION_PENDING: i32 = 42; -pub const FIDO_ERR_UNSUPPORTED_OPTION: i32 = 43; -pub const FIDO_ERR_INVALID_OPTION: i32 = 44; -pub const FIDO_ERR_KEEPALIVE_CANCEL: i32 = 45; -pub const FIDO_ERR_NO_CREDENTIALS: i32 = 46; -pub const FIDO_ERR_USER_ACTION_TIMEOUT: i32 = 47; -pub const FIDO_ERR_NOT_ALLOWED: i32 = 48; -pub const FIDO_ERR_PIN_INVALID: i32 = 49; -pub const FIDO_ERR_PIN_BLOCKED: i32 = 50; -pub const FIDO_ERR_PIN_AUTH_INVALID: i32 = 51; -pub const FIDO_ERR_PIN_AUTH_BLOCKED: i32 = 52; -pub const FIDO_ERR_PIN_NOT_SET: i32 = 53; -pub const FIDO_ERR_PIN_REQUIRED: i32 = 54; -pub const FIDO_ERR_PIN_POLICY_VIOLATION: i32 = 55; -pub const FIDO_ERR_PIN_TOKEN_EXPIRED: i32 = 56; -pub const FIDO_ERR_REQUEST_TOO_LARGE: i32 = 57; -pub const FIDO_ERR_ACTION_TIMEOUT: i32 = 58; -pub const FIDO_ERR_UP_REQUIRED: i32 = 59; -pub const FIDO_ERR_UV_BLOCKED: i32 = 60; -pub const FIDO_ERR_UV_INVALID: i32 = 63; -pub const FIDO_ERR_UNAUTHORIZED_PERM: i32 = 64; -pub const FIDO_ERR_ERR_OTHER: i32 = 127; -pub const FIDO_ERR_SPEC_LAST: i32 = 223; -pub const FIDO_OK: i32 = 0; -pub const FIDO_ERR_TX: i32 = -1; -pub const FIDO_ERR_RX: i32 = -2; -pub const FIDO_ERR_RX_NOT_CBOR: i32 = -3; -pub const FIDO_ERR_RX_INVALID_CBOR: i32 = -4; -pub const FIDO_ERR_INVALID_PARAM: i32 = -5; -pub const FIDO_ERR_INVALID_SIG: i32 = -6; -pub const FIDO_ERR_INVALID_ARGUMENT: i32 = -7; -pub const FIDO_ERR_USER_PRESENCE_REQUIRED: i32 = -8; -pub const FIDO_ERR_INTERNAL: i32 = -9; -pub const FIDO_ERR_NOTFOUND: i32 = -10; -pub const FIDO_ERR_COMPRESS: i32 = -11; -pub const CTAP_AUTHDATA_USER_PRESENT: i32 = 1; -pub const CTAP_AUTHDATA_USER_VERIFIED: i32 = 4; -pub const CTAP_AUTHDATA_ATT_CRED: i32 = 64; -pub const CTAP_AUTHDATA_EXT_DATA: i32 = 128; -pub const CTAP_CMD_PING: i32 = 1; -pub const CTAP_CMD_MSG: i32 = 3; -pub const CTAP_CMD_LOCK: i32 = 4; -pub const CTAP_CMD_INIT: i32 = 6; -pub const CTAP_CMD_WINK: i32 = 8; -pub const CTAP_CMD_CBOR: i32 = 16; -pub const CTAP_CMD_CANCEL: i32 = 17; -pub const CTAP_KEEPALIVE: i32 = 59; -pub const CTAP_FRAME_INIT: i32 = 128; -pub const CTAP_CBOR_MAKECRED: i32 = 1; -pub const CTAP_CBOR_ASSERT: i32 = 2; -pub const CTAP_CBOR_GETINFO: i32 = 4; -pub const CTAP_CBOR_CLIENT_PIN: i32 = 6; -pub const CTAP_CBOR_RESET: i32 = 7; -pub const CTAP_CBOR_NEXT_ASSERT: i32 = 8; -pub const CTAP_CBOR_LARGEBLOB: i32 = 12; -pub const CTAP_CBOR_CONFIG: i32 = 13; -pub const CTAP_CBOR_BIO_ENROLL_PRE: i32 = 64; -pub const CTAP_CBOR_CRED_MGMT_PRE: i32 = 65; -pub const CTAP_PIN_PROTOCOL1: i32 = 1; -pub const CTAP_PIN_PROTOCOL2: i32 = 2; -pub const U2F_CMD_REGISTER: i32 = 1; -pub const U2F_CMD_AUTH: i32 = 2; -pub const U2F_AUTH_SIGN: i32 = 3; -pub const U2F_AUTH_CHECK: i32 = 7; -pub const CTAP_CID_BROADCAST: i64 = 4294967295; -pub const CTAP_INIT_HEADER_LEN: i32 = 7; -pub const CTAP_CONT_HEADER_LEN: i32 = 5; -pub const CTAP_MAX_REPORT_LEN: i32 = 64; -pub const CTAP_MIN_REPORT_LEN: i32 = 8; -pub const FIDO_RANDOM_DEV: &[u8; 13usize] = b"/dev/urandom\0"; -pub const FIDO_MAXMSG: i32 = 2048; -pub const FIDO_CAP_WINK: i32 = 1; -pub const FIDO_CAP_CBOR: i32 = 4; -pub const FIDO_CAP_NMSG: i32 = 8; -pub const COSE_UNSPEC: i32 = 0; -pub const COSE_ES256: i32 = -7; -pub const COSE_EDDSA: i32 = -8; -pub const COSE_ECDH_ES256: i32 = -25; -pub const COSE_ES384: i32 = -35; -pub const COSE_RS256: i32 = -257; -pub const COSE_RS1: i32 = -65535; -pub const COSE_KTY_OKP: i32 = 1; -pub const COSE_KTY_EC2: i32 = 2; -pub const COSE_KTY_RSA: i32 = 3; -pub const COSE_P256: i32 = 1; -pub const COSE_P384: i32 = 2; -pub const COSE_ED25519: i32 = 6; -pub const FIDO_EXT_HMAC_SECRET: i32 = 1; -pub const FIDO_EXT_CRED_PROTECT: i32 = 2; -pub const FIDO_EXT_LARGEBLOB_KEY: i32 = 4; -pub const FIDO_EXT_CRED_BLOB: i32 = 8; -pub const FIDO_EXT_MINPINLEN: i32 = 16; -pub const FIDO_CRED_PROT_UV_OPTIONAL: i32 = 1; -pub const FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID: i32 = 2; -pub const FIDO_CRED_PROT_UV_REQUIRED: i32 = 3; -pub const FIDO_UV_MODE_TUP: i32 = 1; -pub const FIDO_UV_MODE_FP: i32 = 2; -pub const FIDO_UV_MODE_PIN: i32 = 4; -pub const FIDO_UV_MODE_VOICE: i32 = 8; -pub const FIDO_UV_MODE_FACE: i32 = 16; -pub const FIDO_UV_MODE_LOCATION: i32 = 32; -pub const FIDO_UV_MODE_EYE: i32 = 64; -pub const FIDO_UV_MODE_DRAWN: i32 = 128; -pub const FIDO_UV_MODE_HAND: i32 = 256; -pub const FIDO_UV_MODE_NONE: i32 = 512; -pub const FIDO_UV_MODE_ALL: i32 = 1024; -pub const FIDO_UV_MODE_EXT_PIN: i32 = 2048; -pub const FIDO_UV_MODE_EXT_DRAWN: i32 = 4096; -pub const FIDO_DEBUG: i32 = 1; -pub const FIDO_DISABLE_U2F_FALLBACK: i32 = 2; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct evp_pkey_st { - _unused: [u8; 0], -} -pub type EVP_PKEY = evp_pkey_st; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct rsa_st { - _unused: [u8; 0], -} -pub type RSA = rsa_st; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ec_key_st { - _unused: [u8; 0], -} -pub type EC_KEY = ec_key_st; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct fido_dev { - _unused: [u8; 0], -} -pub type fido_dev_io_open_t = ::std::option::Option< - unsafe extern "C" fn(arg1: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void, ->; -pub type fido_dev_io_close_t = - ::std::option::Option; -pub type fido_dev_io_read_t = ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_uchar, - arg3: usize, - arg4: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int, ->; -pub type fido_dev_io_write_t = ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int, ->; -pub type fido_dev_rx_t = ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut fido_dev, - arg2: u8, - arg3: *mut ::std::os::raw::c_uchar, - arg4: usize, - arg5: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int, ->; -pub type fido_dev_tx_t = ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut fido_dev, - arg2: u8, - arg3: *const ::std::os::raw::c_uchar, - arg4: usize, - ) -> ::std::os::raw::c_int, ->; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct fido_dev_io { - pub open: fido_dev_io_open_t, - pub close: fido_dev_io_close_t, - pub read: fido_dev_io_read_t, - pub write: fido_dev_io_write_t, -} -#[test] -fn bindgen_test_layout_fido_dev_io() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(fido_dev_io)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(fido_dev_io)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).open) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(fido_dev_io), - "::", - stringify!(open) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).close) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(fido_dev_io), - "::", - stringify!(close) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).read) as usize - ptr as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(fido_dev_io), - "::", - stringify!(read) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).write) as usize - ptr as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(fido_dev_io), - "::", - stringify!(write) - ) - ); -} -pub type fido_dev_io_t = fido_dev_io; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct fido_dev_transport { - pub rx: fido_dev_rx_t, - pub tx: fido_dev_tx_t, -} -#[test] -fn bindgen_test_layout_fido_dev_transport() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(fido_dev_transport)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(fido_dev_transport)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rx) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(fido_dev_transport), - "::", - stringify!(rx) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tx) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(fido_dev_transport), - "::", - stringify!(tx) - ) - ); -} -pub type fido_dev_transport_t = fido_dev_transport; -pub const fido_opt_t_FIDO_OPT_OMIT: fido_opt_t = 0; -pub const fido_opt_t_FIDO_OPT_FALSE: fido_opt_t = 1; -pub const fido_opt_t_FIDO_OPT_TRUE: fido_opt_t = 2; -pub type fido_opt_t = ::std::os::raw::c_int; -pub type fido_log_handler_t = - ::std::option::Option; -pub type fido_sigset_t = ::std::os::raw::c_int; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct fido_assert { - _unused: [u8; 0], -} -pub type fido_assert_t = fido_assert; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct fido_cbor_info { - _unused: [u8; 0], -} -pub type fido_cbor_info_t = fido_cbor_info; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct fido_cred { - _unused: [u8; 0], -} -pub type fido_cred_t = fido_cred; -pub type fido_dev_t = fido_dev; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct fido_dev_info { - _unused: [u8; 0], -} -pub type fido_dev_info_t = fido_dev_info; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct es256_pk { - _unused: [u8; 0], -} -pub type es256_pk_t = es256_pk; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct es384_pk { - _unused: [u8; 0], -} -pub type es384_pk_t = es384_pk; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct rs256_pk { - _unused: [u8; 0], -} -pub type rs256_pk_t = rs256_pk; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct eddsa_pk { - _unused: [u8; 0], -} -pub type eddsa_pk_t = eddsa_pk; -extern "C" { - pub fn fido_strerr(arg1: ::std::os::raw::c_int) -> *const ::std::os::raw::c_char; - pub fn fido_assert_new() -> *mut fido_assert_t; - pub fn fido_cred_new() -> *mut fido_cred_t; - pub fn fido_dev_new() -> *mut fido_dev_t; - pub fn fido_dev_new_with_info(arg1: *const fido_dev_info_t) -> *mut fido_dev_t; - pub fn fido_dev_info_new(arg1: usize) -> *mut fido_dev_info_t; - pub fn fido_cbor_info_new() -> *mut fido_cbor_info_t; - pub fn fido_dev_io_handle(arg1: *const fido_dev_t) -> *mut ::std::os::raw::c_void; - pub fn fido_assert_free(arg1: *mut *mut fido_assert_t); - pub fn fido_cbor_info_free(arg1: *mut *mut fido_cbor_info_t); - pub fn fido_cred_free(arg1: *mut *mut fido_cred_t); - pub fn fido_dev_force_fido2(arg1: *mut fido_dev_t); - pub fn fido_dev_force_u2f(arg1: *mut fido_dev_t); - pub fn fido_dev_free(arg1: *mut *mut fido_dev_t); - pub fn fido_dev_info_free(arg1: *mut *mut fido_dev_info_t, arg2: usize); - pub fn fido_init(arg1: ::std::os::raw::c_int); - pub fn fido_set_log_handler(arg1: fido_log_handler_t); - pub fn fido_assert_authdata_ptr( - arg1: *const fido_assert_t, - arg2: usize, - ) -> *const ::std::os::raw::c_uchar; - pub fn fido_assert_clientdata_hash_ptr( - arg1: *const fido_assert_t, - ) -> *const ::std::os::raw::c_uchar; - pub fn fido_assert_hmac_secret_ptr( - arg1: *const fido_assert_t, - arg2: usize, - ) -> *const ::std::os::raw::c_uchar; - pub fn fido_assert_id_ptr( - arg1: *const fido_assert_t, - arg2: usize, - ) -> *const ::std::os::raw::c_uchar; - pub fn fido_assert_largeblob_key_ptr( - arg1: *const fido_assert_t, - arg2: usize, - ) -> *const ::std::os::raw::c_uchar; - pub fn fido_assert_sig_ptr( - arg1: *const fido_assert_t, - arg2: usize, - ) -> *const ::std::os::raw::c_uchar; - pub fn fido_assert_user_id_ptr( - arg1: *const fido_assert_t, - arg2: usize, - ) -> *const ::std::os::raw::c_uchar; - pub fn fido_assert_blob_ptr( - arg1: *const fido_assert_t, - arg2: usize, - ) -> *const ::std::os::raw::c_uchar; - pub fn fido_cbor_info_certs_name_ptr( - arg1: *const fido_cbor_info_t, - ) -> *mut *mut ::std::os::raw::c_char; - pub fn fido_cbor_info_extensions_ptr( - arg1: *const fido_cbor_info_t, - ) -> *mut *mut ::std::os::raw::c_char; - pub fn fido_cbor_info_options_name_ptr( - arg1: *const fido_cbor_info_t, - ) -> *mut *mut ::std::os::raw::c_char; - pub fn fido_cbor_info_transports_ptr( - arg1: *const fido_cbor_info_t, - ) -> *mut *mut ::std::os::raw::c_char; - pub fn fido_cbor_info_versions_ptr( - arg1: *const fido_cbor_info_t, - ) -> *mut *mut ::std::os::raw::c_char; - pub fn fido_cbor_info_options_value_ptr(arg1: *const fido_cbor_info_t) -> *const bool; - pub fn fido_assert_rp_id(arg1: *const fido_assert_t) -> *const ::std::os::raw::c_char; - pub fn fido_assert_user_display_name( - arg1: *const fido_assert_t, - arg2: usize, - ) -> *const ::std::os::raw::c_char; - pub fn fido_assert_user_icon( - arg1: *const fido_assert_t, - arg2: usize, - ) -> *const ::std::os::raw::c_char; - pub fn fido_assert_user_name( - arg1: *const fido_assert_t, - arg2: usize, - ) -> *const ::std::os::raw::c_char; - pub fn fido_cbor_info_algorithm_type( - arg1: *const fido_cbor_info_t, - arg2: usize, - ) -> *const ::std::os::raw::c_char; - pub fn fido_cred_display_name(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_char; - pub fn fido_cred_fmt(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_char; - pub fn fido_cred_rp_id(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_char; - pub fn fido_cred_rp_name(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_char; - pub fn fido_cred_user_name(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_char; - pub fn fido_dev_info_manufacturer_string( - arg1: *const fido_dev_info_t, - ) -> *const ::std::os::raw::c_char; - pub fn fido_dev_info_path(arg1: *const fido_dev_info_t) -> *const ::std::os::raw::c_char; - pub fn fido_dev_info_product_string( - arg1: *const fido_dev_info_t, - ) -> *const ::std::os::raw::c_char; - pub fn fido_dev_info_ptr(arg1: *const fido_dev_info_t, arg2: usize) -> *const fido_dev_info_t; - pub fn fido_cbor_info_protocols_ptr(arg1: *const fido_cbor_info_t) -> *const u8; - pub fn fido_cbor_info_certs_value_ptr(arg1: *const fido_cbor_info_t) -> *const u64; - pub fn fido_cbor_info_aaguid_ptr( - arg1: *const fido_cbor_info_t, - ) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_aaguid_ptr(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_attstmt_ptr(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_authdata_ptr(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_authdata_raw_ptr(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_clientdata_hash_ptr( - arg1: *const fido_cred_t, - ) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_id_ptr(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_largeblob_key_ptr(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_pubkey_ptr(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_sig_ptr(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_user_id_ptr(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_uchar; - pub fn fido_cred_x5c_ptr(arg1: *const fido_cred_t) -> *const ::std::os::raw::c_uchar; - pub fn fido_assert_allow_cred( - arg1: *mut fido_assert_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_set_authdata( - arg1: *mut fido_assert_t, - arg2: usize, - arg3: *const ::std::os::raw::c_uchar, - arg4: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_set_authdata_raw( - arg1: *mut fido_assert_t, - arg2: usize, - arg3: *const ::std::os::raw::c_uchar, - arg4: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_set_clientdata( - arg1: *mut fido_assert_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_set_clientdata_hash( - arg1: *mut fido_assert_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_set_count(arg1: *mut fido_assert_t, arg2: usize) -> ::std::os::raw::c_int; - pub fn fido_assert_set_extensions( - arg1: *mut fido_assert_t, - arg2: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_set_hmac_salt( - arg1: *mut fido_assert_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_set_hmac_secret( - arg1: *mut fido_assert_t, - arg2: usize, - arg3: *const ::std::os::raw::c_uchar, - arg4: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_set_options( - arg1: *mut fido_assert_t, - arg2: bool, - arg3: bool, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_set_rp( - arg1: *mut fido_assert_t, - arg2: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_set_up(arg1: *mut fido_assert_t, arg2: fido_opt_t) -> ::std::os::raw::c_int; - pub fn fido_assert_set_uv(arg1: *mut fido_assert_t, arg2: fido_opt_t) -> ::std::os::raw::c_int; - pub fn fido_assert_set_sig( - arg1: *mut fido_assert_t, - arg2: usize, - arg3: *const ::std::os::raw::c_uchar, - arg4: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_verify( - arg1: *const fido_assert_t, - arg2: usize, - arg3: ::std::os::raw::c_int, - arg4: *const ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int; - pub fn fido_cbor_info_algorithm_cose( - arg1: *const fido_cbor_info_t, - arg2: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_exclude( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_prot(arg1: *const fido_cred_t) -> ::std::os::raw::c_int; - pub fn fido_cred_set_attstmt( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_authdata( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_authdata_raw( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_blob( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_clientdata( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_clientdata_hash( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_extensions( - arg1: *mut fido_cred_t, - arg2: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_fmt( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_id( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_options( - arg1: *mut fido_cred_t, - arg2: bool, - arg3: bool, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_pin_minlen(arg1: *mut fido_cred_t, arg2: usize) -> ::std::os::raw::c_int; - pub fn fido_cred_set_prot( - arg1: *mut fido_cred_t, - arg2: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_rk(arg1: *mut fido_cred_t, arg2: fido_opt_t) -> ::std::os::raw::c_int; - pub fn fido_cred_set_rp( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_char, - arg3: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_sig( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_type( - arg1: *mut fido_cred_t, - arg2: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_uv(arg1: *mut fido_cred_t, arg2: fido_opt_t) -> ::std::os::raw::c_int; - pub fn fido_cred_type(arg1: *const fido_cred_t) -> ::std::os::raw::c_int; - pub fn fido_cred_set_user( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - arg4: *const ::std::os::raw::c_char, - arg5: *const ::std::os::raw::c_char, - arg6: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_set_x509( - arg1: *mut fido_cred_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn fido_cred_verify(arg1: *const fido_cred_t) -> ::std::os::raw::c_int; - pub fn fido_cred_verify_self(arg1: *const fido_cred_t) -> ::std::os::raw::c_int; - pub fn fido_dev_set_sigmask( - arg1: *mut fido_dev_t, - arg2: *const fido_sigset_t, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_cancel(arg1: *mut fido_dev_t) -> ::std::os::raw::c_int; - pub fn fido_dev_close(arg1: *mut fido_dev_t) -> ::std::os::raw::c_int; - pub fn fido_dev_get_assert( - arg1: *mut fido_dev_t, - arg2: *mut fido_assert_t, - arg3: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_get_cbor_info( - arg1: *mut fido_dev_t, - arg2: *mut fido_cbor_info_t, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_get_retry_count( - arg1: *mut fido_dev_t, - arg2: *mut ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_get_uv_retry_count( - arg1: *mut fido_dev_t, - arg2: *mut ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_get_touch_begin(arg1: *mut fido_dev_t) -> ::std::os::raw::c_int; - pub fn fido_dev_get_touch_status( - arg1: *mut fido_dev_t, - arg2: *mut ::std::os::raw::c_int, - arg3: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_info_manifest( - arg1: *mut fido_dev_info_t, - arg2: usize, - arg3: *mut usize, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_info_set( - arg1: *mut fido_dev_info_t, - arg2: usize, - arg3: *const ::std::os::raw::c_char, - arg4: *const ::std::os::raw::c_char, - arg5: *const ::std::os::raw::c_char, - arg6: *const fido_dev_io_t, - arg7: *const fido_dev_transport_t, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_make_cred( - arg1: *mut fido_dev_t, - arg2: *mut fido_cred_t, - arg3: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_open_with_info(arg1: *mut fido_dev_t) -> ::std::os::raw::c_int; - pub fn fido_dev_open( - arg1: *mut fido_dev_t, - arg2: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_reset(arg1: *mut fido_dev_t) -> ::std::os::raw::c_int; - pub fn fido_dev_set_io_functions( - arg1: *mut fido_dev_t, - arg2: *const fido_dev_io_t, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_set_pin( - arg1: *mut fido_dev_t, - arg2: *const ::std::os::raw::c_char, - arg3: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_set_transport_functions( - arg1: *mut fido_dev_t, - arg2: *const fido_dev_transport_t, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_set_timeout( - arg1: *mut fido_dev_t, - arg2: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; - pub fn fido_assert_authdata_len(arg1: *const fido_assert_t, arg2: usize) -> usize; - pub fn fido_assert_clientdata_hash_len(arg1: *const fido_assert_t) -> usize; - pub fn fido_assert_count(arg1: *const fido_assert_t) -> usize; - pub fn fido_assert_hmac_secret_len(arg1: *const fido_assert_t, arg2: usize) -> usize; - pub fn fido_assert_id_len(arg1: *const fido_assert_t, arg2: usize) -> usize; - pub fn fido_assert_largeblob_key_len(arg1: *const fido_assert_t, arg2: usize) -> usize; - pub fn fido_assert_sig_len(arg1: *const fido_assert_t, arg2: usize) -> usize; - pub fn fido_assert_user_id_len(arg1: *const fido_assert_t, arg2: usize) -> usize; - pub fn fido_assert_blob_len(arg1: *const fido_assert_t, arg2: usize) -> usize; - pub fn fido_cbor_info_aaguid_len(arg1: *const fido_cbor_info_t) -> usize; - pub fn fido_cbor_info_algorithm_count(arg1: *const fido_cbor_info_t) -> usize; - pub fn fido_cbor_info_certs_len(arg1: *const fido_cbor_info_t) -> usize; - pub fn fido_cbor_info_extensions_len(arg1: *const fido_cbor_info_t) -> usize; - pub fn fido_cbor_info_options_len(arg1: *const fido_cbor_info_t) -> usize; - pub fn fido_cbor_info_protocols_len(arg1: *const fido_cbor_info_t) -> usize; - pub fn fido_cbor_info_transports_len(arg1: *const fido_cbor_info_t) -> usize; - pub fn fido_cbor_info_versions_len(arg1: *const fido_cbor_info_t) -> usize; - pub fn fido_cred_aaguid_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_attstmt_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_authdata_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_authdata_raw_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_clientdata_hash_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_id_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_largeblob_key_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_pin_minlen(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_pubkey_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_sig_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_user_id_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_cred_x5c_len(arg1: *const fido_cred_t) -> usize; - pub fn fido_assert_flags(arg1: *const fido_assert_t, arg2: usize) -> u8; - pub fn fido_assert_sigcount(arg1: *const fido_assert_t, arg2: usize) -> u32; - pub fn fido_cred_flags(arg1: *const fido_cred_t) -> u8; - pub fn fido_cred_sigcount(arg1: *const fido_cred_t) -> u32; - pub fn fido_dev_protocol(arg1: *const fido_dev_t) -> u8; - pub fn fido_dev_major(arg1: *const fido_dev_t) -> u8; - pub fn fido_dev_minor(arg1: *const fido_dev_t) -> u8; - pub fn fido_dev_build(arg1: *const fido_dev_t) -> u8; - pub fn fido_dev_flags(arg1: *const fido_dev_t) -> u8; - pub fn fido_dev_info_vendor(arg1: *const fido_dev_info_t) -> i16; - pub fn fido_dev_info_product(arg1: *const fido_dev_info_t) -> i16; - pub fn fido_cbor_info_fwversion(arg1: *const fido_cbor_info_t) -> u64; - pub fn fido_cbor_info_maxcredbloblen(arg1: *const fido_cbor_info_t) -> u64; - pub fn fido_cbor_info_maxcredcntlst(arg1: *const fido_cbor_info_t) -> u64; - pub fn fido_cbor_info_maxcredidlen(arg1: *const fido_cbor_info_t) -> u64; - pub fn fido_cbor_info_maxlargeblob(arg1: *const fido_cbor_info_t) -> u64; - pub fn fido_cbor_info_maxmsgsiz(arg1: *const fido_cbor_info_t) -> u64; - pub fn fido_cbor_info_maxrpid_minpinlen(arg1: *const fido_cbor_info_t) -> u64; - pub fn fido_cbor_info_minpinlen(arg1: *const fido_cbor_info_t) -> u64; - pub fn fido_cbor_info_uv_attempts(arg1: *const fido_cbor_info_t) -> u64; - pub fn fido_cbor_info_uv_modality(arg1: *const fido_cbor_info_t) -> u64; - pub fn fido_cbor_info_rk_remaining(arg1: *const fido_cbor_info_t) -> i64; - pub fn fido_dev_has_pin(arg1: *const fido_dev_t) -> bool; - pub fn fido_dev_has_uv(arg1: *const fido_dev_t) -> bool; - pub fn fido_dev_is_fido2(arg1: *const fido_dev_t) -> bool; - pub fn fido_dev_is_winhello(arg1: *const fido_dev_t) -> bool; - pub fn fido_dev_supports_credman(arg1: *const fido_dev_t) -> bool; - pub fn fido_dev_supports_cred_prot(arg1: *const fido_dev_t) -> bool; - pub fn fido_dev_supports_permissions(arg1: *const fido_dev_t) -> bool; - pub fn fido_dev_supports_pin(arg1: *const fido_dev_t) -> bool; - pub fn fido_dev_supports_uv(arg1: *const fido_dev_t) -> bool; - pub fn fido_cbor_info_new_pin_required(arg1: *const fido_cbor_info_t) -> bool; - pub fn fido_dev_largeblob_get( - arg1: *mut fido_dev_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - arg4: *mut *mut ::std::os::raw::c_uchar, - arg5: *mut usize, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_largeblob_set( - arg1: *mut fido_dev_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - arg4: *const ::std::os::raw::c_uchar, - arg5: usize, - arg6: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_largeblob_remove( - arg1: *mut fido_dev_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - arg4: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_largeblob_get_array( - arg1: *mut fido_dev_t, - arg2: *mut *mut ::std::os::raw::c_uchar, - arg3: *mut usize, - ) -> ::std::os::raw::c_int; - pub fn fido_dev_largeblob_set_array( - arg1: *mut fido_dev_t, - arg2: *const ::std::os::raw::c_uchar, - arg3: usize, - arg4: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; - pub fn rs256_pk_new() -> *mut rs256_pk_t; - pub fn rs256_pk_free(arg1: *mut *mut rs256_pk_t); - pub fn rs256_pk_to_EVP_PKEY(arg1: *const rs256_pk_t) -> *mut EVP_PKEY; - pub fn rs256_pk_from_EVP_PKEY( - arg1: *mut rs256_pk_t, - arg2: *const EVP_PKEY, - ) -> ::std::os::raw::c_int; - pub fn rs256_pk_from_RSA(arg1: *mut rs256_pk_t, arg2: *const RSA) -> ::std::os::raw::c_int; - pub fn rs256_pk_from_ptr( - arg1: *mut rs256_pk_t, - arg2: *const ::std::os::raw::c_void, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn es256_pk_new() -> *mut es256_pk_t; - pub fn es256_pk_free(arg1: *mut *mut es256_pk_t); - pub fn es256_pk_to_EVP_PKEY(arg1: *const es256_pk_t) -> *mut EVP_PKEY; - pub fn es256_pk_from_EC_KEY( - arg1: *mut es256_pk_t, - arg2: *const EC_KEY, - ) -> ::std::os::raw::c_int; - pub fn es256_pk_from_EVP_PKEY( - arg1: *mut es256_pk_t, - arg2: *const EVP_PKEY, - ) -> ::std::os::raw::c_int; - pub fn es256_pk_from_ptr( - arg1: *mut es256_pk_t, - arg2: *const ::std::os::raw::c_void, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn es384_pk_new() -> *mut es384_pk_t; - pub fn es384_pk_free(arg1: *mut *mut es384_pk_t); - pub fn es384_pk_to_EVP_PKEY(arg1: *const es384_pk_t) -> *mut EVP_PKEY; - pub fn es384_pk_from_EC_KEY( - arg1: *mut es384_pk_t, - arg2: *const EC_KEY, - ) -> ::std::os::raw::c_int; - pub fn es384_pk_from_EVP_PKEY( - arg1: *mut es384_pk_t, - arg2: *const EVP_PKEY, - ) -> ::std::os::raw::c_int; - pub fn es384_pk_from_ptr( - arg1: *mut es384_pk_t, - arg2: *const ::std::os::raw::c_void, - arg3: usize, - ) -> ::std::os::raw::c_int; - pub fn eddsa_pk_new() -> *mut eddsa_pk_t; - pub fn eddsa_pk_free(arg1: *mut *mut eddsa_pk_t); - pub fn eddsa_pk_to_EVP_PKEY(arg1: *const eddsa_pk_t) -> *mut EVP_PKEY; - pub fn eddsa_pk_from_EVP_PKEY( - arg1: *mut eddsa_pk_t, - arg2: *const EVP_PKEY, - ) -> ::std::os::raw::c_int; - pub fn eddsa_pk_from_ptr( - arg1: *mut eddsa_pk_t, - arg2: *const ::std::os::raw::c_void, - arg3: usize, - ) -> ::std::os::raw::c_int; -} diff --git a/fido-rs/libfido2-sys/src/lib.rs b/fido-rs/libfido2-sys/src/lib.rs deleted file mode 100644 index f5865ab..0000000 --- a/fido-rs/libfido2-sys/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[allow(non_camel_case_types, non_snake_case, non_upper_case_globals)] -mod ffi; - -pub use ffi::*; diff --git a/src/main.rs b/src/main.rs index 1d7ff0d..4e8e549 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,11 +10,12 @@ use anyhow::anyhow; use bitflags::bitflags; use clap::{Parser, ValueEnum}; use dialoguer::{console, Confirm, Password, Select}; -use fido2_rs::{ - credentials::{CoseType, Credential, Opt}, - device::DeviceList, -}; +// use fido2_rs::{ +// credentials::{CoseType, Credential, Opt}, +// device::DeviceList, +// }; use gethostname::gethostname; +use libfido2::{device::DeviceList, cred::{Credential, CredType, CredProtection}, fido_init}; use rand::RngCore; use ssh_encoding::{Decode, Encode, LineEnding}; use ssh_key::{private, PrivateKey}; @@ -57,11 +58,11 @@ enum KeyTypeArg { EcdsaSk, } -impl From for CoseType { +impl From for CredType { fn from(value: KeyTypeArg) -> Self { match value { - KeyTypeArg::Ed25519Sk => Self::EDDSA, - KeyTypeArg::EcdsaSk => Self::ES256, + KeyTypeArg::Ed25519Sk => Self::Ed25519, + KeyTypeArg::EcdsaSk => Self::Ecdsa256, } } } @@ -76,6 +77,7 @@ impl Display for KeyTypeArg { } fn main() -> anyhow::Result<()> { + fido_init(false); let args = Args::parse(); let privkey_path = Path::new(&args.key_name); @@ -107,11 +109,7 @@ fn main() -> anyhow::Result<()> { let mut challenge = [0; 32]; rand::thread_rng().fill_bytes(&mut challenge); - // Must be leaked to prevent DeviceList from prematurely freeing memory on drop and allowing - // references to freed memory. - // Note: Report unsoundness bug - let devices_iter = Box::leak(Box::new(DeviceList::list_devices(12))); - let devices = devices_iter.collect::>(); + let devices = DeviceList::get_list(12)?; let device = if devices.len() > 1 { Select::new() .with_prompt("Select FIDO2 key") @@ -119,11 +117,11 @@ fn main() -> anyhow::Result<()> { devices .iter() .map(|dev| { - let product = dev.product.to_string_lossy(); + let product = dev.product(); if product.is_empty() { "Unknown".to_string() } else { - format!("{}", dev.product.to_string_lossy()) + format!("{}", dev.product()) } }) .collect::>() @@ -134,9 +132,9 @@ fn main() -> anyhow::Result<()> { } else { 0 }; - let device = &devices[device].open()?; + let mut device = devices[device].open()?; - let device_has_pin = device.info().map_or(false, |info| { + let device_has_pin = device.get_info().map_or(false, |info| { info.options().get("clientPin").copied().unwrap_or(false) }); @@ -146,19 +144,19 @@ fn main() -> anyhow::Result<()> { None }; - let mut credential = Credential::new(); - credential.set_client_data(&challenge)?; - credential.set_cose_type(args.key_type.into())?; - credential.set_rk(Opt::Omit)?; + let mut credential = Credential::new()?; + credential.set_clientdata(&challenge)?; + credential.set_type(args.key_type.into())?; + credential.set_rk(None)?; credential.set_rp("ssh:", "")?; credential.set_user([0; 32], "openssh", Some("openssh"), None)?; if args.user_verify { - credential.set_protection(fido2_rs::credentials::Protection::UvRequired)?; + credential.set_prot(CredProtection::UvRequired)?; } println!("Touch your authenticator now."); - device.make_credential(&mut credential, pin.as_deref())?; + device.make_cred(&mut credential, pin.as_deref())?; credential.verify()?; @@ -169,12 +167,12 @@ fn main() -> anyhow::Result<()> { match args.key_type { KeyTypeArg::Ed25519Sk => { - credential.public_key().encode(&mut privkey_bytes)?; + credential.pubkey().encode(&mut privkey_bytes)?; } KeyTypeArg::EcdsaSk => { p256::EncodedPoint::from_affine_coordinates( - (&credential.public_key()[0..32]).into(), - (&credential.public_key()[32..64]).into(), + (&credential.pubkey()[0..32]).into(), + (&credential.pubkey()[32..64]).into(), false, ) .to_bytes() @@ -185,7 +183,7 @@ fn main() -> anyhow::Result<()> { let mut flags = SshSkFlags::UserPresenceRequired; flags.set(SshSkFlags::UserVerificationRequired, args.user_verify); privkey_bytes.push(flags.bits()); - credential.id().encode(&mut privkey_bytes)?; + credential.cred_id().encode(&mut privkey_bytes)?; "".encode(&mut privkey_bytes)?; let comment = if let Some(comment) = args.comment { comment @@ -220,11 +218,11 @@ fn main() -> anyhow::Result<()> { ); if args.write_attestation { let mut ssh_attest = Vec::new(); - dbg!(credential.auth_data()); + dbg!(credential.authdata()); "ssh-sk-attest-v01".encode(&mut ssh_attest)?; - credential.certificate().encode(&mut ssh_attest)?; - credential.signature().encode(&mut ssh_attest)?; - credential.auth_data().encode(&mut ssh_attest)?; + credential.x5c().encode(&mut ssh_attest)?; + credential.sig().encode(&mut ssh_attest)?; + credential.authdata().encode(&mut ssh_attest)?; 0u32.encode(&mut ssh_attest)?; "".encode(&mut ssh_attest)?;