diff --git a/README.md b/README.md index b9f2719..c6314a5 100644 --- a/README.md +++ b/README.md @@ -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 = 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