Refactor "Open" to use a borrowed CardApp (instead of owning the CardApp).
This commit is contained in:
parent
8dd83b6c55
commit
8674b0e65c
11 changed files with 218 additions and 165 deletions
|
@ -9,8 +9,9 @@ use openpgp_card_sequoia::card::Open;
|
|||
fn main() -> Result<()> {
|
||||
println!("The following OpenPGP cards are connected to your system:");
|
||||
|
||||
for card in PcscClient::cards()? {
|
||||
let open = Open::open_card(card)?;
|
||||
for ccb in PcscClient::cards()? {
|
||||
let mut ca = ccb.into();
|
||||
let open = Open::open(&mut ca)?;
|
||||
println!(" {}", open.application_identifier()?.ident());
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ use openpgp_card;
|
|||
use openpgp_card::algorithm::AlgoSimple;
|
||||
use openpgp_card::card_do::{KeyGenerationTime, Sex};
|
||||
use openpgp_card::{CardApp, Error, KeyType, StatusBytes};
|
||||
use openpgp_card_sequoia::card::Open;
|
||||
use openpgp_card_sequoia::util::{
|
||||
make_cert, public_key_material_to_key, public_to_fingerprint,
|
||||
};
|
||||
|
@ -220,7 +221,7 @@ pub fn test_upload_keys(
|
|||
|
||||
/// Generate keys for each of the three KeyTypes
|
||||
pub fn test_keygen(
|
||||
ca: &mut CardApp,
|
||||
mut ca: &mut CardApp,
|
||||
param: &[&str],
|
||||
) -> Result<TestOutput, TestError> {
|
||||
ca.verify_pw3("12345678")?;
|
||||
|
@ -253,8 +254,9 @@ pub fn test_keygen(
|
|||
public_key_material_to_key(&pkm, KeyType::Authentication, ts)?;
|
||||
|
||||
// Generate a Cert for this set of generated keys
|
||||
|
||||
let cert = make_cert(ca, key_sig, key_dec, key_aut)?;
|
||||
let mut open = Open::open(&mut ca)?;
|
||||
let cert =
|
||||
make_cert(&mut open, key_sig, Some(key_dec), Some(key_aut), "123456")?;
|
||||
let armored = String::from_utf8(cert.armored().to_vec()?)?;
|
||||
|
||||
let res = TestResult::Text(armored);
|
||||
|
|
|
@ -22,7 +22,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let pin_file = &args[1];
|
||||
let cert_file = &args[2];
|
||||
|
||||
let mut open = Open::open_card(PcscClient::open_by_ident(&card_ident)?)?;
|
||||
let mut ca = PcscClient::open_by_ident(&card_ident)?.into();
|
||||
let mut open = Open::open(&mut ca)?;
|
||||
|
||||
let pin = std::fs::read_to_string(pin_file)?;
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let test_card_ident = &args[0];
|
||||
let card_ident = &args[0];
|
||||
let pin_file = &args[1];
|
||||
let cert_file = &args[2];
|
||||
|
||||
let mut open =
|
||||
Open::open_card(PcscClient::open_by_ident(&test_card_ident)?)?;
|
||||
let mut ca = PcscClient::open_by_ident(&card_ident)?.into();
|
||||
let mut open = Open::open(&mut ca)?;
|
||||
|
||||
let pin = std::fs::read_to_string(pin_file)?;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ use sequoia_openpgp::packet::key::SecretParts;
|
|||
use sequoia_openpgp::policy::Policy;
|
||||
use sequoia_openpgp::Cert;
|
||||
|
||||
use openpgp_card::algorithm::{Algo, AlgoInfo};
|
||||
use openpgp_card::algorithm::{Algo, AlgoInfo, AlgoSimple};
|
||||
use openpgp_card::card_do::{
|
||||
ApplicationIdentifier, ApplicationRelatedData, CardholderRelatedData,
|
||||
ExtendedCapabilities, ExtendedLengthInfo, Fingerprint, HistoricalBytes,
|
||||
|
@ -21,12 +21,14 @@ use openpgp_card::{CardApp, CardClientBox, Error, KeySet, KeyType, Response};
|
|||
|
||||
use crate::decryptor::CardDecryptor;
|
||||
use crate::signer::CardSigner;
|
||||
use crate::util::vka_as_uploadable_key;
|
||||
use crate::util::{public_to_fingerprint, vka_as_uploadable_key};
|
||||
use crate::PublicKey;
|
||||
use openpgp_card::crypto_data::PublicKeyMaterial;
|
||||
|
||||
/// Representation of an opened OpenPGP card in its base state (i.e. no
|
||||
/// passwords have been verified, default authorization applies).
|
||||
pub struct Open {
|
||||
card_app: CardApp,
|
||||
pub struct Open<'a> {
|
||||
card_app: &'a mut CardApp,
|
||||
|
||||
// Cache of "application related data".
|
||||
//
|
||||
|
@ -44,8 +46,16 @@ pub struct Open {
|
|||
pw3: bool,
|
||||
}
|
||||
|
||||
impl Open {
|
||||
fn new(card_app: CardApp, ard: ApplicationRelatedData) -> Self {
|
||||
impl<'a> Open<'a> {
|
||||
pub fn open(card_app: &'a mut CardApp) -> Result<Self, Error> {
|
||||
let ard = card_app.get_application_related_data()?;
|
||||
|
||||
card_app.init_caps(&ard)?;
|
||||
|
||||
Ok(Self::new(card_app, ard))
|
||||
}
|
||||
|
||||
fn new(card_app: &'a mut CardApp, ard: ApplicationRelatedData) -> Self {
|
||||
Self {
|
||||
card_app,
|
||||
ard,
|
||||
|
@ -55,21 +65,6 @@ impl Open {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set up connection to a CardClient (read and cache "application
|
||||
/// related data").
|
||||
///
|
||||
/// The OpenPGP applet must already be opened in the CardClient.
|
||||
pub fn open_card(ccb: CardClientBox) -> Result<Self, Error> {
|
||||
// read and cache "application related data"
|
||||
let mut card_app = CardApp::from(ccb);
|
||||
|
||||
let ard = card_app.get_application_related_data()?;
|
||||
|
||||
card_app.init_caps(&ard)?;
|
||||
|
||||
Ok(Self::new(card_app, ard))
|
||||
}
|
||||
|
||||
pub fn verify_user(&mut self, pin: &str) -> Result<(), Error> {
|
||||
let _ = self.card_app.verify_pw1(pin)?;
|
||||
self.pw1 = true;
|
||||
|
@ -131,7 +126,7 @@ impl Open {
|
|||
}
|
||||
|
||||
/// Get a view of the card authenticated for "User" commands.
|
||||
pub fn user_card(&mut self) -> Option<User> {
|
||||
pub fn user_card<'b>(&'a mut self) -> Option<User<'a, 'b>> {
|
||||
if self.pw1 {
|
||||
Some(User { oc: self })
|
||||
} else {
|
||||
|
@ -140,7 +135,7 @@ impl Open {
|
|||
}
|
||||
|
||||
/// Get a view of the card authenticated for Signing.
|
||||
pub fn signing_card(&mut self) -> Option<Sign> {
|
||||
pub fn signing_card<'b>(&'b mut self) -> Option<Sign<'a, 'b>> {
|
||||
if self.pw1_sign {
|
||||
Some(Sign { oc: self })
|
||||
} else {
|
||||
|
@ -149,7 +144,7 @@ impl Open {
|
|||
}
|
||||
|
||||
/// Get a view of the card authenticated for "Admin" commands.
|
||||
pub fn admin_card(&mut self) -> Option<Admin> {
|
||||
pub fn admin_card<'b>(&'b mut self) -> Option<Admin<'a, 'b>> {
|
||||
if self.pw3 {
|
||||
Some(Admin { oc: self })
|
||||
} else {
|
||||
|
@ -288,11 +283,11 @@ impl Open {
|
|||
|
||||
/// An OpenPGP card after successfully verifying PW1 in mode 82
|
||||
/// (verification for user operations other than signing)
|
||||
pub struct User<'a> {
|
||||
oc: &'a mut Open,
|
||||
pub struct User<'app, 'open> {
|
||||
oc: &'open mut Open<'app>,
|
||||
}
|
||||
|
||||
impl User<'_> {
|
||||
impl User<'_, '_> {
|
||||
pub fn decryptor(
|
||||
&mut self,
|
||||
cert: &Cert,
|
||||
|
@ -304,11 +299,11 @@ impl User<'_> {
|
|||
|
||||
/// An OpenPGP card after successfully verifying PW1 in mode 81
|
||||
/// (verification for signing)
|
||||
pub struct Sign<'a> {
|
||||
oc: &'a mut Open,
|
||||
pub struct Sign<'app, 'open> {
|
||||
oc: &'open mut Open<'app>,
|
||||
}
|
||||
|
||||
impl Sign<'_> {
|
||||
impl Sign<'_, '_> {
|
||||
pub fn signer(
|
||||
&mut self,
|
||||
cert: &Cert,
|
||||
|
@ -319,14 +314,27 @@ impl Sign<'_> {
|
|||
|
||||
CardSigner::new(&mut self.oc.card_app, cert, policy)
|
||||
}
|
||||
|
||||
pub fn signer_from_pubkey(&mut self, pubkey: PublicKey) -> CardSigner {
|
||||
// FIXME: depending on the setting in "PW1 Status byte", only one
|
||||
// signature can be made after verification for signing
|
||||
|
||||
CardSigner::with_pubkey(&mut self.oc.card_app, pubkey)
|
||||
}
|
||||
}
|
||||
|
||||
/// An OpenPGP card after successful verification of PW3 ("Admin privileges")
|
||||
pub struct Admin<'a> {
|
||||
oc: &'a mut Open,
|
||||
pub struct Admin<'app, 'open> {
|
||||
oc: &'open mut Open<'app>,
|
||||
}
|
||||
|
||||
impl Admin<'_> {
|
||||
impl<'app, 'open> Admin<'app, 'open> {
|
||||
pub fn get_open(&'_ mut self) -> &mut Open<'app> {
|
||||
self.oc
|
||||
}
|
||||
}
|
||||
|
||||
impl Admin<'_, '_> {
|
||||
pub fn set_name(&mut self, name: &str) -> Result<Response, Error> {
|
||||
if name.len() >= 40 {
|
||||
return Err(anyhow!("name too long").into());
|
||||
|
@ -396,4 +404,16 @@ impl Admin<'_> {
|
|||
let key = vka_as_uploadable_key(vka, password);
|
||||
self.oc.card_app.key_import(key, key_type)
|
||||
}
|
||||
|
||||
pub fn generate_key_simple(
|
||||
&mut self,
|
||||
key_type: KeyType,
|
||||
algo: AlgoSimple,
|
||||
) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> {
|
||||
self.oc.card_app.generate_key_simple(
|
||||
public_to_fingerprint,
|
||||
key_type,
|
||||
algo,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! for card in PcscClient::cards()? {
|
||||
//! let open = Open::open_card(card)?;
|
||||
//! let mut ca = card.into();
|
||||
//! let open = Open::open(&mut ca)?;
|
||||
//! println!("Found OpenPGP card with ident '{}'",
|
||||
//! open.application_identifier()?.ident());
|
||||
//! }
|
||||
|
@ -32,8 +33,8 @@
|
|||
//! use openpgp_card_sequoia::card::Open;
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! let card = PcscClient::open_by_ident("abcd:12345678")?;
|
||||
//! let mut open = Open::open_card(card)?;
|
||||
//! let mut ca = PcscClient::open_by_ident("abcd:12345678")?.into();
|
||||
//! let mut open = Open::open(&mut ca)?;
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
|
@ -54,8 +55,8 @@
|
|||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // Open card via PCSC
|
||||
//! use sequoia_openpgp::policy::StandardPolicy;
|
||||
//! let card = PcscClient::open_by_ident("abcd:12345678")?;
|
||||
//! let mut open = Open::open_card(card)?;
|
||||
//! let mut ca = PcscClient::open_by_ident("abcd:12345678")?.into();
|
||||
//! let mut open = Open::open(&mut ca)?;
|
||||
//!
|
||||
//! // Get authorization for user access to the card with password
|
||||
//! open.verify_user("123456")?;
|
||||
|
@ -95,8 +96,8 @@
|
|||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // Open card via PCSC
|
||||
//! use sequoia_openpgp::policy::StandardPolicy;
|
||||
//! let card = PcscClient::open_by_ident("abcd:12345678")?;
|
||||
//! let mut open = Open::open_card(card)?;
|
||||
//! let mut ca = PcscClient::open_by_ident("abcd:12345678")?.into();
|
||||
//! let mut open = Open::open(&mut ca)?;
|
||||
//!
|
||||
//! // Get authorization for signing access to the card with password
|
||||
//! open.verify_user_for_signing("123456")?;
|
||||
|
@ -125,8 +126,8 @@
|
|||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // Open card via PCSC
|
||||
//! let card = PcscClient::open_by_ident("abcd:12345678")?;
|
||||
//! let mut open = Open::open_card(card)?;
|
||||
//! let mut ca = PcscClient::open_by_ident("abcd:12345678")?.into();
|
||||
//! let mut open = Open::open(&mut ca)?;
|
||||
//!
|
||||
//! // Get authorization for admin access to the card with password
|
||||
//! open.verify_admin("12345678")?;
|
||||
|
|
|
@ -21,6 +21,7 @@ use openpgp_card_sequoia::sq_util::{decryption_helper, sign_helper};
|
|||
// const TEST_KEY_PATH: &str = "example/test4k.sec";
|
||||
// const TEST_ENC_MSG: &str = "example/encrypted_to_rsa4k.asc";
|
||||
|
||||
// const TEST_KEY_PATH: &str = "example/nist521.sec";
|
||||
// const TEST_KEY_PATH: &str = "example/nist521.sec";
|
||||
// const TEST_ENC_MSG: &str = "example/encrypted_to_nist521.asc";
|
||||
|
||||
|
@ -34,8 +35,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
let test_card_ident = env::var("TEST_CARD_IDENT");
|
||||
|
||||
if let Ok(test_card_ident) = test_card_ident {
|
||||
let mut open =
|
||||
Open::open_card(PcscClient::open_by_ident(&test_card_ident)?)?;
|
||||
let mut card = PcscClient::open_by_ident(&test_card_ident)?.into();
|
||||
let mut open = Open::open(&mut card)?;
|
||||
|
||||
// card metadata
|
||||
|
||||
|
@ -149,9 +150,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
// -----------------------------
|
||||
// Open fresh Card for decrypt
|
||||
// -----------------------------
|
||||
|
||||
let mut open =
|
||||
Open::open_card(PcscClient::open_by_ident(&test_card_ident)?)?;
|
||||
let mut card = PcscClient::open_by_ident(&test_card_ident)?.into();
|
||||
let mut open = Open::open(&mut card)?;
|
||||
|
||||
// Check that we're still using the expected card
|
||||
let app_id = open.application_identifier()?;
|
||||
|
@ -189,8 +189,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
// -----------------------------
|
||||
// Open fresh Card for signing
|
||||
// -----------------------------
|
||||
let mut open =
|
||||
Open::open_card(PcscClient::open_by_ident(&test_card_ident)?)?;
|
||||
let mut card = PcscClient::open_by_ident(&test_card_ident)?.into();
|
||||
let mut open = Open::open(&mut card)?;
|
||||
|
||||
// Sign
|
||||
open.verify_user_for_signing("123456")?;
|
||||
|
@ -220,7 +220,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
println!("The following OpenPGP cards are connected to your system:");
|
||||
|
||||
for card in PcscClient::cards()? {
|
||||
let open = Open::open_card(card)?;
|
||||
let mut card = card.into();
|
||||
let open = Open::open(&mut card)?;
|
||||
println!(" {}", open.application_identifier()?.ident());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ use openpgp_card::card_do::{Fingerprint, KeyGenerationTime};
|
|||
use openpgp_card::crypto_data::{CardUploadableKey, PublicKeyMaterial};
|
||||
use openpgp_card::{CardApp, Error, KeyType};
|
||||
|
||||
use crate::card::Open;
|
||||
use crate::privkey::SequoiaKey;
|
||||
use crate::signer::CardSigner;
|
||||
use crate::{decryptor, signer, PublicKey};
|
||||
|
@ -37,16 +38,13 @@ use crate::{decryptor, signer, PublicKey};
|
|||
/// Create a Cert from the three subkeys on a card.
|
||||
/// (Calling this multiple times will result in different Certs!)
|
||||
///
|
||||
/// FIXME: contains hardcoded default passwords!
|
||||
///
|
||||
/// FIXME: make dec/auth keys optional
|
||||
///
|
||||
/// FIXME: accept optional metadata for user_id(s)?
|
||||
pub fn make_cert(
|
||||
ca: &mut CardApp,
|
||||
pub fn make_cert<'a, 'app>(
|
||||
open: &'a mut Open<'app>,
|
||||
key_sig: PublicKey,
|
||||
key_dec: PublicKey,
|
||||
key_aut: PublicKey,
|
||||
key_dec: Option<PublicKey>,
|
||||
key_aut: Option<PublicKey>,
|
||||
pw1: &str,
|
||||
) -> Result<Cert> {
|
||||
let mut pp = vec![];
|
||||
|
||||
|
@ -54,65 +52,74 @@ pub fn make_cert(
|
|||
let pri = PrimaryRole::convert_key(key_sig.clone());
|
||||
pp.push(Packet::from(pri));
|
||||
|
||||
// 2) add decryption key as subkey
|
||||
let sub_dec = SubordinateRole::convert_key(key_dec);
|
||||
pp.push(Packet::from(sub_dec.clone()));
|
||||
if let Some(key_dec) = key_dec {
|
||||
// 2) add decryption key as subkey
|
||||
let sub_dec = SubordinateRole::convert_key(key_dec);
|
||||
pp.push(Packet::from(sub_dec.clone()));
|
||||
|
||||
// Temporary version of the cert
|
||||
let cert = Cert::try_from(pp.clone())?;
|
||||
// Temporary version of the cert
|
||||
let cert = Cert::try_from(pp.clone())?;
|
||||
|
||||
// 3) make binding, sign with card -> add
|
||||
{
|
||||
let signing_builder =
|
||||
SignatureBuilder::new(SignatureType::SubkeyBinding)
|
||||
.set_signature_creation_time(SystemTime::now())?
|
||||
.set_key_validity_period(std::time::Duration::new(0, 0))?
|
||||
.set_key_flags(
|
||||
KeyFlags::empty()
|
||||
.set_storage_encryption()
|
||||
.set_transport_encryption(),
|
||||
)?;
|
||||
// 3) make binding, sign with card -> add
|
||||
{
|
||||
let signing_builder =
|
||||
SignatureBuilder::new(SignatureType::SubkeyBinding)
|
||||
.set_signature_creation_time(SystemTime::now())?
|
||||
.set_key_validity_period(std::time::Duration::new(0, 0))?
|
||||
.set_key_flags(
|
||||
KeyFlags::empty()
|
||||
.set_storage_encryption()
|
||||
.set_transport_encryption(),
|
||||
)?;
|
||||
|
||||
// Allow signing on the card
|
||||
ca.verify_pw1_for_signing("123456")?;
|
||||
// Allow signing on the card
|
||||
open.verify_user_for_signing(pw1)?;
|
||||
if let Some(mut sign) = open.signing_card() {
|
||||
// Card-backed signer for bindings
|
||||
let mut card_signer = sign.signer_from_pubkey(key_sig.clone());
|
||||
|
||||
// Card-backed signer for bindings
|
||||
let mut card_signer = CardSigner::with_pubkey(ca, key_sig.clone());
|
||||
let signing_bsig: Packet = sub_dec
|
||||
.bind(&mut card_signer, &cert, signing_builder)?
|
||||
.into();
|
||||
|
||||
let signing_bsig: Packet = sub_dec
|
||||
.bind(&mut card_signer, &cert, signing_builder)?
|
||||
.into();
|
||||
|
||||
pp.push(signing_bsig);
|
||||
pp.push(signing_bsig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4) add auth subkey
|
||||
let sub_aut = SubordinateRole::convert_key(key_aut);
|
||||
pp.push(Packet::from(sub_aut.clone()));
|
||||
if let Some(key_aut) = key_aut {
|
||||
// 4) add auth subkey
|
||||
let sub_aut = SubordinateRole::convert_key(key_aut);
|
||||
pp.push(Packet::from(sub_aut.clone()));
|
||||
|
||||
// 5) make, sign binding -> add
|
||||
{
|
||||
let signing_builder =
|
||||
SignatureBuilder::new(SignatureType::SubkeyBinding)
|
||||
.set_signature_creation_time(SystemTime::now())?
|
||||
.set_key_validity_period(std::time::Duration::new(0, 0))?
|
||||
.set_key_flags(KeyFlags::empty().set_authentication())?;
|
||||
// 5) make, sign binding -> add
|
||||
{
|
||||
let signing_builder =
|
||||
SignatureBuilder::new(SignatureType::SubkeyBinding)
|
||||
.set_signature_creation_time(SystemTime::now())?
|
||||
.set_key_validity_period(std::time::Duration::new(0, 0))?
|
||||
.set_key_flags(KeyFlags::empty().set_authentication())?;
|
||||
|
||||
// Allow signing on the card
|
||||
ca.verify_pw1_for_signing("123456")?;
|
||||
// Allow signing on the card
|
||||
open.verify_user_for_signing(pw1)?;
|
||||
if let Some(mut sign) = open.signing_card() {
|
||||
// Card-backed signer for bindings
|
||||
let mut card_signer = sign.signer_from_pubkey(key_sig.clone());
|
||||
|
||||
// Card-backed signer for bindings
|
||||
let mut card_signer = CardSigner::with_pubkey(ca, key_sig.clone());
|
||||
// Temporary version of the cert
|
||||
let cert = Cert::try_from(pp.clone())?;
|
||||
|
||||
let signing_bsig: Packet = sub_aut
|
||||
.bind(&mut card_signer, &cert, signing_builder)?
|
||||
.into();
|
||||
let signing_bsig: Packet = sub_aut
|
||||
.bind(&mut card_signer, &cert, signing_builder)?
|
||||
.into();
|
||||
|
||||
pp.push(signing_bsig);
|
||||
pp.push(signing_bsig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6) add user id from name / email
|
||||
let cardholder = ca.get_cardholder_related_data()?;
|
||||
let cardholder = open.cardholder_related_data()?;
|
||||
|
||||
// FIXME: process name field? accept email as argument?!
|
||||
let uid: UserID =
|
||||
|
@ -132,15 +139,20 @@ pub fn make_cert(
|
|||
)?;
|
||||
|
||||
// Allow signing on the card
|
||||
ca.verify_pw1_for_signing("123456")?;
|
||||
open.verify_user_for_signing(pw1)?;
|
||||
|
||||
// Card-backed signer for bindings
|
||||
let mut card_signer = CardSigner::with_pubkey(ca, key_sig);
|
||||
if let Some(mut sign) = open.signing_card() {
|
||||
// Card-backed signer for bindings
|
||||
let mut card_signer = sign.signer_from_pubkey(key_sig);
|
||||
|
||||
let signing_bsig: Packet =
|
||||
uid.bind(&mut card_signer, &cert, signing_builder)?.into();
|
||||
// Temporary version of the cert
|
||||
let cert = Cert::try_from(pp.clone())?;
|
||||
|
||||
pp.push(signing_bsig);
|
||||
let signing_bsig: Packet =
|
||||
uid.bind(&mut card_signer, &cert, signing_builder)?.into();
|
||||
|
||||
pp.push(signing_bsig);
|
||||
}
|
||||
}
|
||||
|
||||
Cert::try_from(pp)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
use anyhow::Result;
|
||||
use structopt::StructOpt;
|
||||
|
||||
use openpgp_card::{Error, Response, StatusBytes};
|
||||
use openpgp_card::{Error, StatusBytes};
|
||||
use openpgp_card_pcsc::PcscClient;
|
||||
use openpgp_card_sequoia::card::Open;
|
||||
|
||||
|
@ -13,8 +13,8 @@ mod cli;
|
|||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let cli = cli::Cli::from_args();
|
||||
|
||||
let ccb = PcscClient::open_by_ident(&cli.ident)?;
|
||||
let mut card = Open::open_card(ccb)?;
|
||||
let mut card = PcscClient::open_by_ident(&cli.ident)?.into();
|
||||
let mut open = Open::open(&mut card)?;
|
||||
|
||||
match cli.cmd {
|
||||
cli::Command::SetUserPin {} => {
|
||||
|
@ -23,7 +23,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
rpassword::read_password_from_tty(Some("Enter user PIN: "))?;
|
||||
|
||||
// verify pin
|
||||
card.verify_user(&pin)?;
|
||||
open.verify_user(&pin)?;
|
||||
println!("PIN was accepted by the card.\n");
|
||||
|
||||
// get new user pin
|
||||
|
@ -39,10 +39,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
|
||||
// set new user pin
|
||||
let res = card.change_user_pin(&pin, &newpin1);
|
||||
let res = open.change_user_pin(&pin, &newpin1);
|
||||
if res.is_err() {
|
||||
println!("\nFailed to change the user PIN!");
|
||||
print_gnuk_note(res, card)?;
|
||||
if let Err(err) = res {
|
||||
print_gnuk_note(err, &open)?;
|
||||
}
|
||||
} else {
|
||||
println!("\nUser PIN has been set.");
|
||||
}
|
||||
|
@ -53,7 +55,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
rpassword::read_password_from_tty(Some("Enter admin PIN: "))?;
|
||||
|
||||
// verify pin
|
||||
card.verify_admin(&pin)?;
|
||||
open.verify_admin(&pin)?;
|
||||
|
||||
// get new admin pin
|
||||
let newpin1 = rpassword::read_password_from_tty(Some(
|
||||
|
@ -68,7 +70,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
|
||||
// set new user pin
|
||||
card.change_admin_pin(&pin, &newpin1)?;
|
||||
open.change_admin_pin(&pin, &newpin1)?;
|
||||
|
||||
println!("\nAdmin PIN has been set.");
|
||||
}
|
||||
|
@ -78,10 +80,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
rpassword::read_password_from_tty(Some("Enter admin PIN: "))?;
|
||||
|
||||
// verify admin pin
|
||||
card.verify_admin(&pin)?;
|
||||
open.verify_admin(&pin)?;
|
||||
println!("PIN was accepted by the card.\n");
|
||||
|
||||
if let Some(mut admin) = card.admin_card() {
|
||||
if let Some(mut admin) = open.admin_card() {
|
||||
// ask user for new resetting code
|
||||
let newpin1 = rpassword::read_password_from_tty(Some(
|
||||
"Enter new resetting code: ",
|
||||
|
@ -113,7 +115,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
))?;
|
||||
|
||||
// verify pin
|
||||
card.verify_admin(&pin)?;
|
||||
open.verify_admin(&pin)?;
|
||||
println!("PIN was accepted by the card.\n");
|
||||
|
||||
None
|
||||
|
@ -142,9 +144,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
let res = if let Some(rst) = rst {
|
||||
// reset to new user pin
|
||||
card.reset_user_pin(&rst, &newpin1)
|
||||
open.reset_user_pin(&rst, &newpin1)
|
||||
} else {
|
||||
if let Some(mut admin) = card.admin_card() {
|
||||
if let Some(mut admin) = open.admin_card() {
|
||||
admin.reset_user_pin(&newpin1)
|
||||
} else {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
@ -156,7 +158,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
if res.is_err() {
|
||||
println!("\nFailed to change the user PIN!");
|
||||
print_gnuk_note(res, card)?;
|
||||
if let Err(err) = res {
|
||||
print_gnuk_note(err, &open)?;
|
||||
}
|
||||
} else {
|
||||
println!("\nUser PIN has been set.");
|
||||
}
|
||||
|
@ -172,10 +176,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
/// 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.
|
||||
fn print_gnuk_note(res: Result<Response, Error>, card: Open) -> Result<()> {
|
||||
if let Err(Error::CardStatus(StatusBytes::ConditionOfUseNotSatisfied)) =
|
||||
res
|
||||
{
|
||||
fn print_gnuk_note(err: Error, card: &Open) -> Result<()> {
|
||||
if matches!(
|
||||
err,
|
||||
Error::CardStatus(StatusBytes::ConditionOfUseNotSatisfied)
|
||||
) {
|
||||
// check if no keys exist on the card
|
||||
let fps = card.fingerprints()?;
|
||||
if fps.signature() == None
|
||||
|
|
|
@ -8,11 +8,14 @@ use structopt::StructOpt;
|
|||
use sequoia_openpgp::parse::{stream::DecryptorBuilder, Parse};
|
||||
use sequoia_openpgp::policy::StandardPolicy;
|
||||
use sequoia_openpgp::serialize::stream::{Armorer, Message, Signer};
|
||||
use sequoia_openpgp::serialize::SerializeInto;
|
||||
use sequoia_openpgp::Cert;
|
||||
|
||||
use openpgp_card_sequoia::card::Admin;
|
||||
use openpgp_card_sequoia::card::{Admin, Open};
|
||||
use openpgp_card_sequoia::sq_util;
|
||||
use openpgp_card_sequoia::util::{make_cert, public_key_material_to_key};
|
||||
|
||||
use openpgp_card::algorithm::AlgoSimple;
|
||||
use openpgp_card::{card_do::Sex, KeyType};
|
||||
|
||||
mod cli;
|
||||
|
@ -67,14 +70,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
pin_file,
|
||||
cmd,
|
||||
} => {
|
||||
let mut open = util::open_card(&ident)?;
|
||||
let mut admin = util::get_admin(&mut open, &pin_file)?;
|
||||
let mut card = util::open_card(&ident)?.into();
|
||||
let mut open = Open::open(&mut card)?;
|
||||
|
||||
match cmd {
|
||||
cli::AdminCommand::Name { name } => {
|
||||
let mut admin = util::get_admin(&mut open, &pin_file)?;
|
||||
|
||||
let _ = admin.set_name(&name)?;
|
||||
}
|
||||
cli::AdminCommand::Url { url } => {
|
||||
let mut admin = util::get_admin(&mut open, &pin_file)?;
|
||||
|
||||
let _ = admin.set_url(&url)?;
|
||||
}
|
||||
cli::AdminCommand::Import {
|
||||
|
@ -83,6 +90,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
dec_fp,
|
||||
auth_fp,
|
||||
} => {
|
||||
let admin = util::get_admin(&mut open, &pin_file)?;
|
||||
let key = Cert::from_file(keyfile)?;
|
||||
|
||||
if (&sig_fp, &dec_fp, &auth_fp) == (&None, &None, &None) {
|
||||
|
@ -109,7 +117,9 @@ fn list_cards() -> Result<()> {
|
|||
println!("Available OpenPGP cards:");
|
||||
|
||||
for card in cards {
|
||||
println!(" {}", card.application_identifier()?.ident());
|
||||
let mut card = card.into();
|
||||
let open = Open::open(&mut card)?;
|
||||
println!(" {}", open.application_identifier()?.ident());
|
||||
}
|
||||
} else {
|
||||
println!("No OpenPGP cards found.");
|
||||
|
@ -118,7 +128,7 @@ fn list_cards() -> Result<()> {
|
|||
}
|
||||
|
||||
fn print_status(ident: Option<String>, verbose: bool) -> Result<()> {
|
||||
let mut open = if let Some(ident) = ident {
|
||||
let ccb = if let Some(ident) = ident {
|
||||
util::open_card(&ident)?
|
||||
} else {
|
||||
let mut cards = util::cards()?;
|
||||
|
@ -128,6 +138,8 @@ fn print_status(ident: Option<String>, verbose: bool) -> Result<()> {
|
|||
return Err(anyhow::anyhow!("Found {} cards", cards.len()).into());
|
||||
}
|
||||
};
|
||||
let mut card = ccb.into();
|
||||
let mut open = Open::open(&mut card)?;
|
||||
|
||||
print!("OpenPGP card {}", open.application_identifier()?.ident());
|
||||
|
||||
|
@ -258,7 +270,9 @@ fn decrypt(
|
|||
|
||||
let input = util::open_or_stdin(input.as_deref())?;
|
||||
|
||||
let mut open = util::open_card(&ident)?;
|
||||
let mut card = util::open_card(&ident)?.into();
|
||||
let mut open = Open::open(&mut card)?;
|
||||
|
||||
let mut user = util::get_user(&mut open, &pin_file)?;
|
||||
let d = user.decryptor(&cert, &p)?;
|
||||
|
||||
|
@ -281,7 +295,9 @@ fn sign_detached(
|
|||
|
||||
let mut input = util::open_or_stdin(input.as_deref())?;
|
||||
|
||||
let mut open = util::open_card(&ident)?;
|
||||
let mut card = util::open_card(&ident)?.into();
|
||||
let mut open = Open::open(&mut card)?;
|
||||
|
||||
let mut sign = util::get_sign(&mut open, &pin_file)?;
|
||||
let s = sign.signer(&cert, &p)?;
|
||||
|
||||
|
@ -296,7 +312,8 @@ fn sign_detached(
|
|||
|
||||
fn factory_reset(ident: &str) -> Result<()> {
|
||||
println!("Resetting Card {}", ident);
|
||||
util::open_card(ident)?.factory_reset()
|
||||
let mut card = util::open_card(ident)?.into();
|
||||
Open::open(&mut card)?.factory_reset()
|
||||
}
|
||||
|
||||
fn key_import_yolo(mut admin: Admin, key: &Cert) -> Result<()> {
|
||||
|
|
|
@ -3,54 +3,47 @@
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use openpgp_card::Error;
|
||||
use openpgp_card::{CardClientBox, Error};
|
||||
use openpgp_card_pcsc::PcscClient;
|
||||
use openpgp_card_sequoia::card::{Admin, Open, Sign, User};
|
||||
use std::path::Path;
|
||||
|
||||
pub(crate) fn cards() -> Result<Vec<Open>> {
|
||||
let mut cards = vec![];
|
||||
|
||||
for card in PcscClient::cards()? {
|
||||
cards.push(Open::open_card(card)?);
|
||||
}
|
||||
|
||||
Ok(cards)
|
||||
pub(crate) fn cards() -> Result<Vec<CardClientBox>> {
|
||||
PcscClient::cards()
|
||||
}
|
||||
|
||||
pub(crate) fn open_card(ident: &str) -> Result<Open, Error> {
|
||||
let ccb = PcscClient::open_by_ident(ident)?;
|
||||
Open::open_card(ccb)
|
||||
pub(crate) fn open_card(ident: &str) -> Result<CardClientBox, Error> {
|
||||
PcscClient::open_by_ident(ident)
|
||||
}
|
||||
|
||||
pub(crate) fn get_user<'a>(
|
||||
open: &'a mut Open,
|
||||
pub(crate) fn get_user<'app, 'open>(
|
||||
open: &'app mut Open<'app>,
|
||||
pin_file: &Path,
|
||||
) -> Result<User<'a>, Box<dyn std::error::Error>> {
|
||||
) -> Result<User<'app, 'open>, Box<dyn std::error::Error>> {
|
||||
open.verify_user(&get_pin(pin_file)?)?;
|
||||
open.user_card()
|
||||
.ok_or_else(|| anyhow::anyhow!("Couldn't get user access").into())
|
||||
}
|
||||
|
||||
pub(crate) fn get_sign<'a>(
|
||||
open: &'a mut Open,
|
||||
pub(crate) fn get_sign<'app, 'open>(
|
||||
open: &'app mut Open<'app>,
|
||||
pin_file: &Path,
|
||||
) -> Result<Sign<'a>, Box<dyn std::error::Error>> {
|
||||
) -> Result<Sign<'app, 'open>, Box<dyn std::error::Error>> {
|
||||
open.verify_user_for_signing(&get_pin(pin_file)?)?;
|
||||
open.signing_card()
|
||||
.ok_or_else(|| anyhow::anyhow!("Couldn't get sign access").into())
|
||||
}
|
||||
|
||||
pub(crate) fn get_admin<'a>(
|
||||
open: &'a mut Open,
|
||||
pub(crate) fn get_admin<'app, 'open>(
|
||||
open: &'app mut Open<'app>,
|
||||
pin_file: &Path,
|
||||
) -> Result<Admin<'a>, Box<dyn std::error::Error>> {
|
||||
) -> Result<Admin<'app, 'open>, Box<dyn std::error::Error>> {
|
||||
open.verify_admin(&get_pin(pin_file)?)?;
|
||||
open.admin_card()
|
||||
.ok_or_else(|| anyhow::anyhow!("Couldn't get admin access").into())
|
||||
}
|
||||
|
||||
fn get_pin(pin_file: &Path) -> Result<String> {
|
||||
pub(crate) fn get_pin(pin_file: &Path) -> Result<String> {
|
||||
let pin = std::fs::read_to_string(pin_file)?;
|
||||
Ok(pin.trim().to_string())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue