Rename error types and re-export them at the crate top level.

This commit is contained in:
Heiko Schaefer 2021-09-01 23:59:56 +02:00
parent f501c09d2f
commit 316ca7eb3a
19 changed files with 184 additions and 261 deletions

View file

@ -1,19 +1,19 @@
// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0
use anyhow::{Error, Result};
use anyhow::Result;
use std::str::FromStr;
use std::string::FromUtf8Error;
use thiserror::Error;
use thiserror;
use sequoia_openpgp::parse::Parse;
use sequoia_openpgp::serialize::SerializeInto;
use sequoia_openpgp::Cert;
use openpgp_card;
use openpgp_card::algorithm::AlgoSimple;
use openpgp_card::card_do::{KeyGenerationTime, Sex};
use openpgp_card::errors::{OcErrorStatus, OpenpgpCardError};
use openpgp_card::{CardApp, KeyType};
use openpgp_card::{CardApp, Error, KeyType, StatusByte};
use openpgp_card_sequoia::{
make_cert, public_key_material_to_key, public_to_fingerprint,
};
@ -23,23 +23,23 @@ use crate::util;
#[derive(Debug)]
pub enum TestResult {
Status(OcErrorStatus),
Status(StatusByte),
StatusOk,
Text(String),
}
type TestOutput = Vec<TestResult>;
#[derive(Error, Debug)]
#[derive(thiserror::Error, Debug)]
pub enum TestError {
#[error("Failed to upload key {0} ({1})")]
KeyUploadError(String, Error),
KeyUploadError(String, anyhow::Error),
#[error(transparent)]
OPGP(#[from] OpenpgpCardError),
OPGP(#[from] Error),
#[error(transparent)]
OCard(#[from] OcErrorStatus),
OCard(#[from] StatusByte),
#[error(transparent)]
Other(#[from] anyhow::Error), // source and Display delegate to anyhow::Error
@ -485,8 +485,8 @@ pub fn test_verify(
// try to set name without verify, assert result is not ok!
let res = ca.set_name("Notverified<<Hello");
if let Err(OpenpgpCardError::OcStatus(s)) = res {
assert_eq!(s, OcErrorStatus::SecurityStatusNotSatisfied);
if let Err(Error::CardStatus(s)) = res {
assert_eq!(s, StatusByte::SecurityStatusNotSatisfied);
} else {
panic!("Status should be 'SecurityStatusNotSatisfied'");
}
@ -494,7 +494,7 @@ pub fn test_verify(
ca.verify_pw3("12345678")?;
match ca.check_pw3() {
Err(OpenpgpCardError::OcStatus(s)) => {
Err(Error::CardStatus(s)) => {
// e.g. yubikey5 returns an error status!
out.push(TestResult::Status(s));
}
@ -512,7 +512,7 @@ pub fn test_verify(
ca.verify_pw1("123456")?;
match ca.check_pw3() {
Err(OpenpgpCardError::OcStatus(s)) => {
Err(Error::CardStatus(s)) => {
// e.g. yubikey5 returns an error status!
out.push(TestResult::Status(s));
}

View file

@ -16,8 +16,7 @@ use openpgp::Cert;
use sequoia_openpgp as openpgp;
use openpgp_card::crypto_data::Cryptogram;
use openpgp_card::errors::OpenpgpCardError;
use openpgp_card::CardApp;
use openpgp_card::{CardApp, Error};
use crate::PublicKey;
@ -38,7 +37,7 @@ impl<'a> CardDecryptor<'a> {
ca: &'a mut CardApp,
cert: &Cert,
policy: &dyn Policy,
) -> Result<CardDecryptor<'a>, OpenpgpCardError> {
) -> Result<CardDecryptor<'a>, Error> {
// Get the fingerprint for the decryption key from the card.
let ard = ca.get_app_data()?;
let fps = ard.get_fingerprints()?;
@ -63,12 +62,12 @@ impl<'a> CardDecryptor<'a> {
let public = keys[0].clone();
Ok(Self { ca, public })
} else {
Err(OpenpgpCardError::InternalError(anyhow!(
Err(Error::InternalError(anyhow!(
"Failed to find a matching (sub)key in cert"
)))
}
} else {
Err(OpenpgpCardError::InternalError(anyhow!(
Err(Error::InternalError(anyhow!(
"Failed to get the decryption key's Fingerprint from the card"
)))
}

View file

@ -7,7 +7,6 @@
use anyhow::{anyhow, Context, Result};
use std::convert::TryFrom;
use std::convert::TryInto;
use std::error::Error;
use std::io;
use std::ops::{Deref, DerefMut};
use std::time::SystemTime;
@ -41,9 +40,7 @@ use openpgp_card::crypto_data::{
CardUploadableKey, Cryptogram, EccKey, EccType, Hash, PrivateKeyMaterial,
PublicKeyMaterial, RSAKey,
};
use openpgp_card::{
errors::OpenpgpCardError, CardApp, CardClientBox, KeyType, Response,
};
use openpgp_card::{CardApp, CardClientBox, Error, KeyType, Response};
use crate::signer::CardSigner;
@ -373,7 +370,7 @@ impl CardUploadableKey for SequoiaKey {
ts.into()
}
fn get_fp(&self) -> Result<Fingerprint, OpenpgpCardError> {
fn get_fp(&self) -> Result<Fingerprint, Error> {
let fp = self.key.fingerprint();
fp.as_bytes().try_into()
}
@ -455,7 +452,7 @@ pub fn upload_from_cert_yolo(
cert: &openpgp::Cert,
key_type: KeyType,
password: Option<String>,
) -> Result<(), Box<dyn Error>> {
) -> Result<(), Box<dyn std::error::Error>> {
let policy = StandardPolicy::new();
// Find all suitable (sub)keys for key_type.
@ -488,7 +485,7 @@ pub fn upload_key(
vka: ValidErasedKeyAmalgamation<SecretParts>,
key_type: KeyType,
password: Option<String>,
) -> Result<(), OpenpgpCardError> {
) -> Result<(), Error> {
let sqk = SequoiaKey::new(vka, password);
oca.upload_key(Box::new(sqk), key_type)
@ -546,7 +543,7 @@ pub fn public_to_fingerprint(
pkm: &PublicKeyMaterial,
time: KeyGenerationTime,
kt: KeyType,
) -> Result<Fingerprint, OpenpgpCardError> {
) -> Result<Fingerprint, Error> {
// Transform PublicKeyMaterial into a Sequoia Key
let key = public_key_material_to_key(pkm, kt, time)?;
@ -581,7 +578,7 @@ impl CardBase {
/// Set up connection (cache "application related data") to a
/// CardClient, on which the openpgp applet has already been opened.
pub fn open_card(ccb: CardClientBox) -> Result<Self, OpenpgpCardError> {
pub fn open_card(ccb: CardClientBox) -> Result<Self, Error> {
// read and cache "application related data"
let mut card_app = CardApp::from(ccb);
@ -602,13 +599,11 @@ impl CardBase {
self.card_app.get_app_data()
}
pub fn get_application_id(
&self,
) -> Result<ApplicationId, OpenpgpCardError> {
pub fn get_application_id(&self) -> Result<ApplicationId, Error> {
self.ard.get_application_id()
}
pub fn get_historical(&self) -> Result<Historical, OpenpgpCardError> {
pub fn get_historical(&self) -> Result<Historical, Error> {
self.ard.get_historical()
}
@ -626,9 +621,7 @@ impl CardBase {
unimplemented!()
}
pub fn get_extended_capabilities(
&self,
) -> Result<ExtendedCap, OpenpgpCardError> {
pub fn get_extended_capabilities(&self) -> Result<ExtendedCap, Error> {
self.ard.get_extended_capabilities()
}
@ -641,9 +634,7 @@ impl CardBase {
self.ard.get_pw_status_bytes()
}
pub fn get_fingerprints(
&self,
) -> Result<KeySet<Fingerprint>, OpenpgpCardError> {
pub fn get_fingerprints(&self) -> Result<KeySet<Fingerprint>, Error> {
self.ard.get_fingerprints()
}
@ -730,7 +721,7 @@ impl CardBase {
}
}
pub fn check_pw1(&mut self) -> Result<Response, OpenpgpCardError> {
pub fn check_pw1(&mut self) -> Result<Response, Error> {
self.card_app.check_pw1()
}
@ -744,7 +735,7 @@ impl CardBase {
}
}
pub fn check_pw3(&mut self) -> Result<Response, OpenpgpCardError> {
pub fn check_pw3(&mut self) -> Result<Response, Error> {
self.card_app.check_pw3()
}
@ -783,10 +774,7 @@ impl DerefMut for CardUser {
impl CardUser {
/// Decrypt the ciphertext in `dm`, on the card.
pub fn decrypt(
&mut self,
dm: Cryptogram,
) -> Result<Vec<u8>, OpenpgpCardError> {
pub fn decrypt(&mut self, dm: Cryptogram) -> Result<Vec<u8>, Error> {
self.card_app.decrypt(dm)
}
}
@ -820,7 +808,7 @@ impl CardSign {
pub fn signature_for_hash(
&mut self,
hash: Hash,
) -> Result<Vec<u8>, OpenpgpCardError> {
) -> Result<Vec<u8>, Error> {
self.card_app.signature_for_hash(hash)
}
}
@ -847,10 +835,7 @@ impl DerefMut for CardAdmin {
}
impl CardAdmin {
pub fn set_name(
&mut self,
name: &str,
) -> Result<Response, OpenpgpCardError> {
pub fn set_name(&mut self, name: &str) -> Result<Response, Error> {
if name.len() >= 40 {
return Err(anyhow!("name too long").into());
}
@ -863,10 +848,7 @@ impl CardAdmin {
self.card_app.set_name(name)
}
pub fn set_lang(
&mut self,
lang: &str,
) -> Result<Response, OpenpgpCardError> {
pub fn set_lang(&mut self, lang: &str) -> Result<Response, Error> {
if lang.len() > 8 {
return Err(anyhow!("lang too long").into());
}
@ -874,14 +856,11 @@ impl CardAdmin {
self.card_app.set_lang(lang)
}
pub fn set_sex(&mut self, sex: Sex) -> Result<Response, OpenpgpCardError> {
pub fn set_sex(&mut self, sex: Sex) -> Result<Response, Error> {
self.card_app.set_sex(sex)
}
pub fn set_url(
&mut self,
url: &str,
) -> Result<Response, OpenpgpCardError> {
pub fn set_url(&mut self, url: &str) -> Result<Response, Error> {
if url.chars().any(|c| !c.is_ascii()) {
return Err(anyhow!("Invalid char in url").into());
}
@ -900,7 +879,7 @@ impl CardAdmin {
&mut self,
key: Box<dyn CardUploadableKey>,
key_type: KeyType,
) -> Result<(), OpenpgpCardError> {
) -> Result<(), Error> {
self.card_app.key_import(key, key_type)
}
}

View file

@ -11,8 +11,7 @@ use openpgp::types::{Curve, PublicKeyAlgorithm};
use sequoia_openpgp as openpgp;
use openpgp_card::crypto_data::Hash;
use openpgp_card::errors::OpenpgpCardError;
use openpgp_card::CardApp;
use openpgp_card::{CardApp, Error};
use crate::PublicKey;
@ -33,7 +32,7 @@ impl<'a> CardSigner<'a> {
ca: &'a mut CardApp,
cert: &openpgp::Cert,
policy: &dyn Policy,
) -> Result<CardSigner<'a>, OpenpgpCardError> {
) -> Result<CardSigner<'a>, Error> {
// Get the fingerprint for the signing key from the card.
let ard = ca.get_app_data()?;
let fps = ard.get_fingerprints()?;
@ -60,12 +59,12 @@ impl<'a> CardSigner<'a> {
Ok(Self::with_pubkey(ca, public))
} else {
Err(OpenpgpCardError::InternalError(anyhow!(
Err(Error::InternalError(anyhow!(
"Failed to find a matching (sub)key in cert"
)))
}
} else {
Err(OpenpgpCardError::InternalError(anyhow!(
Err(Error::InternalError(anyhow!(
"Failed to get the signing key's Fingerprint \
from the card"
)))

View file

@ -11,10 +11,8 @@ pub mod response;
use anyhow::Result;
use std::convert::TryFrom;
use crate::apdu::command::Command;
use crate::apdu::response::RawResponse;
use crate::errors::{OcErrorStatus, OpenpgpCardError};
use crate::CardClientBox;
use crate::apdu::{command::Command, response::RawResponse};
use crate::{CardClientBox, Error, StatusByte};
// "Maximum amount of bytes in a short APDU command or response" (from pcsc)
const MAX_BUFFER_SIZE: usize = 264;
@ -34,7 +32,7 @@ pub(crate) fn send_command(
card_client: &mut CardClientBox,
cmd: Command,
expect_reply: bool,
) -> Result<RawResponse, OpenpgpCardError> {
) -> Result<RawResponse, Error> {
let mut resp = RawResponse::try_from(send_command_low_level(
card_client,
cmd,
@ -75,7 +73,7 @@ fn send_command_low_level(
card_client: &mut CardClientBox,
cmd: Command,
expect_reply: bool,
) -> Result<Vec<u8>, OpenpgpCardError> {
) -> Result<Vec<u8>, Error> {
let (ext_support, chaining_support, mut max_cmd_bytes, max_rsp_bytes) =
if let Some(caps) = card_client.get_caps() {
log::debug!("found card caps data!");
@ -151,9 +149,8 @@ fn send_command_low_level(
d.to_vec(),
);
let serialized = partial
.serialize(ext)
.map_err(OpenpgpCardError::InternalError)?;
let serialized =
partial.serialize(ext).map_err(Error::InternalError)?;
log::debug!(" -> chunked APDU command: {:x?}", &serialized);
@ -162,7 +159,7 @@ fn send_command_low_level(
log::debug!(" <- APDU chunk response: {:x?}", &resp);
if resp.len() < 2 {
return Err(OpenpgpCardError::ResponseLength(resp.len()));
return Err(Error::ResponseLength(resp.len()));
}
if !last {
@ -176,7 +173,7 @@ fn send_command_low_level(
|| (sw1 == 0x68 && sw2 == 0x83))
{
// Unexpected status for a non-final chunked response
return Err(OcErrorStatus::from((sw1, sw2)).into());
return Err(StatusByte::from((sw1, sw2)).into());
}
// ISO: "If SW1-SW2 is set to '6884', then command
@ -193,7 +190,7 @@ fn send_command_low_level(
// Can't send this command to the card, because it is too long and
// the card doesn't support command chaining.
if serialized.len() > max_cmd_bytes {
return Err(OpenpgpCardError::CommandTooLong(serialized.len()));
return Err(Error::CommandTooLong(serialized.len()));
}
log::debug!(" -> APDU command: {:x?}", &serialized);

View file

@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0
use crate::errors::{OcErrorStatus, OpenpgpCardError};
use crate::{Error, StatusByte};
use std::convert::TryFrom;
/// Response from the card to a command.
@ -35,29 +35,27 @@ pub(crate) struct RawResponse {
}
impl TryFrom<RawResponse> for Response {
type Error = OpenpgpCardError;
type Error = Error;
fn try_from(value: RawResponse) -> Result<Self, Self::Error> {
if value.is_ok() {
Ok(Response { data: value.data })
} else {
Err(OpenpgpCardError::OcStatus(OcErrorStatus::from(
value.status(),
)))
Err(Error::CardStatus(StatusByte::from(value.status())))
}
}
}
impl RawResponse {
pub fn check_ok(&self) -> Result<(), OcErrorStatus> {
pub fn check_ok(&self) -> Result<(), StatusByte> {
if !self.is_ok() {
Err(OcErrorStatus::from((self.sw1, self.sw2)))
Err(StatusByte::from((self.sw1, self.sw2)))
} else {
Ok(())
}
}
pub fn data(&self) -> Result<&[u8], OcErrorStatus> {
pub fn data(&self) -> Result<&[u8], StatusByte> {
self.check_ok()?;
Ok(&self.data)
}
@ -87,15 +85,15 @@ impl RawResponse {
}
impl TryFrom<Vec<u8>> for RawResponse {
type Error = OpenpgpCardError;
type Error = Error;
fn try_from(mut data: Vec<u8>) -> Result<Self, Self::Error> {
let sw2 = data
.pop()
.ok_or_else(|| OpenpgpCardError::ResponseLength(data.len()))?;
.ok_or_else(|| Error::ResponseLength(data.len()))?;
let sw1 = data
.pop()
.ok_or_else(|| OpenpgpCardError::ResponseLength(data.len()))?;
.ok_or_else(|| Error::ResponseLength(data.len()))?;
Ok(RawResponse { data, sw1, sw2 })
}

View file

@ -18,8 +18,8 @@ use crate::card_do::{
use crate::crypto_data::{
CardUploadableKey, Cryptogram, EccType, Hash, PublicKeyMaterial,
};
use crate::errors::OpenpgpCardError;
use crate::tlv::{tag::Tag, value::Value, Tlv};
use crate::Error;
use crate::{apdu, keys, CardCaps, CardClientBox, KeyType};
/// Low-level access to OpenPGP card functionality.
@ -92,7 +92,7 @@ impl CardApp {
// --- select ---
/// Select the OpenPGP card application
pub fn select(&mut self) -> Result<Response, OpenpgpCardError> {
pub fn select(&mut self) -> Result<Response, Error> {
let select_openpgp = commands::select_openpgp();
apdu::send_command(&mut self.card_client, select_openpgp, false)?
.try_into()
@ -207,9 +207,7 @@ impl CardApp {
///
/// Call select_data() before calling this fn, to select a particular
/// certificate (if the card supports multiple certificates).
pub fn get_cardholder_certificate(
&mut self,
) -> Result<Response, OpenpgpCardError> {
pub fn get_cardholder_certificate(&mut self) -> Result<Response, Error> {
let cmd = commands::get_cardholder_certificate();
apdu::send_command(&mut self.card_client, cmd, true)?.try_into()
}
@ -233,7 +231,7 @@ impl CardApp {
&mut self,
num: u8,
tag: &[u8],
) -> Result<Response, OpenpgpCardError> {
) -> Result<Response, Error> {
let tlv = Tlv::new(
[0x60],
Value::C(vec![Tlv::new([0x5c], Value::S(tag.to_vec()))]),
@ -308,7 +306,7 @@ impl CardApp {
pub fn verify_pw1_for_signing(
&mut self,
pin: &str,
) -> Result<Response, OpenpgpCardError> {
) -> Result<Response, Error> {
assert!(pin.len() >= 6); // FIXME: Err
let verify = commands::verify_pw1_81(pin.as_bytes().to_vec());
@ -321,19 +319,14 @@ impl CardApp {
///
/// (Note: some cards don't correctly implement this feature,
/// e.g. yubikey 5)
pub fn check_pw1_for_signing(
&mut self,
) -> Result<Response, OpenpgpCardError> {
pub fn check_pw1_for_signing(&mut self) -> Result<Response, Error> {
let verify = commands::verify_pw1_81(vec![]);
apdu::send_command(&mut self.card_client, verify, false)?.try_into()
}
/// Verify PW1 (user) and set an appropriate access status.
/// (For operations except signing, mode 82).
pub fn verify_pw1(
&mut self,
pin: &str,
) -> Result<Response, OpenpgpCardError> {
pub fn verify_pw1(&mut self, pin: &str) -> Result<Response, Error> {
assert!(pin.len() >= 6); // FIXME: Err
let verify = commands::verify_pw1_82(pin.as_bytes().to_vec());
@ -347,16 +340,13 @@ impl CardApp {
///
/// (Note: some cards don't correctly implement this feature,
/// e.g. yubikey 5)
pub fn check_pw1(&mut self) -> Result<Response, OpenpgpCardError> {
pub fn check_pw1(&mut self) -> Result<Response, Error> {
let verify = commands::verify_pw1_82(vec![]);
apdu::send_command(&mut self.card_client, verify, false)?.try_into()
}
/// Verify PW3 (admin) and set an appropriate access status.
pub fn verify_pw3(
&mut self,
pin: &str,
) -> Result<Response, OpenpgpCardError> {
pub fn verify_pw3(&mut self, pin: &str) -> Result<Response, Error> {
assert!(pin.len() >= 8); // FIXME: Err
let verify = commands::verify_pw3(pin.as_bytes().to_vec());
@ -369,7 +359,7 @@ impl CardApp {
///
/// (Note: some cards don't correctly implement this feature,
/// e.g. yubikey 5)
pub fn check_pw3(&mut self) -> Result<Response, OpenpgpCardError> {
pub fn check_pw3(&mut self) -> Result<Response, Error> {
let verify = commands::verify_pw3(vec![]);
apdu::send_command(&mut self.card_client, verify, false)?.try_into()
}
@ -380,10 +370,7 @@ impl CardApp {
///
/// (This is a convenience wrapper around the low-level pso_decipher
/// operation, it builds the required `data` field from `dm`)
pub fn decrypt(
&mut self,
dm: Cryptogram,
) -> Result<Vec<u8>, OpenpgpCardError> {
pub fn decrypt(&mut self, dm: Cryptogram) -> Result<Vec<u8>, Error> {
match dm {
Cryptogram::RSA(message) => {
let mut data = vec![0x0];
@ -409,10 +396,7 @@ impl CardApp {
/// Run decryption operation on the smartcard (low level operation)
/// (7.2.11 PSO: DECIPHER)
fn pso_decipher(
&mut self,
data: Vec<u8>,
) -> Result<Vec<u8>, OpenpgpCardError> {
fn pso_decipher(&mut self, data: Vec<u8>) -> Result<Vec<u8>, Error> {
// The OpenPGP card is already connected and PW1 82 has been verified
let dec_cmd = commands::decryption(data);
let resp = apdu::send_command(&mut self.card_client, dec_cmd, true)?;
@ -431,7 +415,7 @@ impl CardApp {
pub fn signature_for_hash(
&mut self,
hash: Hash,
) -> Result<Vec<u8>, OpenpgpCardError> {
) -> Result<Vec<u8>, Error> {
let data = match hash {
Hash::SHA256(_) | Hash::SHA384(_) | Hash::SHA512(_) => {
let tlv = Tlv::new(
@ -466,7 +450,7 @@ impl CardApp {
fn pso_compute_digital_signature(
&mut self,
data: Vec<u8>,
) -> Result<Vec<u8>, OpenpgpCardError> {
) -> Result<Vec<u8>, Error> {
let dec_cmd = commands::signature(data);
let resp = apdu::send_command(&mut self.card_client, dec_cmd, true)?;
@ -492,33 +476,24 @@ impl CardApp {
Ok(resp.data()?.to_vec())
}
pub fn set_name(
&mut self,
name: &str,
) -> Result<Response, OpenpgpCardError> {
pub fn set_name(&mut self, name: &str) -> Result<Response, Error> {
let put_name = commands::put_name(name.as_bytes().to_vec());
apdu::send_command(&mut self.card_client, put_name, false)?.try_into()
}
pub fn set_lang(
&mut self,
lang: &str,
) -> Result<Response, OpenpgpCardError> {
pub fn set_lang(&mut self, lang: &str) -> Result<Response, Error> {
let put_lang = commands::put_lang(lang.as_bytes().to_vec());
apdu::send_command(self.card_client.borrow_mut(), put_lang, false)?
.try_into()
}
pub fn set_sex(&mut self, sex: Sex) -> Result<Response, OpenpgpCardError> {
pub fn set_sex(&mut self, sex: Sex) -> Result<Response, Error> {
let put_sex = commands::put_sex((&sex).into());
apdu::send_command(self.card_client.borrow_mut(), put_sex, false)?
.try_into()
}
pub fn set_url(
&mut self,
url: &str,
) -> Result<Response, OpenpgpCardError> {
pub fn set_url(&mut self, url: &str) -> Result<Response, Error> {
let put_url = commands::put_url(url.as_bytes().to_vec());
apdu::send_command(&mut self.card_client, put_url, false)?.try_into()
}
@ -527,7 +502,7 @@ impl CardApp {
&mut self,
time: KeyGenerationTime,
key_type: KeyType,
) -> Result<Response, OpenpgpCardError> {
) -> Result<Response, Error> {
// Timestamp update
let time_value: Vec<u8> = time
.get()
@ -549,7 +524,7 @@ impl CardApp {
&mut self,
fp: Fingerprint,
key_type: KeyType,
) -> Result<Response, OpenpgpCardError> {
) -> Result<Response, Error> {
let fp_cmd = commands::put_data(
&[key_type.get_fingerprint_put_tag()],
fp.as_bytes().to_vec(),
@ -573,7 +548,7 @@ impl CardApp {
&mut self,
pw_status: &PWStatus,
long: bool,
) -> Result<Response, OpenpgpCardError> {
) -> Result<Response, Error> {
let data = pw_status.serialize_for_put(long);
let cmd = commands::put_pw_status(data);
@ -587,7 +562,7 @@ impl CardApp {
pub fn set_cardholder_certificate(
&mut self,
data: Vec<u8>,
) -> Result<Response, OpenpgpCardError> {
) -> Result<Response, Error> {
let cmd = commands::put_cardholder_certificate(data);
apdu::send_command(&mut self.card_client, cmd, false)?.try_into()
}
@ -598,7 +573,7 @@ impl CardApp {
&mut self,
key_type: KeyType,
algo: &Algo,
) -> Result<Response, OpenpgpCardError> {
) -> Result<Response, Error> {
// FIXME: caching?
let ard = self.get_app_data()?;
@ -668,7 +643,7 @@ impl CardApp {
&mut self,
key: Box<dyn CardUploadableKey>,
key_type: KeyType,
) -> Result<(), OpenpgpCardError> {
) -> Result<(), Error> {
let algo_list = self.get_algo_info();
// An error is ok - it's fine if a card doesn't offer a list of
@ -689,10 +664,10 @@ impl CardApp {
&PublicKeyMaterial,
KeyGenerationTime,
KeyType,
) -> Result<Fingerprint, OpenpgpCardError>,
) -> Result<Fingerprint, Error>,
key_type: KeyType,
algo: Option<&Algo>,
) -> Result<(PublicKeyMaterial, KeyGenerationTime), OpenpgpCardError> {
) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> {
keys::gen_key_with_metadata(self, fp_from_pub, key_type, algo)
}
@ -707,10 +682,10 @@ impl CardApp {
&PublicKeyMaterial,
KeyGenerationTime,
KeyType,
) -> Result<Fingerprint, OpenpgpCardError>,
) -> Result<Fingerprint, Error>,
key_type: KeyType,
algo: AlgoSimple,
) -> Result<(PublicKeyMaterial, KeyGenerationTime), OpenpgpCardError> {
) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> {
let algo = algo.get_algo(key_type);
self.generate_key(fp_from_pub, key_type, Some(&algo))
}
@ -724,7 +699,7 @@ impl CardApp {
pub fn get_pub_key(
&mut self,
key_type: KeyType,
) -> Result<PublicKeyMaterial, OpenpgpCardError> {
) -> Result<PublicKeyMaterial, Error> {
keys::get_pub_key(self, key_type)
}
}

View file

@ -8,9 +8,8 @@ use nom::{combinator, number::complete as number, sequence};
use std::collections::HashSet;
use std::convert::TryFrom;
use crate::card_do::complete;
use crate::card_do::{ExtendedCap, Features};
use crate::errors::OpenpgpCardError;
use crate::card_do::{complete, ExtendedCap, Features};
use crate::Error;
fn features(input: &[u8]) -> nom::IResult<&[u8], HashSet<Features>> {
combinator::map(number::u8, |b| {
@ -70,7 +69,7 @@ impl ExtendedCap {
}
impl TryFrom<&[u8]> for ExtendedCap {
type Error = OpenpgpCardError;
type Error = Error;
fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
let ec = complete(parse(input))?;

View file

@ -10,7 +10,7 @@ use std::convert::TryInto;
use std::fmt;
use crate::card_do::{Fingerprint, KeySet};
use crate::errors::OpenpgpCardError;
use crate::Error;
impl From<[u8; 20]> for Fingerprint {
fn from(data: [u8; 20]) -> Self {
@ -19,7 +19,7 @@ impl From<[u8; 20]> for Fingerprint {
}
impl TryFrom<&[u8]> for Fingerprint {
type Error = OpenpgpCardError;
type Error = Error;
fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
log::trace!(
@ -84,9 +84,7 @@ fn fingerprints(input: &[u8]) -> nom::IResult<&[u8], KeySet<Fingerprint>> {
}
/// Parse three fingerprints from the card into a KeySet of Fingerprints
pub(crate) fn to_keyset(
input: &[u8],
) -> Result<KeySet<Fingerprint>, OpenpgpCardError> {
pub(crate) fn to_keyset(input: &[u8]) -> Result<KeySet<Fingerprint>, Error> {
log::trace!("Fingerprint from input: {:x?}, len {}", input, input.len());
// The input may be longer than 3 fingerprint, don't fail if it hasn't
@ -94,5 +92,5 @@ pub(crate) fn to_keyset(
self::fingerprints(input)
.map(|res| res.1)
.map_err(|err| anyhow!("Parsing failed: {:?}", err))
.map_err(OpenpgpCardError::InternalError)
.map_err(Error::InternalError)
}

View file

@ -4,7 +4,7 @@
//! 6 Historical Bytes
use crate::card_do::{CardCapabilities, CardServiceData, Historical};
use crate::errors::OpenpgpCardError;
use crate::Error;
use anyhow::{anyhow, Result};
use std::convert::TryFrom;
@ -78,7 +78,7 @@ impl Historical {
}
impl TryFrom<&[u8]> for Historical {
type Error = OpenpgpCardError;
type Error = Error;
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
let len = data.len();

View file

@ -7,9 +7,8 @@ use anyhow::anyhow;
use chrono::{DateTime, NaiveDateTime, Utc};
use nom::{combinator, number::complete as number, sequence};
use crate::card_do::KeyGenerationTime;
use crate::card_do::KeySet;
use crate::errors::OpenpgpCardError;
use crate::card_do::{KeyGenerationTime, KeySet};
use crate::Error;
impl From<KeyGenerationTime> for DateTime<Utc> {
fn from(kg: KeyGenerationTime) -> Self {
@ -54,9 +53,7 @@ fn key_generation_set(
)))(input)
}
pub fn from(
input: &[u8],
) -> Result<KeySet<KeyGenerationTime>, OpenpgpCardError> {
pub fn from(input: &[u8]) -> Result<KeySet<KeyGenerationTime>, Error> {
// List of generation dates/times of key pairs, binary.
// 4 bytes, Big Endian each for Sig, Dec and Aut. Each
// value shall be seconds since Jan 1, 1970. Default
@ -73,5 +70,5 @@ pub fn from(
self::key_generation_set(input)
.map(|res| res.1)
.map_err(|err| anyhow!("Parsing failed: {:?}", err))
.map_err(OpenpgpCardError::InternalError)
.map_err(Error::InternalError)
}

View file

@ -3,15 +3,12 @@
//! OpenPGP card data objects (DO)
use anyhow::{anyhow, Error, Result};
use anyhow::{anyhow, Result};
use std::collections::HashSet;
use std::convert::TryFrom;
use std::convert::TryInto;
use crate::algorithm::Algo;
use crate::errors::OpenpgpCardError;
use crate::tlv::Tlv;
use crate::KeyType;
use crate::{algorithm::Algo, tlv::Tlv, Error, KeyType};
mod algo_attrs;
mod algo_info;
@ -36,9 +33,7 @@ pub struct ApplicationRelatedData(pub(crate) Tlv);
impl ApplicationRelatedData {
/// Application identifier (AID), ISO 7816-4
pub fn get_application_id(
&self,
) -> Result<ApplicationId, OpenpgpCardError> {
pub fn get_application_id(&self) -> Result<ApplicationId, Error> {
// get from cached "application related data"
let aid = self.0.find(&[0x4f].into());
@ -50,7 +45,7 @@ impl ApplicationRelatedData {
}
/// Historical bytes
pub fn get_historical(&self) -> Result<Historical, OpenpgpCardError> {
pub fn get_historical(&self) -> Result<Historical, Error> {
// get from cached "application related data"
let hist = self.0.find(&[0x5f, 0x52].into());
@ -90,9 +85,7 @@ impl ApplicationRelatedData {
}
/// Extended Capabilities
pub fn get_extended_capabilities(
&self,
) -> Result<ExtendedCap, OpenpgpCardError> {
pub fn get_extended_capabilities(&self) -> Result<ExtendedCap, Error> {
// get from cached "application related data"
let ecap = self.0.find(&[0xc0].into());
@ -136,9 +129,7 @@ impl ApplicationRelatedData {
/// Fingerprint, per key type.
/// Zero bytes indicate a not defined private key.
pub fn get_fingerprints(
&self,
) -> Result<KeySet<Fingerprint>, OpenpgpCardError> {
pub fn get_fingerprints(&self) -> Result<KeySet<Fingerprint>, Error> {
// Get from cached "application related data"
let fp = self.0.find(&[0xc5].into());
@ -156,7 +147,7 @@ impl ApplicationRelatedData {
/// Generation dates/times of key pairs
pub fn get_key_generation_times(
&self,
) -> Result<KeySet<KeyGenerationTime>, OpenpgpCardError> {
) -> Result<KeySet<KeyGenerationTime>, Error> {
let kg = self.0.find(&[0xcd].into());
if let Some(kg) = kg {
@ -373,7 +364,9 @@ impl<T> KeySet<T> {
}
/// nom parsing helper
pub(crate) fn complete<O>(result: nom::IResult<&[u8], O>) -> Result<O, Error> {
pub(crate) fn complete<O>(
result: nom::IResult<&[u8], O>,
) -> Result<O, anyhow::Error> {
let (rem, output) =
result.map_err(|err| anyhow!("Parsing failed: {:?}", err))?;
if rem.is_empty() {

View file

@ -6,10 +6,10 @@
use anyhow::anyhow;
use crate::card_do::PWStatus;
use crate::errors::OpenpgpCardError;
use crate::Error;
impl PWStatus {
pub fn try_from(input: &[u8]) -> Result<Self, OpenpgpCardError> {
pub fn try_from(input: &[u8]) -> Result<Self, Error> {
if input.len() == 7 {
let pw1_cds_multi = input[0] == 0x01;
let pw1_pin_block = input[1] & 0x80 != 0;
@ -33,7 +33,7 @@ impl PWStatus {
err_count_pw3,
})
} else {
Err(OpenpgpCardError::InternalError(anyhow!(
Err(Error::InternalError(anyhow!(
"Unexpected length of PW Status Bytes: {}",
input.len()
)))

View file

@ -9,7 +9,7 @@ use anyhow::Result;
use crate::algorithm::Algo;
use crate::card_do::{Fingerprint, KeyGenerationTime};
use crate::errors::OpenpgpCardError;
use crate::Error;
/// A hash value that can be signed by the card.
#[non_exhaustive]
@ -71,7 +71,7 @@ pub trait CardUploadableKey {
fn get_ts(&self) -> KeyGenerationTime;
/// fingerprint
fn get_fp(&self) -> Result<Fingerprint, OpenpgpCardError>;
fn get_fp(&self) -> Result<Fingerprint, Error>;
}
/// Algorithm-independent container for private key material to upload to

View file

@ -3,24 +3,22 @@
//! Error types used by this crate.
//!
//! [`OpenpgpCardError`] is a wrapper enum for all error types that are used.
//! [`Error`] is a wrapper enum for all error types that are used.
//!
//! The two main classes of errors are:
//! - [`SmartcardError`], for problems on the reader/smartcard layer
//! - [`OcErrorStatus`], which models error statuses reported by the OpenPGP
//! - [`StatusByte`], which models error statuses reported by the OpenPGP
//! card application
use thiserror::Error;
/// Enum that wraps the different error types that this crate can return
#[derive(Error, Debug)]
/// Enum wrapper for the different error types of this crate
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum OpenpgpCardError {
pub enum Error {
#[error("Error interacting with smartcard: {0}")]
Smartcard(SmartcardError),
#[error("OpenPGP card error status: {0}")]
OcStatus(OcErrorStatus),
CardStatus(StatusByte),
#[error("Command too long ({0} bytes)")]
CommandTooLong(usize),
@ -32,22 +30,22 @@ pub enum OpenpgpCardError {
InternalError(anyhow::Error),
}
impl From<OcErrorStatus> for OpenpgpCardError {
fn from(oce: OcErrorStatus) -> Self {
OpenpgpCardError::OcStatus(oce)
impl From<StatusByte> for Error {
fn from(oce: StatusByte) -> Self {
Error::CardStatus(oce)
}
}
impl From<anyhow::Error> for OpenpgpCardError {
impl From<anyhow::Error> for Error {
fn from(ae: anyhow::Error) -> Self {
OpenpgpCardError::InternalError(ae)
Error::InternalError(ae)
}
}
/// OpenPGP card "Status Byte" errors
#[derive(Error, Debug, PartialEq)]
#[derive(thiserror::Error, Debug, PartialEq)]
#[non_exhaustive]
pub enum OcErrorStatus {
pub enum StatusByte {
#[error("Selected file or DO in termination state")]
TerminationState,
@ -118,40 +116,40 @@ pub enum OcErrorStatus {
UnknownStatus(u8, u8),
}
impl From<(u8, u8)> for OcErrorStatus {
impl From<(u8, u8)> for StatusByte {
fn from(status: (u8, u8)) -> Self {
match (status.0, status.1) {
(0x62, 0x85) => OcErrorStatus::TerminationState,
(0x62, 0x85) => StatusByte::TerminationState,
(0x63, 0xC0..=0xCF) => {
OcErrorStatus::PasswordNotChecked(status.1 & 0xf)
StatusByte::PasswordNotChecked(status.1 & 0xf)
}
(0x64, 0x02..=0x80) => OcErrorStatus::TriggeringByCard(status.1),
(0x65, 0x01) => OcErrorStatus::MemoryFailure,
(0x66, 0x00) => OcErrorStatus::SecurityRelatedIssues,
(0x67, 0x00) => OcErrorStatus::WrongLength,
(0x68, 0x81) => OcErrorStatus::LogicalChannelNotSupported,
(0x68, 0x82) => OcErrorStatus::SecureMessagingNotSupported,
(0x68, 0x83) => OcErrorStatus::LastCommandOfChainExpected,
(0x68, 0x84) => OcErrorStatus::CommandChainingUnsupported,
(0x69, 0x82) => OcErrorStatus::SecurityStatusNotSatisfied,
(0x69, 0x83) => OcErrorStatus::AuthenticationMethodBlocked,
(0x69, 0x85) => OcErrorStatus::ConditionOfUseNotSatisfied,
(0x69, 0x87) => OcErrorStatus::ExpectedSecureMessagingDOsMissing,
(0x69, 0x88) => OcErrorStatus::SMDataObjectsIncorrect,
(0x6A, 0x80) => OcErrorStatus::IncorrectParametersCommandDataField,
(0x6A, 0x82) => OcErrorStatus::FileOrApplicationNotFound,
(0x6A, 0x88) => OcErrorStatus::ReferencedDataNotFound,
(0x6B, 0x00) => OcErrorStatus::WrongParametersP1P2,
(0x6D, 0x00) => OcErrorStatus::INSNotSupported,
(0x6E, 0x00) => OcErrorStatus::CLANotSupported,
(0x6F, 0x00) => OcErrorStatus::NoPreciseDiagnosis,
_ => OcErrorStatus::UnknownStatus(status.0, status.1),
(0x64, 0x02..=0x80) => StatusByte::TriggeringByCard(status.1),
(0x65, 0x01) => StatusByte::MemoryFailure,
(0x66, 0x00) => StatusByte::SecurityRelatedIssues,
(0x67, 0x00) => StatusByte::WrongLength,
(0x68, 0x81) => StatusByte::LogicalChannelNotSupported,
(0x68, 0x82) => StatusByte::SecureMessagingNotSupported,
(0x68, 0x83) => StatusByte::LastCommandOfChainExpected,
(0x68, 0x84) => StatusByte::CommandChainingUnsupported,
(0x69, 0x82) => StatusByte::SecurityStatusNotSatisfied,
(0x69, 0x83) => StatusByte::AuthenticationMethodBlocked,
(0x69, 0x85) => StatusByte::ConditionOfUseNotSatisfied,
(0x69, 0x87) => StatusByte::ExpectedSecureMessagingDOsMissing,
(0x69, 0x88) => StatusByte::SMDataObjectsIncorrect,
(0x6A, 0x80) => StatusByte::IncorrectParametersCommandDataField,
(0x6A, 0x82) => StatusByte::FileOrApplicationNotFound,
(0x6A, 0x88) => StatusByte::ReferencedDataNotFound,
(0x6B, 0x00) => StatusByte::WrongParametersP1P2,
(0x6D, 0x00) => StatusByte::INSNotSupported,
(0x6E, 0x00) => StatusByte::CLANotSupported,
(0x6F, 0x00) => StatusByte::NoPreciseDiagnosis,
_ => StatusByte::UnknownStatus(status.0, status.1),
}
}
}
/// Errors on the smartcard/reader layer
#[derive(Error, Debug)]
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum SmartcardError {
#[error("Failed to create a pcsc smartcard context {0}")]

View file

@ -16,8 +16,8 @@ use crate::crypto_data::{
CardUploadableKey, EccKey, EccPub, PrivateKeyMaterial, PublicKeyMaterial,
RSAKey, RSAPub,
};
use crate::errors::OpenpgpCardError;
use crate::tlv::{length::tlv_encode_length, value::Value, Tlv};
use crate::Error;
use crate::{apdu, KeyType};
/// Generate asymmetric key pair on the card.
@ -36,10 +36,10 @@ pub(crate) fn gen_key_with_metadata(
&PublicKeyMaterial,
KeyGenerationTime,
KeyType,
) -> Result<Fingerprint, OpenpgpCardError>,
) -> Result<Fingerprint, Error>,
key_type: KeyType,
algo: Option<&Algo>,
) -> Result<(PublicKeyMaterial, KeyGenerationTime), OpenpgpCardError> {
) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> {
// set algo on card if it's Some
if let Some(algo) = algo {
card_app.set_algorithm_attributes(key_type, algo)?;
@ -63,7 +63,7 @@ pub(crate) fn gen_key_with_metadata(
// Store creation timestamp (unix time format, limited to u32)
let ts = time
.duration_since(UNIX_EPOCH)
.map_err(|e| OpenpgpCardError::InternalError(anyhow!(e)))?
.map_err(|e| Error::InternalError(anyhow!(e)))?
.as_secs() as u32;
let ts = ts.into();
@ -100,8 +100,7 @@ fn tlv_to_pubkey(tlv: &Tlv, algo: &Algo) -> Result<PublicKeyMaterial> {
(_, _, _) => Err(anyhow!(
"Unexpected public key material from card {:?}",
tlv
)
.into()),
)),
}
}
@ -112,7 +111,7 @@ fn tlv_to_pubkey(tlv: &Tlv, algo: &Algo) -> Result<PublicKeyMaterial> {
pub(crate) fn generate_asymmetric_key_pair(
card_app: &mut CardApp,
key_type: KeyType,
) -> Result<Tlv, OpenpgpCardError> {
) -> Result<Tlv, Error> {
// generate key
let crt = get_crt(key_type)?;
let gen_key_cmd = commands::gen_key(crt.serialize().to_vec());
@ -136,7 +135,7 @@ pub(crate) fn generate_asymmetric_key_pair(
pub(crate) fn get_pub_key(
card_app: &mut CardApp,
key_type: KeyType,
) -> Result<PublicKeyMaterial, OpenpgpCardError> {
) -> Result<PublicKeyMaterial, Error> {
// algo
let ard = card_app.get_app_data()?; // FIXME: caching
let algo = ard.get_algorithm_attributes(key_type)?;
@ -163,7 +162,7 @@ pub(crate) fn key_import(
key: Box<dyn CardUploadableKey>,
key_type: KeyType,
algo_list: Option<AlgoInfo>,
) -> Result<(), OpenpgpCardError> {
) -> Result<(), Error> {
let (algo, key_cmd) = match key.get_key()? {
PrivateKeyMaterial::R(rsa_key) => {
// RSA bitsize
@ -262,7 +261,7 @@ fn get_card_algo_rsa(
algo_list: AlgoInfo,
key_type: KeyType,
rsa_bits: u16,
) -> Result<RsaAttrs, OpenpgpCardError> {
) -> Result<RsaAttrs, Error> {
// Find suitable algorithm parameters (from card's list of algorithms).
// FIXME: handle "no list available" (older cards?)
// (Current algo parameters of the key slot should be used, then (?))
@ -323,7 +322,7 @@ fn check_card_algo_ecc(
fn ecc_key_import_cmd(
ecc_key: Box<dyn EccKey>,
key_type: KeyType,
) -> Result<Command, OpenpgpCardError> {
) -> Result<Command, Error> {
let scalar_data = ecc_key.get_scalar();
let scalar_len = scalar_data.len() as u8;
@ -348,7 +347,7 @@ fn rsa_key_import_cmd(
key_type: KeyType,
rsa_key: Box<dyn RSAKey>,
algo_attrs: &RsaAttrs,
) -> Result<Command, OpenpgpCardError> {
) -> Result<Command, Error> {
// Assemble key command, which contains three sub-TLV:
// 1) "Control Reference Template"
@ -411,17 +410,13 @@ fn rsa_key_import_cmd(
}
/// Get "Control Reference Template" Tlv for `key_type`
fn get_crt(key_type: KeyType) -> Result<Tlv, OpenpgpCardError> {
fn get_crt(key_type: KeyType) -> Result<Tlv, Error> {
// "Control Reference Template" (0xB8 | 0xB6 | 0xA4)
let tag = match key_type {
KeyType::Decryption => 0xB8,
KeyType::Signing => 0xB6,
KeyType::Authentication => 0xA4,
_ => {
return Err(OpenpgpCardError::InternalError(anyhow!(
"Unexpected KeyType"
)))
}
_ => return Err(Error::InternalError(anyhow!("Unexpected KeyType"))),
};
Ok(Tlv::new([tag], Value::S(vec![])))
}

View file

@ -32,12 +32,13 @@ mod apdu;
mod card_app;
pub mod card_do;
pub mod crypto_data;
pub mod errors;
mod errors;
mod keys;
mod tlv;
pub use crate::apdu::response::Response;
pub use crate::card_app::CardApp;
pub use crate::errors::{Error, SmartcardError, StatusByte};
/// The CardClient trait defines communication with an OpenPGP card via a
/// backend implementation (e.g. the pcsc backend in the crate

View file

@ -2,10 +2,11 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use anyhow::{anyhow, Result};
use pcsc::{Card, Context, Error, Protocols, Scope, ShareMode};
use pcsc::{Card, Context, Protocols, Scope, ShareMode};
use openpgp_card::errors::{OpenpgpCardError, SmartcardError};
use openpgp_card::{CardApp, CardCaps, CardClient, CardClientBox};
use openpgp_card::{
CardApp, CardCaps, CardClient, CardClientBox, Error, SmartcardError,
};
pub struct PcscClient {
card: Card,
@ -51,7 +52,7 @@ impl PcscClient {
let card =
match ctx.connect(reader, ShareMode::Shared, Protocols::ANY) {
Ok(card) => card,
Err(Error::NoSmartcard) => {
Err(pcsc::Error::NoSmartcard) => {
continue; // try next reader
}
Err(err) => {
@ -94,16 +95,14 @@ impl PcscClient {
}
/// Try to select the OpenPGP application on a card
fn select(card_client: PcscClient) -> Result<CardApp, OpenpgpCardError> {
fn select(card_client: PcscClient) -> Result<CardApp, Error> {
let ccb = Box::new(card_client) as CardClientBox;
let mut ca = CardApp::from(ccb);
if ca.select().is_ok() {
Ok(ca)
} else {
Err(OpenpgpCardError::Smartcard(
SmartcardError::SelectOpenPGPCardFailed,
))
Err(Error::Smartcard(SmartcardError::SelectOpenPGPCardFailed))
}
}
@ -111,14 +110,14 @@ impl PcscClient {
///
/// If multiple cards are connected, this will effectively be a random
/// pick. You should consider using `open_by_ident` instead.
pub fn open_yolo() -> Result<CardClientBox, OpenpgpCardError> {
pub fn open_yolo() -> Result<CardClientBox, Error> {
for card in Self::unopened_cards()? {
if let Ok(ca) = Self::select(card) {
return Ok(ca.into());
}
}
Err(OpenpgpCardError::Smartcard(SmartcardError::CardNotFound(
Err(Error::Smartcard(SmartcardError::CardNotFound(
"No OpenPGP card found".to_string(),
)))
}
@ -128,7 +127,7 @@ impl PcscClient {
fn match_by_ident(
mut ca: CardApp,
ident: &str,
) -> Result<Option<CardClientBox>, OpenpgpCardError> {
) -> Result<Option<CardClientBox>, Error> {
let ard = ca.get_app_data()?;
let aid = ard.get_application_id()?;
@ -141,9 +140,7 @@ impl PcscClient {
/// Returns the OpenPGP card that matches `ident`, if it is available.
/// The OpenPGP application of the `CardClientBox` has been selected.
pub fn open_by_ident(
ident: &str,
) -> Result<CardClientBox, OpenpgpCardError> {
pub fn open_by_ident(ident: &str) -> Result<CardClientBox, Error> {
for card in Self::unopened_cards()? {
if let Ok(ca) = Self::select(card) {
if let Some(matched_card) =
@ -154,7 +151,7 @@ impl PcscClient {
}
}
Err(OpenpgpCardError::Smartcard(SmartcardError::CardNotFound(
Err(Error::Smartcard(SmartcardError::CardNotFound(
ident.to_string(),
)))
}
@ -165,7 +162,7 @@ impl CardClient for PcscClient {
let mut resp_buffer = vec![0; buf_size];
let resp = self.card.transmit(cmd, &mut resp_buffer).map_err(|e| {
OpenpgpCardError::Smartcard(SmartcardError::Error(format!(
Error::Smartcard(SmartcardError::Error(format!(
"Transmit failed: {:?}",
e
)))

View file

@ -13,7 +13,7 @@ use sequoia_ipc::gnupg::{Agent, Context};
use std::sync::Mutex;
use tokio::runtime::Runtime;
use openpgp_card::errors::OpenpgpCardError;
use openpgp_card::Error;
use openpgp_card::{CardCaps, CardClient, CardClientBox};
lazy_static! {
@ -108,9 +108,7 @@ impl ScdClient {
/// Create a CardClientBox object that uses an scdaemon instance as its
/// backend. If multiple cards are available, scdaemon implicitly
/// selects one.
pub fn open(
agent: Option<Agent>,
) -> Result<CardClientBox, OpenpgpCardError> {
pub fn open(agent: Option<Agent>) -> Result<CardClientBox, Error> {
let card = ScdClient::new(agent, true)?;
Ok(Box::new(card) as CardClientBox)
}
@ -120,7 +118,7 @@ impl ScdClient {
pub fn open_by_serial(
agent: Option<Agent>,
serial: &str,
) -> Result<CardClientBox, OpenpgpCardError> {
) -> Result<CardClientBox, Error> {
let mut card = ScdClient::new(agent, true)?;
card.select_card(serial)?;