opgpcard: Add optional user-id parameter for "pubkey" and "admin generate", to bind User IDs to the certificate.
This commit is contained in:
parent
8e6f03a2c5
commit
96e28b1b4f
4 changed files with 53 additions and 12 deletions
|
@ -276,6 +276,7 @@ pub fn test_keygen(
|
||||||
Some(b"123456"),
|
Some(b"123456"),
|
||||||
&|| {},
|
&|| {},
|
||||||
&|| {},
|
&|| {},
|
||||||
|
&[],
|
||||||
)?;
|
)?;
|
||||||
let armored = String::from_utf8(cert.armored().to_vec()?)?;
|
let armored = String::from_utf8(cert.armored().to_vec()?)?;
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ use crate::PublicKey;
|
||||||
/// `prompt` notifies the user when a pinpad needs the user pin as input.
|
/// `prompt` notifies the user when a pinpad needs the user pin as input.
|
||||||
///
|
///
|
||||||
/// FIXME: accept optional metadata for user_id(s)?
|
/// FIXME: accept optional metadata for user_id(s)?
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn make_cert<'app>(
|
pub fn make_cert<'app>(
|
||||||
open: &mut Open<'app>,
|
open: &mut Open<'app>,
|
||||||
key_sig: PublicKey,
|
key_sig: PublicKey,
|
||||||
|
@ -53,6 +54,7 @@ pub fn make_cert<'app>(
|
||||||
pw1: Option<&[u8]>,
|
pw1: Option<&[u8]>,
|
||||||
pinpad_prompt: &dyn Fn(),
|
pinpad_prompt: &dyn Fn(),
|
||||||
touch_prompt: &(dyn Fn() + Send + Sync),
|
touch_prompt: &(dyn Fn() + Send + Sync),
|
||||||
|
user_ids: &[String],
|
||||||
) -> Result<Cert> {
|
) -> Result<Cert> {
|
||||||
let mut pp = vec![];
|
let mut pp = vec![];
|
||||||
|
|
||||||
|
@ -137,8 +139,12 @@ pub fn make_cert<'app>(
|
||||||
|
|
||||||
// FIXME: accept user id/email as argument?!
|
// FIXME: accept user id/email as argument?!
|
||||||
|
|
||||||
if let Some(name) = cardholder.name() {
|
for uid in user_ids
|
||||||
let uid: UserID = name.into();
|
.iter()
|
||||||
|
.map(|uid| uid.as_bytes())
|
||||||
|
.chain(cardholder.name())
|
||||||
|
{
|
||||||
|
let uid: UserID = uid.into();
|
||||||
|
|
||||||
pp.push(uid.clone().into());
|
pp.push(uid.clone().into());
|
||||||
|
|
||||||
|
@ -161,7 +167,7 @@ pub fn make_cert<'app>(
|
||||||
|
|
||||||
if let Some(mut sign) = open.signing_card() {
|
if let Some(mut sign) = open.signing_card() {
|
||||||
// Card-backed signer for bindings
|
// Card-backed signer for bindings
|
||||||
let mut card_signer = sign.signer_from_public(key_sig, touch_prompt);
|
let mut card_signer = sign.signer_from_public(key_sig.clone(), touch_prompt);
|
||||||
|
|
||||||
// Temporary version of the cert
|
// Temporary version of the cert
|
||||||
let cert = Cert::try_from(pp.clone())?;
|
let cert = Cert::try_from(pp.clone())?;
|
||||||
|
|
|
@ -54,6 +54,10 @@ pub enum Command {
|
||||||
|
|
||||||
#[clap(name = "User PIN file", short = 'p', long = "user-pin")]
|
#[clap(name = "User PIN file", short = 'p', long = "user-pin")]
|
||||||
user_pin: Option<PathBuf>,
|
user_pin: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// User ID to add to the exported certificate representation
|
||||||
|
#[clap(name = "User ID", short = 'u', long = "user-id")]
|
||||||
|
user_id: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Administer data on a card (including keys and metadata)
|
/// Administer data on a card (including keys and metadata)
|
||||||
|
@ -175,6 +179,10 @@ pub enum AdminCommand {
|
||||||
/// Algorithm (rsa2048|rsa3072|rsa4096|nistp256|nistp384|nistp521|25519)
|
/// Algorithm (rsa2048|rsa3072|rsa4096|nistp256|nistp384|nistp521|25519)
|
||||||
#[clap()]
|
#[clap()]
|
||||||
algo: Option<String>,
|
algo: Option<String>,
|
||||||
|
|
||||||
|
/// User ID to add to the exported certificate representation
|
||||||
|
#[clap(name = "User ID", short = 'u', long = "user-id")]
|
||||||
|
user_id: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Set touch policy
|
/// Set touch policy
|
||||||
|
|
|
@ -56,8 +56,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
cli::Command::Ssh { ident } => {
|
cli::Command::Ssh { ident } => {
|
||||||
print_ssh(ident)?;
|
print_ssh(ident)?;
|
||||||
}
|
}
|
||||||
cli::Command::Pubkey { ident, user_pin } => {
|
cli::Command::Pubkey {
|
||||||
print_pubkey(ident, user_pin)?;
|
ident,
|
||||||
|
user_pin,
|
||||||
|
user_id,
|
||||||
|
} => {
|
||||||
|
print_pubkey(ident, user_pin, user_id)?;
|
||||||
}
|
}
|
||||||
cli::Command::SetIdentity { ident, id } => {
|
cli::Command::SetIdentity { ident, id } => {
|
||||||
set_identity(&ident, id)?;
|
set_identity(&ident, id)?;
|
||||||
|
@ -300,6 +304,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
no_decrypt,
|
no_decrypt,
|
||||||
no_auth,
|
no_auth,
|
||||||
algo,
|
algo,
|
||||||
|
user_id,
|
||||||
} => {
|
} => {
|
||||||
let user_pin = util::get_pin(&mut open, user_pin, ENTER_USER_PIN);
|
let user_pin = util::get_pin(&mut open, user_pin, ENTER_USER_PIN);
|
||||||
|
|
||||||
|
@ -311,6 +316,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
!no_decrypt,
|
!no_decrypt,
|
||||||
!no_auth,
|
!no_auth,
|
||||||
algo,
|
algo,
|
||||||
|
user_id,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
cli::AdminCommand::Touch { key, policy } => {
|
cli::AdminCommand::Touch { key, policy } => {
|
||||||
|
@ -902,7 +908,11 @@ fn print_ssh(ident: Option<String>) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_pubkey(ident: Option<String>, user_pin: Option<PathBuf>) -> Result<()> {
|
fn print_pubkey(
|
||||||
|
ident: Option<String>,
|
||||||
|
user_pin: Option<PathBuf>,
|
||||||
|
user_ids: Vec<String>,
|
||||||
|
) -> Result<()> {
|
||||||
let mut card = pick_card_for_reading(ident)?;
|
let mut card = pick_card_for_reading(ident)?;
|
||||||
|
|
||||||
let mut pgp = OpenPgp::new(&mut *card);
|
let mut pgp = OpenPgp::new(&mut *card);
|
||||||
|
@ -956,6 +966,7 @@ fn print_pubkey(ident: Option<String>, user_pin: Option<PathBuf>) -> Result<()>
|
||||||
key_dec,
|
key_dec,
|
||||||
key_aut,
|
key_aut,
|
||||||
user_pin.as_deref(),
|
user_pin.as_deref(),
|
||||||
|
&user_ids,
|
||||||
&|| println!("Enter User PIN on card reader pinpad."),
|
&|| println!("Enter User PIN on card reader pinpad."),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1061,6 +1072,7 @@ fn get_cert(
|
||||||
key_dec: Option<PublicKey>,
|
key_dec: Option<PublicKey>,
|
||||||
key_aut: Option<PublicKey>,
|
key_aut: Option<PublicKey>,
|
||||||
user_pin: Option<&[u8]>,
|
user_pin: Option<&[u8]>,
|
||||||
|
user_ids: &[String],
|
||||||
prompt: &dyn Fn(),
|
prompt: &dyn Fn(),
|
||||||
) -> Result<Cert> {
|
) -> Result<Cert> {
|
||||||
if user_pin.is_none() && open.feature_pinpad_verify() {
|
if user_pin.is_none() && open.feature_pinpad_verify() {
|
||||||
|
@ -1070,9 +1082,16 @@ fn get_cert(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
make_cert(open, key_sig, key_dec, key_aut, user_pin, prompt, &|| {
|
make_cert(
|
||||||
println!("Touch confirmation needed for signing")
|
open,
|
||||||
})
|
key_sig,
|
||||||
|
key_dec,
|
||||||
|
key_aut,
|
||||||
|
user_pin,
|
||||||
|
prompt,
|
||||||
|
&|| println!("Touch confirmation needed for signing"),
|
||||||
|
&user_ids,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_keys(
|
fn generate_keys(
|
||||||
|
@ -1083,6 +1102,7 @@ fn generate_keys(
|
||||||
decrypt: bool,
|
decrypt: bool,
|
||||||
auth: bool,
|
auth: bool,
|
||||||
algo: Option<String>,
|
algo: Option<String>,
|
||||||
|
user_ids: Vec<String>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// 1) Interpret the user's choice of algorithm.
|
// 1) Interpret the user's choice of algorithm.
|
||||||
//
|
//
|
||||||
|
@ -1124,9 +1144,15 @@ fn generate_keys(
|
||||||
// 3) Generate a Cert from the generated keys. For this, we
|
// 3) Generate a Cert from the generated keys. For this, we
|
||||||
// need "signing" access to the card (to make binding signatures within
|
// need "signing" access to the card (to make binding signatures within
|
||||||
// the Cert).
|
// the Cert).
|
||||||
let cert = get_cert(&mut open, key_sig, key_dec, key_aut, user_pin, &|| {
|
let cert = get_cert(
|
||||||
println!("Enter User PIN on card reader pinpad.")
|
&mut open,
|
||||||
})?;
|
key_sig,
|
||||||
|
key_dec,
|
||||||
|
key_aut,
|
||||||
|
user_pin,
|
||||||
|
&user_ids,
|
||||||
|
&|| println!("Enter User PIN on card reader pinpad."),
|
||||||
|
)?;
|
||||||
|
|
||||||
let armored = String::from_utf8(cert.armored().to_vec()?)?;
|
let armored = String::from_utf8(cert.armored().to_vec()?)?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue