Work
This commit is contained in:
parent
e23a743a10
commit
a2587c2a4f
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -491,6 +491,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
"ctap-hid-fido2",
|
"ctap-hid-fido2",
|
||||||
|
"rpassword",
|
||||||
"ssh-encoding",
|
"ssh-encoding",
|
||||||
"ssh-key",
|
"ssh-key",
|
||||||
]
|
]
|
||||||
@ -935,6 +936,17 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rpassword"
|
||||||
|
version = "7.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rtoolbox",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.9.2"
|
version = "0.9.2"
|
||||||
@ -958,6 +970,16 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rtoolbox"
|
||||||
|
version = "0.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -9,5 +9,6 @@ edition = "2021"
|
|||||||
anyhow = "1.0.72"
|
anyhow = "1.0.72"
|
||||||
clap = { version = "4.3.21", features = ["derive"] }
|
clap = { version = "4.3.21", features = ["derive"] }
|
||||||
ctap-hid-fido2 = "3.5.0"
|
ctap-hid-fido2 = "3.5.0"
|
||||||
|
rpassword = "7.2.0"
|
||||||
ssh-encoding = { version = "0.2.0" }
|
ssh-encoding = { version = "0.2.0" }
|
||||||
ssh-key = { version = "0.6.0", features = ["ed25519"] }
|
ssh-key = { version = "0.6.0", features = ["ed25519"] }
|
||||||
|
35
src/main.rs
35
src/main.rs
@ -1,13 +1,13 @@
|
|||||||
use std::{
|
use std::{
|
||||||
fs::Permissions,
|
fs::Permissions,
|
||||||
os::unix::prelude::PermissionsExt,
|
os::unix::prelude::PermissionsExt,
|
||||||
path::{Path, PathBuf}, fmt::Display,
|
path::{Path, PathBuf}, fmt::Display, io::Write,
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use clap::{Parser, ValueEnum};
|
use clap::{Parser, ValueEnum};
|
||||||
use ctap_hid_fido2::{
|
use ctap_hid_fido2::{
|
||||||
fidokey::{CredentialSupportedKeyType, MakeCredentialArgsBuilder},
|
fidokey::{CredentialSupportedKeyType, MakeCredentialArgsBuilder, CredentialExtension, credential_management::credential_management_params::CredentialProtectionPolicy},
|
||||||
verifier, FidoKeyHidFactory, LibCfg,
|
verifier, FidoKeyHidFactory, LibCfg,
|
||||||
};
|
};
|
||||||
use ssh_encoding::{Decode, Encode, LineEnding};
|
use ssh_encoding::{Decode, Encode, LineEnding};
|
||||||
@ -23,10 +23,15 @@ struct Args {
|
|||||||
/// Overwrite existing key files
|
/// Overwrite existing key files
|
||||||
#[arg(short = 'f', long)]
|
#[arg(short = 'f', long)]
|
||||||
force: bool,
|
force: bool,
|
||||||
|
/// Type of key to generate
|
||||||
#[arg(short = 't', long = "type")]
|
#[arg(short = 't', long = "type")]
|
||||||
key_type: KeyTypeArg,
|
key_type: KeyTypeArg,
|
||||||
|
/// Write attestation info for later verification
|
||||||
#[arg(long = "write-attestation")]
|
#[arg(long = "write-attestation")]
|
||||||
write_attestation: bool,
|
write_attestation: bool,
|
||||||
|
/// Require user verification on use (PIN/biometrics)
|
||||||
|
#[arg(long = "user-verify")]
|
||||||
|
user_verify: bool,
|
||||||
/// Name of key to generate
|
/// Name of key to generate
|
||||||
key_name: String,
|
key_name: String,
|
||||||
}
|
}
|
||||||
@ -71,14 +76,32 @@ fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
println!("Generating public/private {} key pair", args.key_type);
|
println!("Generating public/private {} key pair", args.key_type);
|
||||||
|
|
||||||
|
|
||||||
let challenge = verifier::create_challenge();
|
let challenge = verifier::create_challenge();
|
||||||
let make_credential_args = MakeCredentialArgsBuilder::new("ssh:", &challenge)
|
|
||||||
.without_pin_and_uv()
|
|
||||||
.key_type(args.key_type.into())
|
|
||||||
.build();
|
|
||||||
let mut libcfg = LibCfg::init();
|
let mut libcfg = LibCfg::init();
|
||||||
libcfg.keep_alive_msg = "Touch the authenticator now.".into();
|
libcfg.keep_alive_msg = "Touch the authenticator now.".into();
|
||||||
let device = FidoKeyHidFactory::create(&libcfg)?;
|
let device = FidoKeyHidFactory::create(&libcfg)?;
|
||||||
|
|
||||||
|
let device_has_pin = device.get_info()?.options.contains(&("clientPin".into(), true));
|
||||||
|
let pin = if device_has_pin {
|
||||||
|
rpassword::prompt_password("Enter FIDO2 PIN:")?
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
let make_credential_args = if device_has_pin {
|
||||||
|
MakeCredentialArgsBuilder::new("ssh:", &challenge)
|
||||||
|
.pin(&pin)
|
||||||
|
.extensions(&[CredentialExtension::CredProtect(Some(CredentialProtectionPolicy::UserVerificationOptionalWithCredentialIdList))])
|
||||||
|
.key_type(args.key_type.into())
|
||||||
|
.build()
|
||||||
|
} else {
|
||||||
|
MakeCredentialArgsBuilder::new("ssh:", &challenge)
|
||||||
|
.without_pin_and_uv()
|
||||||
|
.extensions(&[CredentialExtension::CredProtect(Some(CredentialProtectionPolicy::UserVerificationOptionalWithCredentialIdList))])
|
||||||
|
.key_type(args.key_type.into())
|
||||||
|
.build()
|
||||||
|
};
|
||||||
|
|
||||||
let attestation = device.make_credential_with_args(&make_credential_args)?;
|
let attestation = device.make_credential_with_args(&make_credential_args)?;
|
||||||
let verify_result = verifier::verify_attestation("ssh:", &challenge, &attestation);
|
let verify_result = verifier::verify_attestation("ssh:", &challenge, &attestation);
|
||||||
if !verify_result.is_success {
|
if !verify_result.is_success {
|
||||||
|
Loading…
Reference in New Issue
Block a user