diff --git a/Cargo.lock b/Cargo.lock index f1aeb1f4..617a1daf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -820,9 +820,9 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" dependencies = [ "proc-macro2", "quote", diff --git a/cli/src/commands.rs b/cli/src/commands.rs index f29e7b13..60bd2abe 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -36,7 +36,7 @@ pub struct YubiKeyCli { impl YubiKeyCli { /// Print usage information - pub fn print_usage() -> Result<(), io::Error> { + pub fn print_usage() -> io::Result<()> { let mut stdout = STDOUT.lock(); stdout.reset()?; diff --git a/cli/src/commands/readers.rs b/cli/src/commands/readers.rs index 2cee8129..06da6690 100644 --- a/cli/src/commands/readers.rs +++ b/cli/src/commands/readers.rs @@ -53,7 +53,7 @@ impl ReadersCmd { index: usize, name: &str, serial: Serial, - ) -> Result<(), io::Error> { + ) -> io::Result<()> { stream.set_color(ColorSpec::new().set_bold(true))?; write!(stream, "{:>3}:", index)?; stream.reset()?; diff --git a/cli/src/commands/status.rs b/cli/src/commands/status.rs index 0f3694b8..74538f99 100644 --- a/cli/src/commands/status.rs +++ b/cli/src/commands/status.rs @@ -51,7 +51,7 @@ impl StatusCmd { stream: &mut StandardStreamLock<'_>, name: &str, value: impl ToString, - ) -> Result<(), io::Error> { + ) -> io::Result<()> { stream.set_color(ColorSpec::new().set_bold(true))?; write!(stream, "{:>12}:", name)?; stream.reset()?; diff --git a/cli/src/lib.rs b/cli/src/lib.rs index cdb68ed1..115d93e2 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -27,7 +27,7 @@ pub fn print_cert_info( yubikey: &mut YubiKey, slot: SlotId, stream: &mut StandardStreamLock<'_>, -) -> Result<(), io::Error> { +) -> io::Result<()> { let cert = match Certificate::read(yubikey, slot) { Ok(c) => c, Err(e) => { @@ -82,7 +82,7 @@ fn print_cert_attr( stream: &mut StandardStreamLock<'_>, name: &str, value: impl ToString, -) -> Result<(), io::Error> { +) -> io::Result<()> { stream.set_color(ColorSpec::new().set_bold(true))?; write!(stream, "{:>12}:", name)?; stream.reset()?; diff --git a/cli/src/terminal.rs b/cli/src/terminal.rs index a4a724df..3be4ec64 100644 --- a/cli/src/terminal.rs +++ b/cli/src/terminal.rs @@ -143,7 +143,7 @@ impl Status { } /// Print the given message - fn print(self, stream: &StandardStream, msg: impl AsRef) -> Result<(), io::Error> { + fn print(self, stream: &StandardStream, msg: impl AsRef) -> io::Result<()> { let mut s = stream.lock(); s.reset()?; s.set_color(ColorSpec::new().set_fg(self.color).set_bold(self.bold))?; diff --git a/src/apdu.rs b/src/apdu.rs index 8f776470..acfddb61 100644 --- a/src/apdu.rs +++ b/src/apdu.rs @@ -30,7 +30,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::{error::Error, transaction::Transaction, Buffer}; +use crate::{transaction::Transaction, Buffer, Result}; use log::trace; use zeroize::{Zeroize, Zeroizing}; @@ -109,7 +109,7 @@ impl Apdu { } /// Transmit this APDU using the given card transaction - pub fn transmit(&self, txn: &Transaction<'_>, recv_len: usize) -> Result { + pub fn transmit(&self, txn: &Transaction<'_>, recv_len: usize) -> Result { trace!(">>> {:?}", self); let response = Response::from(txn.transmit(&self.to_bytes(), recv_len)?); trace!("<<< {:?}", &response); diff --git a/src/cccid.rs b/src/cccid.rs index 33fba887..65ec99e9 100644 --- a/src/cccid.rs +++ b/src/cccid.rs @@ -30,7 +30,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::{error::Error, yubikey::YubiKey}; +use crate::{Error, Result, YubiKey}; use getrandom::getrandom; use std::fmt::{self, Debug, Display}; use subtle_encoding::hex; @@ -68,7 +68,7 @@ pub struct CardId(pub [u8; CCCID_SIZE]); impl CardId { /// Generate a random CCC Card ID - pub fn generate() -> Result { + pub fn generate() -> Result { let mut id = [0u8; CCCID_SIZE]; getrandom(&mut id).map_err(|_| Error::RandomnessError)?; Ok(Self(id)) @@ -81,14 +81,14 @@ pub struct Ccc(pub [u8; CCC_SIZE]); impl Ccc { /// Return CardId component of CCC - pub fn card_id(&self) -> Result { + pub fn card_id(&self) -> Result { let mut cccid = [0u8; CCCID_SIZE]; cccid.copy_from_slice(&self.0[CCC_ID_OFFS..(CCC_ID_OFFS + CCCID_SIZE)]); Ok(CardId(cccid)) } /// Get Cardholder Capability Container (CCC) ID - pub fn get(yubikey: &mut YubiKey) -> Result { + pub fn get(yubikey: &mut YubiKey) -> Result { let txn = yubikey.begin_transaction()?; let response = txn.fetch_object(OBJ_CAPABILITY)?; @@ -103,7 +103,7 @@ impl Ccc { /// Set Cardholder Capability Container (CCC) ID #[cfg(feature = "untested")] - pub fn set(&self, yubikey: &mut YubiKey) -> Result<(), Error> { + pub fn set(&self, yubikey: &mut YubiKey) -> Result<()> { let mut buf = CCC_TMPL.to_vec(); buf[0..self.0.len()].copy_from_slice(&self.0); diff --git a/src/certificate.rs b/src/certificate.rs index 947fbe28..87762537 100644 --- a/src/certificate.rs +++ b/src/certificate.rs @@ -31,7 +31,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{ - error::Error, + error::{Error, Result}, key::{sign_data, AlgorithmId, SlotId}, serialization::*, transaction::Transaction, @@ -82,13 +82,13 @@ impl From<[u8; 20]> for Serial { } impl TryFrom<&[u8]> for Serial { - type Error = (); + type Error = Error; - fn try_from(bytes: &[u8]) -> Result { + fn try_from(bytes: &[u8]) -> Result { if bytes.len() <= 20 { Ok(Serial(BigUint::from_bytes_be(&bytes))) } else { - Err(()) + Err(Error::ParseError) } } } @@ -112,7 +112,7 @@ pub enum CertInfo { impl TryFrom for CertInfo { type Error = Error; - fn try_from(value: u8) -> Result { + fn try_from(value: u8) -> Result { match value { 0x00 => Ok(CertInfo::Uncompressed), 0x01 => Ok(CertInfo::Gzip), @@ -190,7 +190,7 @@ impl fmt::Debug for PublicKeyInfo { } impl PublicKeyInfo { - fn parse(subject_pki: &SubjectPublicKeyInfo<'_>) -> Result { + fn parse(subject_pki: &SubjectPublicKeyInfo<'_>) -> Result { match subject_pki.algorithm.algorithm.to_string().as_str() { OID_RSA_ENCRYPTION => { let pubkey = read_pki::rsa_pubkey(subject_pki.subject_public_key.data)?; @@ -330,7 +330,7 @@ pub struct Certificate { impl<'a> TryFrom<&'a [u8]> for Certificate { type Error = Error; - fn try_from(bytes: &'a [u8]) -> Result { + fn try_from(bytes: &'a [u8]) -> Result { Self::from_bytes(bytes.to_vec()) } } @@ -350,7 +350,7 @@ impl Certificate { subject: &[RelativeDistinguishedName<'_>], subject_pki: PublicKeyInfo, extensions: &[x509::Extension<'_, O>], - ) -> Result { + ) -> Result { let serial = serial.into(); let mut tbs_cert = Buffer::new(Vec::with_capacity(CB_OBJ_MAX)); @@ -453,7 +453,7 @@ impl Certificate { } /// Read a certificate from the given slot in the YubiKey - pub fn read(yubikey: &mut YubiKey, slot: SlotId) -> Result { + pub fn read(yubikey: &mut YubiKey, slot: SlotId) -> Result { let txn = yubikey.begin_transaction()?; let buf = read_certificate(&txn, slot)?; @@ -465,25 +465,20 @@ impl Certificate { } /// Write this certificate into the YubiKey in the given slot - pub fn write( - &self, - yubikey: &mut YubiKey, - slot: SlotId, - certinfo: CertInfo, - ) -> Result<(), Error> { + pub fn write(&self, yubikey: &mut YubiKey, slot: SlotId, certinfo: CertInfo) -> Result<()> { let txn = yubikey.begin_transaction()?; write_certificate(&txn, slot, Some(&self.data), certinfo) } /// Delete a certificate located at the given slot of the given YubiKey #[cfg(feature = "untested")] - pub fn delete(yubikey: &mut YubiKey, slot: SlotId) -> Result<(), Error> { + pub fn delete(yubikey: &mut YubiKey, slot: SlotId) -> Result<()> { let txn = yubikey.begin_transaction()?; write_certificate(&txn, slot, None, CertInfo::Uncompressed) } /// Initialize a local certificate struct from the given bytebuffer - pub fn from_bytes(cert: impl Into) -> Result { + pub fn from_bytes(cert: impl Into) -> Result { let cert = cert.into(); if cert.is_empty() { @@ -544,7 +539,7 @@ impl AsRef<[u8]> for Certificate { } /// Read certificate -pub(crate) fn read_certificate(txn: &Transaction<'_>, slot: SlotId) -> Result { +pub(crate) fn read_certificate(txn: &Transaction<'_>, slot: SlotId) -> Result { let object_id = slot.object_id(); let buf = match txn.fetch_object(object_id) { @@ -572,7 +567,7 @@ pub(crate) fn write_certificate( slot: SlotId, data: Option<&[u8]>, certinfo: CertInfo, -) -> Result<(), Error> { +) -> Result<()> { let object_id = slot.object_id(); if data.is_none() { @@ -602,7 +597,7 @@ mod read_pki { use rsa::{BigUint, RSAPublicKey}; use super::{OID_NIST_P256, OID_NIST_P384}; - use crate::{error::Error, key::AlgorithmId}; + use crate::{key::AlgorithmId, Error, Result}; /// From [RFC 8017](https://tools.ietf.org/html/rfc8017#appendix-A.1.1): /// ```text @@ -611,7 +606,7 @@ mod read_pki { /// publicExponent INTEGER -- e /// } /// ``` - pub(super) fn rsa_pubkey(encoded: &[u8]) -> Result { + pub(super) fn rsa_pubkey(encoded: &[u8]) -> Result { fn parse_rsa_pubkey(i: &[u8]) -> IResult<&[u8], DerObject<'_>, BerError> { parse_der_sequence_defined!(i, parse_der_integer >> parse_der_integer) } @@ -650,7 +645,7 @@ mod read_pki { /// -- specifiedCurve SpecifiedECDomain /// } /// ``` - pub(super) fn ec_parameters(parameters: &DerObject<'_>) -> Result { + pub(super) fn ec_parameters(parameters: &DerObject<'_>) -> Result { let curve_oid = parameters.as_oid_val().map_err(|_| Error::InvalidObject)?; match curve_oid.to_string().as_str() { diff --git a/src/chuid.rs b/src/chuid.rs index bb6ec5f1..92c3dc8b 100644 --- a/src/chuid.rs +++ b/src/chuid.rs @@ -30,7 +30,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::{error::Error, yubikey::YubiKey}; +use crate::{Error, Result, YubiKey}; use getrandom::getrandom; use std::fmt::{self, Debug, Display}; use subtle_encoding::hex; @@ -87,7 +87,7 @@ pub struct Uuid(pub [u8; CARDID_SIZE]); impl Uuid { /// Generate a random Cardholder Unique Identifier (CHUID) UUID - pub fn generate() -> Result { + pub fn generate() -> Result { let mut id = [0u8; CARDID_SIZE]; getrandom(&mut id).map_err(|_| Error::RandomnessError)?; Ok(Self(id)) @@ -100,14 +100,14 @@ pub struct ChuId(pub [u8; CHUID_SIZE]); impl ChuId { /// Return FASC-N component of CHUID - pub fn fascn(&self) -> Result<[u8; FASCN_SIZE], Error> { + pub fn fascn(&self) -> Result<[u8; FASCN_SIZE]> { let mut fascn = [0u8; FASCN_SIZE]; fascn.copy_from_slice(&self.0[CHUID_FASCN_OFFS..(CHUID_FASCN_OFFS + FASCN_SIZE)]); Ok(fascn) } /// Return Card UUID/GUID component of CHUID - pub fn uuid(&self) -> Result<[u8; CARDID_SIZE], Error> { + pub fn uuid(&self) -> Result<[u8; CARDID_SIZE]> { let mut uuid = [0u8; CARDID_SIZE]; uuid.copy_from_slice(&self.0[CHUID_GUID_OFFS..(CHUID_GUID_OFFS + CARDID_SIZE)]); Ok(uuid) @@ -115,7 +115,7 @@ impl ChuId { /// Return expiration date component of CHUID // TODO(tarcieri): parse expiration? - pub fn expiration(&self) -> Result<[u8; EXPIRATION_SIZE], Error> { + pub fn expiration(&self) -> Result<[u8; EXPIRATION_SIZE]> { let mut expiration = [0u8; EXPIRATION_SIZE]; expiration.copy_from_slice( &self.0[CHUID_EXPIRATION_OFFS..(CHUID_EXPIRATION_OFFS + EXPIRATION_SIZE)], @@ -124,7 +124,7 @@ impl ChuId { } /// Get Cardholder Unique Identifier (CHUID) - pub fn get(yubikey: &mut YubiKey) -> Result { + pub fn get(yubikey: &mut YubiKey) -> Result { let txn = yubikey.begin_transaction()?; let response = txn.fetch_object(OBJ_CHUID)?; @@ -140,7 +140,7 @@ impl ChuId { /// Set Cardholder Unique Identifier (CHUID) #[cfg(feature = "untested")] - pub fn set(&self, yubikey: &mut YubiKey) -> Result<(), Error> { + pub fn set(&self, yubikey: &mut YubiKey) -> Result<()> { let mut buf = CHUID_TMPL.to_vec(); buf[0..self.0.len()].copy_from_slice(&self.0); diff --git a/src/config.rs b/src/config.rs index b3ea4c92..850e447c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -31,11 +31,10 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{ - error::Error, metadata::{AdminData, ProtectedData}, mgm::{MgmType, ADMIN_FLAGS_1_PROTECTED_MGM}, yubikey::{YubiKey, ADMIN_FLAGS_1_PUK_BLOCKED}, - TAG_ADMIN_FLAGS_1, TAG_ADMIN_SALT, TAG_ADMIN_TIMESTAMP, TAG_PROTECTED_FLAGS_1, + Result, TAG_ADMIN_FLAGS_1, TAG_ADMIN_SALT, TAG_ADMIN_TIMESTAMP, TAG_PROTECTED_FLAGS_1, TAG_PROTECTED_MGM, }; use log::error; @@ -68,7 +67,7 @@ pub struct Config { impl Config { /// Get YubiKey config - pub fn get(yubikey: &mut YubiKey) -> Result { + pub fn get(yubikey: &mut YubiKey) -> Result { let mut config = Config { protected_data_available: false, puk_blocked: false, diff --git a/src/error.rs b/src/error.rs index 9954dece..3d21ea78 100644 --- a/src/error.rs +++ b/src/error.rs @@ -32,65 +32,69 @@ use std::fmt::{self, Display}; +/// Result type with [`Error`]. +pub type Result = core::result::Result; + /// Kinds of errors #[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[non_exhaustive] pub enum Error { - /// Memory error - MemoryError, - - /// PCSC error - PcscError { - /// Original PC/SC error - inner: Option, - }, - - /// Size error - SizeError, + /// Algorithm error + AlgorithmError, /// Applet error AppletError, + /// Argument error + ArgumentError, + /// Authentication error AuthenticationError, - /// Randomness error - RandomnessError, - /// Generic error GenericError, + /// Invalid object + InvalidObject, + /// Key error KeyError, + /// Memory error + MemoryError, + + /// Not supported + NotSupported, + + /// Not found + NotFound, + /// Parse error ParseError, - /// Wrong PIN - WrongPin { - /// Number of tries remaining - tries: u8, + /// PCSC error + PcscError { + /// Original PC/SC error + inner: Option, }, - /// Invalid object - InvalidObject, - - /// Algorithm error - AlgorithmError, - /// PIN locked PinLocked, - /// Argument error - ArgumentError, + /// Randomness error + RandomnessError, /// Range error RangeError, - /// Not supported - NotSupported, + /// Size error + SizeError, - /// Not found - NotFound, + /// Wrong PIN + WrongPin { + /// Number of tries remaining + tries: u8, + }, } impl Error { @@ -98,48 +102,48 @@ impl Error { /// /// These names map to the legacy names from the Yubico C library, to /// assist in web searches for relevant information for these errors. - pub fn name(self) -> &'static str { - match self { - Error::MemoryError => "YKPIV_MEMORY_ERROR", - Error::PcscError { .. } => "YKPIV_PCSC_ERROR", - Error::SizeError => "YKPIV_SIZE_ERROR", + pub fn name(self) -> Option<&'static str> { + Some(match self { + Error::AlgorithmError => "YKPIV_ALGORITHM_ERROR", Error::AppletError => "YKPIV_APPLET_ERROR", + Error::ArgumentError => "YKPIV_ARGUMENT_ERROR", Error::AuthenticationError => "YKPIV_AUTHENTICATION_ERROR", - Error::RandomnessError => "YKPIV_RANDOMNESS_ERROR", Error::GenericError => "YKPIV_GENERIC_ERROR", + Error::InvalidObject => "YKPIV_INVALID_OBJECT", Error::KeyError => "YKPIV_KEY_ERROR", + Error::MemoryError => "YKPIV_MEMORY_ERROR", + Error::NotSupported => "YKPIV_NOT_SUPPORTED", Error::ParseError => "YKPIV_PARSE_ERROR", - Error::WrongPin { .. } => "YKPIV_WRONG_PIN", - Error::InvalidObject => "YKPIV_INVALID_OBJECT", - Error::AlgorithmError => "YKPIV_ALGORITHM_ERROR", + Error::PcscError { .. } => "YKPIV_PCSC_ERROR", Error::PinLocked => "YKPIV_PIN_LOCKED", - Error::ArgumentError => "YKPIV_ARGUMENT_ERROR", + Error::RandomnessError => "YKPIV_RANDOMNESS_ERROR", Error::RangeError => "YKPIV_RANGE_ERROR", - Error::NotSupported => "YKPIV_NOT_SUPPORTED", - Error::NotFound => "", - } + Error::SizeError => "YKPIV_SIZE_ERROR", + Error::WrongPin { .. } => "YKPIV_WRONG_PIN", + _ => return None, + }) } /// Error message pub fn msg(self) -> &'static str { match self { - Error::MemoryError => "memory error", - Error::PcscError { .. } => "PCSC error", - Error::SizeError => "size error", + Error::AlgorithmError => "algorithm error", Error::AppletError => "applet error", + Error::ArgumentError => "argument error", Error::AuthenticationError => "authentication error", - Error::RandomnessError => "randomness error", Error::GenericError => "generic error", + Error::InvalidObject => "invalid object", Error::KeyError => "key error", + Error::MemoryError => "memory error", + Error::NotSupported => "not supported", + Error::NotFound => "not found", Error::ParseError => "parse error", - Error::WrongPin { .. } => "wrong pin", - Error::InvalidObject => "invalid object", - Error::AlgorithmError => "algorithm error", + Error::PcscError { .. } => "PC/SC error", Error::PinLocked => "PIN locked", - Error::ArgumentError => "argument error", + Error::RandomnessError => "randomness error", Error::RangeError => "range error", - Error::NotSupported => "not supported", - Error::NotFound => "not found", + Error::SizeError => "size error", + Error::WrongPin { .. } => "wrong pin", } } } @@ -159,10 +163,8 @@ impl From for Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - #[allow(trivial_casts)] // why doesn't this work without the cast??? - Error::PcscError { inner } => inner - .as_ref() - .map(|err| err as &(dyn std::error::Error + 'static)), + #[allow(trivial_casts)] + Error::PcscError { inner } => inner.as_ref().map(|err| err as &_), _ => None, } } diff --git a/src/key.rs b/src/key.rs index 7f4edadc..243f65c8 100644 --- a/src/key.rs +++ b/src/key.rs @@ -39,23 +39,19 @@ use crate::{ apdu::{Ins, StatusWords}, - certificate::{self, Certificate}, - error::Error, + certificate::{self, Certificate, PublicKeyInfo}, + error::{Error, Result}, + policy::{PinPolicy, TouchPolicy}, serialization::*, settings, yubikey::YubiKey, - ObjectId, + Buffer, ObjectId, }; use log::debug; use std::convert::TryFrom; #[cfg(feature = "untested")] use crate::CB_OBJ_MAX; -use crate::{ - certificate::PublicKeyInfo, - policy::{PinPolicy, TouchPolicy}, - Buffer, -}; use elliptic_curve::sec1::EncodedPoint as EcPublicKey; use log::{error, warn}; #[cfg(feature = "untested")] @@ -126,7 +122,7 @@ pub enum SlotId { impl TryFrom for SlotId { type Error = Error; - fn try_from(value: u8) -> Result { + fn try_from(value: u8) -> Result { match value { 0x9a => Ok(SlotId::Authentication), 0x9c => Ok(SlotId::Signature), @@ -154,7 +150,7 @@ impl From for u8 { impl TryFrom for SlotId { type Error = Error; - fn try_from(s: String) -> Result { + fn try_from(s: String) -> Result { match s.as_ref() { "9a" => Ok(SlotId::Authentication), "9c" => Ok(SlotId::Signature), @@ -209,7 +205,7 @@ pub enum RetiredSlotId { impl TryFrom for RetiredSlotId { type Error = Error; - fn try_from(value: u8) -> Result { + fn try_from(value: u8) -> Result { match value { 0x82 => Ok(RetiredSlotId::R1), 0x83 => Ok(RetiredSlotId::R2), @@ -239,7 +235,7 @@ impl TryFrom for RetiredSlotId { impl TryFrom for RetiredSlotId { type Error = Error; - fn try_from(value: String) -> Result { + fn try_from(value: String) -> Result { match value.as_ref() { "82" => Ok(RetiredSlotId::R1), "83" => Ok(RetiredSlotId::R2), @@ -365,7 +361,7 @@ pub enum AlgorithmId { impl TryFrom for AlgorithmId { type Error = Error; - fn try_from(value: u8) -> Result { + fn try_from(value: u8) -> Result { match value { 0x06 => Ok(AlgorithmId::Rsa1024), 0x07 => Ok(AlgorithmId::Rsa2048), @@ -389,7 +385,7 @@ impl From for u8 { impl AlgorithmId { /// Writes the `AlgorithmId` in the format the YubiKey expects during key generation. - pub(crate) fn write(self, buf: &mut [u8]) -> Result { + pub(crate) fn write(self, buf: &mut [u8]) -> Result { Tlv::write(buf, 0x80, &[self.into()]) } @@ -424,7 +420,7 @@ pub struct Key { impl Key { /// List Personal Identity Verification (PIV) keys stored in a YubiKey - pub fn list(yubikey: &mut YubiKey) -> Result, Error> { + pub fn list(yubikey: &mut YubiKey) -> Result> { let mut keys = vec![]; let txn = yubikey.begin_transaction()?; @@ -465,7 +461,7 @@ pub fn generate( algorithm: AlgorithmId, pin_policy: PinPolicy, touch_policy: TouchPolicy, -) -> Result { +) -> Result { // Keygen messages // TODO(tarcieri): extract these into an I18N-handling type? const SZ_SETTING_ROCA: &str = "Enable_Unsafe_Keygen_ROCA"; @@ -671,7 +667,7 @@ fn write_key( pin_policy: PinPolicy, touch_policy: TouchPolicy, algorithm: AlgorithmId, -) -> Result<(), Error> { +) -> Result<()> { let mut key_data = Buffer::new(vec![0u8; KEYDATA_LEN]); let templ = [0, Ins::ImportKey.code(), algorithm.into(), slot.into()]; let mut offset = 0; @@ -780,7 +776,7 @@ pub fn import_rsa_key( key_data: RsaKeyData, touch_policy: TouchPolicy, pin_policy: PinPolicy, -) -> Result<(), Error> { +) -> Result<()> { match algorithm { AlgorithmId::Rsa1024 | AlgorithmId::Rsa2048 => (), _ => return Err(Error::AlgorithmError), @@ -814,7 +810,7 @@ pub fn import_ecc_key( key_data: &[u8], touch_policy: TouchPolicy, pin_policy: PinPolicy, -) -> Result<(), Error> { +) -> Result<()> { match algorithm { AlgorithmId::EccP256 | AlgorithmId::EccP384 => (), _ => return Err(Error::AlgorithmError), @@ -834,7 +830,7 @@ pub fn import_ecc_key( /// Generate an attestation certificate for a stored key. /// #[cfg(feature = "untested")] -pub fn attest(yubikey: &mut YubiKey, key: SlotId) -> Result { +pub fn attest(yubikey: &mut YubiKey, key: SlotId) -> Result { let templ = [0, Ins::Attest.code(), key.into(), 0]; let txn = yubikey.begin_transaction()?; let response = txn.transfer_data(&templ, &[], CB_OBJ_MAX)?; @@ -860,7 +856,7 @@ pub fn sign_data( raw_in: &[u8], algorithm: AlgorithmId, key: SlotId, -) -> Result { +) -> Result { let txn = yubikey.begin_transaction()?; // don't attempt to reselect in crypt operations to avoid problems with PIN_ALWAYS @@ -874,7 +870,7 @@ pub fn decrypt_data( input: &[u8], algorithm: AlgorithmId, key: SlotId, -) -> Result { +) -> Result { let txn = yubikey.begin_transaction()?; // don't attempt to reselect in crypt operations to avoid problems with PIN_ALWAYS diff --git a/src/lib.rs b/src/lib.rs index bdff8ff0..e2946df7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -149,7 +149,7 @@ mod transaction; pub mod yubikey; pub use self::{ - error::Error, + error::{Error, Result}, key::Key, mgm::MgmKey, readers::Readers, diff --git a/src/metadata.rs b/src/metadata.rs index b9ccb539..9415cb6b 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -33,7 +33,7 @@ use std::marker::PhantomData; use zeroize::Zeroizing; -use crate::{error::Error, serialization::*, transaction::Transaction, Buffer}; +use crate::{serialization::*, transaction::Transaction, Buffer, Error, Result}; #[cfg(feature = "untested")] use crate::{CB_OBJ_MAX, CB_OBJ_TAG_MAX}; @@ -78,7 +78,7 @@ impl Default for Metadata { impl Metadata { /// Read metadata - pub(crate) fn read(txn: &Transaction<'_>) -> Result { + pub(crate) fn read(txn: &Transaction<'_>) -> Result { let data = txn.fetch_object(T::obj_id())?; Ok(Metadata { inner: Tlv::parse_single(data, T::tag())?, @@ -88,7 +88,7 @@ impl Metadata { /// Write metadata #[cfg(feature = "untested")] - pub(crate) fn write(&self, txn: &Transaction<'_>) -> Result<(), Error> { + pub(crate) fn write(&self, txn: &Transaction<'_>) -> Result<()> { if self.inner.len() > CB_OBJ_MAX - CB_OBJ_TAG_MAX { return Err(Error::GenericError); } @@ -105,12 +105,12 @@ impl Metadata { /// Delete metadata #[cfg(feature = "untested")] - pub(crate) fn delete(txn: &Transaction<'_>) -> Result<(), Error> { + pub(crate) fn delete(txn: &Transaction<'_>) -> Result<()> { txn.save_object(T::obj_id(), &[]) } /// Get metadata item - pub(crate) fn get_item(&self, tag: u8) -> Result<&[u8], Error> { + pub(crate) fn get_item(&self, tag: u8) -> Result<&[u8]> { let mut data = &self.inner[..]; while !data.is_empty() { @@ -128,7 +128,7 @@ impl Metadata { /// Set metadata item #[cfg(feature = "untested")] - pub(crate) fn set_item(&mut self, tag: u8, item: &[u8]) -> Result<(), Error> { + pub(crate) fn set_item(&mut self, tag: u8, item: &[u8]) -> Result<()> { let mut cb_temp: usize = 0; let mut tag_temp: u8 = 0; let mut cb_len: usize = 0; diff --git a/src/mgm.rs b/src/mgm.rs index 228a12e6..2c176d41 100644 --- a/src/mgm.rs +++ b/src/mgm.rs @@ -30,7 +30,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::error::Error; +use crate::{Error, Result}; use getrandom::getrandom; use log::error; use std::convert::{TryFrom, TryInto}; @@ -97,7 +97,7 @@ pub struct MgmKey([u8; DES_LEN_3DES]); impl MgmKey { /// Generate a random MGM key - pub fn generate() -> Result { + pub fn generate() -> Result { let mut key_bytes = [0u8; DES_LEN_3DES]; if getrandom(&mut key_bytes).is_err() { @@ -110,14 +110,14 @@ impl MgmKey { /// Create an MGM key from byte slice. /// /// Returns an error if the slice is the wrong size or the key is weak. - pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { + pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { bytes.as_ref().try_into() } /// Create an MGM key from the given byte array. /// /// Returns an error if the key is weak. - pub fn new(key_bytes: [u8; DES_LEN_3DES]) -> Result { + pub fn new(key_bytes: [u8; DES_LEN_3DES]) -> Result { if is_weak_key(&key_bytes) { error!( "blacklisting key '{:?}' since it's weak (with odd parity)", @@ -132,7 +132,7 @@ impl MgmKey { /// Get derived management key (MGM) #[cfg(feature = "untested")] - pub fn get_derived(yubikey: &mut YubiKey, pin: &[u8]) -> Result { + pub fn get_derived(yubikey: &mut YubiKey, pin: &[u8]) -> Result { let txn = yubikey.begin_transaction()?; // recover management key @@ -157,7 +157,7 @@ impl MgmKey { /// Get protected management key (MGM) #[cfg(feature = "untested")] - pub fn get_protected(yubikey: &mut YubiKey) -> Result { + pub fn get_protected(yubikey: &mut YubiKey) -> Result { let txn = yubikey.begin_transaction()?; let protected_data = ProtectedData::read(&txn).map_err(|e| { @@ -187,7 +187,7 @@ impl MgmKey { /// /// This will wipe any metadata related to derived and PIN-protected management keys. #[cfg(feature = "untested")] - pub fn set_default(yubikey: &mut YubiKey) -> Result<(), Error> { + pub fn set_default(yubikey: &mut YubiKey) -> Result<()> { MgmKey::default().set_manual(yubikey, false) } @@ -198,7 +198,7 @@ impl MgmKey { /// /// This will wipe any metadata related to derived and PIN-protected management keys. #[cfg(feature = "untested")] - pub fn set_manual(&self, yubikey: &mut YubiKey, require_touch: bool) -> Result<(), Error> { + pub fn set_manual(&self, yubikey: &mut YubiKey, require_touch: bool) -> Result<()> { let txn = yubikey.begin_transaction()?; txn.set_mgm_key(&self, require_touch).map_err(|e| { @@ -257,7 +257,7 @@ impl MgmKey { /// /// This enables key management operations to be performed with access to the PIN. #[cfg(feature = "untested")] - pub fn set_protected(&self, yubikey: &mut YubiKey) -> Result<(), Error> { + pub fn set_protected(&self, yubikey: &mut YubiKey) -> Result<()> { let txn = yubikey.begin_transaction()?; txn.set_mgm_key(self, false).map_err(|e| { @@ -364,7 +364,7 @@ impl Drop for MgmKey { impl<'a> TryFrom<&'a [u8]> for MgmKey { type Error = Error; - fn try_from(key_bytes: &'a [u8]) -> Result { + fn try_from(key_bytes: &'a [u8]) -> Result { Self::new(key_bytes.try_into().map_err(|_| Error::SizeError)?) } } diff --git a/src/mscmap.rs b/src/mscmap.rs index d866e499..63b0def8 100644 --- a/src/mscmap.rs +++ b/src/mscmap.rs @@ -33,7 +33,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::{error::Error, key::SlotId, serialization::*, yubikey::YubiKey, CB_OBJ_MAX}; +use crate::{key::SlotId, serialization::*, Error, Result, YubiKey, CB_OBJ_MAX}; use log::error; use std::convert::{TryFrom, TryInto}; @@ -77,7 +77,7 @@ pub struct Container { impl Container { /// Read MS Container Map records - pub fn read_mscmap(yubikey: &mut YubiKey) -> Result, Error> { + pub fn read_mscmap(yubikey: &mut YubiKey) -> Result> { let txn = yubikey.begin_transaction()?; let response = txn.fetch_object(OBJ_MSCMAP)?; let mut containers = vec![]; @@ -103,7 +103,7 @@ impl Container { } /// Write MS Container Map records. - pub fn write_mscmap(yubikey: &mut YubiKey, containers: &[Self]) -> Result<(), Error> { + pub fn write_mscmap(yubikey: &mut YubiKey, containers: &[Self]) -> Result<()> { let n_containers = containers.len(); let data_len = n_containers * CONTAINER_REC_LEN; @@ -124,7 +124,7 @@ impl Container { } /// Parse a container record from a byte slice - pub fn new(bytes: &[u8]) -> Result { + pub fn new(bytes: &[u8]) -> Result { if bytes.len() != CONTAINER_REC_LEN { error!( "couldn't parse PIV container: expected {}-bytes, got {}-bytes", @@ -161,7 +161,7 @@ impl Container { } /// Parse the container name as a UTF-16 string - pub fn parse_name(&self) -> Result { + pub fn parse_name(&self) -> Result { String::from_utf16(&self.name).map_err(|_| Error::ParseError) } @@ -188,7 +188,7 @@ impl Container { impl<'a> TryFrom<&'a [u8]> for Container { type Error = Error; - fn try_from(bytes: &'a [u8]) -> Result { + fn try_from(bytes: &'a [u8]) -> Result { Self::new(bytes) } } diff --git a/src/msroots.rs b/src/msroots.rs index b7d65b73..6c8a027e 100644 --- a/src/msroots.rs +++ b/src/msroots.rs @@ -37,7 +37,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::{error::Error, serialization::*, yubikey::YubiKey}; +use crate::{serialization::*, Error, Result, YubiKey}; use crate::{CB_OBJ_MAX, CB_OBJ_TAG_MAX}; use log::error; @@ -58,12 +58,12 @@ pub struct MsRoots(Vec); impl MsRoots { /// Initialize a local certificate struct from the given bytebuffer - pub fn new(msroots: impl AsRef<[u8]>) -> Result { + pub fn new(msroots: impl AsRef<[u8]>) -> Result { Ok(MsRoots(msroots.as_ref().into())) } /// Read `msroots` file from YubiKey - pub fn read(yubikey: &mut YubiKey) -> Result, Error> { + pub fn read(yubikey: &mut YubiKey) -> Result> { let txn = yubikey.begin_transaction()?; // allocate first page @@ -100,7 +100,7 @@ impl MsRoots { } /// Write `msroots` file to YubiKey - pub fn write(&self, yubikey: &mut YubiKey) -> Result<(), Error> { + pub fn write(&self, yubikey: &mut YubiKey) -> Result<()> { let mut buf = [0u8; CB_OBJ_MAX]; let mut offset: usize; let mut data_offset: usize = 0; diff --git a/src/policy.rs b/src/policy.rs index b67674e5..f891743f 100644 --- a/src/policy.rs +++ b/src/policy.rs @@ -1,6 +1,6 @@ //! Enums representing key policies. -use crate::{error::Error, serialization::Tlv}; +use crate::{serialization::Tlv, Result}; /// Specifies how often the PIN needs to be entered for access to the credential in a /// given slot. This policy must be set upon key generation or importation, and cannot be @@ -37,7 +37,7 @@ impl From for u8 { impl PinPolicy { /// Writes the `PinPolicy` in the format the YubiKey expects during key generation or /// importation. - pub(crate) fn write(self, buf: &mut [u8]) -> Result { + pub(crate) fn write(self, buf: &mut [u8]) -> Result { match self { PinPolicy::Default => Ok(0), _ => Tlv::write(buf, 0xaa, &[self.into()]), @@ -81,7 +81,7 @@ impl From for u8 { impl TouchPolicy { /// Writes the `TouchPolicy` in the format the YubiKey expects during key generation /// or importation. - pub(crate) fn write(self, buf: &mut [u8]) -> Result { + pub(crate) fn write(self, buf: &mut [u8]) -> Result { match self { TouchPolicy::Default => Ok(0), _ => Tlv::write(buf, 0xab, &[self.into()]), diff --git a/src/readers.rs b/src/readers.rs index b5051872..7daf89b0 100644 --- a/src/readers.rs +++ b/src/readers.rs @@ -1,6 +1,6 @@ //! Support for enumerating available readers -use crate::{error::Error, yubikey::YubiKey}; +use crate::{Result, YubiKey}; use std::{ borrow::Cow, convert::TryInto, @@ -23,7 +23,7 @@ pub struct Readers { impl Readers { /// Open a PC/SC context, which can be used to enumerate available PC/SC /// readers (which can be used to connect to YubiKeys). - pub fn open() -> Result { + pub fn open() -> Result { let ctx = pcsc::Context::establish(pcsc::Scope::System)?; let reader_names = vec![0u8; ctx.list_readers_len()?]; Ok(Self { @@ -33,7 +33,7 @@ impl Readers { } /// Iterate over the available readers - pub fn iter(&mut self) -> Result, Error> { + pub fn iter(&mut self) -> Result> { let Self { ctx, reader_names } = self; let reader_cstrs: Vec<_> = { @@ -77,12 +77,12 @@ impl<'ctx> Reader<'ctx> { } /// Open a connection to this reader, returning a `YubiKey` if successful - pub fn open(&self) -> Result { + pub fn open(&self) -> Result { self.try_into() } /// Connect to this reader, returning its `pcsc::Card` - pub(crate) fn connect(&self) -> Result { + pub(crate) fn connect(&self) -> Result { let ctx = self.ctx.lock().unwrap(); Ok(ctx.connect(self.name, pcsc::ShareMode::Shared, pcsc::Protocols::T1)?) } diff --git a/src/serialization.rs b/src/serialization.rs index 9bde6e4e..d6c89f8d 100644 --- a/src/serialization.rs +++ b/src/serialization.rs @@ -30,7 +30,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::{error::Error, Buffer, ObjectId, CB_OBJ_TAG_MIN}; +use crate::{Buffer, Error, ObjectId, Result, CB_OBJ_TAG_MIN}; pub const OBJ_DISCOVERY: u32 = 0x7e; @@ -44,7 +44,7 @@ pub(crate) struct Tlv<'a> { impl<'a> Tlv<'a> { /// Parses a `Tlv` from a buffer, returning the remainder of the buffer. - pub(crate) fn parse(buffer: &'a [u8]) -> Result<(&'a [u8], Self), Error> { + pub(crate) fn parse(buffer: &'a [u8]) -> Result<(&'a [u8], Self)> { if buffer.len() < CB_OBJ_TAG_MIN || !has_valid_length(&buffer[1..], buffer.len() - 1) { return Err(Error::SizeError); } @@ -61,7 +61,7 @@ impl<'a> Tlv<'a> { /// Takes a [`Buffer`] containing a single `Tlv` with the given tag, and returns a /// `Buffer` containing only the value part of the `Tlv`. - pub(crate) fn parse_single(mut buffer: Buffer, tag: u8) -> Result { + pub(crate) fn parse_single(mut buffer: Buffer, tag: u8) -> Result { if buffer.len() < CB_OBJ_TAG_MIN || !has_valid_length(&buffer[1..], buffer.len() - 1) { return Err(Error::SizeError); } @@ -79,7 +79,7 @@ impl<'a> Tlv<'a> { } /// Writes a TLV to the given buffer. - pub(crate) fn write(buffer: &mut [u8], tag: u8, value: &[u8]) -> Result { + pub(crate) fn write(buffer: &mut [u8], tag: u8, value: &[u8]) -> Result { if buffer.len() < CB_OBJ_TAG_MIN { return Err(Error::SizeError); } @@ -103,7 +103,7 @@ impl<'a> Tlv<'a> { tag: u8, length: usize, value: Gen, - ) -> Result + ) -> Result where Gen: FnOnce(&mut [u8]), { @@ -124,7 +124,7 @@ impl<'a> Tlv<'a> { } /// Set length -pub(crate) fn set_length(buffer: &mut [u8], length: usize) -> Result { +pub(crate) fn set_length(buffer: &mut [u8], length: usize) -> Result { if length < 0x80 { if buffer.is_empty() { Err(Error::SizeError) diff --git a/src/transaction.rs b/src/transaction.rs index 187b8c65..8116f8a4 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -3,7 +3,7 @@ use crate::{ apdu::Response, apdu::{Apdu, Ins, StatusWords}, - error::Error, + error::{Error, Result}, key::{AlgorithmId, SlotId}, serialization::*, yubikey::*, @@ -32,7 +32,7 @@ pub(crate) struct Transaction<'tx> { impl<'tx> Transaction<'tx> { /// Create a new transaction with the given card. - pub fn new(card: &'tx mut pcsc::Card) -> Result { + pub fn new(card: &'tx mut pcsc::Card) -> Result { Ok(Transaction { inner: card.transaction()?, }) @@ -45,7 +45,7 @@ impl<'tx> Transaction<'tx> { /// single APDU messages at a time. For larger messages that need to be /// split into multiple APDUs, use the [`Transaction::transfer_data`] /// method instead. - pub fn transmit(&self, send_buffer: &[u8], recv_len: usize) -> Result, Error> { + pub fn transmit(&self, send_buffer: &[u8], recv_len: usize) -> Result> { trace!(">>> {:?}", send_buffer); let mut recv_buffer = vec![0u8; recv_len]; @@ -60,7 +60,7 @@ impl<'tx> Transaction<'tx> { } /// Select application. - pub fn select_application(&self) -> Result<(), Error> { + pub fn select_application(&self) -> Result<()> { let response = Apdu::new(Ins::SelectApplication) .p1(0x04) .data(&PIV_AID) @@ -82,7 +82,7 @@ impl<'tx> Transaction<'tx> { } /// Get the version of the PIV application installed on the YubiKey. - pub fn get_version(&self) -> Result { + pub fn get_version(&self) -> Result { // get version from device let response = Apdu::new(Ins::GetVersion).transmit(self, 261)?; @@ -98,7 +98,7 @@ impl<'tx> Transaction<'tx> { } /// Get YubiKey device serial number. - pub fn get_serial(&self, version: Version) -> Result { + pub fn get_serial(&self, version: Version) -> Result { let response = if version.major < 5 { // YK4 requires switching to the yk applet to retrieve the serial let sw = Apdu::new(Ins::SelectApplication) @@ -157,7 +157,7 @@ impl<'tx> Transaction<'tx> { } /// Verify device PIN. - pub fn verify_pin(&self, pin: &[u8]) -> Result<(), Error> { + pub fn verify_pin(&self, pin: &[u8]) -> Result<()> { if pin.len() > CB_PIN_MAX { return Err(Error::SizeError); } @@ -191,7 +191,7 @@ impl<'tx> Transaction<'tx> { action: ChangeRefAction, current_pin: &[u8], new_pin: &[u8], - ) -> Result<(), Error> { + ) -> Result<()> { if current_pin.len() > CB_PIN_MAX || new_pin.len() > CB_PIN_MAX { return Err(Error::SizeError); } @@ -229,7 +229,7 @@ impl<'tx> Transaction<'tx> { /// Set the management key (MGM). #[cfg(feature = "untested")] - pub fn set_mgm_key(&self, new_key: &MgmKey, require_touch: bool) -> Result<(), Error> { + pub fn set_mgm_key(&self, new_key: &MgmKey, require_touch: bool) -> Result<()> { let p2 = if require_touch { 0xfe } else { 0xff }; let mut data = [0u8; DES_LEN_3DES + 3]; @@ -263,7 +263,7 @@ impl<'tx> Transaction<'tx> { algorithm: AlgorithmId, key: SlotId, decipher: bool, - ) -> Result { + ) -> Result { let in_len = sign_in.len(); let mut indata = [0u8; 1024]; let templ = [0, Ins::Authenticate.code(), algorithm.into(), key.into()]; @@ -358,12 +358,7 @@ impl<'tx> Transaction<'tx> { /// messages into smaller APDU-sized messages (using the provided APDU /// template to construct them), and then sending those via /// [`Transaction::transmit`]. - pub fn transfer_data( - &self, - templ: &[u8], - in_data: &[u8], - max_out: usize, - ) -> Result { + pub fn transfer_data(&self, templ: &[u8], in_data: &[u8], max_out: usize) -> Result { let mut in_offset = 0; let mut out_data = vec![]; let mut sw; @@ -441,7 +436,7 @@ impl<'tx> Transaction<'tx> { } /// Fetch an object. - pub fn fetch_object(&self, object_id: ObjectId) -> Result { + pub fn fetch_object(&self, object_id: ObjectId) -> Result { let mut indata = [0u8; 5]; let templ = [0, Ins::GetData.code(), 0x3f, 0xff]; @@ -475,7 +470,7 @@ impl<'tx> Transaction<'tx> { } /// Save an object. - pub fn save_object(&self, object_id: ObjectId, indata: &[u8]) -> Result<(), Error> { + pub fn save_object(&self, object_id: ObjectId, indata: &[u8]) -> Result<()> { let templ = [0, Ins::PutData.code(), 0x3f, 0xff]; // TODO(tarcieri): replace with vector diff --git a/src/yubikey.rs b/src/yubikey.rs index 59385f46..44469e00 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -35,7 +35,7 @@ use crate::{ cccid::Ccc, chuid::ChuId, config::Config, - error::Error, + error::{Error, Result}, mgm::MgmKey, readers::{Reader, Readers}, transaction::Transaction, @@ -92,7 +92,7 @@ impl From for u32 { impl FromStr for Serial { type Err = Error; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { u32::from_str(s).map(Serial).map_err(|_| Error::ParseError) } } @@ -157,7 +157,7 @@ impl YubiKey { /// attached to the same system, use [`YubiKey::open_by_serial`] or /// [`yubikey::Readers`][`Readers`] to select from the available /// PC/SC readers. - pub fn open() -> Result { + pub fn open() -> Result { let mut readers = Readers::open().map_err(|e| match e { Error::PcscError { inner: Some(pcsc::Error::NoReadersAvailable), @@ -180,7 +180,7 @@ impl YubiKey { } /// Open a YubiKey with a specific serial number. - pub fn open_by_serial(serial: Serial) -> Result { + pub fn open_by_serial(serial: Serial) -> Result { let mut readers = Readers::open().map_err(|e| match e { Error::PcscError { inner: Some(pcsc::Error::NoReadersAvailable), @@ -205,7 +205,7 @@ impl YubiKey { /// Reconnect to a YubiKey #[cfg(feature = "untested")] - pub fn reconnect(&mut self) -> Result<(), Error> { + pub fn reconnect(&mut self) -> Result<()> { info!("trying to reconnect to current reader"); self.card.reconnect( @@ -230,7 +230,7 @@ impl YubiKey { } /// Begin a transaction. - pub(crate) fn begin_transaction(&mut self) -> Result, Error> { + pub(crate) fn begin_transaction(&mut self) -> Result> { // TODO(tarcieri): reconnect support Transaction::new(&mut self.card) } @@ -255,22 +255,22 @@ impl YubiKey { } /// Get device configuration. - pub fn config(&mut self) -> Result { + pub fn config(&mut self) -> Result { Config::get(self) } /// Get CHUID - pub fn chuid(&mut self) -> Result { + pub fn chuid(&mut self) -> Result { ChuId::get(self) } /// Get CCCID - pub fn cccid(&mut self) -> Result { + pub fn cccid(&mut self) -> Result { Ccc::get(self) } /// Authenticate to the card using the provided management key (MGM). - pub fn authenticate(&mut self, mgm_key: MgmKey) -> Result<(), Error> { + pub fn authenticate(&mut self, mgm_key: MgmKey) -> Result<()> { let txn = self.begin_transaction()?; // get a challenge from the card @@ -325,7 +325,7 @@ impl YubiKey { /// Deauthenticate #[cfg(feature = "untested")] - pub fn deauthenticate(&mut self) -> Result<(), Error> { + pub fn deauthenticate(&mut self) -> Result<()> { let txn = self.begin_transaction()?; let status_words = Apdu::new(Ins::SelectApplication) @@ -346,7 +346,7 @@ impl YubiKey { } /// Verify device PIN. - pub fn verify_pin(&mut self, pin: &[u8]) -> Result<(), Error> { + pub fn verify_pin(&mut self, pin: &[u8]) -> Result<()> { { let txn = self.begin_transaction()?; txn.verify_pin(pin)?; @@ -360,7 +360,7 @@ impl YubiKey { } /// Get the number of PIN retries - pub fn get_pin_retries(&mut self) -> Result { + pub fn get_pin_retries(&mut self) -> Result { let txn = self.begin_transaction()?; // Force a re-select to unverify, because once verified the spec dictates that @@ -378,7 +378,7 @@ impl YubiKey { /// Set the number of PIN retries #[cfg(feature = "untested")] - pub fn set_pin_retries(&mut self, pin_tries: u8, puk_tries: u8) -> Result<(), Error> { + pub fn set_pin_retries(&mut self, pin_tries: u8, puk_tries: u8) -> Result<()> { // Special case: if either retry count is 0, it's a successful no-op if pin_tries == 0 || puk_tries == 0 { return Ok(()); @@ -402,7 +402,7 @@ impl YubiKey { /// /// The default PIN code is 123456 #[cfg(feature = "untested")] - pub fn change_pin(&mut self, current_pin: &[u8], new_pin: &[u8]) -> Result<(), Error> { + pub fn change_pin(&mut self, current_pin: &[u8], new_pin: &[u8]) -> Result<()> { { let txn = self.begin_transaction()?; txn.change_ref(ChangeRefAction::ChangePin, current_pin, new_pin)?; @@ -417,7 +417,7 @@ impl YubiKey { /// Set PIN last changed #[cfg(feature = "untested")] - pub fn set_pin_last_changed(yubikey: &mut YubiKey) -> Result<(), Error> { + pub fn set_pin_last_changed(yubikey: &mut YubiKey) -> Result<()> { let txn = yubikey.begin_transaction()?; let mut admin_data = AdminData::read(&txn)?; @@ -452,14 +452,14 @@ impl YubiKey { /// /// The default PUK code is 12345678. #[cfg(feature = "untested")] - pub fn change_puk(&mut self, current_puk: &[u8], new_puk: &[u8]) -> Result<(), Error> { + pub fn change_puk(&mut self, current_puk: &[u8], new_puk: &[u8]) -> Result<()> { let txn = self.begin_transaction()?; txn.change_ref(ChangeRefAction::ChangePuk, current_puk, new_puk) } /// Block PUK: permanently prevent the PIN from becoming unblocked #[cfg(feature = "untested")] - pub fn block_puk(yubikey: &mut YubiKey) -> Result<(), Error> { + pub fn block_puk(yubikey: &mut YubiKey) -> Result<()> { let mut puk = [0x30, 0x42, 0x41, 0x44, 0x46, 0x30, 0x30, 0x44]; let mut tries_remaining: i32 = -1; let mut flags = [0]; @@ -523,28 +523,28 @@ impl YubiKey { /// Unblock a Personal Identification Number (PIN) using a previously /// configured PIN Unblocking Key (PUK). #[cfg(feature = "untested")] - pub fn unblock_pin(&mut self, puk: &[u8], new_pin: &[u8]) -> Result<(), Error> { + pub fn unblock_pin(&mut self, puk: &[u8], new_pin: &[u8]) -> Result<()> { let txn = self.begin_transaction()?; txn.change_ref(ChangeRefAction::UnblockPin, puk, new_pin) } /// Fetch an object from the YubiKey #[cfg(feature = "untested")] - pub fn fetch_object(&mut self, object_id: ObjectId) -> Result { + pub fn fetch_object(&mut self, object_id: ObjectId) -> Result { let txn = self.begin_transaction()?; txn.fetch_object(object_id) } /// Save an object #[cfg(feature = "untested")] - pub fn save_object(&mut self, object_id: ObjectId, indata: &mut [u8]) -> Result<(), Error> { + pub fn save_object(&mut self, object_id: ObjectId, indata: &mut [u8]) -> Result<()> { let txn = self.begin_transaction()?; txn.save_object(object_id, indata) } /// Get an auth challenge #[cfg(feature = "untested")] - pub fn get_auth_challenge(&mut self) -> Result<[u8; 8], Error> { + pub fn get_auth_challenge(&mut self) -> Result<[u8; 8]> { let txn = self.begin_transaction()?; let response = Apdu::new(Ins::Authenticate) @@ -561,7 +561,7 @@ impl YubiKey { /// Verify an auth response #[cfg(feature = "untested")] - pub fn verify_auth_response(&mut self, response: [u8; 8]) -> Result<(), Error> { + pub fn verify_auth_response(&mut self, response: [u8; 8]) -> Result<()> { let mut data = [0u8; 12]; data[0] = 0x7c; data[1] = 0x0a; @@ -591,7 +591,7 @@ impl YubiKey { /// /// The reset function is only available when both pins are blocked. #[cfg(feature = "untested")] - pub fn reset_device(&mut self) -> Result<(), Error> { + pub fn reset_device(&mut self) -> Result<()> { let templ = [0, Ins::Reset.code(), 0, 0]; let txn = self.begin_transaction()?; let status_words = txn.transfer_data(&templ, &[], 255)?.status_words(); @@ -607,7 +607,7 @@ impl YubiKey { impl<'a> TryFrom<&'a Reader<'_>> for YubiKey { type Error = Error; - fn try_from(reader: &'a Reader<'_>) -> Result { + fn try_from(reader: &'a Reader<'_>) -> Result { let mut card = reader.connect().map_err(|e| { error!("error connecting to reader '{}': {}", reader.name(), e); e