Work
This commit is contained in:
parent
3ddc7edfc5
commit
331f74415a
18
src/cred.rs
18
src/cred.rs
@ -1,12 +1,11 @@
|
||||
use std::{ffi::{CStr, CString}};
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
use libfido2_sys::*;
|
||||
use num_enum::TryFromPrimitive;
|
||||
|
||||
use crate::{
|
||||
check_initialized,
|
||||
error::{check, Result},
|
||||
opt_bool_to_fido_opt,
|
||||
util::{opt_bool_to_fido_opt, check_initialized},
|
||||
};
|
||||
|
||||
#[repr(i32)]
|
||||
@ -298,18 +297,19 @@ impl CredentialRef {
|
||||
) -> Result<()> {
|
||||
let id = id.as_ref();
|
||||
let name = CString::new(name.as_ref()).unwrap();
|
||||
let display_name = display_name
|
||||
.map(|x| CString::new(x).unwrap())
|
||||
.unwrap_or_default();
|
||||
let icon = icon.map(|x| CString::new(x).unwrap()).unwrap_or_default();
|
||||
let display_name = display_name.map(|x| CString::new(x).unwrap());
|
||||
let display_name_ptr = display_name.as_ref().map_or(std::ptr::null(), |x| x.as_ptr());
|
||||
let icon = icon.map(|x| CString::new(x).unwrap());
|
||||
let icon_ptr = icon.as_ref().map_or(std::ptr::null(), |x| x.as_ptr());
|
||||
|
||||
unsafe {
|
||||
check(fido_cred_set_user(
|
||||
self.as_ptr_mut(),
|
||||
&id[0],
|
||||
id.len(),
|
||||
name.as_ptr(),
|
||||
display_name.as_ptr(),
|
||||
icon.as_ptr(),
|
||||
display_name_ptr,
|
||||
icon_ptr,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
mod info;
|
||||
|
||||
use std::{
|
||||
ffi::{CStr, CString},
|
||||
fmt::Debug,
|
||||
@ -9,11 +11,13 @@ use libfido2_sys::*;
|
||||
|
||||
use crate::{
|
||||
assert::Assertion,
|
||||
check_initialized,
|
||||
util::check_initialized,
|
||||
cred::CredentialRef,
|
||||
error::{check, Result},
|
||||
};
|
||||
|
||||
use self::info::DeviceCborInfo;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DeviceList {
|
||||
ptr: NonNull<fido_dev_info_t>,
|
||||
@ -49,6 +53,10 @@ impl DeviceList {
|
||||
pub fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> DeviceListIterator<'_> {
|
||||
DeviceListIterator { info: self, idx: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<usize> for DeviceList {
|
||||
@ -68,6 +76,24 @@ impl Drop for DeviceList {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DeviceListIterator<'a> {
|
||||
info: &'a DeviceList,
|
||||
idx: usize
|
||||
}
|
||||
|
||||
impl<'a> Iterator for DeviceListIterator<'a> {
|
||||
type Item = &'a DeviceInfoRef;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.idx == self.info.len() {
|
||||
return None;
|
||||
}
|
||||
let item = &self.info[self.idx];
|
||||
self.idx += 1;
|
||||
Some(item)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
c_type_wrapper_ref!(fido_dev_info_t, DeviceInfo);
|
||||
|
||||
@ -116,13 +142,13 @@ impl DeviceInfoRef {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open(&self) -> Device {
|
||||
pub fn open(&self) -> Result<Device> {
|
||||
unsafe {
|
||||
let dev_ptr = fido_dev_new_with_info(self.as_ptr());
|
||||
fido_dev_open_with_info(dev_ptr);
|
||||
Device {
|
||||
check(fido_dev_open_with_info(dev_ptr))?;
|
||||
Ok(Device {
|
||||
ptr: NonNull::new_unchecked(dev_ptr),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -216,22 +242,31 @@ impl DeviceRef {
|
||||
}
|
||||
|
||||
pub fn get_assert(&mut self, assert: &mut Assertion, pin: Option<&str>) -> Result<()> {
|
||||
let pin = pin.map(|x| CString::new(x).unwrap()).unwrap_or_default();
|
||||
let pin = pin.map(|x| CString::new(x).unwrap());
|
||||
let pin_ptr = pin.as_ref().map_or(std::ptr::null(), |x| x.as_ptr());
|
||||
unsafe {
|
||||
check(fido_dev_get_assert(
|
||||
self.as_ptr_mut(),
|
||||
assert.as_ptr_mut(),
|
||||
pin.as_ptr(),
|
||||
pin_ptr,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: CBOR info
|
||||
pub fn get_info(&mut self) -> Result<DeviceCborInfo> {
|
||||
unsafe {
|
||||
let info_ptr = fido_cbor_info_new();
|
||||
check(fido_dev_get_cbor_info(self.as_ptr_mut(), info_ptr))?;
|
||||
Ok(DeviceCborInfo::from_ptr(info_ptr))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn set_pin(&mut self, pin: impl AsRef<str>, oldpin: Option<&str>) -> Result<()> {
|
||||
let pin = CString::new(pin.as_ref()).unwrap();
|
||||
let oldpin = oldpin.map_or(ptr::null(), |str| str.as_ptr()).cast();
|
||||
unsafe { check(fido_dev_set_pin(self.as_ptr_mut(), pin.as_ptr(), oldpin)) }
|
||||
let oldpin = oldpin.map(|x| CString::new(x).unwrap());
|
||||
let oldpin_ptr = oldpin.as_ref().map_or(std::ptr::null(), |x| x.as_ptr());
|
||||
unsafe { check(fido_dev_set_pin(self.as_ptr_mut(), pin.as_ptr(), oldpin_ptr)) }
|
||||
}
|
||||
|
||||
pub fn get_retry_count(&mut self) -> Result<u32> {
|
||||
@ -257,14 +292,16 @@ impl DeviceRef {
|
||||
//TODO: largeBlobs
|
||||
|
||||
pub fn make_cred(&mut self, cred: &mut CredentialRef, pin: Option<&str>) -> Result<()> {
|
||||
let pin = pin.map(|x| CString::new(x).unwrap()).unwrap_or_default();
|
||||
unsafe {
|
||||
let pin = pin.map(|x| CString::new(x).unwrap());
|
||||
let pin_ptr = pin.as_ref().map_or(std::ptr::null(), |x| x.as_ptr());
|
||||
let res = unsafe {
|
||||
check(fido_dev_make_cred(
|
||||
self.as_ptr_mut(),
|
||||
cred.as_ptr_mut(),
|
||||
pin.as_ptr(),
|
||||
pin_ptr,
|
||||
))
|
||||
}
|
||||
};
|
||||
res
|
||||
}
|
||||
|
||||
}
|
||||
|
23
src/device/info.rs
Normal file
23
src/device/info.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use std::{collections::HashMap, ffi::CStr};
|
||||
|
||||
use libfido2_sys::*;
|
||||
|
||||
c_type_wrapper!(fido_cbor_info_t, DeviceCborInfo);
|
||||
|
||||
impl DeviceCborInfoRef {
|
||||
pub fn options(&self) -> HashMap<String, bool> {
|
||||
let mut map = HashMap::new();
|
||||
unsafe{
|
||||
let name_ptr = fido_cbor_info_options_name_ptr(self.as_ptr());
|
||||
let value_ptr = fido_cbor_info_options_value_ptr(self.as_ptr());
|
||||
for i in 0..fido_cbor_info_options_len(self.as_ptr()) {
|
||||
let key = CStr::from_ptr(*(name_ptr.add(i))).to_string_lossy().to_string();
|
||||
let value = *(value_ptr.add(i));
|
||||
map.insert(key, value);
|
||||
}
|
||||
}
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
|
30
src/lib.rs
30
src/lib.rs
@ -1,18 +1,16 @@
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use libfido2_sys::{
|
||||
fido_opt_t_FIDO_OPT_FALSE, fido_opt_t_FIDO_OPT_OMIT, fido_opt_t_FIDO_OPT_TRUE, FIDO_DEBUG,
|
||||
};
|
||||
use libfido2_sys::FIDO_DEBUG;
|
||||
|
||||
use crate::util::check_initialized;
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
mod util;
|
||||
pub mod assert;
|
||||
pub mod cred;
|
||||
pub mod device;
|
||||
pub mod error;
|
||||
|
||||
use error::{Error, Result};
|
||||
|
||||
static FIDO_INITIALIZED: AtomicBool = AtomicBool::new(false);
|
||||
pub(crate) static FIDO_INITIALIZED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
pub fn fido_init(debug: bool) {
|
||||
static FIDO_INITIALIZE_STARTED: AtomicBool = AtomicBool::new(false);
|
||||
@ -30,21 +28,3 @@ pub fn fido_init(debug: bool) {
|
||||
FIDO_INITIALIZED.store(true, Ordering::Relaxed);
|
||||
check_initialized().unwrap();
|
||||
}
|
||||
|
||||
fn check_initialized() -> Result<()> {
|
||||
if !FIDO_INITIALIZED.load(Ordering::Relaxed) {
|
||||
Err(Error::NotInitialized)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn opt_bool_to_fido_opt(opt: Option<bool>) -> i32 {
|
||||
match opt {
|
||||
Some(true) => fido_opt_t_FIDO_OPT_TRUE,
|
||||
Some(false) => fido_opt_t_FIDO_OPT_FALSE,
|
||||
None => fido_opt_t_FIDO_OPT_OMIT,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,28 @@
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use libfido2_sys::{fido_opt_t_FIDO_OPT_TRUE, fido_opt_t_FIDO_OPT_FALSE, fido_opt_t_FIDO_OPT_OMIT};
|
||||
|
||||
use crate::FIDO_INITIALIZED;
|
||||
use crate::error::{Result, Error};
|
||||
|
||||
pub fn check_initialized() -> Result<()> {
|
||||
if !FIDO_INITIALIZED.load(Ordering::Relaxed) {
|
||||
Err(Error::NotInitialized)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn opt_bool_to_fido_opt(opt: Option<bool>) -> i32 {
|
||||
match opt {
|
||||
Some(true) => fido_opt_t_FIDO_OPT_TRUE,
|
||||
Some(false) => fido_opt_t_FIDO_OPT_FALSE,
|
||||
None => fido_opt_t_FIDO_OPT_OMIT,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
macro_rules! c_type_wrapper {
|
||||
($c: ident, $t: ident, free = $f: ident) => {
|
||||
c_type_wrapper!($c, $t);
|
||||
@ -17,7 +42,7 @@ macro_rules! c_type_wrapper {
|
||||
|
||||
impl $t {
|
||||
#[allow(unused)]
|
||||
unsafe fn from_ptr<'a>(ptr: *mut $c) -> Self {
|
||||
pub unsafe fn from_ptr<'a>(ptr: *mut $c) -> Self {
|
||||
unsafe {
|
||||
$t {
|
||||
ptr: ::core::ptr::NonNull::new_unchecked(ptr),
|
||||
@ -60,12 +85,12 @@ macro_rules! c_type_wrapper_ref {
|
||||
pub struct [<$t Ref>](::core::marker::PhantomData<::core::cell::UnsafeCell<*mut ()>>);
|
||||
impl [<$t Ref>] {
|
||||
#[allow(unused)]
|
||||
unsafe fn from_ptr<'a>(ptr: *const $c) -> &'a Self {
|
||||
pub unsafe fn from_ptr<'a>(ptr: *const $c) -> &'a Self {
|
||||
unsafe { &*(ptr as *const _) }
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
unsafe fn from_ptr_mut<'a>(ptr: *mut $c) -> &'a mut Self {
|
||||
pub unsafe fn from_ptr_mut<'a>(ptr: *mut $c) -> &'a mut Self {
|
||||
unsafe { &mut *(ptr as *mut _)}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user