init
This commit is contained in:
commit
41042ecbb0
7 changed files with 1576 additions and 0 deletions
158
src/main.rs
Normal file
158
src/main.rs
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::io::stdin;
|
||||
|
||||
use ctap_hid_fido2::fidokey::{GetAssertionArgsBuilder, MakeCredentialArgsBuilder};
|
||||
use ctap_hid_fido2::public_key::PublicKey;
|
||||
use ctap_hid_fido2::public_key_credential_user_entity::PublicKeyCredentialUserEntity;
|
||||
use ctap_hid_fido2::util::to_hex_str;
|
||||
use ctap_hid_fido2::{Cfg, FidoKeyHidFactory, verifier};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use sha2::Digest;
|
||||
|
||||
const RPID: &str = "thistle.lava.moe";
|
||||
const RPID_HASH: [u8; 32] = sha2_const::Sha256::new()
|
||||
.update(RPID.as_bytes())
|
||||
.finalize();
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
|
||||
struct Directory {
|
||||
nonresidents: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
|
||||
enum DirectoryFormat {
|
||||
Version1(Directory)
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
|
||||
struct VaultBlock {
|
||||
salt: [u8; 8],
|
||||
keys: Vec<[u8; 32]>,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
|
||||
struct Vault {
|
||||
id: u128,
|
||||
salt: [u8; 32],
|
||||
blocks: Vec<VaultBlock>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
|
||||
enum VaultFormat {
|
||||
Version1(Vault)
|
||||
}
|
||||
|
||||
fn prompt(msg: &str) -> anyhow::Result<String> {
|
||||
print!("{}", msg);
|
||||
let mut res = String::new();
|
||||
stdin().read_line(&mut res)?;
|
||||
Ok(res.trim().to_string())
|
||||
}
|
||||
|
||||
fn cmd_auth() -> anyhow::Result<()> {
|
||||
// let f = format!("{:x}",
|
||||
let device = FidoKeyHidFactory::create(&Cfg::init())?;
|
||||
let challenge = verifier::create_challenge();
|
||||
let pin = rpassword::prompt_password("Input PIN: ")?;
|
||||
|
||||
let get_assertion_args = GetAssertionArgsBuilder::new(RPID, &challenge)
|
||||
.pin(&pin)
|
||||
// .without_pin_and_uv()
|
||||
.without_up()
|
||||
.build();
|
||||
|
||||
let assertions = device.get_assertion_with_args(&get_assertion_args)?;
|
||||
println!("-- Authenticate Success");
|
||||
println!("-- Assertion Num = {:?}", assertions.len());
|
||||
for assertion in &assertions {
|
||||
println!("- assertion = {}", assertion);
|
||||
println!("- user = {}", assertion.user);
|
||||
}
|
||||
|
||||
let enu = device.credential_management_enumerate_credentials(Some(&pin), &RPID_HASH)?;
|
||||
println!("-- Cred Num = {:?}", enu.len());
|
||||
for enume in &enu {
|
||||
println!("{}", enume);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cmd_create() -> anyhow::Result<()> {
|
||||
let device = FidoKeyHidFactory::create(&Cfg::init())?;
|
||||
let pin = rpassword::prompt_password("Input PIN: ")?;
|
||||
let file_id: u128 = rand::random();
|
||||
|
||||
let ent = PublicKeyCredentialUserEntity::new(
|
||||
Some(&file_id.to_le_bytes()),
|
||||
None, None,
|
||||
);
|
||||
let challenge = verifier::create_challenge();
|
||||
let make_credential_args = MakeCredentialArgsBuilder::new(RPID, &challenge)
|
||||
.user_entity(&ent)
|
||||
.resident_key()
|
||||
.pin(&pin)
|
||||
.build();
|
||||
|
||||
let attestation = device.make_credential_with_args(&make_credential_args)?;
|
||||
println!("{}", attestation);
|
||||
println!("Registered");
|
||||
|
||||
let verify_result = verifier::verify_attestation(RPID, &challenge, &attestation);
|
||||
if !verify_result.is_success {
|
||||
println!("! Verification failed, faulty key?");
|
||||
return Ok(());
|
||||
}
|
||||
println!("Verified");
|
||||
|
||||
let vault = Vault {
|
||||
id: file_id,
|
||||
salt: rand::random(),
|
||||
blocks: vec![],
|
||||
};
|
||||
|
||||
fs::write(format!("./data/{}.vault", to_hex_str(&file_id.to_le_bytes())), postcard::to_stdvec(&vault)?)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cmd_decrypt(name: &str) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cmd_encrypt(name: &str) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cmd_info() -> anyhow::Result<()> {
|
||||
let device = FidoKeyHidFactory::create(&Cfg::init())?;
|
||||
println!("{}", device.get_info()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
println!("Hello, world!");
|
||||
|
||||
let args = std::env::args().collect::<Vec<_>>();
|
||||
let Some(cmd) = args.get(1) else {
|
||||
eprintln!("Missing args");
|
||||
return Ok(())
|
||||
};
|
||||
|
||||
let fname = args.get(2);
|
||||
|
||||
match cmd.as_str() {
|
||||
"auth" => cmd_auth()?,
|
||||
"create" => cmd_create()?,
|
||||
"decrypt" => cmd_create()?,
|
||||
"encrypt" => cmd_create()?,
|
||||
"info" => cmd_info()?,
|
||||
_ => {
|
||||
eprintln!("Unknown command");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue