Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 2 additions & 120 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,127 +53,9 @@ The `nusb` backend has the advantage of not depending on `libusb`, thus making i
> [!NOTE]
> The `nusb` feature is not available on Windows. If configured, the library will default to using the `rusb` backend instead.

### Perform a Challenge-Response (HMAC-SHA1 mode)

If you are using a YubiKey, you can configure the HMAC-SHA1 Challenge-Response
with the [Yubikey Personalization GUI](https://developers.yubico.com/yubikey-personalization-gui/).

```rust,ignore
extern crate challenge_response;
extern crate hex;

use challenge_response::config::{Config, Mode, Slot};
use challenge_response::ChallengeResponse;
use std::ops::Deref;

fn main() {
let mut cr_client = match ChallengeResponse::new() {
Ok(c) => c,
Err(e) => {
eprintln!("{}", e.to_string());
return;
}
};

let device = match cr_client.find_device() {
Ok(d) => d,
Err(e) => {
eprintln!("Device not found: {}", e.to_string());
return;
}
};

println!(
"Vendor ID: {:?} Product ID {:?}",
device.vendor_id, device.product_id
);

let config = Config::new_from(device)
.set_variable_size(true)
.set_mode(Mode::Sha1)
.set_slot(Slot::Slot2);

// Challenge can not be greater than 64 bytes
let challenge = String::from("mychallenge");
// In HMAC Mode, the result will always be the
// SAME for the SAME provided challenge
let hmac_result = cr_client
.challenge_response_hmac(challenge.as_bytes(), config)
.unwrap();

// Just for debug, lets check the hex
let v: &[u8] = hmac_result.deref();
let hex_string = hex::encode(v);

println!("{}", hex_string);
}
```
## Examples

### Configure Yubikey (HMAC-SHA1 mode)

Note, please read about the [initial configuration](https://wiki.archlinux.org/index.php/yubikey#Initial_configuration)
Alternatively you can configure the yubikey with the official [Yubikey Personalization GUI](https://developers.yubico.com/yubikey-personalization-gui/).

```rust,ignore
extern crate challenge_response;
extern crate rand;

use challenge_response::config::{Command, Config};
use challenge_response::configure::DeviceModeConfig;
use challenge_response::hmacmode::{
HmacKey, HmacSecret, HMAC_SECRET_SIZE,
};
use challenge_response::ChallengeResponse;
use rand::distr::Alphanumeric;
use rand::{rng, RngExt};

fn main() {
let mut cr_client = match ChallengeResponse::new() {
Ok(y) => y,
Err(e) => {
eprintln!("{}", e.to_string());
return;
}
};

let device = match cr_client.find_device() {
Ok(d) => d,
Err(e) => {
eprintln!("Device not found: {}", e.to_string());
return;
}
};

println!(
"Vendor ID: {:?} Product ID {:?}",
device.vendor_id, device.product_id
);

let config = Config::new_from(device)
.set_command(Command::Configuration2);

let mut rng = rng();

// Used rand here, but you can set your own secret:
// let secret: &HmacSecret = b"my_awesome_secret_20";
let secret: Vec<u8> = rng
.sample_iter(&Alphanumeric)
.take(HMAC_SECRET_SIZE)
.collect();
let hmac_key: HmacKey = HmacKey::from_slice(&secret);

let mut device_config = DeviceModeConfig::default();
device_config.challenge_response_hmac(&hmac_key, false, false);

if let Err(err) =
cr_client.write_config(config, &mut device_config)
{
println!("{:?}", err);
} else {
println!("Device configured");
}
}
```
Code examples for performing a challenge-response (both HMAC and OTP) as well as configuring a device can be found in the [examples/](./examples/) directory.

## Credits

Expand Down