Correct flag byte contents

This commit is contained in:
pjht 2023-08-16 09:36:05 -05:00
parent a2587c2a4f
commit 55112f5869
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E
3 changed files with 19 additions and 10 deletions

1
Cargo.lock generated
View File

@ -489,6 +489,7 @@ name = "fido_ssh_maker"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags",
"clap", "clap",
"ctap-hid-fido2", "ctap-hid-fido2",
"rpassword", "rpassword",

View File

@ -7,6 +7,7 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.72" anyhow = "1.0.72"
bitflags = "2.4.0"
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" rpassword = "7.2.0"

View File

@ -1,18 +1,29 @@
use std::{ use std::{
fs::Permissions, fs::Permissions,
os::unix::prelude::PermissionsExt, os::unix::prelude::PermissionsExt,
path::{Path, PathBuf}, fmt::Display, io::Write, path::{Path, PathBuf}, fmt::Display,
}; };
use anyhow::anyhow; use anyhow::anyhow;
use bitflags::bitflags;
use clap::{Parser, ValueEnum}; use clap::{Parser, ValueEnum};
use ctap_hid_fido2::{ use ctap_hid_fido2::{
fidokey::{CredentialSupportedKeyType, MakeCredentialArgsBuilder, CredentialExtension, credential_management::credential_management_params::CredentialProtectionPolicy}, fidokey::{CredentialSupportedKeyType, MakeCredentialArgsBuilder},
verifier, FidoKeyHidFactory, LibCfg, verifier, FidoKeyHidFactory, LibCfg,
}; };
use ssh_encoding::{Decode, Encode, LineEnding}; use ssh_encoding::{Decode, Encode, LineEnding};
use ssh_key::{private, PrivateKey}; use ssh_key::{private, PrivateKey};
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct SshSkFlags: u8 {
const UserPresenceRequired = 0x01;
const UserVerificationRequired = 0x4;
const ForceOperation = 0x10;
const ResidentKey = 0x20;
}
}
/// Generate FIDO-backed SSH keys /// Generate FIDO-backed SSH keys
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(author, version, about, long_about = None, arg_required_else_help = true)] #[command(author, version, about, long_about = None, arg_required_else_help = true)]
@ -84,20 +95,18 @@ fn main() -> anyhow::Result<()> {
let device_has_pin = device.get_info()?.options.contains(&("clientPin".into(), true)); let device_has_pin = device.get_info()?.options.contains(&("clientPin".into(), true));
let pin = if device_has_pin { let pin = if device_has_pin {
rpassword::prompt_password("Enter FIDO2 PIN:")? rpassword::prompt_password("Enter FIDO2 PIN: ")?
} else { } else {
String::new() String::new()
}; };
let make_credential_args = if device_has_pin { let make_credential_args = if device_has_pin {
MakeCredentialArgsBuilder::new("ssh:", &challenge) MakeCredentialArgsBuilder::new("ssh:", &challenge)
.pin(&pin) .pin(&pin)
.extensions(&[CredentialExtension::CredProtect(Some(CredentialProtectionPolicy::UserVerificationOptionalWithCredentialIdList))])
.key_type(args.key_type.into()) .key_type(args.key_type.into())
.build() .build()
} else { } else {
MakeCredentialArgsBuilder::new("ssh:", &challenge) MakeCredentialArgsBuilder::new("ssh:", &challenge)
.without_pin_and_uv() .without_pin_and_uv()
.extensions(&[CredentialExtension::CredProtect(Some(CredentialProtectionPolicy::UserVerificationOptionalWithCredentialIdList))])
.key_type(args.key_type.into()) .key_type(args.key_type.into())
.build() .build()
}; };
@ -117,11 +126,9 @@ fn main() -> anyhow::Result<()> {
.der .der
.encode(&mut privkey_bytes)?; .encode(&mut privkey_bytes)?;
"ssh:".encode(&mut privkey_bytes)?; "ssh:".encode(&mut privkey_bytes)?;
let flags = (attestation.flags_user_present_result as u8) let mut flags = SshSkFlags::UserPresenceRequired;
| (attestation.flags_user_verified_result as u8) << 2 flags.set(SshSkFlags::UserVerificationRequired, args.user_verify);
| (attestation.flags_attested_credential_data_included as u8) << 6 privkey_bytes.push(flags.bits());
| (attestation.flags_extension_data_included as u8) << 7;
privkey_bytes.push(flags);
verify_result.credential_id.encode(&mut privkey_bytes)?; verify_result.credential_id.encode(&mut privkey_bytes)?;
"".encode(&mut privkey_bytes)?; "".encode(&mut privkey_bytes)?;
let privkey = match args.key_type { let privkey = match args.key_type {