implement fido 2.1
This commit is contained in:
parent
80c175077f
commit
bb202c8a54
39
src/cbor.rs
39
src/cbor.rs
@ -274,6 +274,12 @@ pub struct GetInfoResponse {
|
||||
pub options: OptionsInfo,
|
||||
pub max_msg_size: u16,
|
||||
pub pin_protocols: Vec<u8>,
|
||||
pub max_credential_count_in_list: Option<u32>,
|
||||
pub max_credential_id_len: Option<u32>,
|
||||
pub transports: Vec<String>,
|
||||
pub algorithms: Vec<CoseKey>,
|
||||
pub max_authenticator_config_len: Option<u32>,
|
||||
pub default_cred_protect: Option<u8>,
|
||||
}
|
||||
|
||||
impl GetInfoResponse {
|
||||
@ -282,28 +288,49 @@ impl GetInfoResponse {
|
||||
if status != 0 {
|
||||
Err(FidoErrorKind::CborError(CborErrorCode::from(status)))?
|
||||
}
|
||||
let mut decoder = Decoder::new(Config::default(), reader);
|
||||
let mut generic = GenericDecoder::new(Config::default(), reader);
|
||||
let mut response = GetInfoResponse::default();
|
||||
for _ in 0..decoder.object()? {
|
||||
match decoder.u8()? {
|
||||
for _ in 0..generic.borrow_mut().object()? {
|
||||
match generic.borrow_mut().u8()? {
|
||||
0x01 => {
|
||||
let decoder = generic.borrow_mut();
|
||||
for _ in 0..decoder.array()? {
|
||||
response.versions.push(decoder.text()?);
|
||||
}
|
||||
}
|
||||
0x02 => {
|
||||
let decoder = generic.borrow_mut();
|
||||
for _ in 0..decoder.array()? {
|
||||
response.extensions.push(decoder.text()?);
|
||||
}
|
||||
}
|
||||
0x03 => response.aaguid.copy_from_slice(&decoder.bytes()?[..]),
|
||||
0x04 => response.options = OptionsInfo::decode(&mut decoder)?,
|
||||
0x05 => response.max_msg_size = decoder.u16()?,
|
||||
0x03 => response
|
||||
.aaguid
|
||||
.copy_from_slice(&generic.borrow_mut().bytes()?[..]),
|
||||
0x04 => response.options = OptionsInfo::decode(&mut generic.borrow_mut())?,
|
||||
0x05 => response.max_msg_size = generic.borrow_mut().u16()?,
|
||||
0x06 => {
|
||||
let decoder = generic.borrow_mut();
|
||||
for _ in 0..decoder.array()? {
|
||||
response.pin_protocols.push(decoder.u8()?);
|
||||
}
|
||||
}
|
||||
0x07 => response.max_credential_count_in_list = Some(generic.borrow_mut().u32()?),
|
||||
0x08 => response.max_credential_id_len = Some(generic.borrow_mut().u32()?),
|
||||
0x09 => {
|
||||
let decoder = generic.borrow_mut();
|
||||
for _ in 0..decoder.array()? {
|
||||
response.transports.push(decoder.text()?);
|
||||
}
|
||||
}
|
||||
0x0A => {
|
||||
for _ in 0..generic.borrow_mut().array()? {
|
||||
response.algorithms.push(CoseKey::decode(&mut generic)?);
|
||||
}
|
||||
}
|
||||
0x0B => response.max_authenticator_config_len = Some(generic.borrow_mut().u32()?),
|
||||
|
||||
0x0C => response.default_cred_protect = Some(generic.borrow_mut().u8()?),
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
|
25
src/lib.rs
25
src/lib.rs
@ -75,6 +75,7 @@ use self::hid_linux as hid;
|
||||
use self::packet::CtapCommand;
|
||||
pub use self::util::*;
|
||||
use crate::cbor::{AuthenticatorData, GetAssertionRequest};
|
||||
use crate::packet::CtapStatus;
|
||||
use failure::{Fail, ResultExt};
|
||||
use num_traits::FromPrimitive;
|
||||
use rand::prelude::*;
|
||||
@ -117,7 +118,7 @@ pub struct FidoCancelHandle {
|
||||
|
||||
impl FidoCancelHandle {
|
||||
pub fn cancel(&mut self) -> FidoResult<()> {
|
||||
let payload = &[1u8];
|
||||
let payload = &[];
|
||||
let to_send = payload.len() as u16;
|
||||
let max_payload = (self.packet_size - 7) as usize;
|
||||
let (frame, payload) = payload.split_at(cmp::min(payload.len(), max_payload));
|
||||
@ -538,6 +539,26 @@ impl FidoDevice {
|
||||
.map(|cred| (cred, response.auth_data))
|
||||
}
|
||||
|
||||
pub fn ping(&mut self, data: &[u8]) -> FidoResult<Vec<u8>> {
|
||||
self.exchange(CtapCommand::Ping, data)
|
||||
}
|
||||
|
||||
pub fn wink(&mut self) -> FidoResult<()> {
|
||||
self.send(&CtapCommand::Wink, &[]).map(|_| ())
|
||||
}
|
||||
|
||||
fn lock(&mut self, time_sec: u8) -> FidoResult<()> {
|
||||
self.exchange(CtapCommand::Lock, &[time_sec]).map(|_| ())
|
||||
}
|
||||
|
||||
fn keepalive(&mut self) -> FidoResult<CtapStatus> {
|
||||
self.exchange(CtapCommand::Keepalive, &[])?
|
||||
.first()
|
||||
.cloned()
|
||||
.and_then(CtapStatus::from_u8)
|
||||
.ok_or(FidoError::from(FidoErrorKind::CborDecode))
|
||||
}
|
||||
|
||||
fn cbor(&mut self, request: cbor::Request) -> FidoResult<cbor::Response> {
|
||||
let mut buf = Cursor::new(Vec::new());
|
||||
request
|
||||
@ -556,7 +577,7 @@ impl FidoDevice {
|
||||
}
|
||||
|
||||
fn send(&mut self, cmd: &CtapCommand, payload: &[u8]) -> FidoResult<()> {
|
||||
if payload.is_empty() || payload.len() > u16::MAX as usize {
|
||||
if payload.len() > u16::MAX as usize {
|
||||
Err(FidoErrorKind::WritePacket)?
|
||||
}
|
||||
let to_send = payload.len() as u16;
|
||||
|
@ -13,7 +13,7 @@ use std::io::{Read, Write};
|
||||
static FRAME_INIT: u8 = 0x80;
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq)]
|
||||
#[derive(Debug, FromPrimitive, ToPrimitive, PartialEq)]
|
||||
pub enum CtapCommand {
|
||||
Invalid = 0x00,
|
||||
Ping = 0x01,
|
||||
@ -36,6 +36,13 @@ impl CtapCommand {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, FromPrimitive, ToPrimitive, PartialEq)]
|
||||
pub enum CtapStatus {
|
||||
Processing = 0x01,
|
||||
AwaitingUserPresence = 0x02,
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(FromPrimitive, Fail, Debug)]
|
||||
pub enum CtapError {
|
||||
|
Loading…
x
Reference in New Issue
Block a user