Add supprt for CBOR authenticator info

This commit is contained in:
pjht 2023-08-29 09:07:37 -05:00
parent 4e50a45db7
commit 4ee3ed91ea
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E
6 changed files with 225 additions and 70 deletions

View File

@ -69,39 +69,39 @@
- fido_bio_template_set_id
- fido_bio_template_set_name
- fido_cbor_info_aaguid_len
- fido_cbor_info_aaguid_ptr
- fido_cbor_info_algorithm_cose
- fido_cbor_info_algorithm_count
- fido_cbor_info_algorithm_type
- fido_cbor_info_certs_len
- fido_cbor_info_certs_name_ptr
- fido_cbor_info_certs_value_ptr
- fido_cbor_info_extensions_len
- fido_cbor_info_extensions_ptr
Y fido_cbor_info_aaguid_len
Y fido_cbor_info_aaguid_ptr
Y fido_cbor_info_algorithm_cose
Y fido_cbor_info_algorithm_count
Y fido_cbor_info_algorithm_type
Y fido_cbor_info_certs_len
Y fido_cbor_info_certs_name_ptr
Y fido_cbor_info_certs_value_ptr
Y fido_cbor_info_extensions_len
Y fido_cbor_info_extensions_ptr
Y fido_cbor_info_free
- fido_cbor_info_fwversion
- fido_cbor_info_maxcredbloblen
- fido_cbor_info_maxcredcntlst
- fido_cbor_info_maxcredidlen
- fido_cbor_info_maxlargeblob
- fido_cbor_info_maxmsgsiz
- fido_cbor_info_maxrpid_minpinlen
- fido_cbor_info_minpinlen
Y fido_cbor_info_fwversion
Y fido_cbor_info_maxcredbloblen
Y fido_cbor_info_maxcredcntlst
Y fido_cbor_info_maxcredidlen
Y fido_cbor_info_maxlargeblob
Y fido_cbor_info_maxmsgsiz
Y fido_cbor_info_maxrpid_minpinlen
Y fido_cbor_info_minpinlen
Y fido_cbor_info_new
- fido_cbor_info_new_pin_required
Y fido_cbor_info_new_pin_required
Y fido_cbor_info_options_len
Y fido_cbor_info_options_name_ptr
Y fido_cbor_info_options_value_ptr
- fido_cbor_info_protocols_len
- fido_cbor_info_protocols_ptr
- fido_cbor_info_rk_remaining
- fido_cbor_info_transports_len
- fido_cbor_info_transports_ptr
Y fido_cbor_info_protocols_len
Y fido_cbor_info_protocols_ptr
Y fido_cbor_info_rk_remaining
Y fido_cbor_info_transports_len
Y fido_cbor_info_transports_ptr
- fido_cbor_info_uv_attempts
- fido_cbor_info_uv_modality
- fido_cbor_info_versions_len
- fido_cbor_info_versions_ptr
Y fido_cbor_info_versions_len
Y fido_cbor_info_versions_ptr
Y fido_cred_aaguid_len
Y fido_cred_aaguid_ptr

View File

@ -5,7 +5,8 @@ use num_enum::TryFromPrimitive;
use crate::{
error::{check, Result},
util::{opt_bool_to_fido_opt, check_initialized},
util::{check_initialized, opt_bool_to_fido_opt},
CoseAlg,
};
#[repr(i32)]
@ -16,15 +17,6 @@ pub enum CredProtection {
UvRequired = FIDO_CRED_PROT_UV_REQUIRED,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, TryFromPrimitive)]
pub enum CredType {
Ecdsa256 = COSE_ES256,
Ecdsa384 = COSE_ES384,
Rsa = COSE_RS256,
Ed25519 = COSE_EDDSA,
}
c_type_wrapper!(fido_cred_t, Credential, free = fido_cred_free);
impl Credential {
@ -284,7 +276,7 @@ impl CredentialRef {
unsafe { check(fido_cred_set_sig(self.as_ptr_mut(), &sig[0], sig.len())) }
}
pub fn set_type(&mut self, typ: CredType) -> Result<()> {
pub fn set_type(&mut self, typ: CoseAlg) -> Result<()> {
unsafe { check(fido_cred_set_type(self.as_ptr_mut(), typ as i32)) }
}
@ -298,7 +290,9 @@ impl CredentialRef {
let id = id.as_ref();
let name = CString::new(name.as_ref()).unwrap();
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 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());
@ -340,13 +334,13 @@ impl CredentialRef {
unsafe { fido_cred_sigcount(self.as_ptr()) }
}
pub fn get_type(&self) -> Option<CredType> {
pub fn get_type(&self) -> Option<CoseAlg> {
unsafe {
let typ = fido_cred_type(self.as_ptr());
if typ == 0 {
None
} else {
Some(CredType::try_from(typ).unwrap())
Some(CoseAlg::try_from(typ).unwrap())
}
}
}
@ -387,5 +381,4 @@ impl CredentialRef {
)
}
}
}

View File

@ -11,9 +11,9 @@ use libfido2_sys::*;
use crate::{
assert::Assertion,
util::check_initialized,
cred::CredentialRef,
error::{check, Result},
util::check_initialized,
};
use self::info::DeviceCborInfo;
@ -78,7 +78,7 @@ impl Drop for DeviceList {
pub struct DeviceListIterator<'a> {
info: &'a DeviceList,
idx: usize
idx: usize,
}
impl<'a> Iterator for DeviceListIterator<'a> {
@ -94,7 +94,6 @@ impl<'a> Iterator for DeviceListIterator<'a> {
}
}
c_type_wrapper_ref!(fido_dev_info_t, DeviceInfo);
impl Debug for DeviceInfoRef {
@ -261,12 +260,17 @@ impl DeviceRef {
}
}
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(|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)) }
unsafe {
check(fido_dev_set_pin(
self.as_ptr_mut(),
pin.as_ptr(),
oldpin_ptr,
))
}
}
pub fn get_retry_count(&mut self) -> Result<u32> {
@ -303,5 +307,4 @@ impl DeviceRef {
};
res
}
}

View File

@ -2,22 +2,175 @@ use std::{collections::HashMap, ffi::CStr};
use libfido2_sys::*;
use crate::CoseAlg;
c_type_wrapper!(fido_cbor_info_t, DeviceCborInfo, free = fido_cbor_info_free);
impl DeviceCborInfoRef {
pub fn options(&self) -> HashMap<String, bool> {
pub fn aaguid(&self) -> &[u8] {
unsafe {
std::slice::from_raw_parts(
fido_cbor_info_aaguid_ptr(self.as_ptr()),
fido_cbor_info_aaguid_len(self.as_ptr()),
)
}
}
pub fn algorithms(&self) -> HashMap<String, CoseAlg> {
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();
unsafe {
for i in 0..fido_cbor_info_algorithm_count(self.as_ptr()) {
let algorithm = fido_cbor_info_algorithm_cose(self.as_ptr(), i);
let type_ptr = fido_cbor_info_algorithm_type(self.as_ptr(), i);
let key = CStr::from_ptr(type_ptr).to_string_lossy().to_string();
let value = CoseAlg::try_from(algorithm).unwrap();
map.insert(key, value);
}
}
map
}
pub fn certs(&self) -> HashMap<String, u64> {
let mut map = HashMap::new();
unsafe {
let name_ptr = fido_cbor_info_certs_name_ptr(self.as_ptr());
let value_ptr = fido_cbor_info_certs_value_ptr(self.as_ptr());
for i in 0..fido_cbor_info_certs_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
}
}
pub fn extensions(&self) -> Vec<String> {
let mut list = Vec::new();
unsafe {
let extensions_ptr = fido_cbor_info_extensions_ptr(self.as_ptr());
for i in 0..fido_cbor_info_extensions_len(self.as_ptr()) {
let key = CStr::from_ptr(*(extensions_ptr.add(i)))
.to_string_lossy()
.to_string();
list.push(key);
}
}
list
}
pub fn fwversion(&self) -> u64 {
unsafe { fido_cbor_info_fwversion(self.as_ptr()) }
}
pub fn maxcredbloblen(&self) -> u64 {
unsafe { fido_cbor_info_maxcredbloblen(self.as_ptr()) }
}
pub fn maxcredcntlst(&self) -> u64 {
unsafe { fido_cbor_info_maxcredcntlst(self.as_ptr()) }
}
pub fn maxcredidlen(&self) -> u64 {
unsafe { fido_cbor_info_maxcredidlen(self.as_ptr()) }
}
pub fn maxlargeblob(&self) -> u64 {
unsafe { fido_cbor_info_maxlargeblob(self.as_ptr()) }
}
pub fn maxmsgsiz(&self) -> u64 {
unsafe { fido_cbor_info_maxmsgsiz(self.as_ptr()) }
}
pub fn maxrpid_minpinlen(&self) -> u64 {
unsafe { fido_cbor_info_maxrpid_minpinlen(self.as_ptr()) }
}
pub fn minpinlen(&self) -> u64 {
unsafe { fido_cbor_info_minpinlen(self.as_ptr()) }
}
pub fn new_pin_required(&self) -> bool {
unsafe { fido_cbor_info_new_pin_required(self.as_ptr()) }
}
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
}
pub fn pin_protocols(&self) -> Vec<u8> {
let mut list = Vec::new();
unsafe {
let protocols_ptr = fido_cbor_info_protocols_ptr(self.as_ptr());
for i in 0..fido_cbor_info_protocols_len(self.as_ptr()) {
let key = *(protocols_ptr.add(i));
list.push(key);
}
}
list
}
pub fn rk_remaining(&self) -> Option<u64> {
unsafe { match fido_cbor_info_rk_remaining(self.as_ptr()) {
-1 => None,
x => Some(x as u64),
}}
}
pub fn transports(&self) -> Vec<String> {
let mut list = Vec::new();
unsafe {
let transports_ptr = fido_cbor_info_transports_ptr(self.as_ptr());
for i in 0..fido_cbor_info_transports_len(self.as_ptr()) {
let key = CStr::from_ptr(*(transports_ptr.add(i)))
.to_string_lossy()
.to_string();
list.push(key);
}
}
list
}
pub fn uv_attempts(&self) -> Option<u64> {
unsafe { match fido_cbor_info_uv_attempts(self.as_ptr()) {
0 => None,
x => Some(x),
}}
}
pub fn uv_modality(&self) -> Option<u64> {
unsafe { match fido_cbor_info_uv_modality(self.as_ptr()) {
0 => None,
x => Some(x),
}}
}
pub fn versions(&self) -> Vec<String> {
let mut list = Vec::new();
unsafe {
let versions_ptr = fido_cbor_info_versions_ptr(self.as_ptr());
for i in 0..fido_cbor_info_versions_len(self.as_ptr()) {
let key = CStr::from_ptr(*(versions_ptr.add(i)))
.to_string_lossy()
.to_string();
list.push(key);
}
}
list
}
}

