26 stable releases (3 major)

3.5.1 Mar 24, 2024
3.5.0 May 5, 2023
3.4.2 Sep 11, 2022
3.4.1 Jul 10, 2022
0.4.0 Oct 3, 2020

#32 in Authentication

Download history 19/week @ 2024-02-12 44/week @ 2024-02-19 41/week @ 2024-02-26 41/week @ 2024-03-04 28/week @ 2024-03-11 142/week @ 2024-03-18 28/week @ 2024-03-25 58/week @ 2024-04-01

259 downloads per month
Used in 2 crates

MIT license

195KB
4.5K SLoC

license macOS Windows Raspberry-Pi

ctap-hid-fido2

Rust FIDO2 CTAP library ( and cli tool ctapcli ).

Authentication using FIDO2-compliant security keys (e.g. Yubikey) is possible.

Features

  • Register and Authenticate.
  • Register or change PIN.
  • Enrollment and deletion of fingerprints.
  • Management of credentials recorded in security keys.

Version

Ver 3.5.1

  • Dependency Updates.

Ver 3.5.0

  • Specify multiple key_types in MakeCredentialArgsBuilder.
  • ED25519 support.
  • update dependencies → base64, x509-parser, hidapi, clap, env_logger
  • remove dependencies → serde_json, ihex, base64-url

Ver 3.4.2

  • update dependencies → aes, cbc, x509-parser, rpassword
  • remove dependencies → block-modes

Ver 3.4.1

  • Bug fix

Ver 3.4.0

Ver 3.3.1

Ver 3.3.0

Ver 3.2.0

Ver 3.1.0

Ver 3.0.0

  • The usage has changed from Ver2. → How to Use.

How to use Registration and Authentication

use ctap_hid_fido2::{
    fidokey::{GetAssertionArgsBuilder, MakeCredentialArgsBuilder},
    verifier, Cfg, FidoKeyHidFactory,
};

fn main() {
    let rpid = "reg-auth-example-app";
    let pin = get_input_with_message("input PIN:");

    println!("Register");
    // create `challenge`
    let challenge = verifier::create_challenge();

    // create `MakeCredentialArgs`
    let make_credential_args = MakeCredentialArgsBuilder::new(rpid, &challenge)
        .pin(&pin)
        .build();

    // create `FidoKeyHid`
    let device = FidoKeyHidFactory::create(&Cfg::init()).unwrap();

    // get `Attestation` Object
    let attestation = device
        .make_credential_with_args(&make_credential_args)
        .unwrap();
    println!("- Register Success");

    // verify `Attestation` Object
    let verify_result = verifier::verify_attestation(rpid, &challenge, &attestation);
    if !verify_result.is_success {
        println!("- ! Verify Failed");
        return;
    }

    // store Credential Id and Publickey
    let userdata_credential_id = verify_result.credential_id;
    let userdata_credential_public_key = verify_result.credential_public_key;

    println!("Authenticate");
    // create `challenge`
    let challenge = verifier::create_challenge();

    // create `GetAssertionArgs`
    let get_assertion_args = GetAssertionArgsBuilder::new(rpid, &challenge)
        .pin(&pin)
        .credential_id(&userdata_credential_id)
        .build();

    // get `Assertion` Object
    let assertions = device.get_assertion_with_args(&get_assertion_args).unwrap();
    println!("- Authenticate Success");

    // verify `Assertion` Object
    if !verifier::verify_assertion(
        rpid,
        &userdata_credential_public_key,
        &challenge,
        &assertions[0],
    ) {
        println!("- ! Verify Assertion Failed");
    }
}

pub fn get_input() -> String {
    let mut word = String::new();
    std::io::stdin().read_line(&mut word).ok();
    return word.trim().to_string();
}

pub fn get_input_with_message(message: &str) -> String {
    println!("{}", message);
    let input = get_input();
    println!();
    input
}
  • See [How to use](#How to use) and Examples for detailed instructions.

Description

ctap-hid-fido2 is a crate implementing CTAP 2.0 and 2.1, allowing direct control of FIDO2-compliant Authenticators such as Yubikey.
For more information on FIDO, see FIDO Alliance Page.

Author

gebo

Build and run

macOS

Nothing in particular to worry about using it.

Windows

  • Run as administrator

In Windows, the security key via HID cannot be accessed unless the executing exe has administrator privileges.

raspberry Pi

  • installing libusb and libudev package

(The same may be true for Linux, such as Ubuntu)

If you get the following error with the libusb-1.0 dependency and cannot build, you can solve the problem by doing the following.

sudo apt install -y libusb-1.0-0-dev libudev-dev

How to use

PIN has to be set

Unless noted in the following Examples, a PIN must be set in the Authenticator.

create FidoKeyHid object

First, create a device object with FidoKeyHidFactory::create.

If no Authenticator can be detected on the HID device, an error will result.

use ctap_hid_fido2::{Cfg, FidoKeyHidFactory};
...

let device = match FidoKeyHidFactory::create(&Cfg::init()) {
  Ok(d) => d,
  Err(e) => {
      println!("error: {:?}", e);
      return;
  }
};

If more than one Authenticator is detected, an error will result. See the following description for Multi-Authenticator support

Cfg

The argument Cfg is fine with the default value you create using init(), but you can customize it to change the behavior a bit, see Cfg definition.

FidoKeyHid

Use Authenticator with the methods implemented in FidoKeyHid.
For example, get_pin_retries() can be used to obtain the number of PIN retries.

match device.get_pin_retries() {
    Ok(retry) => println!("{}", retry),
    Err(e) => println!("error: {:?}", e),
}

Multi-Authenticator support

If you have multiple Authenticators connected to the HID and want to control each device individually, use get_fidokey_devices() and create_by_params().

let devs = ctap_hid_fido2::get_fidokey_devices();
for dev in devs {
  println!("- vid=0x{:04x} , pid=0x{:04x} , info={:?}",dev.vid, dev.pid, dev.info);

  let fidokey = FidoKeyHidFactory::create_by_params(&vec![dev.param], &Cfg::init()).unwrap();
  let info = fidokey.get_info().unwrap();
  println!("{}", info);
}

Examples

See the following links for examples of various patterns.

CLI tool

CLI tool can be used.

Dependencies

~11–21MB
~368K SLoC