Correct flag byte contents
This commit is contained in:
parent
a2587c2a4f
commit
55112f5869
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -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",
|
||||||
|
@ -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"
|
||||||
|
27
src/main.rs
27
src/main.rs
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user