implement fido 2.1

This commit is contained in:
shimun 2020-04-10 20:55:53 +02:00
parent 80c175077f
commit bb202c8a54
Signed by: shimun
GPG Key ID: E81D8382DC2F971B
3 changed files with 64 additions and 9 deletions

View File

@ -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,
}
}

View File

@ -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;

View File

@ -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 {