challenge_response 0.4.0

Challenge-Response library for Rust
Documentation

challenge-response

Latest Version Documentation Build Status Dependency Status MIT licensed Apache-2.0 licensed

challenge-response is a Rust library for performing challenge-response operations (hashing and encryption) using security keys like the YubiKey and the OnlyKey.

Current features

Supported devices

  • YubiKey 2.2 and later
  • OnlyKey (untested)

Usage

Add this to your Cargo.toml

[dependencies]
challenge_response = "0"

Configure Yubikey (HMAC-SHA1 mode)

Note, please read about the initial configuration Alternatively you can configure the yubikey with the official Yubikey Personalization GUI.

extern crate challenge_response;
extern crate rand;

use challenge_response::config::{Command, Config};
use challenge_response::configure::DeviceModeConfig;
use challenge_response::hmacmode::HmacKey;
use challenge_response::ChallengeResponse;
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};

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

    if let Ok(device) = challenge_response.find_device() {
        println!(
            "Vendor ID: {:?} Product ID {:?}",
            device.vendor_id, device.product_id
        );

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

        let mut rng = thread_rng();

        // Secret must have 20 bytes
        // Used rand here, but you can set your own secret: let secret: &[u8; 20] = b"my_awesome_secret_20";
        let secret: Vec<u8> = rng.sample_iter(&Alphanumeric).take(20).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) = challenge_response.write_config(config, &mut device_config) {
            println!("{:?}", err);
        } else {
            println!("Device configured");
        }
    } else {
        println!("Device not found");
    }
}

Example Challenge-Response (HMAC-SHA1 mode)

Configure the yubikey with Yubikey Personalization GUI

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 challenge_response = match ChallengeResponse::new() {
        Ok(y) => y,
        Err(e) => {
            eprintln!("{}", e.to_string());
            return;
        }
    };

    if let Ok(device) = challenge_response.find_device() {
        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 = challenge_response
            .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);
    } else {
        println!("Device not found");
    }
}

Credits

This library was originally a fork of the yubico_manager library.