Initial parts of key generation.

This commit is contained in:
Heiko Schaefer 2021-11-02 21:33:16 +01:00
parent 8674b0e65c
commit 02401d12f4
3 changed files with 122 additions and 1 deletions

View file

@ -121,7 +121,10 @@ pub fn make_cert<'a, 'app>(
// 6) add user id from name / email // 6) add user id from name / email
let cardholder = open.cardholder_related_data()?; 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 = let uid: UserID =
cardholder.name().expect("expecting name on card").into(); cardholder.name().expect("expecting name on card").into();

View file

@ -116,4 +116,19 @@ pub enum AdminCommand {
)] )]
auth_fp: Option<String>, 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>,
},
} }

View file

@ -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(()) 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(())
}