View File

@ -1,6 +1,7 @@
use std::sync::atomic::{AtomicBool, Ordering};
use libfido2_sys::FIDO_DEBUG;
use libfido2_sys::*;
use num_enum::TryFromPrimitive;
use crate::util::check_initialized;
#[macro_use]
@ -10,6 +11,15 @@ pub mod cred;
pub mod device;
pub mod error;
#[repr(i32)]
#[derive(Debug, Clone, Copy, TryFromPrimitive)]
pub enum CoseAlg {
Ecdsa256 = COSE_ES256,
Ecdsa384 = COSE_ES384,
Rsa = COSE_RS256,
Ed25519 = COSE_EDDSA,
}
pub(crate) static FIDO_INITIALIZED: AtomicBool = AtomicBool::new(false);
pub fn fido_init(debug: bool) {

View File

@ -1,9 +1,9 @@
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 libfido2_sys::{fido_opt_t_FIDO_OPT_FALSE, fido_opt_t_FIDO_OPT_OMIT, fido_opt_t_FIDO_OPT_TRUE};
use crate::error::{Error, Result};
use crate::FIDO_INITIALIZED;
use crate::error::{Result, Error};
pub fn check_initialized() -> Result<()> {
if !FIDO_INITIALIZED.load(Ordering::Relaxed) {
@ -21,16 +21,12 @@ pub fn opt_bool_to_fido_opt(opt: Option<bool>) -> i32 {
}
}
macro_rules! c_type_wrapper {
($c: ident, $t: ident, free = $f: ident) => {
c_type_wrapper!($c, $t);
impl ::core::ops::Drop for $t {
fn drop(&mut self) {
unsafe {
$f(&mut self.ptr.as_ptr())
}
unsafe { $f(&mut self.ptr.as_ptr()) }
}
}
};
@ -43,21 +39,21 @@ macro_rules! c_type_wrapper {
impl $t {
#[allow(unused)]
pub unsafe fn from_ptr<'a>(ptr: *mut $c) -> Self {
unsafe {
unsafe {
$t {
ptr: ::core::ptr::NonNull::new_unchecked(ptr),
}
}
}
}
#[allow(unused)]
pub(crate) fn as_ptr(&self) -> *const $c {
self.ptr.as_ptr()
self.ptr.as_ptr()
}
#[allow(unused)]
pub(crate) fn as_ptr_mut(&mut self) -> *mut $c {
self.ptr.as_ptr()
self.ptr.as_ptr()
}
}
@ -76,7 +72,7 @@ macro_rules! c_type_wrapper {
}
c_type_wrapper_ref!($c, $t);
}
}
};
}
macro_rules! c_type_wrapper_ref {
@ -105,5 +101,5 @@ macro_rules! c_type_wrapper_ref {
}
}
}
}
};
}