update to 0.2.2
This commit is contained in:
14
src/cli.rs
14
src/cli.rs
@@ -70,10 +70,6 @@ pub fn add_password_to_luks(
|
||||
Ok(slot)
|
||||
}
|
||||
|
||||
pub fn authenticator_connected() -> Fido2LuksResult<bool> {
|
||||
Ok(!device::get_devices()?.is_empty())
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct Args {
|
||||
/// Request passwords via Stdin instead of using the password helper
|
||||
@@ -181,7 +177,11 @@ pub enum Command {
|
||||
},
|
||||
/// Generate a new FIDO credential
|
||||
#[structopt(name = "credential")]
|
||||
Credential,
|
||||
Credential {
|
||||
/// Name to be displayed on the authenticator if it has a display
|
||||
#[structopt(env = "FIDO2LUKS_CREDENTIAL_NAME")]
|
||||
name: Option<String>,
|
||||
},
|
||||
/// Check if an authenticator is connected
|
||||
#[structopt(name = "connected")]
|
||||
Connected,
|
||||
@@ -195,8 +195,8 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
||||
let mut stdout = io::stdout();
|
||||
let args = parse_cmdline();
|
||||
match &args.command {
|
||||
Command::Credential => {
|
||||
let cred = make_credential_id()?;
|
||||
Command::Credential { name } => {
|
||||
let cred = make_credential_id(name.as_ref().map(|n| n.as_ref()))?;
|
||||
println!("{}", hex::encode(&cred.id));
|
||||
Ok(())
|
||||
}
|
||||
|
@@ -1,19 +1,53 @@
|
||||
use crate::error::*;
|
||||
use crate::util::sha256;
|
||||
|
||||
use ctap::{
|
||||
self,
|
||||
extensions::hmac::{FidoHmacCredential, HmacExtension},
|
||||
FidoDevice, FidoError, FidoErrorKind,
|
||||
AuthenticatorOptions, FidoDevice, FidoError, FidoErrorKind, PublicKeyCredentialRpEntity,
|
||||
PublicKeyCredentialUserEntity,
|
||||
};
|
||||
|
||||
pub fn make_credential_id() -> Fido2LuksResult<FidoHmacCredential> {
|
||||
const RP_ID: &'static str = "fido2luks";
|
||||
|
||||
fn authenticator_options() -> Option<AuthenticatorOptions> {
|
||||
Some(AuthenticatorOptions {
|
||||
uv: false, //TODO: should get this from config
|
||||
rk: true,
|
||||
})
|
||||
}
|
||||
|
||||
fn authenticator_rp() -> PublicKeyCredentialRpEntity<'static> {
|
||||
PublicKeyCredentialRpEntity {
|
||||
id: RP_ID,
|
||||
name: None,
|
||||
icon: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn authenticator_user(name: Option<&str>) -> PublicKeyCredentialUserEntity {
|
||||
PublicKeyCredentialUserEntity {
|
||||
id: &[0u8],
|
||||
name: name.unwrap_or(""),
|
||||
icon: None,
|
||||
display_name: name,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_credential_id(name: Option<&str>) -> Fido2LuksResult<FidoHmacCredential> {
|
||||
let mut errs = Vec::new();
|
||||
match get_devices()? {
|
||||
ref devs if devs.is_empty() => Err(Fido2LuksError::NoAuthenticatorError)?,
|
||||
devs => {
|
||||
for mut dev in devs.into_iter() {
|
||||
match dev
|
||||
.make_credential("fido2luks", &[0u8], "", &[0u8; 32])
|
||||
.make_hmac_credential_full(
|
||||
authenticator_rp(),
|
||||
authenticator_user(name),
|
||||
&[0u8; 32],
|
||||
&[],
|
||||
authenticator_options(),
|
||||
)
|
||||
.map(|cred| cred.into())
|
||||
{
|
||||
//TODO: make credentials device specific
|
||||
@@ -33,16 +67,16 @@ pub fn make_credential_id() -> Fido2LuksResult<FidoHmacCredential> {
|
||||
pub fn perform_challenge(credential_id: &str, salt: &[u8; 32]) -> Fido2LuksResult<[u8; 32]> {
|
||||
let cred = FidoHmacCredential {
|
||||
id: hex::decode(credential_id).unwrap(),
|
||||
rp_id: "fido2luks".to_string(),
|
||||
rp_id: RP_ID.to_string(),
|
||||
};
|
||||
let mut errs = Vec::new();
|
||||
match get_devices()? {
|
||||
ref devs if devs.is_empty() => Err(Fido2LuksError::NoAuthenticatorError)?,
|
||||
devs => {
|
||||
for mut dev in devs.into_iter() {
|
||||
match dev.hmac_challange(&cred, &salt[..]) {
|
||||
match dev.get_hmac_assertion(&cred, &sha256(&[&salt[..]]), None, None) {
|
||||
Ok(secret) => {
|
||||
return Ok(secret);
|
||||
return Ok(secret.0);
|
||||
}
|
||||
Err(e) => {
|
||||
errs.push(e);
|
||||
|
10
src/main.rs
10
src/main.rs
@@ -7,9 +7,8 @@ use crate::device::*;
|
||||
use crate::error::*;
|
||||
use cryptsetup_rs as luks;
|
||||
use cryptsetup_rs::Luks1CryptDevice;
|
||||
use ring::digest;
|
||||
|
||||
use std::io::{self};
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::process::exit;
|
||||
|
||||
@@ -26,12 +25,7 @@ fn open_container(device: &PathBuf, name: &str, secret: &[u8; 32]) -> Fido2LuksR
|
||||
}
|
||||
|
||||
fn assemble_secret(hmac_result: &[u8], salt: &[u8]) -> [u8; 32] {
|
||||
let mut digest = digest::Context::new(&digest::SHA256);
|
||||
digest.update(salt);
|
||||
digest.update(hmac_result);
|
||||
let mut secret = [0u8; 32];
|
||||
secret.as_mut().copy_from_slice(digest.finish().as_ref());
|
||||
secret
|
||||
util::sha256(&[salt, hmac_result])
|
||||
}
|
||||
|
||||
fn main() -> Fido2LuksResult<()> {
|
||||
|
11
src/util.rs
11
src/util.rs
@@ -1,8 +1,19 @@
|
||||
use crate::error::*;
|
||||
use ring::digest;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn sha256<'a>(messages: &[&[u8]]) -> [u8; 32] {
|
||||
let mut digest = digest::Context::new(&digest::SHA256);
|
||||
for m in messages.iter() {
|
||||
digest.update(m);
|
||||
}
|
||||
let mut secret = [0u8; 32];
|
||||
secret.as_mut().copy_from_slice(digest.finish().as_ref());
|
||||
secret
|
||||
}
|
||||
|
||||
pub fn read_password(q: &str, verify: bool) -> Fido2LuksResult<String> {
|
||||
match rpassword::read_password_from_tty(Some(&[q, ": "].join("")))? {
|
||||
ref pass
|
||||
|
Reference in New Issue
Block a user