Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for multiple Yubikeys and Maintenance #15

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
Moved new read serial function
ashuio committed Dec 24, 2023
commit a9a5a629cb6c81fd81ceb1a5806b6066a04815ce
37 changes: 34 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ use config::Command;
use config::{Config, Slot};
use configure::DeviceModeConfig;
use hmacmode::Hmac;
use manager::{read_serial_from_device, Flags, Frame};
use manager::{Flags, Frame};
use otpmode::Aes128Block;
use rusb::{Context, UsbContext};
use sec::{crc16, CRC_RESIDUAL_OK};
@@ -58,12 +58,43 @@ impl Yubico {
}
}

pub fn read_serial_from_device(&mut self, device: rusb::Device<Context>) -> Result<u32> {
// let mut context = Context::new()?;
let mut handle =
manager::open_device(&mut self.context, device.bus_number(), device.address())?;
let challenge = [0; 64];
let command = Command::DeviceSerial;

let d = Frame::new(challenge, command); // FixMe: do not need a challange
let mut buf = [0; 8];
manager::wait(
&mut handle.0,
|f| !f.contains(Flags::SLOT_WRITE_FLAG),
&mut buf,
)?;

manager::write_frame(&mut handle.0, &d)?;

// Read the response.
let mut response = [0; 36];
manager::read_response(&mut handle.0, &mut response)?;

// Check response.
if crc16(&response[..6]) != crate::sec::CRC_RESIDUAL_OK {
return Err(YubicoError::WrongCRC);
}

let serial = structure!("2I").unpack(response[..8].to_vec())?;

Ok(serial.0)
}

pub fn find_yubikey(&mut self) -> Result<Yubikey> {
for device in self.context.devices().unwrap().iter() {
let descr = device.device_descriptor().unwrap();
if descr.vendor_id() == VENDOR_ID {
let name = device.open()?.read_product_string_ascii(&descr)?;
let serial = read_serial_from_device(&mut self.context.clone(), device.clone())?;
let serial = self.read_serial_from_device(device.clone())?;
let yubikey = Yubikey {
name: name,
serial: serial,
@@ -86,7 +117,7 @@ impl Yubico {
let descr = device.device_descriptor().unwrap();
if descr.vendor_id() == VENDOR_ID {
let name = device.open()?.read_product_string_ascii(&descr)?;
let serial = read_serial_from_device(&mut self.context.clone(), device.clone())?;
let serial = self.read_serial_from_device(device.clone())?;
let yubikey = Yubikey {
name: name,
serial: serial,
37 changes: 1 addition & 36 deletions src/manager.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use crate::config::Command;
use crate::sec::crc16;
use crate::yubicoerror::YubicoError;
use rusb::{
request_type, Context, Device, DeviceHandle, Direction, Recipient, RequestType, UsbContext,
};
use rusb::{request_type, Context, DeviceHandle, Direction, Recipient, RequestType, UsbContext};
use std::time::Duration;
use std::{slice, thread};

@@ -19,39 +17,6 @@ bitflags! {
}
}

pub fn read_serial_from_device(
context: &mut Context,
device: Device<Context>,
) -> Result<u32, YubicoError> {
// let mut context = Context::new()?;
let mut handle = open_device(context, device.bus_number(), device.address())?;
let challenge = [0; 64];
let command = Command::DeviceSerial;

let d = Frame::new(challenge, command); // FixMe: do not need a challange
let mut buf = [0; 8];
wait(
&mut handle.0,
|f| !f.contains(Flags::SLOT_WRITE_FLAG),
&mut buf,
)?;

write_frame(&mut handle.0, &d)?;

// Read the response.
let mut response = [0; 36];
read_response(&mut handle.0, &mut response)?;

// Check response.
if crc16(&response[..6]) != crate::sec::CRC_RESIDUAL_OK {
return Err(YubicoError::WrongCRC);
}

let serial = structure!("2I").unpack(response[..8].to_vec())?;

Ok(serial.0)
}

pub fn open_device(
context: &mut Context,
bus_id: u8,