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

Version

Ver 3.3.1

Ver 3.3.0

How to use Registration and Authentication

```rust use ctaphidfido2::{ fidokey::{GetAssertionArgsBuilder, MakeCredentialArgsBuilder}, verifier, Cfg, FidoKeyHidFactory, };

fn main() { let rpid = "reg-auth-example-app"; let pin = getinputwith_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_publickey_der = verify_result.credential_publickey_der;

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_publickey_der,
    &challenge,
    &assertions[0],
) {
    println!("- ! Verify Assertion Failed");
}

}

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

pub fn getinputwithmessage(message: &str) -> String { println!("{}", message); let input = getinput(); println!(); input } ```

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

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

raspberry Pi

(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.

sh 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.

```rust use ctaphidfido2::{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.

rust 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().

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

let fidokey = FidoKeyHidFactory::createbyparams(&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.