Skip to content

Commit

Permalink
Add serial field to Yubikey
Browse files Browse the repository at this point in the history
  • Loading branch information
ashuio committed Dec 24, 2023
1 parent 30cdadb commit 6f46a0b
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 20 deletions.
43 changes: 28 additions & 15 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use config::Command;
use config::{Config, Slot};
use configure::DeviceModeConfig;
use hmacmode::Hmac;
use manager::{Flags, Frame};
use manager::{read_serial_from_device, Flags, Frame};
use otpmode::Aes128Block;
use rusb::{Context, UsbContext};
use sec::{crc16, CRC_RESIDUAL_OK};
Expand All @@ -39,6 +39,7 @@ type Result<T> = ::std::result::Result<T, YubicoError>;
#[derive(Clone, Debug, PartialEq)]
pub struct Yubikey {
pub name: String,
pub serial: u32,
pub product_id: u16,
pub vendor_id: u16,
pub bus_id: u8,
Expand All @@ -61,13 +62,11 @@ impl Yubico {
for device in self.context.devices().unwrap().iter() {
let descr = device.device_descriptor().unwrap();
if descr.vendor_id() == VENDOR_ID {
let name = device
.open()
.unwrap()
.read_product_string_ascii(&descr)
.unwrap();
let name = device.open()?.read_product_string_ascii(&descr)?;
let serial = read_serial_from_device(device.clone())?;
let yubikey = Yubikey {
name: name,
serial: serial,
product_id: descr.product_id(),
vendor_id: descr.vendor_id(),
bus_id: device.bus_number(),
Expand All @@ -86,13 +85,11 @@ impl Yubico {
for device in self.context.devices().unwrap().iter() {
let descr = device.device_descriptor().unwrap();
if descr.vendor_id() == VENDOR_ID {
let name = device
.open()
.unwrap()
.read_product_string_ascii(&descr)
.unwrap();
let name = device.open()?.read_product_string_ascii(&descr)?;
let serial = read_serial_from_device(device.clone())?;
let yubikey = Yubikey {
name: name,
serial: serial,
product_id: descr.product_id(),
vendor_id: descr.vendor_id(),
bus_id: device.bus_number(),
Expand All @@ -117,7 +114,11 @@ impl Yubico {
let d = device_config.to_frame(conf.command);
let mut buf = [0; 8];

match manager::open_device(&mut self.context, conf.yubikey) {
match manager::open_device(
&mut self.context,
conf.yubikey.bus_id,
conf.yubikey.address_id,
) {
Ok((mut handle, interfaces)) => {
manager::wait(
&mut handle,
Expand All @@ -142,7 +143,11 @@ impl Yubico {
}

pub fn read_serial_number(&mut self, conf: Config) -> Result<u32> {
match manager::open_device(&mut self.context, conf.yubikey) {
match manager::open_device(
&mut self.context,
conf.yubikey.bus_id,
conf.yubikey.address_id,
) {
Ok((mut handle, interfaces)) => {
let challenge = [0; 64];
let command = Command::DeviceSerial;
Expand Down Expand Up @@ -178,7 +183,11 @@ impl Yubico {
pub fn challenge_response_hmac(&mut self, chall: &[u8], conf: Config) -> Result<Hmac> {
let mut hmac = Hmac([0; 20]);

match manager::open_device(&mut self.context, conf.yubikey) {
match manager::open_device(
&mut self.context,
conf.yubikey.bus_id,
conf.yubikey.address_id,
) {
Ok((mut handle, interfaces)) => {
let mut challenge = [0; 64];

Expand Down Expand Up @@ -225,7 +234,11 @@ impl Yubico {
block: GenericArray::clone_from_slice(&[0; 16]),
};

match manager::open_device(&mut self.context, conf.yubikey) {
match manager::open_device(
&mut self.context,
conf.yubikey.bus_id,
conf.yubikey.address_id,
) {
Ok((mut handle, interfaces)) => {
let mut challenge = [0; 64];
//(&mut challenge[..6]).copy_from_slice(chall);
Expand Down
41 changes: 36 additions & 5 deletions src/manager.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::config::Command;
use crate::sec::crc16;
use crate::yubicoerror::YubicoError;
use rusb::{request_type, Context, DeviceHandle, Direction, Recipient, RequestType, UsbContext};
use rusb::{
request_type, Context, Device, DeviceHandle, Direction, Recipient, RequestType, UsbContext,
};
use std::time::Duration;
use std::{slice, thread};

use crate::Yubikey;

const DATA_SIZE: usize = 64;
const HID_GET_REPORT: u8 = 0x01;
const HID_SET_REPORT: u8 = 0x09;
Expand All @@ -19,9 +19,40 @@ bitflags! {
}
}

pub fn read_serial_from_device(device: Device<Context>) -> Result<u32, YubicoError> {
let mut context = Context::new()?;
let mut handle = open_device(&mut 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,
yubikey: Yubikey,
bus_id: u8,
address_id: u8,
) -> Result<(DeviceHandle<Context>, Vec<u8>), YubicoError> {
let devices = match context.devices() {
Ok(device) => device,
Expand All @@ -38,7 +69,7 @@ pub fn open_device(
}
};

if device.bus_number() == yubikey.bus_id && device.address() == yubikey.address_id {
if device.bus_number() == bus_id && device.address() == address_id {
match device.open() {
Ok(mut handle) => {
let config = match device.config_descriptor(0) {
Expand Down

0 comments on commit 6f46a0b

Please sign in to comment.