Skip to content

Commit 94395e1

Browse files
committed
fix: bump nusb
1 parent 99b93d3 commit 94395e1

File tree

8 files changed

+183
-143
lines changed

8 files changed

+183
-143
lines changed

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "challenge_response"
33
version = "0.0.0-placeholder-version"
44
authors = ["Ashutosh Varma <github@ashu.io>", "louib <code@louib.net>"]
5+
edition = "2021"
56

67
description = "Perform HMAC-SHA1 and OTP challenges with YubiKey, OnlyKey and NitroKey, in pure Rust."
78
license = "MIT OR Apache-2.0"
@@ -33,13 +34,15 @@ aes = "0.8"
3334
block-modes = "0.9"
3435
hmac = "0.12"
3536
sha-1 = "0.10"
37+
tokio = { version = "1", features = ["rt", "macros", "time"] }
38+
async-trait = "0.1"
3639

3740
[target.'cfg(windows)'.dependencies]
3841
rusb = { version = "0.9" }
3942

4043
[target.'cfg(not(windows))'.dependencies]
4144
rusb = { version = "0.9", optional = true }
42-
nusb = { version = "0.1", optional = true }
45+
nusb = { version = "0.2", optional = true }
4346

4447
[dev-dependencies]
4548
hex = "0.4"

src/configure.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use config::Command;
2-
use hmacmode::HmacKey;
3-
use otpmode::Aes128Key;
4-
use sec::crc16;
1+
use crate::config::Command;
2+
use crate::hmacmode::HmacKey;
3+
use crate::otpmode::Aes128Key;
4+
use crate::sec::crc16;
55
use std;
6-
use usb::{Frame, PAYLOAD_SIZE};
6+
use crate::usb::{Frame, PAYLOAD_SIZE};
77

88
const FIXED_SIZE: usize = 16;
99
const UID_SIZE: usize = 6;

src/error.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#[cfg(any(feature = "rusb", target_os = "windows"))]
22
use rusb::Error as usbError;
3+
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
4+
use nusb::{Error as nusbError, transfer::TransferError as nusbTransferError};
35
use std::error;
46
use std::fmt;
57
use std::io::Error as ioError;
@@ -9,6 +11,10 @@ pub enum ChallengeResponseError {
911
IOError(ioError),
1012
#[cfg(any(feature = "rusb", target_os = "windows"))]
1113
UsbError(usbError),
14+
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
15+
NusbError(nusbError),
16+
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
17+
NusbTransferError(nusbTransferError),
1218
CommandNotSupported,
1319
DeviceNotFound,
1420
OpenDeviceError,
@@ -25,6 +31,10 @@ impl fmt::Display for ChallengeResponseError {
2531
ChallengeResponseError::IOError(ref err) => write!(f, "IO error: {}", err),
2632
#[cfg(any(feature = "rusb", target_os = "windows"))]
2733
ChallengeResponseError::UsbError(ref err) => write!(f, "USB error: {}", err),
34+
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
35+
ChallengeResponseError::NusbError(ref err) => write!(f, "NUSB error: {}", err),
36+
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
37+
ChallengeResponseError::NusbTransferError(ref err) => write!(f, "NUSB transfer error: {}", err),
2838
ChallengeResponseError::DeviceNotFound => write!(f, "Device not found"),
2939
ChallengeResponseError::OpenDeviceError => write!(f, "Can not open device"),
3040
ChallengeResponseError::CommandNotSupported => write!(f, "Command Not Supported"),
@@ -42,6 +52,10 @@ impl error::Error for ChallengeResponseError {
4252
match *self {
4353
#[cfg(any(feature = "rusb", target_os = "windows"))]
4454
ChallengeResponseError::UsbError(ref err) => Some(err),
55+
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
56+
ChallengeResponseError::NusbError(ref err) => Some(err),
57+
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
58+
ChallengeResponseError::NusbTransferError(ref err) => Some(err),
4559
_ => None,
4660
}
4761
}
@@ -59,3 +73,17 @@ impl From<usbError> for ChallengeResponseError {
5973
ChallengeResponseError::UsbError(err)
6074
}
6175
}
76+
77+
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
78+
impl From<nusbError> for ChallengeResponseError {
79+
fn from(err: nusbError) -> ChallengeResponseError {
80+
ChallengeResponseError::NusbError(err)
81+
}
82+
}
83+
84+
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
85+
impl From<nusbTransferError> for ChallengeResponseError {
86+
fn from(err: nusbTransferError) -> ChallengeResponseError {
87+
ChallengeResponseError::NusbTransferError(err)
88+
}
89+
}

src/hmacmode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rand::Rng;
2-
use sec::hmac_sha1;
2+
use crate::sec::hmac_sha1;
33
use std;
44

55
/// Size of the secret used by the HMAC algorithm

src/lib.rs

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ compile_error!("Either the rusb or nusb feature must be enabled for this crate")
55

66
#[cfg(all(feature = "nusb", not(feature = "rusb"), not(target_os = "windows")))]
77
extern crate nusb;
8+
#[cfg(all(feature = "nusb", not(feature = "rusb"), not(target_os = "windows")))]
9+
extern crate tokio;
810
#[cfg(any(feature = "rusb", target_os = "windows"))]
911
extern crate rusb;
1012

1113
#[macro_use]
1214
extern crate structure;
1315

1416
extern crate aes;
17+
extern crate async_trait;
1518
extern crate block_modes;
1619
extern crate hmac;
1720
extern crate rand;
@@ -54,50 +57,55 @@ impl ChallengeResponse {
5457
Ok(ChallengeResponse { backend })
5558
}
5659

57-
pub fn find_device(&mut self) -> Result<Device> {
58-
self.backend.find_device()
60+
pub async fn find_device(&mut self) -> Result<Device> {
61+
self.backend.find_device().await
5962
}
6063

61-
pub fn find_device_from_serial(&mut self, serial: u32) -> Result<Device> {
62-
self.backend.find_device_from_serial(serial)
64+
pub async fn find_device_from_serial(&mut self, serial: u32) -> Result<Device> {
65+
self.backend.find_device_from_serial(serial).await
6366
}
6467

65-
pub fn find_all_devices(&mut self) -> Result<Vec<Device>> {
66-
self.backend.find_all_devices()
68+
pub async fn find_all_devices(&mut self) -> Result<Vec<Device>> {
69+
self.backend.find_all_devices().await
6770
}
6871

69-
pub fn read_serial_number(&mut self, conf: Config) -> Result<u32> {
72+
pub async fn read_serial_number(&mut self, conf: Config) -> Result<u32> {
7073
self.backend
7174
.read_serial_from_device(conf.device.bus_id, conf.device.address_id)
75+
.await
7276
}
7377

74-
pub fn write_config(&mut self, conf: Config, device_config: &mut DeviceModeConfig) -> Result<()> {
78+
pub async fn write_config(&mut self, conf: Config, device_config: &mut DeviceModeConfig) -> Result<()> {
7579
let d = device_config.to_frame(conf.command);
7680
let mut buf = [0; usb::STATUS_UPDATE_PAYLOAD_SIZE];
7781

7882
let (mut handle, interfaces) = self
7983
.backend
80-
.open_device(conf.device.bus_id, conf.device.address_id)?;
84+
.open_device(conf.device.bus_id, conf.device.address_id)
85+
.await?;
8186

8287
self.backend
83-
.wait(&mut handle, |f| !f.contains(Flags::SLOT_WRITE_FLAG), &mut buf)?;
88+
.wait(&mut handle, |f| !f.contains(Flags::SLOT_WRITE_FLAG), &mut buf)
89+
.await?;
8490

8591
// TODO: Should check version number.
8692

87-
self.backend.write_frame(&mut handle, &d)?;
93+
self.backend.write_frame(&mut handle, &d).await?;
8894
self.backend
89-
.wait(&mut handle, |f| !f.contains(Flags::SLOT_WRITE_FLAG), &mut buf)?;
90-
self.backend.close_device(handle, interfaces)?;
95+
.wait(&mut handle, |f| !f.contains(Flags::SLOT_WRITE_FLAG), &mut buf)
96+
.await?;
97+
self.backend.close_device(handle, interfaces).await?;
9198

9299
Ok(())
93100
}
94101

95-
pub fn challenge_response_hmac(&mut self, chall: &[u8], conf: Config) -> Result<Hmac> {
102+
pub async fn challenge_response_hmac(&mut self, chall: &[u8], conf: Config) -> Result<Hmac> {
96103
let mut hmac = Hmac([0; 20]);
97104

98105
let (mut handle, interfaces) = self
99106
.backend
100-
.open_device(conf.device.bus_id, conf.device.address_id)?;
107+
.open_device(conf.device.bus_id, conf.device.address_id)
108+
.await?;
101109

102110
let mut challenge = [0; CHALLENGE_SIZE];
103111

@@ -113,18 +121,20 @@ impl ChallengeResponse {
113121
(&mut challenge[..chall.len()]).copy_from_slice(chall);
114122
let d = Frame::new(challenge, command);
115123
let mut buf = [0; usb::STATUS_UPDATE_PAYLOAD_SIZE];
116-
self.backend.wait(
117-
&mut handle,
118-
|f| !f.contains(usb::Flags::SLOT_WRITE_FLAG),
119-
&mut buf,
120-
)?;
124+
self.backend
125+
.wait(
126+
&mut handle,
127+
|f| !f.contains(usb::Flags::SLOT_WRITE_FLAG),
128+
&mut buf,
129+
)
130+
.await?;
121131

122-
self.backend.write_frame(&mut handle, &d)?;
132+
self.backend.write_frame(&mut handle, &d).await?;
123133

124134
// Read the response.
125135
let mut response = [0; usb::RESPONSE_SIZE];
126-
self.backend.read_response(&mut handle, &mut response)?;
127-
self.backend.close_device(handle, interfaces)?;
136+
self.backend.read_response(&mut handle, &mut response).await?;
137+
self.backend.close_device(handle, interfaces).await?;
128138

129139
// Check response.
130140
if crc16(&response[..22]) != CRC_RESIDUAL_OK {
@@ -136,14 +146,15 @@ impl ChallengeResponse {
136146
Ok(hmac)
137147
}
138148

139-
pub fn challenge_response_otp(&mut self, chall: &[u8], conf: Config) -> Result<Aes128Block> {
149+
pub async fn challenge_response_otp(&mut self, chall: &[u8], conf: Config) -> Result<Aes128Block> {
140150
let mut block = Aes128Block {
141151
block: GenericArray::clone_from_slice(&[0; 16]),
142152
};
143153

144154
let (mut handle, interfaces) = self
145155
.backend
146-
.open_device(conf.device.bus_id, conf.device.address_id)?;
156+
.open_device(conf.device.bus_id, conf.device.address_id)
157+
.await?;
147158

148159
let mut challenge = [0; CHALLENGE_SIZE];
149160

@@ -156,17 +167,19 @@ impl ChallengeResponse {
156167
let d = Frame::new(challenge, command);
157168
let mut buf = [0; usb::STATUS_UPDATE_PAYLOAD_SIZE];
158169

159-
self.backend.wait(
160-
&mut handle,
161-
|f| !f.contains(usb::Flags::SLOT_WRITE_FLAG),
162-
&mut buf,
163-
)?;
170+
self.backend
171+
.wait(
172+
&mut handle,
173+
|f| !f.contains(usb::Flags::SLOT_WRITE_FLAG),
174+
&mut buf,
175+
)
176+
.await?;
164177

165-
self.backend.write_frame(&mut handle, &d)?;
178+
self.backend.write_frame(&mut handle, &d).await?;
166179

167180
let mut response = [0; usb::RESPONSE_SIZE];
168-
self.backend.read_response(&mut handle, &mut response)?;
169-
self.backend.close_device(handle, interfaces)?;
181+
self.backend.read_response(&mut handle, &mut response).await?;
182+
self.backend.close_device(handle, interfaces).await?;
170183

171184
// Check response.
172185
if crc16(&response[..18]) != CRC_RESIDUAL_OK {
@@ -183,8 +196,8 @@ impl ChallengeResponse {
183196
mod tests {
184197
use super::*;
185198

186-
#[test]
187-
fn test_find_device() {
199+
#[tokio::test]
200+
async fn test_find_device() {
188201
let mut cr_client = match ChallengeResponse::new() {
189202
Ok(c) => c,
190203
Err(e) => {
@@ -193,13 +206,13 @@ mod tests {
193206
}
194207
};
195208

196-
if let Err(e) = cr_client.find_device() {
209+
if let Err(e) = cr_client.find_device().await {
197210
assert!(matches!(e, ChallengeResponseError::DeviceNotFound));
198211
};
199212
}
200213

201-
#[test]
202-
fn test_find_all_devices() {
214+
#[tokio::test]
215+
async fn test_find_all_devices() {
203216
let mut cr_client = match ChallengeResponse::new() {
204217
Ok(c) => c,
205218
Err(e) => {
@@ -208,7 +221,7 @@ mod tests {
208221
}
209222
};
210223

211-
if let Err(e) = cr_client.find_all_devices() {
224+
if let Err(e) = cr_client.find_all_devices().await {
212225
assert!(matches!(e, ChallengeResponseError::DeviceNotFound));
213226
};
214227
}

0 commit comments

Comments
 (0)