opgpcard: use new Card<State> interface
This commit is contained in:
parent
da65260736
commit
538fc645c5
13 changed files with 180 additions and 182 deletions
|
@ -5,7 +5,7 @@
|
|||
|
||||
use anyhow::{anyhow, Result};
|
||||
use clap::{Parser, ValueEnum};
|
||||
use openpgp_card_sequoia::card::{Admin, Open};
|
||||
use openpgp_card_sequoia::card::{Admin, Open, Transaction};
|
||||
use openpgp_card_sequoia::util::public_key_material_to_key;
|
||||
use sequoia_openpgp::types::{HashAlgorithm, SymmetricAlgorithm};
|
||||
|
||||
|
@ -114,7 +114,7 @@ pub enum BasePlusAttKeySlot {
|
|||
Att,
|
||||
}
|
||||
|
||||
impl From<BasePlusAttKeySlot> for openpgp_card_sequoia::types::KeyType {
|
||||
impl From<BasePlusAttKeySlot> for KeyType {
|
||||
fn from(ks: BasePlusAttKeySlot) -> Self {
|
||||
match ks {
|
||||
BasePlusAttKeySlot::Sig => KeyType::Signing,
|
||||
|
@ -164,7 +164,7 @@ pub enum Algo {
|
|||
Curve25519,
|
||||
}
|
||||
|
||||
impl From<Algo> for openpgp_card_sequoia::types::AlgoSimple {
|
||||
impl From<Algo> for AlgoSimple {
|
||||
fn from(a: Algo) -> Self {
|
||||
match a {
|
||||
Algo::Rsa2048 => AlgoSimple::RSA2k,
|
||||
|
@ -184,17 +184,17 @@ pub fn admin(
|
|||
command: AdminCommand,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let backend = util::open_card(&command.ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
let admin_pin = util::get_pin(&mut open, command.admin_pin, ENTER_ADMIN_PIN);
|
||||
let admin_pin = util::get_pin(&mut card, command.admin_pin, ENTER_ADMIN_PIN);
|
||||
|
||||
match command.cmd {
|
||||
AdminSubCommand::Name { name } => {
|
||||
name_command(&name, open, admin_pin.as_deref())?;
|
||||
name_command(&name, card, admin_pin.as_deref())?;
|
||||
}
|
||||
AdminSubCommand::Url { url } => {
|
||||
url_command(&url, open, admin_pin.as_deref())?;
|
||||
url_command(&url, card, admin_pin.as_deref())?;
|
||||
}
|
||||
AdminSubCommand::Import {
|
||||
keyfile,
|
||||
|
@ -202,19 +202,19 @@ pub fn admin(
|
|||
dec_fp,
|
||||
auth_fp,
|
||||
} => {
|
||||
import_command(keyfile, sig_fp, dec_fp, auth_fp, open, admin_pin.as_deref())?;
|
||||
import_command(keyfile, sig_fp, dec_fp, auth_fp, card, admin_pin.as_deref())?;
|
||||
}
|
||||
AdminSubCommand::Generate(cmd) => {
|
||||
generate_command(
|
||||
output_format,
|
||||
output_version,
|
||||
open,
|
||||
card,
|
||||
admin_pin.as_deref(),
|
||||
cmd,
|
||||
)?;
|
||||
}
|
||||
AdminSubCommand::Touch { key, policy } => {
|
||||
touch_command(open, admin_pin.as_deref(), key, policy)?;
|
||||
touch_command(card, admin_pin.as_deref(), key, policy)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -249,7 +249,7 @@ fn keys_pick_explicit<'a>(
|
|||
}
|
||||
|
||||
fn gen_subkeys(
|
||||
admin: &mut Admin,
|
||||
admin: &mut Card<Admin>,
|
||||
decrypt: bool,
|
||||
auth: bool,
|
||||
algo: Option<AlgoSimple>,
|
||||
|
@ -297,10 +297,10 @@ fn gen_subkeys(
|
|||
|
||||
fn name_command(
|
||||
name: &str,
|
||||
mut open: Open,
|
||||
mut card: Card<Transaction>,
|
||||
admin_pin: Option<&[u8]>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut admin = util::verify_to_admin(&mut open, admin_pin)?;
|
||||
let mut admin = util::verify_to_admin(&mut card, admin_pin)?;
|
||||
|
||||
admin.set_name(name)?;
|
||||
Ok(())
|
||||
|
@ -308,10 +308,10 @@ fn name_command(
|
|||
|
||||
fn url_command(
|
||||
url: &str,
|
||||
mut open: Open,
|
||||
mut card: Card<Transaction>,
|
||||
admin_pin: Option<&[u8]>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut admin = util::verify_to_admin(&mut open, admin_pin)?;
|
||||
let mut admin = util::verify_to_admin(&mut card, admin_pin)?;
|
||||
|
||||
admin.set_url(url)?;
|
||||
Ok(())
|
||||
|
@ -322,7 +322,7 @@ fn import_command(
|
|||
sig_fp: Option<String>,
|
||||
dec_fp: Option<String>,
|
||||
auth_fp: Option<String>,
|
||||
mut open: Open,
|
||||
mut card: Card<Transaction>,
|
||||
admin_pin: Option<&[u8]>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let key = Cert::from_file(keyfile)?;
|
||||
|
@ -410,7 +410,7 @@ fn import_command(
|
|||
let auth_p = get_pw_for_key(&auth, "authentication")?;
|
||||
|
||||
// upload keys to card
|
||||
let mut admin = util::verify_to_admin(&mut open, admin_pin)?;
|
||||
let mut admin = util::verify_to_admin(&mut card, admin_pin)?;
|
||||
|
||||
if let Some(sig) = sig {
|
||||
println!("Uploading {} as signing key", sig.fingerprint());
|
||||
|
@ -430,16 +430,16 @@ fn import_command(
|
|||
fn generate_command(
|
||||
output_format: OutputFormat,
|
||||
output_version: OutputVersion,
|
||||
mut open: Open,
|
||||
mut card: Card<Transaction>,
|
||||
|
||||
admin_pin: Option<&[u8]>,
|
||||
|
||||
cmd: AdminGenerateCommand,
|
||||
) -> Result<()> {
|
||||
let user_pin = util::get_pin(&mut open, cmd.user_pin, ENTER_USER_PIN);
|
||||
let user_pin = util::get_pin(&mut card, cmd.user_pin, ENTER_USER_PIN);
|
||||
|
||||
let mut output = output::AdminGenerate::default();
|
||||
output.ident(open.application_identifier()?.ident());
|
||||
output.ident(card.application_identifier()?.ident());
|
||||
|
||||
// 1) Interpret the user's choice of algorithm.
|
||||
//
|
||||
|
@ -461,7 +461,7 @@ fn generate_command(
|
|||
// 2) Then, generate keys on the card.
|
||||
// We need "admin" access to the card for this).
|
||||
let (key_sig, key_dec, key_aut) = {
|
||||
if let Ok(mut admin) = util::verify_to_admin(&mut open, admin_pin) {
|
||||
if let Ok(mut admin) = util::verify_to_admin(&mut card, admin_pin) {
|
||||
gen_subkeys(&mut admin, cmd.decrypt, cmd.auth, algo)?
|
||||
} else {
|
||||
return Err(anyhow!("Failed to open card in admin mode."));
|
||||
|
@ -472,7 +472,7 @@ fn generate_command(
|
|||
// need "signing" access to the card (to make binding signatures within
|
||||
// the Cert).
|
||||
let cert = crate::get_cert(
|
||||
&mut open,
|
||||
&mut card,
|
||||
key_sig,
|
||||
key_dec,
|
||||
key_aut,
|
||||
|
@ -493,7 +493,7 @@ fn generate_command(
|
|||
}
|
||||
|
||||
fn touch_command(
|
||||
mut open: Open,
|
||||
mut card: Card<Transaction>,
|
||||
admin_pin: Option<&[u8]>,
|
||||
key: BasePlusAttKeySlot,
|
||||
policy: TouchPolicy,
|
||||
|
@ -502,7 +502,7 @@ fn touch_command(
|
|||
|
||||
let pol = openpgp_card_sequoia::types::TouchPolicy::from(policy);
|
||||
|
||||
let mut admin = util::verify_to_admin(&mut open, admin_pin)?;
|
||||
let mut admin = util::verify_to_admin(&mut card, admin_pin)?;
|
||||
|
||||
admin.set_uif(kt, pol)?;
|
||||
Ok(())
|
||||
|
|
|
@ -7,8 +7,8 @@ use std::path::PathBuf;
|
|||
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, ValueEnum};
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
|
||||
use openpgp_card_sequoia::card::Card;
|
||||
use openpgp_card_sequoia::types::KeyType;
|
||||
|
||||
use crate::versioned_output::{OutputBuilder, OutputFormat, OutputVersion};
|
||||
|
@ -60,7 +60,7 @@ pub enum BaseKeySlot {
|
|||
Aut,
|
||||
}
|
||||
|
||||
impl From<BaseKeySlot> for openpgp_card_sequoia::types::KeyType {
|
||||
impl From<BaseKeySlot> for KeyType {
|
||||
fn from(ks: BaseKeySlot) -> Self {
|
||||
match ks {
|
||||
BaseKeySlot::Sig => KeyType::Signing,
|
||||
|
@ -94,12 +94,12 @@ fn cert(
|
|||
let mut output = output::AttestationCert::default();
|
||||
|
||||
let backend = pick_card_for_reading(ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
output.ident(open.application_identifier()?.ident());
|
||||
output.ident(card.application_identifier()?.ident());
|
||||
|
||||
if let Ok(ac) = open.attestation_certificate() {
|
||||
if let Ok(ac) = card.attestation_certificate() {
|
||||
let pem = util::pem_encode(ac);
|
||||
output.attestation_cert(pem);
|
||||
}
|
||||
|
@ -114,12 +114,12 @@ fn generate(
|
|||
user_pin: Option<PathBuf>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let backend = util::open_card(ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
let user_pin = util::get_pin(&mut open, user_pin, ENTER_USER_PIN);
|
||||
let user_pin = util::get_pin(&mut card, user_pin, ENTER_USER_PIN);
|
||||
|
||||
let mut sign = util::verify_to_sign(&mut open, user_pin.as_deref())?;
|
||||
let mut sign = util::verify_to_sign(&mut card, user_pin.as_deref())?;
|
||||
|
||||
let kt = KeyType::from(key);
|
||||
sign.generate_attestation(kt, &|| {
|
||||
|
@ -130,15 +130,15 @@ fn generate(
|
|||
|
||||
fn statement(ident: Option<String>, key: BaseKeySlot) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let backend = pick_card_for_reading(ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
// Get cardholder certificate from card.
|
||||
|
||||
let mut select_data_workaround = false;
|
||||
// Use "select data" workaround if the card reports a
|
||||
// yk firmware version number >= 5 and <= 5.4.3
|
||||
if let Ok(version) = open.firmware_version() {
|
||||
if let Ok(version) = card.firmware_version() {
|
||||
if version.len() == 3
|
||||
&& version[0] == 5
|
||||
&& (version[1] < 4 || (version[1] == 4 && version[2] <= 3))
|
||||
|
@ -149,13 +149,13 @@ fn statement(ident: Option<String>, key: BaseKeySlot) -> Result<(), Box<dyn std:
|
|||
|
||||
// Select cardholder certificate
|
||||
match key {
|
||||
BaseKeySlot::Aut => open.select_data(0, &[0x7F, 0x21], select_data_workaround)?,
|
||||
BaseKeySlot::Dec => open.select_data(1, &[0x7F, 0x21], select_data_workaround)?,
|
||||
BaseKeySlot::Sig => open.select_data(2, &[0x7F, 0x21], select_data_workaround)?,
|
||||
BaseKeySlot::Aut => card.select_data(0, &[0x7F, 0x21], select_data_workaround)?,
|
||||
BaseKeySlot::Dec => card.select_data(1, &[0x7F, 0x21], select_data_workaround)?,
|
||||
BaseKeySlot::Sig => card.select_data(2, &[0x7F, 0x21], select_data_workaround)?,
|
||||
};
|
||||
|
||||
// Get DO "cardholder certificate" (returns the slot that was previously selected)
|
||||
let cert = open.cardholder_certificate()?;
|
||||
let cert = card.cardholder_certificate()?;
|
||||
|
||||
if !cert.is_empty() {
|
||||
let pem = util::pem_encode(cert);
|
||||
|
|
|
@ -7,13 +7,12 @@ use clap::Parser;
|
|||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
use sequoia_openpgp::{
|
||||
parse::{stream::DecryptorBuilder, Parse},
|
||||
policy::StandardPolicy,
|
||||
};
|
||||
|
||||
use openpgp_card_sequoia::card::Card;
|
||||
|
||||
use crate::util;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
|
@ -35,16 +34,16 @@ pub fn decrypt(command: DecryptCommand) -> Result<(), Box<dyn std::error::Error>
|
|||
let input = util::open_or_stdin(command.input.as_deref())?;
|
||||
|
||||
let backend = util::open_card(&command.ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
if open.fingerprints()?.decryption().is_none() {
|
||||
if card.fingerprints()?.decryption().is_none() {
|
||||
return Err(anyhow!("Can't decrypt: this card has no key in the decryption slot.").into());
|
||||
}
|
||||
|
||||
let user_pin = util::get_pin(&mut open, command.pin_file, crate::ENTER_USER_PIN);
|
||||
let user_pin = util::get_pin(&mut card, command.pin_file, crate::ENTER_USER_PIN);
|
||||
|
||||
let mut user = util::verify_to_user(&mut open, user_pin.as_deref())?;
|
||||
let mut user = util::verify_to_user(&mut card, user_pin.as_deref())?;
|
||||
let d = user.decryptor(&|| println!("Touch confirmation needed for decryption"))?;
|
||||
|
||||
let db = DecryptorBuilder::from_reader(input)?;
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
|
||||
use anyhow::{anyhow, Result};
|
||||
use clap::Parser;
|
||||
|
||||
use openpgp_card_sequoia::card::Card;
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
|
||||
use crate::util;
|
||||
|
||||
|
@ -17,9 +16,9 @@ pub struct FactoryResetCommand {
|
|||
|
||||
pub fn factory_reset(command: FactoryResetCommand) -> Result<()> {
|
||||
println!("Resetting Card {}", command.ident);
|
||||
let card = util::open_card(&command.ident)?;
|
||||
let mut card = Card::new(card);
|
||||
let backend = util::open_card(&command.ident)?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
|
||||
let mut open = card.transaction()?;
|
||||
open.factory_reset().map_err(|e| anyhow!(e))
|
||||
let mut card = open.transaction()?;
|
||||
card.factory_reset().map_err(|e| anyhow!(e))
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
|
||||
use openpgp_card_sequoia::card::Card;
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
|
||||
use crate::output;
|
||||
use crate::pick_card_for_reading;
|
||||
|
@ -27,10 +26,10 @@ pub fn print_info(
|
|||
let mut output = output::Info::default();
|
||||
|
||||
let backend = pick_card_for_reading(command.ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
let ai = open.application_identifier()?;
|
||||
let ai = card.application_identifier()?;
|
||||
|
||||
output.ident(ai.ident());
|
||||
|
||||
|
@ -41,34 +40,34 @@ pub fn print_info(
|
|||
output.manufacturer_id(format!("{:04X}", ai.manufacturer()));
|
||||
output.manufacturer_name(ai.manufacturer_name().to_string());
|
||||
|
||||
if let Some(cc) = open.historical_bytes()?.card_capabilities() {
|
||||
if let Some(cc) = card.historical_bytes()?.card_capabilities() {
|
||||
for line in cc.to_string().lines() {
|
||||
let line = line.strip_prefix("- ").unwrap_or(line);
|
||||
output.card_capability(line.to_string());
|
||||
}
|
||||
}
|
||||
if let Some(csd) = open.historical_bytes()?.card_service_data() {
|
||||
if let Some(csd) = card.historical_bytes()?.card_service_data() {
|
||||
for line in csd.to_string().lines() {
|
||||
let line = line.strip_prefix("- ").unwrap_or(line);
|
||||
output.card_service_data(line.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(eli) = open.extended_length_information()? {
|
||||
if let Some(eli) = card.extended_length_information()? {
|
||||
for line in eli.to_string().lines() {
|
||||
let line = line.strip_prefix("- ").unwrap_or(line);
|
||||
output.extended_length_info(line.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let ec = open.extended_capabilities()?;
|
||||
let ec = card.extended_capabilities()?;
|
||||
for line in ec.to_string().lines() {
|
||||
let line = line.strip_prefix("- ").unwrap_or(line);
|
||||
output.extended_capability(line.to_string());
|
||||
}
|
||||
|
||||
// Algorithm information (list of supported algorithms)
|
||||
if let Ok(Some(ai)) = open.algorithm_information() {
|
||||
if let Ok(Some(ai)) = card.algorithm_information() {
|
||||
for line in ai.to_string().lines() {
|
||||
let line = line.strip_prefix("- ").unwrap_or(line);
|
||||
output.algorithm(line.to_string());
|
||||
|
@ -78,7 +77,7 @@ pub fn print_info(
|
|||
// FIXME: print KDF info
|
||||
|
||||
// YubiKey specific (?) firmware version
|
||||
if let Ok(ver) = open.firmware_version() {
|
||||
if let Ok(ver) = card.firmware_version() {
|
||||
let ver = ver.iter().map(u8::to_string).collect::<Vec<_>>().join(".");
|
||||
output.firmware_version(ver);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::path::PathBuf;
|
|||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
use openpgp_card_sequoia::card::{Card, Open, Transaction};
|
||||
|
||||
use crate::util;
|
||||
use crate::util::{load_pin, print_gnuk_note};
|
||||
|
@ -72,51 +72,51 @@ pub enum PinSubCommand {
|
|||
|
||||
pub fn pin(ident: &str, cmd: PinSubCommand) -> Result<()> {
|
||||
let backend = util::open_card(ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let card = open.transaction()?;
|
||||
|
||||
match cmd {
|
||||
PinSubCommand::SetUser {
|
||||
user_pin_old,
|
||||
user_pin_new,
|
||||
} => set_user(user_pin_old, user_pin_new, open),
|
||||
} => set_user(user_pin_old, user_pin_new, card),
|
||||
|
||||
PinSubCommand::SetAdmin {
|
||||
admin_pin_old,
|
||||
admin_pin_new,
|
||||
} => set_admin(admin_pin_old, admin_pin_new, open),
|
||||
} => set_admin(admin_pin_old, admin_pin_new, card),
|
||||
|
||||
PinSubCommand::ResetUser {
|
||||
admin_pin,
|
||||
user_pin_new,
|
||||
} => reset_user(admin_pin, user_pin_new, open),
|
||||
} => reset_user(admin_pin, user_pin_new, card),
|
||||
|
||||
PinSubCommand::SetReset {
|
||||
admin_pin,
|
||||
reset_code,
|
||||
} => set_reset(admin_pin, reset_code, open),
|
||||
} => set_reset(admin_pin, reset_code, card),
|
||||
|
||||
PinSubCommand::ResetUserRc {
|
||||
reset_code,
|
||||
user_pin_new,
|
||||
} => reset_user_rc(reset_code, user_pin_new, open),
|
||||
} => reset_user_rc(reset_code, user_pin_new, card),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_user(
|
||||
user_pin_old: Option<PathBuf>,
|
||||
user_pin_new: Option<PathBuf>,
|
||||
mut open: Open,
|
||||
mut card: Card<Transaction>,
|
||||
) -> Result<()> {
|
||||
let pinpad_modify = open.feature_pinpad_modify();
|
||||
let pinpad_modify = card.feature_pinpad_modify();
|
||||
|
||||
let res = if !pinpad_modify {
|
||||
// get current user pin
|
||||
let user_pin1 = util::get_pin(&mut open, user_pin_old, ENTER_USER_PIN)
|
||||
let user_pin1 = util::get_pin(&mut card, user_pin_old, ENTER_USER_PIN)
|
||||
.expect("this should never be None");
|
||||
|
||||
// verify pin
|
||||
open.verify_user(&user_pin1)?;
|
||||
card.verify_user(&user_pin1)?;
|
||||
println!("PIN was accepted by the card.\n");
|
||||
|
||||
let pin_new = match user_pin_new {
|
||||
|
@ -128,10 +128,10 @@ fn set_user(
|
|||
};
|
||||
|
||||
// set new user pin
|
||||
open.change_user_pin(&user_pin1, &pin_new)
|
||||
card.change_user_pin(&user_pin1, &pin_new)
|
||||
} else {
|
||||
// set new user pin via pinpad
|
||||
open.change_user_pin_pinpad(&|| {
|
||||
card.change_user_pin_pinpad(&|| {
|
||||
println!("Enter old User PIN on card reader pinpad, then new User PIN (twice).")
|
||||
})
|
||||
};
|
||||
|
@ -140,7 +140,7 @@ fn set_user(
|
|||
Err(err) => {
|
||||
println!("\nFailed to change the User PIN!");
|
||||
println!("{:?}", err);
|
||||
print_gnuk_note(err, &open)?;
|
||||
print_gnuk_note(err, &card)?;
|
||||
}
|
||||
Ok(_) => println!("\nUser PIN has been set."),
|
||||
}
|
||||
|
@ -150,17 +150,17 @@ fn set_user(
|
|||
fn set_admin(
|
||||
admin_pin_old: Option<PathBuf>,
|
||||
admin_pin_new: Option<PathBuf>,
|
||||
mut open: Open,
|
||||
mut card: Card<Transaction>,
|
||||
) -> Result<()> {
|
||||
let pinpad_modify = open.feature_pinpad_modify();
|
||||
let pinpad_modify = card.feature_pinpad_modify();
|
||||
|
||||
if !pinpad_modify {
|
||||
// get current admin pin
|
||||
let admin_pin1 = util::get_pin(&mut open, admin_pin_old, ENTER_ADMIN_PIN)
|
||||
let admin_pin1 = util::get_pin(&mut card, admin_pin_old, ENTER_ADMIN_PIN)
|
||||
.expect("this should never be None");
|
||||
|
||||
// verify pin
|
||||
open.verify_admin(&admin_pin1)?;
|
||||
card.verify_admin(&admin_pin1)?;
|
||||
// (Verifying the PIN here fixes this class of problems:
|
||||
// https://developers.yubico.com/PGP/PGP_PIN_Change_Behavior.html
|
||||
// It is also just generally more user friendly than failing later)
|
||||
|
@ -175,10 +175,10 @@ fn set_admin(
|
|||
};
|
||||
|
||||
// set new admin pin
|
||||
open.change_admin_pin(&admin_pin1, &pin_new)?;
|
||||
card.change_admin_pin(&admin_pin1, &pin_new)?;
|
||||
} else {
|
||||
// set new admin pin via pinpad
|
||||
open.change_admin_pin_pinpad(&|| {
|
||||
card.change_admin_pin_pinpad(&|| {
|
||||
println!("Enter old Admin PIN on card reader pinpad, then new Admin PIN (twice).")
|
||||
})?;
|
||||
};
|
||||
|
@ -190,16 +190,16 @@ fn set_admin(
|
|||
fn reset_user(
|
||||
admin_pin: Option<PathBuf>,
|
||||
user_pin_new: Option<PathBuf>,
|
||||
mut open: Open,
|
||||
mut card: Card<Transaction>,
|
||||
) -> Result<()> {
|
||||
// verify admin pin
|
||||
match util::get_pin(&mut open, admin_pin, ENTER_ADMIN_PIN) {
|
||||
match util::get_pin(&mut card, admin_pin, ENTER_ADMIN_PIN) {
|
||||
Some(admin_pin) => {
|
||||
// verify pin
|
||||
open.verify_admin(&admin_pin)?;
|
||||
card.verify_admin(&admin_pin)?;
|
||||
}
|
||||
None => {
|
||||
open.verify_admin_pinpad(&|| println!("Enter Admin PIN on pinpad."))?;
|
||||
card.verify_admin_pinpad(&|| println!("Enter Admin PIN on pinpad."))?;
|
||||
}
|
||||
}
|
||||
println!("PIN was accepted by the card.\n");
|
||||
|
@ -210,7 +210,7 @@ fn reset_user(
|
|||
Some(path) => load_pin(&path)?,
|
||||
};
|
||||
|
||||
let res = if let Some(mut admin) = open.admin_card() {
|
||||
let res = if let Some(mut admin) = card.admin_card() {
|
||||
admin.reset_user_pin(&pin)
|
||||
} else {
|
||||
return Err(anyhow::anyhow!("Failed to use card in admin-mode."));
|
||||
|
@ -219,7 +219,7 @@ fn reset_user(
|
|||
match res {
|
||||
Err(err) => {
|
||||
println!("\nFailed to change the User PIN!");
|
||||
print_gnuk_note(err, &open)?;
|
||||
print_gnuk_note(err, &card)?;
|
||||
}
|
||||
Ok(_) => println!("\nUser PIN has been set."),
|
||||
}
|
||||
|
@ -229,16 +229,16 @@ fn reset_user(
|
|||
fn set_reset(
|
||||
admin_pin: Option<PathBuf>,
|
||||
reset_code: Option<PathBuf>,
|
||||
mut open: Open,
|
||||
mut card: Card<Transaction>,
|
||||
) -> Result<()> {
|
||||
// verify admin pin
|
||||
match util::get_pin(&mut open, admin_pin, ENTER_ADMIN_PIN) {
|
||||
match util::get_pin(&mut card, admin_pin, ENTER_ADMIN_PIN) {
|
||||
Some(admin_pin) => {
|
||||
// verify pin
|
||||
open.verify_admin(&admin_pin)?;
|
||||
card.verify_admin(&admin_pin)?;
|
||||
}
|
||||
None => {
|
||||
open.verify_admin_pinpad(&|| println!("Enter Admin PIN on pinpad."))?;
|
||||
card.verify_admin_pinpad(&|| println!("Enter Admin PIN on pinpad."))?;
|
||||
}
|
||||
}
|
||||
println!("PIN was accepted by the card.\n");
|
||||
|
@ -252,7 +252,7 @@ fn set_reset(
|
|||
Some(path) => load_pin(&path)?,
|
||||
};
|
||||
|
||||
if let Some(mut admin) = open.admin_card() {
|
||||
if let Some(mut admin) = card.admin_card() {
|
||||
admin.set_resetting_code(&code)?;
|
||||
println!("\nResetting code has been set.");
|
||||
Ok(())
|
||||
|
@ -264,7 +264,7 @@ fn set_reset(
|
|||
fn reset_user_rc(
|
||||
reset_code: Option<PathBuf>,
|
||||
user_pin_new: Option<PathBuf>,
|
||||
mut open: Open,
|
||||
mut card: Card<Transaction>,
|
||||
) -> Result<()> {
|
||||
// reset by presenting resetting code
|
||||
|
||||
|
@ -285,10 +285,10 @@ fn reset_user_rc(
|
|||
};
|
||||
|
||||
// reset to new user pin
|
||||
match open.reset_user_pin(&rst, &pin) {
|
||||
match card.reset_user_pin(&rst, &pin) {
|
||||
Err(err) => {
|
||||
println!("\nFailed to change the User PIN!");
|
||||
print_gnuk_note(err, &open)
|
||||
print_gnuk_note(err, &card)
|
||||
}
|
||||
Ok(_) => {
|
||||
println!("\nUser PIN has been set.");
|
||||
|
|
|
@ -8,9 +8,9 @@ use clap::Parser;
|
|||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
use sequoia_openpgp::serialize::SerializeInto;
|
||||
|
||||
use openpgp_card_sequoia::card::Card;
|
||||
use openpgp_card_sequoia::types::KeyType;
|
||||
use openpgp_card_sequoia::util::public_key_material_and_fp_to_key;
|
||||
|
||||
|
@ -40,17 +40,17 @@ pub fn print_pubkey(
|
|||
let mut output = output::PublicKey::default();
|
||||
|
||||
let backend = pick_card_for_reading(command.ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
let ident = open.application_identifier()?.ident();
|
||||
let ident = card.application_identifier()?.ident();
|
||||
output.ident(ident);
|
||||
|
||||
let user_pin = util::get_pin(&mut open, command.user_pin, crate::ENTER_USER_PIN);
|
||||
let user_pin = util::get_pin(&mut card, command.user_pin, crate::ENTER_USER_PIN);
|
||||
|
||||
let pkm = open.public_key(KeyType::Signing)?;
|
||||
let times = open.key_generation_times()?;
|
||||
let fps = open.fingerprints()?;
|
||||
let pkm = card.public_key(KeyType::Signing)?;
|
||||
let times = card.key_generation_times()?;
|
||||
let fps = card.fingerprints()?;
|
||||
|
||||
let key_sig = public_key_material_and_fp_to_key(
|
||||
&pkm,
|
||||
|
@ -60,7 +60,7 @@ pub fn print_pubkey(
|
|||
)?;
|
||||
|
||||
let mut key_dec = None;
|
||||
if let Ok(pkm) = open.public_key(KeyType::Decryption) {
|
||||
if let Ok(pkm) = card.public_key(KeyType::Decryption) {
|
||||
if let Some(ts) = times.decryption() {
|
||||
key_dec = Some(public_key_material_and_fp_to_key(
|
||||
&pkm,
|
||||
|
@ -72,7 +72,7 @@ pub fn print_pubkey(
|
|||
}
|
||||
|
||||
let mut key_aut = None;
|
||||
if let Ok(pkm) = open.public_key(KeyType::Authentication) {
|
||||
if let Ok(pkm) = card.public_key(KeyType::Authentication) {
|
||||
if let Some(ts) = times.authentication() {
|
||||
key_aut = Some(public_key_material_and_fp_to_key(
|
||||
&pkm,
|
||||
|
@ -85,7 +85,7 @@ pub fn print_pubkey(
|
|||
}
|
||||
|
||||
let cert = crate::get_cert(
|
||||
&mut open,
|
||||
&mut card,
|
||||
key_sig,
|
||||
key_dec,
|
||||
key_aut,
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, ValueEnum};
|
||||
|
||||
use openpgp_card_sequoia::card::Card;
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
|
||||
use crate::util;
|
||||
|
||||
|
@ -40,9 +39,9 @@ impl From<SetIdentityId> for u8 {
|
|||
|
||||
pub fn set_identity(command: SetIdentityCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let backend = util::open_card(&command.ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
open.set_identity(u8::from(command.id))?;
|
||||
card.set_identity(u8::from(command.id))?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -7,10 +7,9 @@ use clap::Parser;
|
|||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
use sequoia_openpgp::serialize::stream::{Armorer, Message, Signer};
|
||||
|
||||
use openpgp_card_sequoia::card::Card;
|
||||
|
||||
use crate::util;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
|
@ -46,16 +45,16 @@ pub fn sign_detached(
|
|||
let mut input = util::open_or_stdin(input)?;
|
||||
|
||||
let backend = util::open_card(ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
if open.fingerprints()?.signature().is_none() {
|
||||
if card.fingerprints()?.signature().is_none() {
|
||||
return Err(anyhow!("Can't sign: this card has no key in the signing slot.").into());
|
||||
}
|
||||
|
||||
let user_pin = util::get_pin(&mut open, pin_file, crate::ENTER_USER_PIN);
|
||||
let user_pin = util::get_pin(&mut card, pin_file, crate::ENTER_USER_PIN);
|
||||
|
||||
let mut sign = util::verify_to_sign(&mut open, user_pin.as_deref())?;
|
||||
let mut sign = util::verify_to_sign(&mut card, user_pin.as_deref())?;
|
||||
let s = sign.signer(&|| println!("Touch confirmation needed for signing"))?;
|
||||
|
||||
let message = Armorer::new(Message::new(std::io::stdout())).build()?;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
|
||||
use openpgp_card_sequoia::card::Card;
|
||||
use openpgp_card_sequoia::types::KeyType;
|
||||
|
||||
use crate::output;
|
||||
|
@ -30,21 +30,21 @@ pub fn print_ssh(
|
|||
let ident = command.ident;
|
||||
|
||||
let backend = pick_card_for_reading(ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
let ident = open.application_identifier()?.ident();
|
||||
let ident = card.application_identifier()?.ident();
|
||||
output.ident(ident.clone());
|
||||
|
||||
// Print fingerprint of authentication subkey
|
||||
let fps = open.fingerprints()?;
|
||||
let fps = card.fingerprints()?;
|
||||
|
||||
if let Some(fp) = fps.authentication() {
|
||||
output.authentication_key_fingerprint(fp.to_string());
|
||||
}
|
||||
|
||||
// Show authentication subkey as openssh public key string
|
||||
if let Ok(pkm) = open.public_key(KeyType::Authentication) {
|
||||
if let Ok(pkm) = card.public_key(KeyType::Authentication) {
|
||||
if let Ok(ssh) = util::get_ssh_pubkey_string(&pkm, ident) {
|
||||
output.ssh_public_key(ssh);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
|
||||
use openpgp_card_sequoia::card::Card;
|
||||
use openpgp_card_sequoia::types::KeyType;
|
||||
|
||||
use crate::output;
|
||||
|
@ -35,17 +35,17 @@ pub fn print_status(
|
|||
output.verbose(command.verbose);
|
||||
|
||||
let backend = pick_card_for_reading(command.ident)?;
|
||||
let mut card = Card::new(backend);
|
||||
let mut open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
let mut card = open.transaction()?;
|
||||
|
||||
output.ident(open.application_identifier()?.ident());
|
||||
output.ident(card.application_identifier()?.ident());
|
||||
|
||||
let ai = open.application_identifier()?;
|
||||
let ai = card.application_identifier()?;
|
||||
let version = ai.version().to_be_bytes();
|
||||
output.card_version(format!("{}.{}", version[0], version[1]));
|
||||
|
||||
// card / cardholder metadata
|
||||
let crd = open.cardholder_related_data()?;
|
||||
let crd = card.cardholder_related_data()?;
|
||||
|
||||
if let Some(name) = crd.name() {
|
||||
// FIXME: decoding as utf8 is wrong (the spec defines this field as latin1 encoded)
|
||||
|
@ -67,7 +67,7 @@ pub fn print_status(
|
|||
output.card_holder(name);
|
||||
}
|
||||
|
||||
let url = open.url()?;
|
||||
let url = card.url()?;
|
||||
if !url.is_empty() {
|
||||
output.url(url);
|
||||
}
|
||||
|
@ -79,24 +79,24 @@ pub fn print_status(
|
|||
}
|
||||
|
||||
// key information (imported vs. generated on card)
|
||||
let ki = open.key_information().ok().flatten();
|
||||
let ki = card.key_information().ok().flatten();
|
||||
|
||||
let pws = open.pw_status_bytes()?;
|
||||
let pws = card.pw_status_bytes()?;
|
||||
|
||||
// information about subkeys
|
||||
|
||||
let fps = open.fingerprints()?;
|
||||
let kgt = open.key_generation_times()?;
|
||||
let fps = card.fingerprints()?;
|
||||
let kgt = card.key_generation_times()?;
|
||||
|
||||
let mut signature_key = output::KeySlotInfo::default();
|
||||
if let Some(fp) = fps.signature() {
|
||||
signature_key.fingerprint(fp.to_spaced_hex());
|
||||
}
|
||||
signature_key.algorithm(format!("{}", open.algorithm_attributes(KeyType::Signing)?));
|
||||
signature_key.algorithm(format!("{}", card.algorithm_attributes(KeyType::Signing)?));
|
||||
if let Some(kgt) = kgt.signature() {
|
||||
signature_key.created(format!("{}", kgt.to_datetime()));
|
||||
}
|
||||
if let Some(uif) = open.uif_signing()? {
|
||||
if let Some(uif) = card.uif_signing()? {
|
||||
signature_key.touch_policy(format!("{}", uif.touch_policy()));
|
||||
signature_key.touch_features(format!("{}", uif.features()));
|
||||
}
|
||||
|
@ -109,14 +109,14 @@ pub fn print_status(
|
|||
}
|
||||
|
||||
if command.pkm {
|
||||
if let Ok(pkm) = open.public_key(KeyType::Signing) {
|
||||
if let Ok(pkm) = card.public_key(KeyType::Signing) {
|
||||
signature_key.public_key_material(pkm.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
output.signature_key(signature_key);
|
||||
|
||||
let sst = open.security_support_template()?;
|
||||
let sst = card.security_support_template()?;
|
||||
output.signature_count(sst.signature_count());
|
||||
|
||||
let mut decryption_key = output::KeySlotInfo::default();
|
||||
|
@ -125,12 +125,12 @@ pub fn print_status(
|
|||
}
|
||||
decryption_key.algorithm(format!(
|
||||
"{}",
|
||||
open.algorithm_attributes(KeyType::Decryption)?
|
||||
card.algorithm_attributes(KeyType::Decryption)?
|
||||
));
|
||||
if let Some(kgt) = kgt.decryption() {
|
||||
decryption_key.created(format!("{}", kgt.to_datetime()));
|
||||
}
|
||||
if let Some(uif) = open.uif_decryption()? {
|
||||
if let Some(uif) = card.uif_decryption()? {
|
||||
decryption_key.touch_policy(format!("{}", uif.touch_policy()));
|
||||
decryption_key.touch_features(format!("{}", uif.features()));
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ pub fn print_status(
|
|||
decryption_key.status(format!("{}", ks));
|
||||
}
|
||||
if command.pkm {
|
||||
if let Ok(pkm) = open.public_key(KeyType::Decryption) {
|
||||
if let Ok(pkm) = card.public_key(KeyType::Decryption) {
|
||||
decryption_key.public_key_material(pkm.to_string());
|
||||
}
|
||||
}
|
||||
|
@ -150,12 +150,12 @@ pub fn print_status(
|
|||
}
|
||||
authentication_key.algorithm(format!(
|
||||
"{}",
|
||||
open.algorithm_attributes(KeyType::Authentication)?
|
||||
card.algorithm_attributes(KeyType::Authentication)?
|
||||
));
|
||||
if let Some(kgt) = kgt.authentication() {
|
||||
authentication_key.created(format!("{}", kgt.to_datetime()));
|
||||
}
|
||||
if let Some(uif) = open.uif_authentication()? {
|
||||
if let Some(uif) = card.uif_authentication()? {
|
||||
authentication_key.touch_policy(format!("{}", uif.touch_policy()));
|
||||
authentication_key.touch_features(format!("{}", uif.features()));
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ pub fn print_status(
|
|||
authentication_key.status(format!("{}", ks));
|
||||
}
|
||||
if command.pkm {
|
||||
if let Ok(pkm) = open.public_key(KeyType::Authentication) {
|
||||
if let Ok(pkm) = card.public_key(KeyType::Authentication) {
|
||||
authentication_key.public_key_material(pkm.to_string());
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ pub fn print_status(
|
|||
// own `Option<KeySlotInfo>`, and (if any information about the
|
||||
// attestation key exists at all, which is not the case for most
|
||||
// cards) it should be printed as a fourth KeySlot block.
|
||||
if let Some(uif) = open.uif_attestation()? {
|
||||
if let Some(uif) = card.uif_attestation()? {
|
||||
output.card_touch_policy(uif.touch_policy().to_string());
|
||||
output.card_touch_features(uif.features().to_string());
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ pub fn print_status(
|
|||
}
|
||||
}
|
||||
|
||||
if let Ok(fps) = open.ca_fingerprints() {
|
||||
if let Ok(fps) = card.ca_fingerprints() {
|
||||
for fp in fps.iter().flatten() {
|
||||
output.ca_fingerprint(fp.to_string());
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use clap::Parser;
|
|||
|
||||
use sequoia_openpgp::Cert;
|
||||
|
||||
use openpgp_card_sequoia::card::{Card, Open};
|
||||
use openpgp_card_sequoia::card::{Card, Open, Transaction};
|
||||
use openpgp_card_sequoia::types::CardBackend;
|
||||
use openpgp_card_sequoia::util::make_cert;
|
||||
use openpgp_card_sequoia::PublicKey;
|
||||
|
@ -90,10 +90,9 @@ fn list_cards(format: OutputFormat, output_version: OutputVersion) -> Result<()>
|
|||
let mut output = output::List::default();
|
||||
if !cards.is_empty() {
|
||||
for backend in cards {
|
||||
let mut card = Card::new(backend);
|
||||
let open = card.transaction()?;
|
||||
let mut open: Card<Open> = backend.into();
|
||||
|
||||
output.push(open.application_identifier()?.ident());
|
||||
output.push(open.transaction()?.application_identifier()?.ident());
|
||||
}
|
||||
}
|
||||
println!("{}", output.print(format, output_version)?);
|
||||
|
@ -123,7 +122,7 @@ fn pick_card_for_reading(ident: Option<String>) -> Result<Box<dyn CardBackend +
|
|||
}
|
||||
|
||||
fn get_cert(
|
||||
open: &mut Open,
|
||||
card: &mut Card<Transaction>,
|
||||
key_sig: PublicKey,
|
||||
key_dec: Option<PublicKey>,
|
||||
key_aut: Option<PublicKey>,
|
||||
|
@ -131,7 +130,7 @@ fn get_cert(
|
|||
user_ids: &[String],
|
||||
prompt: &dyn Fn(),
|
||||
) -> Result<Cert> {
|
||||
if user_pin.is_none() && open.feature_pinpad_verify() {
|
||||
if user_pin.is_none() && card.feature_pinpad_verify() {
|
||||
println!(
|
||||
"The public cert will now be generated.\n\n\
|
||||
You will need to enter your User PIN multiple times during this process.\n\n"
|
||||
|
@ -139,7 +138,7 @@ fn get_cert(
|
|||
}
|
||||
|
||||
make_cert(
|
||||
open,
|
||||
card,
|
||||
key_sig,
|
||||
key_dec,
|
||||
key_aut,
|
||||
|
|
|
@ -5,7 +5,7 @@ use anyhow::{anyhow, Context, Result};
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use openpgp_card_pcsc::PcscBackend;
|
||||
use openpgp_card_sequoia::card::{Admin, Open, Sign, User};
|
||||
use openpgp_card_sequoia::card::{Admin, Card, Sign, Transaction, User};
|
||||
use openpgp_card_sequoia::types::{
|
||||
Algo, CardBackend, Curve, EccType, Error, PublicKeyMaterial, StatusBytes,
|
||||
};
|
||||
|
@ -23,11 +23,15 @@ pub(crate) fn open_card(ident: &str) -> Result<Box<dyn CardBackend + Send + Sync
|
|||
/// If a pinpad is available, return Null (the pinpad will be used to get access to the card).
|
||||
///
|
||||
/// `msg` is the message to show when asking the user to enter a PIN.
|
||||
pub(crate) fn get_pin(open: &mut Open, pin_file: Option<PathBuf>, msg: &str) -> Option<Vec<u8>> {
|
||||
pub(crate) fn get_pin(
|
||||
card: &mut Card<Transaction<'_>>,
|
||||
pin_file: Option<PathBuf>,
|
||||
msg: &str,
|
||||
) -> Option<Vec<u8>> {
|
||||
if let Some(path) = pin_file {
|
||||
// we have a pin file
|
||||
Some(load_pin(&path).ok()?)
|
||||
} else if !open.feature_pinpad_verify() {
|
||||
} else if !card.feature_pinpad_verify() {
|
||||
// we have no pin file and no pinpad
|
||||
let pin = rpassword::prompt_password(msg).ok()?;
|
||||
Some(pin.into_bytes())
|
||||
|
@ -51,53 +55,53 @@ pub(crate) fn input_pin_twice(msg1: &str, msg2: &str) -> Result<Vec<u8>> {
|
|||
}
|
||||
|
||||
pub(crate) fn verify_to_user<'app, 'open>(
|
||||
open: &'open mut Open<'app>,
|
||||
card: &'open mut Card<Transaction<'app>>,
|
||||
pin: Option<&[u8]>,
|
||||
) -> Result<User<'app, 'open>, Box<dyn std::error::Error>> {
|
||||
) -> Result<Card<User<'app, 'open>>, Box<dyn std::error::Error>> {
|
||||
if let Some(pin) = pin {
|
||||
open.verify_user(pin)?;
|
||||
card.verify_user(pin)?;
|
||||
} else {
|
||||
if !open.feature_pinpad_verify() {
|
||||
if !card.feature_pinpad_verify() {
|
||||
return Err(anyhow!("No user PIN file provided, and no pinpad found").into());
|
||||
};
|
||||
|
||||
open.verify_user_pinpad(&|| println!("Enter user PIN on card reader pinpad."))?;
|
||||
card.verify_user_pinpad(&|| println!("Enter user PIN on card reader pinpad."))?;
|
||||
}
|
||||
|
||||
open.user_card()
|
||||
card.user_card()
|
||||
.ok_or_else(|| anyhow!("Couldn't get user access").into())
|
||||
}
|
||||
|
||||
pub(crate) fn verify_to_sign<'app, 'open>(
|
||||
open: &'open mut Open<'app>,
|
||||
card: &'open mut Card<Transaction<'app>>,
|
||||
pin: Option<&[u8]>,
|
||||
) -> Result<Sign<'app, 'open>, Box<dyn std::error::Error>> {
|
||||
) -> Result<Card<Sign<'app, 'open>>, Box<dyn std::error::Error>> {
|
||||
if let Some(pin) = pin {
|
||||
open.verify_user_for_signing(pin)?;
|
||||
card.verify_user_for_signing(pin)?;
|
||||
} else {
|
||||
if !open.feature_pinpad_verify() {
|
||||
if !card.feature_pinpad_verify() {
|
||||
return Err(anyhow!("No user PIN file provided, and no pinpad found").into());
|
||||
}
|
||||
open.verify_user_for_signing_pinpad(&|| println!("Enter user PIN on card reader pinpad."))?;
|
||||
card.verify_user_for_signing_pinpad(&|| println!("Enter user PIN on card reader pinpad."))?;
|
||||
}
|
||||
open.signing_card()
|
||||
card.signing_card()
|
||||
.ok_or_else(|| anyhow!("Couldn't get sign access").into())
|
||||
}
|
||||
|
||||
pub(crate) fn verify_to_admin<'app, 'open>(
|
||||
open: &'open mut Open<'app>,
|
||||
card: &'open mut Card<Transaction<'app>>,
|
||||
pin: Option<&[u8]>,
|
||||
) -> Result<Admin<'app, 'open>, Box<dyn std::error::Error>> {
|
||||
) -> Result<Card<Admin<'app, 'open>>, Box<dyn std::error::Error>> {
|
||||
if let Some(pin) = pin {
|
||||
open.verify_admin(pin)?;
|
||||
card.verify_admin(pin)?;
|
||||
} else {
|
||||
if !open.feature_pinpad_verify() {
|
||||
if !card.feature_pinpad_verify() {
|
||||
return Err(anyhow!("No admin PIN file provided, and no pinpad found").into());
|
||||
}
|
||||
|
||||
open.verify_admin_pinpad(&|| println!("Enter admin PIN on card reader pinpad."))?;
|
||||
card.verify_admin_pinpad(&|| println!("Enter admin PIN on card reader pinpad."))?;
|
||||
}
|
||||
open.admin_card()
|
||||
card.admin_card()
|
||||
.ok_or_else(|| anyhow!("Couldn't get admin access").into())
|
||||
}
|
||||
|
||||
|
@ -215,7 +219,7 @@ pub(crate) fn get_ssh_pubkey_string(pkm: &PublicKeyMaterial, ident: String) -> R
|
|||
/// This fn checks for Gnuk's Status code and the case that no keys exist
|
||||
/// on the card, and prints a note to the user, pointing out that the
|
||||
/// absence of keys on the card might be the reason for the error they get.
|
||||
pub(crate) fn print_gnuk_note(err: Error, card: &Open) -> Result<()> {
|
||||
pub(crate) fn print_gnuk_note(err: Error, card: &Card<Transaction>) -> Result<()> {
|
||||
if matches!(
|
||||
err,
|
||||
Error::CardStatus(StatusBytes::ConditionOfUseNotSatisfied)
|
||||
|
|
Loading…
Reference in a new issue