Initial parts of key generation.
This commit is contained in:
parent
8674b0e65c
commit
02401d12f4
3 changed files with 122 additions and 1 deletions
|
@ -121,7 +121,10 @@ pub fn make_cert<'a, 'app>(
|
|||
// 6) add user id from name / email
|
||||
let cardholder = open.cardholder_related_data()?;
|
||||
|
||||
// FIXME: process name field? accept email as argument?!
|
||||
// FIXME: process name field?
|
||||
|
||||
// FIXME: accept email as argument?!
|
||||
|
||||
let uid: UserID =
|
||||
cardholder.name().expect("expecting name on card").into();
|
||||
|
||||
|
|
|
@ -116,4 +116,19 @@ pub enum AdminCommand {
|
|||
)]
|
||||
auth_fp: Option<String>,
|
||||
},
|
||||
/// Generate a Key.
|
||||
///
|
||||
/// A signing key is always created, decryption and authentication keys
|
||||
/// are optional.
|
||||
Generate {
|
||||
#[structopt(long = "no-decrypt")]
|
||||
no_decrypt: bool,
|
||||
|
||||
#[structopt(long = "no-auth")]
|
||||
no_auth: bool,
|
||||
|
||||
#[structopt(about = "Algorithm \
|
||||
(rsa2048|rsa3072|rsa4096|nistp256|nistp384|nistp521|25519)")]
|
||||
algo: Option<String>,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -104,6 +104,23 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
)?;
|
||||
}
|
||||
}
|
||||
cli::AdminCommand::Generate {
|
||||
no_decrypt,
|
||||
no_auth,
|
||||
algo,
|
||||
} => {
|
||||
let pw3 = util::get_pin(&pin_file)?;
|
||||
// FIXME: get PW1 from user
|
||||
|
||||
generate_keys(
|
||||
open,
|
||||
&pw3,
|
||||
"123456",
|
||||
!no_decrypt,
|
||||
!no_auth,
|
||||
algo,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -394,3 +411,89 @@ fn key_import_explicit(
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_keys(
|
||||
mut open: Open,
|
||||
pw3: &str,
|
||||
pw1: &str,
|
||||
decrypt: bool,
|
||||
auth: bool,
|
||||
algo: Option<String>,
|
||||
) -> Result<()> {
|
||||
// Figure out which algorithm the user wants
|
||||
|
||||
// FIXME:
|
||||
// (rsa2048|rsa3072|rsa4096|nistp256|nistp384|nistp521|25519) or None
|
||||
// let alg = AlgoSimple::from(algo);
|
||||
|
||||
let a = algo.unwrap();
|
||||
let a: &str = &a;
|
||||
|
||||
// temporary approach:
|
||||
let alg = AlgoSimple::from(a);
|
||||
|
||||
// FIXME: if rsa, try 32 and 17 bit e
|
||||
|
||||
// FIXME: handle None (leave algo as is)
|
||||
|
||||
// ---
|
||||
|
||||
// Then, we make the card generate keys (we need "admin" access to
|
||||
// the card for that).
|
||||
|
||||
open.verify_admin(pw3)?;
|
||||
|
||||
let (key_sig, key_dec, key_aut) = {
|
||||
if let Some(mut admin) = open.admin_card() {
|
||||
println!(" Generate subkey for Signing");
|
||||
let (pkm, ts) =
|
||||
admin.generate_key_simple(KeyType::Signing, alg)?;
|
||||
let key_sig =
|
||||
public_key_material_to_key(&pkm, KeyType::Signing, ts)?;
|
||||
|
||||
let key_dec = if decrypt {
|
||||
println!(" Generate subkey for Decryption");
|
||||
let (pkm, ts) =
|
||||
admin.generate_key_simple(KeyType::Decryption, alg)?;
|
||||
Some(public_key_material_to_key(
|
||||
&pkm,
|
||||
KeyType::Decryption,
|
||||
ts,
|
||||
)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let key_aut = if auth {
|
||||
println!(" Generate subkey for Authentication");
|
||||
let (pkm, ts) =
|
||||
admin.generate_key_simple(KeyType::Authentication, alg)?;
|
||||
|
||||
Some(public_key_material_to_key(
|
||||
&pkm,
|
||||
KeyType::Authentication,
|
||||
ts,
|
||||
)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(key_sig, key_dec, key_aut)
|
||||
} else {
|
||||
// FIXME: couldn't get admin mode
|
||||
unimplemented!()
|
||||
}
|
||||
};
|
||||
|
||||
// Then we generate a Cert for this set of generated keys. For this, we
|
||||
// need "signing" access to the card, to make a number of binding
|
||||
// signatures.
|
||||
|
||||
// FIXME: get pw1 from user
|
||||
let cert = make_cert(&mut open, key_sig, key_dec, key_aut, pw1)?;
|
||||
let armored = String::from_utf8(cert.armored().to_vec()?)?;
|
||||
|
||||
println!("{}", armored);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue